feat: account settings page + dedicated help page
- Add /settings page with password change form and personas list - Add /help dedicated page (replaces help modal); renders HELP.md with collapsible sections, dark theme, back link to active persona - Add 👤 account button and convert ? button to link in header - Remove help modal HTML and ~55 lines of modal JS from main app - Register settings and help routers in main.py Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -912,8 +912,6 @@
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape') {
|
||||
if (fileModal.classList.contains('open')) fileModal.classList.remove('open');
|
||||
if (document.getElementById('help-modal')?.classList.contains('open'))
|
||||
document.getElementById('help-modal').classList.remove('open');
|
||||
}
|
||||
// Ctrl+S to save when file modal is open
|
||||
if ((e.ctrlKey || e.metaKey) && e.key === 's' && fileModal.classList.contains('open')) {
|
||||
@@ -1121,62 +1119,6 @@
|
||||
syncHeight();
|
||||
addMessage('system', 'Session started');
|
||||
|
||||
// ── Help modal ────────────────────────────────────────────────
|
||||
const helpBtn = document.getElementById('help-btn');
|
||||
const helpModal = document.getElementById('help-modal');
|
||||
const helpBody = document.getElementById('help-modal-body');
|
||||
const helpClose = document.getElementById('help-close-btn');
|
||||
|
||||
// Sections open by default — everything after "Notes" starts collapsed
|
||||
const HELP_OPEN_SECTIONS = new Set(['Header Controls', 'Chat', 'Sessions', 'Notes']);
|
||||
|
||||
function makeCollapsible(container) {
|
||||
const h2s = Array.from(container.querySelectorAll('h2'));
|
||||
for (const h2 of h2s) {
|
||||
const title = h2.textContent.trim();
|
||||
const details = document.createElement('details');
|
||||
if (HELP_OPEN_SECTIONS.has(title)) details.open = true;
|
||||
|
||||
const summary = document.createElement('summary');
|
||||
summary.textContent = title;
|
||||
details.appendChild(summary);
|
||||
|
||||
// Collect all following siblings until the next h2
|
||||
const siblings = [];
|
||||
let node = h2.nextSibling;
|
||||
while (node && node.nodeName !== 'H2') {
|
||||
siblings.push(node);
|
||||
node = node.nextSibling;
|
||||
}
|
||||
for (const sib of siblings) details.appendChild(sib);
|
||||
|
||||
h2.parentNode.replaceChild(details, h2);
|
||||
}
|
||||
}
|
||||
|
||||
async function openHelp() {
|
||||
helpBody.textContent = 'Loading…';
|
||||
helpModal.classList.add('open');
|
||||
try {
|
||||
const res = await fetch(`/files/HELP.md?${_fileParams}`);
|
||||
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
||||
const data = await res.json();
|
||||
helpBody.innerHTML = marked.parse(data.content);
|
||||
helpBody.querySelectorAll('a').forEach(a => {
|
||||
a.target = '_blank'; a.rel = 'noopener noreferrer';
|
||||
});
|
||||
makeCollapsible(helpBody);
|
||||
} catch (err) {
|
||||
helpBody.textContent = `Failed to load help: ${err.message}`;
|
||||
}
|
||||
}
|
||||
|
||||
helpBtn.addEventListener('click', openHelp);
|
||||
helpClose.addEventListener('click', () => helpModal.classList.remove('open'));
|
||||
helpModal.addEventListener('click', (e) => {
|
||||
if (e.target === helpModal) helpModal.classList.remove('open');
|
||||
});
|
||||
|
||||
// ── Auth token warning banner ─────────────────────────────
|
||||
const authBanner = document.getElementById('auth-banner');
|
||||
const authBannerMsg = document.getElementById('auth-banner-msg');
|
||||
|
||||
Reference in New Issue
Block a user