Nav: collapsible hamburger menu for right-side items on mobile

This commit is contained in:
Davide Scaini
2026-05-11 08:44:33 +02:00
parent bce24ed7cf
commit 8ea820aeaf
+40 -8
View File
@@ -141,10 +141,13 @@ const { title = 'BincioWiki', description = 'La memoria collettiva del gruppo Bi
</div>
)}
<div class="ml-auto shrink-0 flex items-center gap-2">
<span id="nav-handle" class="text-xs text-zinc-500" style="display:none"></span>
<a id="nav-wikilog" href="/log/" class="text-xs text-zinc-500 hover:text-white transition-colors px-1" style="display:none">WikiLog</a>
<a id="nav-invites" href="/invites/" class="text-xs text-zinc-500 hover:text-white transition-colors px-1" style="display:none">Inviti</a>
<button id="nav-logout" class="text-xs text-zinc-500 hover:text-white transition-colors px-1" style="display:none">Log out</button>
<!-- Desktop-only items: hidden on mobile, shown by JS on sm+ -->
<span id="nav-handle" class="hidden sm:inline text-xs text-zinc-500" style="display:none"></span>
<a id="nav-wikilog" href="/log/" class="hidden sm:inline text-xs text-zinc-500 hover:text-white transition-colors px-1" style="display:none">WikiLog</a>
<a id="nav-invites" href="/invites/" class="hidden sm:inline text-xs text-zinc-500 hover:text-white transition-colors px-1" style="display:none">Inviti</a>
<button id="nav-logout" class="hidden sm:inline text-xs text-zinc-500 hover:text-white transition-colors px-1" style="display:none">Log out</button>
<!-- Hamburger: mobile only, shown after auth -->
<button id="nav-hamburger" class="sm:hidden text-zinc-400 hover:text-white w-8 h-8 flex items-center justify-center rounded-md hover:bg-zinc-800 text-base" style="display:none" aria-label="Menu">☰</button>
<button
id="theme-toggle"
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"
@@ -152,6 +155,15 @@ const { title = 'BincioWiki', description = 'La memoria collettiva del gruppo Bi
>☀</button>
</div>
</div>
<!-- Mobile dropdown (inside sticky nav so it scrolls with it) -->
<div id="nav-menu" class="hidden border-t sm:hidden" style="border-color: var(--border); background: var(--bg-card)">
<div class="max-w-5xl mx-auto px-4 py-2 flex flex-col">
<span id="nav-handle-m" class="text-xs px-2 py-1.5" style="color: var(--text-5)"></span>
<a href="/log/" class="text-sm px-2 py-1.5 rounded hover:bg-zinc-800 transition-colors" style="color: var(--text-4)">WikiLog</a>
<a href="/invites/" class="text-sm px-2 py-1.5 rounded hover:bg-zinc-800 transition-colors" style="color: var(--text-4)">Inviti</a>
<button id="nav-logout-m" class="text-sm px-2 py-1.5 rounded hover:bg-zinc-800 transition-colors text-left" style="color: var(--text-4)">Log out</button>
</div>
</div>
</nav>
<main class="max-w-5xl mx-auto px-4 py-6">
@@ -176,20 +188,40 @@ const { title = 'BincioWiki', description = 'La memoria collettiva del gruppo Bi
const user = await r.json().catch(() => null);
if (user) {
const handleEl = document.getElementById('nav-handle');
const handleMEl = document.getElementById('nav-handle-m');
const wikilogEl = document.getElementById('nav-wikilog');
const logoutEl = document.getElementById('nav-logout');
if (handleEl) { handleEl.textContent = '@' + user.handle; handleEl.style.display = ''; }
if (wikilogEl) wikilogEl.style.display = '';
const invitesEl = document.getElementById('nav-invites');
const logoutEl = document.getElementById('nav-logout');
const hamburgerEl = document.getElementById('nav-hamburger');
if (handleEl) { handleEl.textContent = '@' + user.handle; handleEl.style.display = ''; }
if (handleMEl) handleMEl.textContent = '@' + user.handle;
if (wikilogEl) wikilogEl.style.display = '';
if (invitesEl) invitesEl.style.display = '';
if (logoutEl) logoutEl.style.display = '';
if (hamburgerEl) hamburgerEl.style.display = '';
}
})
.catch(() => { document.body.removeAttribute('data-auth-pending'); });
document.getElementById('nav-logout')?.addEventListener('click', async () => {
const logoutHandler = async () => {
await fetch('/api/auth/logout', { method: 'POST', credentials: 'include' }).catch(() => {});
window.location.replace('/login/');
};
document.getElementById('nav-logout')?.addEventListener('click', logoutHandler);
document.getElementById('nav-logout-m')?.addEventListener('click', logoutHandler);
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 as Node) && !hamburger?.contains(e.target as Node)) {
navMenu.classList.add('hidden');
if (hamburger) hamburger.textContent = '☰';
}
});
}
</script>