updated layout for small screens - colapsable sidepanel, fix issue with link to favicon when url_prefix is used

This commit is contained in:
2026-04-23 06:49:02 +00:00
parent a30eb4d42d
commit 62bf16589f
7 changed files with 156 additions and 55 deletions
+74 -50
View File
@@ -5,6 +5,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{.app_name}}</title>
<link rel="icon" type="image/x-icon" href="{{url "/favicon.ico"}}">
<link rel="stylesheet" href="{{url "/static/tailwind.css"}}">
<link rel="stylesheet" href="{{url "/static/styles.css"}}">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css">
@@ -166,26 +167,6 @@
background-color: #b91c1c;
}
/* Sidebar collapse behavior */
#sidebar.collapsed {
width: 2.5rem !important; /* 10px * 10 = 2.5rem */
border-right: none;
}
#sidebar.collapsed .sidebar-title,
#sidebar.collapsed .sidebar-actions,
#sidebar.collapsed .sidebar-content {
display: none;
}
#sidebar .toggle-btn {
background: transparent;
color: #cbd5e1;
padding: 0.25rem;
border-radius: 0.375rem;
}
#sidebar .toggle-btn:hover {
background: #374151;
}
/* Modal styles */
.modal-overlay {
position: fixed;
@@ -315,9 +296,6 @@
{{end}}
{{end}}
</div>
<button id="sidebar-toggle" class="toggle-btn" title="Toggle sidebar" aria-label="Toggle sidebar">
<i id="sidebar-toggle-icon" class="fas fa-chevron-left"></i>
</button>
</div>
</div>
</div>
@@ -345,9 +323,16 @@
<!-- Main Content -->
<div class="flex-1 flex flex-col overflow-hidden">
<!-- Breadcrumbs -->
{{if .breadcrumbs}}
<div class="bg-slate-800 border-b border-gray-700 px-6 py-3">
<!-- Top Bar (Toggle + Breadcrumbs) -->
{{if or (not .NoSidebar) .breadcrumbs}}
<div class="bg-slate-800 border-b border-gray-700 px-6 py-3 flex items-center">
{{if not .NoSidebar}}
<button id="mobile-sidebar-toggle-btn" class="text-gray-400 hover:text-white mr-4" aria-label="Toggle sidebar">
<i class="fas fa-bars text-xl"></i>
</button>
{{end}}
{{if .breadcrumbs}}
<nav class="flex items-center flex-wrap gap-1.5 text-sm">
{{range $i, $crumb := .breadcrumbs}}
{{if $i}}<i class="fas fa-chevron-right text-gray-500 text-xs mx-1"></i>{{end}}
@@ -363,7 +348,9 @@
{{end}}
{{end}}
</nav>
{{end}}
</div>
<div id="sidebar-overlay" class="sidebar-overlay hidden"></div>
{{end}}
<!-- Content Area -->
@@ -563,26 +550,24 @@
}, duration);
}
// Sidebar toggle persistence
function applySidebarState(collapsed) {
// Sidebar visibility persistence
function applySidebarVisibility() {
const sidebar = document.getElementById('sidebar');
const icon = document.getElementById('sidebar-toggle-icon');
if (!sidebar || !icon) return;
if (collapsed) {
sidebar.classList.add('collapsed');
icon.classList.remove('fa-chevron-left');
icon.classList.add('fa-chevron-right');
} else {
sidebar.classList.remove('collapsed');
icon.classList.remove('fa-chevron-right');
icon.classList.add('fa-chevron-left');
if (!sidebar) return;
// Only apply persisted state on desktop
if (window.innerWidth > 768) {
const visible = localStorage.getItem('sidebarVisible') !== 'false';
if (!visible) {
sidebar.classList.add('hidden');
} else {
sidebar.classList.remove('hidden');
}
}
}
document.addEventListener('DOMContentLoaded', function() {
// Restore sidebar state
const collapsed = localStorage.getItem('sidebarCollapsed') === 'true';
applySidebarState(collapsed);
// Apply persisted visibility
applySidebarVisibility();
// Check for error in query params
const urlParams = new URLSearchParams(window.location.search);
@@ -590,17 +575,56 @@
showNotification('The page does not exist', 'error', 5000);
}
// Wire toggle button
const toggleBtn = document.getElementById('sidebar-toggle');
if (toggleBtn) {
toggleBtn.addEventListener('click', function() {
const currentlyCollapsed = document.getElementById('sidebar').classList.contains('collapsed');
const next = !currentlyCollapsed;
localStorage.setItem('sidebarCollapsed', String(next));
applySidebarState(next);
});
// Sidebar toggle (unified for mobile/desktop)
const mobileToggleBtn = document.getElementById('mobile-sidebar-toggle-btn');
const sidebarOverlay = document.getElementById('sidebar-overlay');
const sidebar = document.getElementById('sidebar');
function toggleSidebar() {
if (!sidebar) return;
if (window.innerWidth <= 768) {
// Mobile behavior: toggle mobile-open class and overlay
const isOpen = sidebar.classList.contains('mobile-open');
if (isOpen) {
sidebar.classList.remove('mobile-open');
sidebarOverlay && sidebarOverlay.classList.add('hidden');
document.body.classList.remove('overflow-hidden');
} else {
sidebar.classList.add('mobile-open');
sidebarOverlay && sidebarOverlay.classList.remove('hidden');
document.body.classList.add('overflow-hidden');
}
} else {
// Desktop behavior: toggle hidden class and persist
const isHidden = sidebar.classList.contains('hidden');
if (isHidden) {
sidebar.classList.remove('hidden');
localStorage.setItem('sidebarVisible', 'true');
} else {
sidebar.classList.add('hidden');
localStorage.setItem('sidebarVisible', 'false');
}
}
}
if (mobileToggleBtn) {
mobileToggleBtn.addEventListener('click', toggleSidebar);
}
if (sidebarOverlay) {
sidebarOverlay.addEventListener('click', toggleSidebar);
}
// Close sidebar when clicking on a sidebar item on mobile
sidebar && sidebar.addEventListener('click', function(e) {
if (window.innerWidth <= 768) {
const item = e.target.closest('.sidebar-item');
if (item && !item.hasAttribute('target')) {
toggleSidebar();
}
}
});
// Apply persisted expanded folders, then ensure active path is expanded
applyExpandedState();
expandActivePath();