update frontend
This commit is contained in:
@@ -10,6 +10,21 @@ marked.setOptions({
|
||||
mangle: false,
|
||||
});
|
||||
|
||||
// ---- Theme ----
|
||||
function initTheme() {
|
||||
const saved = localStorage.getItem('rag-theme') || 'dark';
|
||||
document.documentElement.setAttribute('data-theme', saved);
|
||||
}
|
||||
|
||||
function toggleTheme() {
|
||||
const current = document.documentElement.getAttribute('data-theme');
|
||||
const next = current === 'dark' ? 'light' : 'dark';
|
||||
document.documentElement.setAttribute('data-theme', next);
|
||||
localStorage.setItem('rag-theme', next);
|
||||
}
|
||||
|
||||
initTheme();
|
||||
|
||||
// DOM
|
||||
const sessionList = document.getElementById('session-list');
|
||||
const messages = document.getElementById('messages');
|
||||
@@ -21,6 +36,7 @@ const btnNewSession = document.getElementById('btn-new-session');
|
||||
const btnClear = document.getElementById('btn-clear');
|
||||
const btnDelete = document.getElementById('btn-delete');
|
||||
const btnMenu = document.getElementById('btn-menu');
|
||||
const btnTheme = document.getElementById('btn-theme');
|
||||
const chatTitle = document.getElementById('chat-title');
|
||||
const statsEl = document.getElementById('stats');
|
||||
|
||||
@@ -232,6 +248,7 @@ btnNewSession.onclick = createSession;
|
||||
btnClear.onclick = clearMessages;
|
||||
btnDelete.onclick = deleteSession;
|
||||
btnSend.onclick = sendMessage;
|
||||
btnTheme.onclick = toggleTheme;
|
||||
|
||||
btnMenu.onclick = () => {
|
||||
document.getElementById('sidebar').classList.toggle('open');
|
||||
|
||||
+73
-12
@@ -1,3 +1,4 @@
|
||||
/* ===== Dark theme (default) ===== */
|
||||
:root {
|
||||
--bg: #0f0f0f;
|
||||
--bg-sidebar: #161616;
|
||||
@@ -18,6 +19,34 @@
|
||||
--radius: 12px;
|
||||
--radius-sm: 8px;
|
||||
--sidebar-w: 280px;
|
||||
--footer-bg: #111;
|
||||
--footer-border: #222;
|
||||
--code-bg: #0a0a0a;
|
||||
--table-header: #ffffff08;
|
||||
}
|
||||
|
||||
/* ===== Light theme ===== */
|
||||
[data-theme="light"] {
|
||||
--bg: #ffffff;
|
||||
--bg-sidebar: #f7f7f8;
|
||||
--bg-chat: #ffffff;
|
||||
--bg-input: #f0f0f0;
|
||||
--bg-user: #2563eb;
|
||||
--bg-assistant: #f4f4f5;
|
||||
--bg-hover: #ececec;
|
||||
--bg-active: #2563eb15;
|
||||
--border: #e0e0e0;
|
||||
--text: #1a1a1a;
|
||||
--text-dim: #666;
|
||||
--text-muted: #999;
|
||||
--accent: #2563eb;
|
||||
--accent-hover: #1d4ed8;
|
||||
--danger: #dc2626;
|
||||
--danger-hover: #b91c1c;
|
||||
--footer-bg: #f7f7f8;
|
||||
--footer-border: #e0e0e0;
|
||||
--code-bg: #f0f0f0;
|
||||
--table-header: #00000008;
|
||||
}
|
||||
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
@@ -35,7 +64,7 @@ body {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
/* Sidebar */
|
||||
/* ===== Sidebar ===== */
|
||||
.sidebar {
|
||||
width: var(--sidebar-w);
|
||||
background: var(--bg-sidebar);
|
||||
@@ -59,6 +88,11 @@ body {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.sidebar-actions {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.session-list {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
@@ -111,7 +145,7 @@ body {
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* Main */
|
||||
/* ===== Main ===== */
|
||||
.main {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
@@ -139,7 +173,7 @@ body {
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
/* Messages */
|
||||
/* ===== Messages ===== */
|
||||
.messages {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
@@ -213,7 +247,7 @@ body {
|
||||
.bubble li { margin: 2px 0; }
|
||||
|
||||
.bubble code {
|
||||
background: #ffffff10;
|
||||
background: var(--code-bg);
|
||||
padding: 1px 5px;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
@@ -221,7 +255,7 @@ body {
|
||||
}
|
||||
|
||||
.bubble pre {
|
||||
background: #0a0a0a;
|
||||
background: var(--code-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 10px 12px;
|
||||
@@ -243,9 +277,10 @@ body {
|
||||
}
|
||||
|
||||
.bubble a {
|
||||
color: #60a5fa;
|
||||
color: #2563eb;
|
||||
text-decoration: none;
|
||||
}
|
||||
[data-theme="dark"] .bubble a { color: #60a5fa; }
|
||||
.bubble a:hover { text-decoration: underline; }
|
||||
|
||||
.bubble table {
|
||||
@@ -259,7 +294,7 @@ body {
|
||||
padding: 6px 10px;
|
||||
text-align: left;
|
||||
}
|
||||
.bubble th { background: #ffffff08; font-weight: 600; }
|
||||
.bubble th { background: var(--table-header); font-weight: 600; }
|
||||
|
||||
.bubble strong { font-weight: 600; }
|
||||
.bubble em { font-style: italic; }
|
||||
@@ -328,9 +363,9 @@ body {
|
||||
30% { transform: translateY(-4px); }
|
||||
}
|
||||
|
||||
/* Input */
|
||||
/* ===== Input ===== */
|
||||
.input-area {
|
||||
padding: 12px 16px 16px;
|
||||
padding: 12px 16px 12px;
|
||||
border-top: 1px solid var(--border);
|
||||
background: var(--bg-sidebar);
|
||||
}
|
||||
@@ -390,7 +425,27 @@ body {
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
/* ===== Footer ===== */
|
||||
.app-footer {
|
||||
padding: 10px 16px;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
background: var(--footer-bg);
|
||||
border-top: 1px solid var(--footer-border);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.app-footer a {
|
||||
color: var(--accent);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.app-footer a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* ===== Buttons ===== */
|
||||
.btn-icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
@@ -408,13 +463,19 @@ body {
|
||||
.btn-icon:hover { background: var(--bg-hover); color: var(--text); }
|
||||
.btn-icon.btn-danger:hover { background: var(--danger); color: white; }
|
||||
|
||||
/* Scrollbar */
|
||||
/* Theme toggle icons */
|
||||
[data-theme="dark"] .icon-sun { display: none; }
|
||||
[data-theme="dark"] .icon-moon { display: block; }
|
||||
[data-theme="light"] .icon-sun { display: block; }
|
||||
[data-theme="light"] .icon-moon { display: none; }
|
||||
|
||||
/* ===== Scrollbar ===== */
|
||||
::-webkit-scrollbar { width: 6px; }
|
||||
::-webkit-scrollbar-track { background: transparent; }
|
||||
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
|
||||
::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }
|
||||
|
||||
/* Responsive */
|
||||
/* ===== Responsive ===== */
|
||||
@media (max-width: 768px) {
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
|
||||
+14
-4
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="vi">
|
||||
<html lang="vi" data-theme="dark">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
@@ -13,9 +13,15 @@
|
||||
<aside class="sidebar" id="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<h2>Blog RAG</h2>
|
||||
<button class="btn-icon" id="btn-new-session" title="Phiên mới">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
||||
</button>
|
||||
<div class="sidebar-actions">
|
||||
<button class="btn-icon" id="btn-theme" title="Chế độ sáng/tối">
|
||||
<svg class="icon-sun" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>
|
||||
<svg class="icon-moon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>
|
||||
</button>
|
||||
<button class="btn-icon" id="btn-new-session" title="Phiên mới">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="session-list" id="session-list"></div>
|
||||
<div class="sidebar-footer">
|
||||
@@ -60,6 +66,10 @@
|
||||
</div>
|
||||
<div class="input-hint">Enter để gửi, Shift+Enter xuống dòng</div>
|
||||
</div>
|
||||
|
||||
<footer class="app-footer">
|
||||
Copyright © 2026 - Blog RAG Solution - <a href="https://ttaisolutions.com" target="_blank">TTAI Solutions Software</a>
|
||||
</footer>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user