add https server functionality - befor auth functionality implementation

This commit is contained in:
2025-10-23 11:41:03 +06:00
parent 3e1cb1e078
commit e1bd79db8c
27 changed files with 2164 additions and 97 deletions

View File

@@ -11,6 +11,15 @@ var ExecutePageScriptsTemplate = template.Must(template.New("execute_scripts").P
e.preventDefault();
return false;
}
// Валидация длины полей
const prompt = document.getElementById('prompt').value;
const maxUserMessageLength = {{.MaxUserMessageLength}};
if (prompt.length > maxUserMessageLength) {
alert('Пользовательское сообщение слишком длинное: максимум ' + maxUserMessageLength + ' символов');
e.preventDefault();
return false;
}
this.dataset.submitting = 'true';
const submitBtn = document.getElementById('submitBtn');
const loading = document.getElementById('loading');

View File

@@ -7,13 +7,13 @@ const FileViewTemplate = `
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>%s - LCG Results</title>
<title>{{.Filename}} - LCG Results</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
margin: 0;
padding: 20px;
background: linear-gradient(135deg, #56ab2f 0%%, #a8e6cf 100%%);
background: linear-gradient(135deg, #56ab2f 0%, #a8e6cf 100%);
min-height: 100vh;
}
.container {
@@ -25,7 +25,7 @@ const FileViewTemplate = `
overflow: hidden;
}
.header {
background: linear-gradient(135deg, #2d5016 0%%, #4a7c59 100%%);
background: linear-gradient(135deg, #2d5016 0%, #4a7c59 100%);
color: white;
padding: 20px 30px;
display: flex;
@@ -125,11 +125,11 @@ const FileViewTemplate = `
<body>
<div class="container">
<div class="header">
<h1>📄 %s</h1>
<h1>📄 {{.Filename}}</h1>
<a href="/" class="back-btn">← Назад к списку</a>
</div>
<div class="content">
%s
{{.Content}}
</div>
</div>
</body>

View File

@@ -143,6 +143,7 @@ const HistoryPageTemplate = `
.history-header { flex-direction: column; align-items: flex-start; gap: 8px; }
.history-item { padding: 15px; }
.history-response { font-size: 0.85em; }
.search-container input { font-size: 16px; width: 96% !important; }
}
@media (max-width: 480px) {

View File

@@ -7,13 +7,13 @@ const HistoryViewTemplate = `
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Запись #%d - LCG History</title>
<title>Запись #{{.Index}} - LCG History</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
margin: 0;
padding: 20px;
background: linear-gradient(135deg, #56ab2f 0%%, #a8e6cf 100%%);
background: linear-gradient(135deg, #56ab2f 0%, #a8e6cf 100%);
min-height: 100vh;
}
.container {
@@ -25,7 +25,7 @@ const HistoryViewTemplate = `
overflow: hidden;
}
.header {
background: linear-gradient(135deg, #2d5016 0%%, #4a7c59 100%%);
background: linear-gradient(135deg, #2d5016 0%, #4a7c59 100%);
color: white;
padding: 20px 30px;
display: flex;
@@ -212,7 +212,7 @@ const HistoryViewTemplate = `
.back-btn { padding: 6px 12px; font-size: 0.9em; }
.content { padding: 20px; }
.actions { flex-direction: column; }
.action-btn { width: 100%; text-align: center; }
.action-btn { text-align: center; }
.history-response-content { font-size: 0.9em; }
}
@media (max-width: 480px) {
@@ -223,34 +223,34 @@ const HistoryViewTemplate = `
<body>
<div class="container">
<div class="header">
<h1>📝 Запись #%d</h1>
<h1>📝 Запись #{{.Index}}</h1>
<a href="/history" class="back-btn">← Назад к истории</a>
</div>
<div class="content">
<div class="history-meta">
<div class="history-meta-item">
<span class="history-meta-label">📅 Время:</span> %s
<span class="history-meta-label">📅 Время:</span> {{.Timestamp}}
</div>
<div class="history-meta-item">
<span class="history-meta-label">🔢 Индекс:</span> #%d
<span class="history-meta-label">🔢 Индекс:</span> #{{.Index}}
</div>
</div>
<div class="history-command">
<h3>💬 Запрос пользователя:</h3>
<div class="history-command-text">%s</div>
<div class="history-command-text">{{.Command}}</div>
</div>
<div class="history-response">
<h3>🤖 Ответ Модели:</h3>
<div class="history-response-content">%s</div>
<div class="history-response-content">{{.Response}}</div>
</div>
%s
{{.ExplanationHTML}}
<div class="actions">
<a href="/history" class="action-btn">📝 К истории</a>
<button class="action-btn delete-btn" onclick="deleteHistoryEntry(%d)">🗑️ Удалить запись</button>
<button class="action-btn delete-btn" onclick="deleteHistoryEntry({{.Index}})">🗑️ Удалить запись</button>
</div>
</div>
</div>

View File

@@ -407,7 +407,12 @@ const PromptsPageTemplate = `
function editVerbosePrompt(mode, content) {
// Редактирование промпта подробности
alert('Редактирование промптов подробности будет реализовано');
document.getElementById('formTitle').textContent = 'Редактировать промпт подробности (' + mode + ')';
document.getElementById('promptId').value = mode;
document.getElementById('promptName').value = mode;
document.getElementById('promptDescription').value = 'Промпт для режима ' + mode;
document.getElementById('promptContent').value = content;
document.getElementById('promptForm').style.display = 'block';
}
function deletePrompt(id) {
@@ -432,10 +437,42 @@ const PromptsPageTemplate = `
document.getElementById('promptFormData').addEventListener('submit', function(e) {
e.preventDefault();
// Валидация длины полей
const name = document.getElementById('promptName').value;
const description = document.getElementById('promptDescription').value;
const content = document.getElementById('promptContent').value;
const maxContentLength = {{.MaxSystemPromptLength}};
const maxNameLength = {{.MaxPromptNameLength}};
const maxDescLength = {{.MaxPromptDescLength}};
if (content.length > maxContentLength) {
alert('Содержимое промпта слишком длинное: максимум ' + maxContentLength + ' символов');
return;
}
if (name.length > maxNameLength) {
alert('Название промпта слишком длинное: максимум ' + maxNameLength + ' символов');
return;
}
if (description.length > maxDescLength) {
alert('Описание промпта слишком длинное: максимум ' + maxDescLength + ' символов');
return;
}
const formData = new FormData(this);
const id = formData.get('id');
const url = id ? '/prompts/edit/' + id : '/prompts/add';
const method = id ? 'PUT' : 'POST';
// Определяем, это системный промпт или промпт подробности
const isVerbosePrompt = ['v', 'vv', 'vvv'].includes(id);
let url, method;
if (isVerbosePrompt) {
url = '/prompts/edit-verbose/' + id;
method = 'PUT';
} else {
url = id ? '/prompts/edit/' + id : '/prompts/add';
method = id ? 'PUT' : 'POST';
}
fetch(url, {
method: method,

View File

@@ -171,7 +171,7 @@ const ResultsPageTemplate = `
.stats { grid-template-columns: 1fr 1fr; }
.nav-buttons { flex-direction: column; gap: 8px; }
.nav-btn, .nav-button { text-align: center; padding: 12px 16px; font-size: 14px; }
.search-container input { font-size: 16px; }
.search-container input { font-size: 16px; width: 96% !important; }
}
@media (max-width: 480px) {
.header h1 { font-size: 1.8em; }