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:
@@ -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">
|
||||||
|
|||||||
@@ -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');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user