From 93f6109028c3231e6411caeff89760448ab8efd9 Mon Sep 17 00:00:00 2001 From: Davide Scaini Date: Mon, 11 May 2026 11:37:33 +0200 Subject: [PATCH] Add hamburger menu for mobile nav --- site/src/layouts/Base.astro | 56 +++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/site/src/layouts/Base.astro b/site/src/layouts/Base.astro index 8790fef..d4575c4 100644 --- a/site/src/layouts/Base.astro +++ b/site/src/layouts/Base.astro @@ -237,34 +237,34 @@ try { id="admin-jobs-badge" style="display:none" title="" - class="text-xs px-2 py-0.5 rounded-full bg-amber-900/60 text-amber-300 border border-amber-700/50 animate-pulse cursor-default" + class="hidden sm:flex text-xs px-2 py-0.5 rounded-full bg-amber-900/60 text-amber-300 border border-amber-700/50 animate-pulse cursor-default" > {editEnabled && ( @@ -276,8 +276,32 @@ try { class="text-zinc-400 hover:text-white transition-colors w-8 h-8 flex items-center justify-center rounded-md hover:bg-zinc-800 text-base" aria-label="Toggle theme" >☀ + {!isPublicPage && ( + + )} + {!isPublicPage && ( + + )} {editEnabled && ( @@ -550,6 +574,8 @@ try { if (settingsEl) settingsEl.style.display = ''; const logoutEl = document.getElementById('nav-logout'); if (logoutEl) logoutEl.style.display = ''; + const hamburgerEl = document.getElementById('nav-hamburger'); + if (hamburgerEl) hamburgerEl.style.display = ''; // Pre-populate the "keep original" checkbox from the instance default const chk = document.getElementById('upload-keep-original'); @@ -584,6 +610,8 @@ try { if (user.is_admin) { const adminLink = document.getElementById('nav-admin'); if (adminLink) adminLink.style.display = ''; + const adminLinkM = document.getElementById('nav-admin-m'); + if (adminLinkM) adminLinkM.style.display = ''; const badge = document.getElementById('admin-jobs-badge'); async function pollJobs() { try { @@ -609,9 +637,25 @@ try { } catch (_) {} })(); - document.getElementById('nav-logout')?.addEventListener('click', async () => { + async function doLogout() { try { await fetch('/api/auth/logout', { method: 'POST', credentials: 'include' }); } catch (_) {} window.location.href = baseUrl + 'login/'; + } + document.getElementById('nav-logout')?.addEventListener('click', doLogout); + document.getElementById('nav-logout-m')?.addEventListener('click', doLogout); + + const hamburger = document.getElementById('nav-hamburger'); + const navMenu = document.getElementById('nav-menu'); + hamburger?.addEventListener('click', () => { + const open = navMenu?.classList.toggle('hidden') === false; + hamburger.textContent = open ? '✕' : '☰'; + }); + document.addEventListener('click', (e) => { + if (navMenu && !navMenu.classList.contains('hidden') && + !navMenu.contains(e.target) && !hamburger?.contains(e.target)) { + navMenu.classList.add('hidden'); + if (hamburger) hamburger.textContent = '☰'; + } }); )}