feat: implement responsive mobile navigation header and wiki sidebar drawer
- Refactored templates/base.html to hide navigation on mobile and expose a hamburger menu button. - Built a right-aligned sliding mobile menu drawer sheet in base.html. - Hidden the documentation sidebar in templates/docs/sidebar.html by default on mobile, placing it inside a left-aligned sliding drawer sheet. - Added a floating 'Explore Guides' directory trigger bar at the top of doc pages on mobile. - Updated static/js/components.js to apply active route highlighting globally to both desktop and mobile sidebars.
This commit is contained in:
@@ -626,17 +626,14 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
// --- SIDEBAR NAVIGATION ACTIVE HIGHLIGHTING ---
|
||||
const currentPath = window.location.pathname;
|
||||
const sidebar = document.getElementById('wiki-sidebar');
|
||||
if (sidebar) {
|
||||
sidebar.querySelectorAll('a[data-wiki-path]').forEach(link => {
|
||||
document.querySelectorAll('a[data-wiki-path]').forEach(link => {
|
||||
const path = link.getAttribute('data-wiki-path');
|
||||
if (currentPath === path) {
|
||||
link.className = 'flex items-center px-3 py-2 text-xs font-semibold rounded-lg bg-indigo-600/20 text-indigo-400 border border-indigo-500/10 transition';
|
||||
} else {
|
||||
link.className = 'flex items-center px-3 py-2 text-xs font-semibold text-muted-foreground hover:text-white rounded-lg hover:bg-accent hover:text-accent-foreground transition';
|
||||
link.className = 'flex items-center px-3 py-2 text-xs font-semibold text-muted-foreground hover:text-white rounded-lg hover:bg-secondary transition';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// --- CUSTOM SELECT DROPDOWN LOGIC ---
|
||||
document.addEventListener('click', (event) => {
|
||||
|
||||
+59
-1
@@ -48,7 +48,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Navigation Links -->
|
||||
<nav class="flex items-center space-x-4">
|
||||
<nav class="hidden md:flex items-center space-x-4">
|
||||
<a href="/docs" class="text-sm font-medium text-muted-foreground hover:text-white transition py-2 px-3 rounded-lg hover:bg-secondary">
|
||||
Documentation
|
||||
</a>
|
||||
@@ -74,6 +74,15 @@
|
||||
</a>
|
||||
{% endif %}
|
||||
</nav>
|
||||
|
||||
<!-- Hamburger Menu Button (Mobile) -->
|
||||
<div class="flex items-center md:hidden">
|
||||
<button data-sheet-target="mobile-nav-sheet" class="inline-flex items-center justify-center p-2 rounded-xl text-muted-foreground hover:text-white hover:bg-secondary transition focus:outline-none" aria-label="Open main menu">
|
||||
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M4 6h16M4 12h16M4 18h16" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
@@ -90,5 +99,54 @@
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- Mobile Navigation Drawer (Sheet) -->
|
||||
<div id="mobile-nav-sheet" class="sheet-dialog fixed inset-0 z-50 hidden" role="dialog" aria-modal="true">
|
||||
<!-- Backdrop -->
|
||||
<div class="sheet-backdrop fixed inset-0 bg-[#07090e]/80 backdrop-blur-sm transition-opacity duration-300"></div>
|
||||
<!-- Content Container (sliding in from the right) -->
|
||||
<div class="sheet-content fixed inset-y-0 right-0 z-10 w-full max-w-xs translate-x-full transition-transform duration-300 border-l border-border bg-popover/95 backdrop-blur-xl p-6 shadow-2xl flex flex-col">
|
||||
<!-- Header -->
|
||||
<div class="flex items-center justify-between pb-6 border-b border-border">
|
||||
<span class="text-lg font-bold text-slate-100">Menu</span>
|
||||
<button class="sheet-close p-2 rounded-xl text-muted-foreground hover:text-white hover:bg-secondary transition">
|
||||
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Navigation Links -->
|
||||
<nav class="flex flex-col gap-2 mt-6 grow">
|
||||
<a href="/docs" class="flex items-center px-4 py-3 text-sm font-semibold text-muted-foreground hover:text-white rounded-xl hover:bg-secondary transition sheet-close">
|
||||
Documentation
|
||||
</a>
|
||||
{% if authenticated %}
|
||||
<a href="/tasks" class="flex items-center px-4 py-3 text-sm font-semibold text-muted-foreground hover:text-white rounded-xl hover:bg-secondary transition sheet-close">
|
||||
Dashboard
|
||||
</a>
|
||||
<a href="/developers" class="flex items-center px-4 py-3 text-sm font-semibold text-muted-foreground hover:text-white rounded-xl hover:bg-secondary transition sheet-close">
|
||||
Developers
|
||||
</a>
|
||||
<div class="h-px bg-border my-2"></div>
|
||||
<a href="/auth/password" class="flex items-center justify-between px-4 py-3 text-sm font-semibold text-sky-400 hover:text-sky-300 rounded-xl hover:bg-secondary/40 border border-sky-500/10 transition sheet-close">
|
||||
<span>Logged in as: {{ username }}</span>
|
||||
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
</svg>
|
||||
</a>
|
||||
<form action="/auth/logout" method="post" class="mt-auto">
|
||||
<button type="submit" class="flex w-full items-center justify-center px-4 py-3 text-sm font-semibold text-rose-400 hover:text-rose-300 rounded-xl hover:bg-rose-950/20 transition sheet-close">
|
||||
Logout
|
||||
</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<a href="/auth/login" class="flex items-center px-4 py-3 text-sm font-semibold text-muted-foreground hover:text-white rounded-xl hover:bg-secondary transition sheet-close">
|
||||
Log In
|
||||
</a>
|
||||
{% endif %}
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -125,6 +125,20 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<span class="font-bold text-indigo-400 block mb-1">📱 Mobile-First Responsive Layout</span>
|
||||
<p class="text-slate-400 leading-normal">
|
||||
The navigation elements use responsive design classes to ensure compatibility across screen sizes:
|
||||
</p>
|
||||
<ul class="list-disc pl-5 mt-1.5 space-y-1.5 text-slate-400 leading-normal">
|
||||
<li>
|
||||
<strong class="text-slate-200">Responsive App Navbar:</strong> The master header navigation switches from a horizontal desktop layout (<code>hidden md:flex</code>) to a mobile hamburger menu button (<code>flex md:hidden</code>). The button targets a sliding navigation drawer (<code>#mobile-nav-sheet</code>) that transitions in from the right.
|
||||
</li>
|
||||
<li>
|
||||
<strong class="text-slate-200">Collapsible Wiki Directory:</strong> On documentation views, the large guides sidebar is hidden on mobile devices (<code>hidden lg:block</code>) and replaced with an inline trigger bar (<code>Explore Guides</code>). Clicking this trigger transitions the guides directory drawer (<code>#wiki-sidebar-sheet</code>) from the left.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -232,6 +232,24 @@ where
|
||||
The `payload` field is crucial. By storing the JSON serialization of the model BEFORE or AFTER the action, system administrators can reconstruct state history. For deletions, always record the serial snapshot of the deleted model in the payload so it is never permanently lost to audit inquiries.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span class="font-bold text-indigo-400 block mb-1">🗑️ Compliance & Archival Purging</span>
|
||||
<p class="text-slate-400 leading-normal">
|
||||
To maintain storage hygiene, administrators can purge logs older than <code>x</code> days (minimum 1 day). To prevent accidental loss of audit history, the system enforces a strict <strong>archival download requirement</strong>:
|
||||
</p>
|
||||
<ul class="list-disc pl-5 mt-1.5 space-y-1.5 text-slate-400 leading-normal">
|
||||
<li>
|
||||
The purge action queries the records target for deletion and serializes them to JSON format in memory.
|
||||
</li>
|
||||
<li>
|
||||
The database records are deleted, and a new audit log entry recording the purge event details is created to preserve the audit trail chain.
|
||||
</li>
|
||||
<li>
|
||||
The server immediately streams the JSON data as a downloadable attachment, forcing the browser to save the backup locally.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -1,4 +1,19 @@
|
||||
<aside class="lg:w-64 shrink-0">
|
||||
<!-- Mobile Wiki Sidebar Trigger (Visible on small screens only) -->
|
||||
<div class="lg:hidden w-full mb-6 bg-card/30 backdrop-blur border border-border p-4 rounded-3xl flex items-center justify-between shadow-sm">
|
||||
<div class="flex flex-col gap-0.5">
|
||||
<span class="text-xs font-bold text-slate-100 uppercase tracking-wider">Documentation</span>
|
||||
<span class="text-[10px] text-muted-foreground">Select a guide to read</span>
|
||||
</div>
|
||||
<button data-sheet-target="wiki-sidebar-sheet" class="inline-flex items-center justify-center gap-1.5 px-4 py-2.5 rounded-xl text-xs font-bold bg-indigo-600 hover:bg-indigo-500 text-white shadow-md shadow-indigo-600/10 transition">
|
||||
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M4 6h16M4 12h16M4 18h7" />
|
||||
</svg>
|
||||
Explore Guides
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Desktop Navigation Sidebar (Hidden on mobile) -->
|
||||
<aside class="hidden lg:block lg:w-64 shrink-0">
|
||||
<div class="sticky top-24 space-y-1.5 p-4 rounded-3xl border border-border bg-card/50 backdrop-blur-xl" id="wiki-sidebar">
|
||||
<span class="px-3 text-[10px] font-bold text-slate-500 uppercase tracking-wider block mb-2">Wiki Navigation</span>
|
||||
<a href="/docs" class="flex items-center px-3 py-2 text-xs font-semibold text-muted-foreground hover:text-white rounded-lg hover:bg-secondary transition" data-wiki-path="/docs">Introduction</a>
|
||||
@@ -29,3 +44,49 @@
|
||||
<a href="/docs/feedback" class="flex items-center px-3 py-2 text-xs font-semibold text-muted-foreground hover:text-white rounded-lg hover:bg-secondary transition" data-wiki-path="/docs/feedback">Toasts & Alerts</a>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- Mobile Navigation Sidebar (Sheet - sliding in from left) -->
|
||||
<div id="wiki-sidebar-sheet" class="sheet-dialog fixed inset-0 z-50 hidden" role="dialog" aria-modal="true">
|
||||
<!-- Backdrop -->
|
||||
<div class="sheet-backdrop fixed inset-0 bg-[#07090e]/80 backdrop-blur-sm transition-opacity duration-300"></div>
|
||||
<!-- Content Container -->
|
||||
<div class="sheet-content fixed inset-y-0 left-0 z-10 w-full max-w-xs -translate-x-full transition-transform duration-300 border-r border-border bg-popover/95 backdrop-blur-xl p-6 shadow-2xl flex flex-col overflow-y-auto">
|
||||
<div class="flex items-center justify-between pb-4 border-b border-border mb-4">
|
||||
<span class="text-sm font-bold text-slate-100 uppercase tracking-wider">Wiki Navigation</span>
|
||||
<button class="sheet-close p-2 rounded-xl text-muted-foreground hover:text-white hover:bg-secondary transition">
|
||||
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Mobile Sidebar Links -->
|
||||
<nav class="flex flex-col gap-1.5">
|
||||
<a href="/docs" class="flex items-center px-3 py-2 text-xs font-semibold text-muted-foreground hover:text-white rounded-lg hover:bg-secondary transition sheet-close" data-wiki-path="/docs">Introduction</a>
|
||||
<div class="h-px bg-secondary my-1"></div>
|
||||
|
||||
<span class="px-3 text-[9px] font-bold text-slate-650 uppercase tracking-wider block mt-2 mb-1">Architecture</span>
|
||||
<a href="/docs/logging" class="flex items-center px-3 py-2 text-xs font-semibold text-muted-foreground hover:text-white rounded-lg hover:bg-secondary transition sheet-close" data-wiki-path="/docs/logging">Audit Logging</a>
|
||||
|
||||
<span class="px-3 text-[9px] font-bold text-slate-650 uppercase tracking-wider block mt-2 mb-1">Actions</span>
|
||||
<a href="/docs/buttons" class="flex items-center px-3 py-2 text-xs font-semibold text-muted-foreground hover:text-white rounded-lg hover:bg-secondary transition sheet-close" data-wiki-path="/docs/buttons">Buttons</a>
|
||||
|
||||
<span class="px-3 text-[9px] font-bold text-slate-650 uppercase tracking-wider block mt-2 mb-1">Forms & Inputs</span>
|
||||
<a href="/docs/inputs" class="flex items-center px-3 py-2 text-xs font-semibold text-muted-foreground hover:text-white rounded-lg hover:bg-secondary transition sheet-close" data-wiki-path="/docs/inputs">Form Fields & Select</a>
|
||||
<a href="/docs/date-time" class="flex items-center px-3 py-2 text-xs font-semibold text-muted-foreground hover:text-white rounded-lg hover:bg-secondary transition sheet-close" data-wiki-path="/docs/date-time">Date & Time Pickers</a>
|
||||
<a href="/docs/combobox" class="flex items-center px-3 py-2 text-xs font-semibold text-muted-foreground hover:text-white rounded-lg hover:bg-secondary transition sheet-close" data-wiki-path="/docs/combobox">Autocomplete (Combobox)</a>
|
||||
<a href="/docs/toggles" class="flex items-center px-3 py-2 text-xs font-semibold text-muted-foreground hover:text-white rounded-lg hover:bg-secondary transition sheet-close" data-wiki-path="/docs/toggles">Switches & Checkboxes</a>
|
||||
|
||||
<span class="px-3 text-[9px] font-bold text-slate-650 uppercase tracking-wider block mt-2 mb-1">Overlays</span>
|
||||
<a href="/docs/modals" class="flex items-center px-3 py-2 text-xs font-semibold text-muted-foreground hover:text-white rounded-lg hover:bg-secondary transition sheet-close" data-wiki-path="/docs/modals">Dialog Modals</a>
|
||||
<a href="/docs/sheets" class="flex items-center px-3 py-2 text-xs font-semibold text-muted-foreground hover:text-white rounded-lg hover:bg-secondary transition sheet-close" data-wiki-path="/docs/sheets">Slide-over Drawers</a>
|
||||
|
||||
<span class="px-3 text-[9px] font-bold text-slate-650 uppercase tracking-wider block mt-2 mb-1">Layout & Navigation</span>
|
||||
<a href="/docs/tabs-accordion" class="flex items-center px-3 py-2 text-xs font-semibold text-muted-foreground hover:text-white rounded-lg hover:bg-secondary transition sheet-close" data-wiki-path="/docs/tabs-accordion">Tabs & Accordions</a>
|
||||
<a href="/docs/scrollbars" class="flex items-center px-3 py-2 text-xs font-semibold text-muted-foreground hover:text-white rounded-lg hover:bg-secondary transition sheet-close" data-wiki-path="/docs/scrollbars">Custom Scrollbars</a>
|
||||
|
||||
<span class="px-3 text-[9px] font-bold text-slate-650 uppercase tracking-wider block mt-2 mb-1">Visuals & Feedback</span>
|
||||
<a href="/docs/visuals" class="flex items-center px-3 py-2 text-xs font-semibold text-muted-foreground hover:text-white rounded-lg hover:bg-secondary transition sheet-close" data-wiki-path="/docs/visuals">Avatars & Badges</a>
|
||||
<a href="/docs/feedback" class="flex items-center px-3 py-2 text-xs font-semibold text-muted-foreground hover:text-white rounded-lg hover:bg-secondary transition sheet-close" data-wiki-path="/docs/feedback">Toasts & Alerts</a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user