2026-07-08 14:24:23 +02:00
|
|
|
function currentTheme() {
|
|
|
|
|
const attr = document.documentElement.getAttribute('data-theme');
|
|
|
|
|
if (attr === 'light' || attr === 'dark') return attr;
|
|
|
|
|
return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function applyTheme(theme) {
|
|
|
|
|
document.documentElement.setAttribute('data-theme', theme);
|
|
|
|
|
localStorage.setItem('octane-theme', theme);
|
|
|
|
|
updateThemeToggleIcon();
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-08 14:46:48 +02:00
|
|
|
const SUN_ICON = `<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"></circle><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"/></svg>`;
|
|
|
|
|
const MOON_ICON = `<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>`;
|
|
|
|
|
|
2026-07-08 14:24:23 +02:00
|
|
|
function updateThemeToggleIcon() {
|
|
|
|
|
const btn = document.getElementById('theme-toggle');
|
|
|
|
|
if (!btn) return;
|
2026-07-08 14:46:48 +02:00
|
|
|
btn.innerHTML = currentTheme() === 'dark' ? SUN_ICON : MOON_ICON;
|
2026-07-08 14:24:23 +02:00
|
|
|
}
|
|
|
|
|
|
2026-07-08 11:05:21 +02:00
|
|
|
async function initNav(activePage) {
|
|
|
|
|
const me = await api.get('/api/users/me');
|
|
|
|
|
const nav = document.getElementById('main-nav');
|
|
|
|
|
nav.innerHTML = `
|
2026-07-08 15:27:34 +02:00
|
|
|
<a class="brand" href="/index.html"><span class="brand-dot">♫</span> Octane</a>
|
2026-07-08 17:29:42 +02:00
|
|
|
<div class="nav-menu" id="nav-menu">
|
|
|
|
|
<div class="nav-links" id="nav-links">
|
|
|
|
|
<a href="/index.html" class="${activePage === 'repertoire' ? 'active' : ''}">Répertoire</a>
|
|
|
|
|
<a href="/suggestions.html" class="${activePage === 'suggestions' ? 'active' : ''}">Suggestions</a>
|
|
|
|
|
<a href="/setlist.html" class="${activePage === 'setlist' ? 'active' : ''}">Prochain concert</a>
|
|
|
|
|
<a href="/calendar.html" class="${activePage === 'calendar' ? 'active' : ''}">Disponibilités</a>
|
|
|
|
|
<a href="/history.html" class="${activePage === 'history' ? 'active' : ''}">Historique</a>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="nav-user">
|
2026-07-09 18:15:34 +02:00
|
|
|
<div class="nav-profile" id="nav-profile">
|
|
|
|
|
<button type="button" class="nav-profile-trigger" id="nav-profile-trigger" aria-haspopup="true" aria-expanded="false">
|
|
|
|
|
${avatarHtml(me, 'avatar-sm')}
|
|
|
|
|
<span>${escapeHtml(me.name)}${me.isAdmin ? ' <span class="badge">admin</span>' : ''}</span>
|
|
|
|
|
</button>
|
|
|
|
|
<div class="nav-profile-dropdown" id="nav-profile-dropdown">
|
|
|
|
|
<a href="/profile.html">Voir profil</a>
|
2026-07-09 18:26:25 +02:00
|
|
|
${me.isAdmin ? '<a href="/admin.html">Administration</a>' : ''}
|
2026-07-09 18:15:34 +02:00
|
|
|
<a href="/auth/logout">Se déconnecter</a>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-07-08 17:29:42 +02:00
|
|
|
</div>
|
2026-07-08 11:05:21 +02:00
|
|
|
</div>
|
2026-07-08 17:29:42 +02:00
|
|
|
<div class="nav-controls">
|
2026-07-08 14:24:23 +02:00
|
|
|
<button type="button" class="icon-btn secondary" id="theme-toggle" title="Changer de thème" aria-label="Changer de thème"></button>
|
2026-07-08 17:29:42 +02:00
|
|
|
<button type="button" class="nav-toggle" id="nav-toggle" aria-label="Menu">☰</button>
|
2026-07-08 11:05:21 +02:00
|
|
|
</div>
|
|
|
|
|
`;
|
2026-07-08 11:50:12 +02:00
|
|
|
|
|
|
|
|
const toggle = document.getElementById('nav-toggle');
|
2026-07-08 17:29:42 +02:00
|
|
|
const menu = document.getElementById('nav-menu');
|
|
|
|
|
toggle.addEventListener('click', () => menu.classList.toggle('open'));
|
|
|
|
|
menu.querySelectorAll('a').forEach((a) => a.addEventListener('click', () => menu.classList.remove('open')));
|
2026-07-08 11:50:12 +02:00
|
|
|
|
2026-07-09 18:15:34 +02:00
|
|
|
const profileTrigger = document.getElementById('nav-profile-trigger');
|
|
|
|
|
const profileDropdown = document.getElementById('nav-profile-dropdown');
|
|
|
|
|
function closeProfileDropdown() {
|
|
|
|
|
profileDropdown.classList.remove('open');
|
|
|
|
|
profileTrigger.setAttribute('aria-expanded', 'false');
|
|
|
|
|
}
|
|
|
|
|
profileTrigger.addEventListener('click', (e) => {
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
const isOpen = profileDropdown.classList.toggle('open');
|
|
|
|
|
profileTrigger.setAttribute('aria-expanded', String(isOpen));
|
|
|
|
|
});
|
|
|
|
|
document.addEventListener('click', (e) => {
|
|
|
|
|
if (!document.getElementById('nav-profile').contains(e.target)) closeProfileDropdown();
|
|
|
|
|
});
|
|
|
|
|
document.addEventListener('keydown', (e) => {
|
|
|
|
|
if (e.key === 'Escape') closeProfileDropdown();
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-08 14:24:23 +02:00
|
|
|
updateThemeToggleIcon();
|
|
|
|
|
document.getElementById('theme-toggle').addEventListener('click', () => {
|
|
|
|
|
applyTheme(currentTheme() === 'dark' ? 'light' : 'dark');
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-08 11:05:21 +02:00
|
|
|
return me;
|
|
|
|
|
}
|