Fix navigation: add header to all views, fix back button navigation, add mobile menu to document and editor views

- Document view: Added hamburger menu button and breadcrumb navigation
- Editor view: Added hamburger menu, breadcrumb nav, fixed handleCancel/handleSave
- Editor now navigates to correct parent (project) instead of dashboard
- Mobile menu works on all views (projects, projectView, document, editor)
- Document view back button goes to project (not dashboard)
- Editor cancel/save buttons now go to project or projects list
This commit is contained in:
Hiro
2026-03-28 15:47:09 +00:00
parent 5c54f30b57
commit 98b38ad78a
2 changed files with 85 additions and 7 deletions

View File

@@ -22,6 +22,17 @@ export async function renderDocument(app) {
} }
}; };
// Mobile menu functions
window.toggleDocumentMenu = function() {
const menu = document.getElementById('document-menu');
if (menu) menu.classList.toggle('open');
};
window.closeDocumentMenu = function() {
const menu = document.getElementById('document-menu');
if (menu) menu.classList.remove('open');
};
const appEl = document.getElementById('app'); const appEl = document.getElementById('app');
function render() { function render() {
@@ -31,13 +42,31 @@ export async function renderDocument(app) {
appEl.innerHTML = ` appEl.innerHTML = `
<header class="app-header"> <header class="app-header">
<button type="button" class="mobile-nav-btn" onclick="window.toggleDocumentMenu()" title="Menu">☰</button>
<button type="button" class="btn btn-ghost" onclick="backToProject()">← Back</button> <button type="button" class="btn btn-ghost" onclick="backToProject()">← Back</button>
<div class="breadcrumb-nav">
<span class="breadcrumb-link" onclick="window.app.navigate('projects')">Projects</span>
<span class="breadcrumb-sep">/</span>
${projectId ? `<span class="breadcrumb-link" onclick="window.app.navigate('project', {id: '${projectId}'})">Project</span><span class="breadcrumb-sep">/</span>` : ''}
<span class="breadcrumb-current">${escapeHtml(doc.title || 'Document')}</span>
</div>
<div class="header-actions"> <div class="header-actions">
<button type="button" class="btn btn-ghost" onclick="window.app.navigate('editor', {id: '${doc.id}'})">✏️ Edit</button> <button type="button" class="btn btn-ghost" onclick="window.app.navigate('editor', {id: '${doc.id}', projectId: '${projectId || ''}'})">✏️ Edit</button>
<button type="button" class="btn btn-ghost" onclick="exportDoc()">📥 Export</button> <button type="button" class="btn btn-ghost" onclick="exportDoc()">📥 Export</button>
<button type="button" class="btn btn-ghost danger" onclick="deleteDoc()">🗑️ Delete</button> <button type="button" class="btn btn-ghost danger" onclick="deleteDoc()">🗑️ Delete</button>
</div> </div>
</header> </header>
<div class="mobile-menu" id="document-menu">
<div class="mobile-menu-header">
<span>Menu</span>
<button onclick="window.closeDocumentMenu()">✕</button>
</div>
<div class="mobile-menu-content">
<a href="#" onclick="backToProject(); return false;">← Back to ${projectId ? 'Project' : 'Projects'}</a>
<a href="#" onclick="window.app.navigate('editor', {id: '${doc.id}', projectId: '${projectId || ''}'}); window.closeDocumentMenu(); return false;">✏️ Edit Document</a>
<a href="#" onclick="window.app.navigate('projects'); window.closeDocumentMenu(); return false;">📋 All Projects</a>
</div>
</div>
<main class="main-content"> <main class="main-content">
<div class="content-body"> <div class="content-body">
<div class="doc-viewer"> <div class="doc-viewer">

View File

@@ -3,7 +3,7 @@
import { api } from '../api.js'; import { api } from '../api.js';
export async function renderEditor(app) { export async function renderEditor(app) {
const { id, libraryId } = app.state.params; const { id, projectId, libraryId } = app.state.params;
let doc = null; let doc = null;
let libraries = []; let libraries = [];
@@ -12,7 +12,7 @@ export async function renderEditor(app) {
doc = await api.getDocument(id); doc = await api.getDocument(id);
} catch (e) { } catch (e) {
app.showToast('Failed to load document', 'error'); app.showToast('Failed to load document', 'error');
app.navigate('dashboard'); app.navigate(projectId ? 'project' : 'projects', { id: projectId });
return; return;
} }
} }
@@ -25,6 +25,30 @@ export async function renderEditor(app) {
const isNew = !id; const isNew = !id;
const appEl = document.getElementById('app'); const appEl = document.getElementById('app');
// Determine back navigation target
const backTarget = projectId
? { view: 'project', params: { id: projectId } }
: { view: 'projects', params: {} };
const backToParent = () => {
if (projectId) {
app.navigate('project', { id: projectId });
} else {
app.navigate('projects');
}
};
// Mobile menu functions
window.toggleEditorMenu = function() {
const menu = document.getElementById('editor-menu');
if (menu) menu.classList.toggle('open');
};
window.closeEditorMenu = function() {
const menu = document.getElementById('editor-menu');
if (menu) menu.classList.remove('open');
};
let formData = { let formData = {
title: doc?.title || '', title: doc?.title || '',
content: doc?.content || '', content: doc?.content || '',
@@ -41,10 +65,27 @@ export async function renderEditor(app) {
function render() { function render() {
appEl.innerHTML = ` appEl.innerHTML = `
<header class="app-header"> <header class="app-header">
<button type="button" class="mobile-nav-btn" onclick="window.toggleEditorMenu()" title="Menu">☰</button>
<button type="button" class="btn btn-ghost" onclick="handleCancel()">Cancel</button> <button type="button" class="btn btn-ghost" onclick="handleCancel()">Cancel</button>
<span style="flex:1;margin-left:16px">${isNew ? 'New Document' : 'Editing: ' + escapeHtml(formData.title)}</span> <div class="breadcrumb-nav">
<span class="breadcrumb-link" onclick="window.app.navigate('projects')">Projects</span>
<span class="breadcrumb-sep">/</span>
${projectId ? `<span class="breadcrumb-link" onclick="window.app.navigate('project', {id: '${projectId}'})">Project</span><span class="breadcrumb-sep">/</span>` : ''}
<span class="breadcrumb-current">${isNew ? 'New Document' : escapeHtml(formData.title)}</span>
</div>
<button type="button" class="btn btn-primary" onclick="handleSave()">Save</button> <button type="button" class="btn btn-primary" onclick="handleSave()">Save</button>
</header> </header>
<div class="mobile-menu" id="editor-menu">
<div class="mobile-menu-header">
<span>Menu</span>
<button onclick="window.closeEditorMenu()">✕</button>
</div>
<div class="mobile-menu-content">
<a href="#" onclick="handleCancel(); return false;">← Cancel & Go Back</a>
<a href="#" onclick="handleSave(); window.closeEditorMenu(); return false;">💾 Save Document</a>
<a href="#" onclick="window.app.navigate('projects'); window.closeEditorMenu(); return false;">📋 All Projects</a>
</div>
</div>
<main class="main-content"> <main class="main-content">
<div class="editor-container"> <div class="editor-container">
<form class="editor-form" id="editor-form"> <form class="editor-form" id="editor-form">
@@ -186,7 +227,11 @@ export async function renderEditor(app) {
const confirmed = await app.confirmDelete('You have unsaved changes. Discard?'); const confirmed = await app.confirmDelete('You have unsaved changes. Discard?');
if (!confirmed) return; if (!confirmed) return;
} }
app.navigate('dashboard'); if (projectId) {
app.navigate('project', { id: projectId });
} else {
app.navigate('projects');
}
}; };
window.handleSave = async () => { window.handleSave = async () => {
@@ -204,12 +249,16 @@ export async function renderEditor(app) {
try { try {
if (isNew) { if (isNew) {
await api.createDocument(data); await api.createDocument({...data, projectId});
} else { } else {
await api.updateDocument(id, data); await api.updateDocument(id, data);
} }
app.showToast('Document saved', 'success'); app.showToast('Document saved', 'success');
app.navigate('dashboard'); if (projectId) {
app.navigate('project', { id: projectId });
} else {
app.navigate('projects');
}
} catch (e) { } catch (e) {
app.showToast('Failed to save: ' + e.message, 'error'); app.showToast('Failed to save: ' + e.message, 'error');
} }