Kopfleiste: Timer, Historie und Einstellungen in die Leiste

- Die drei Knöpfe hängen als slot="aktionen" rechts in der Portal-Leiste,
  die aktuelle Ansicht ist hervorgehoben
- Unter 600 px nur die Symbole, der Name steht im title
- Der eigene Header (Logo + Knöpfe) entfällt, solange die Leiste da ist;
  lädt topbar.js nicht, bleibt er als Rückfall
- Nach Ablauf der Sitzung (Anmeldeseite) sind Knöpfe und
  Sitzungsanzeige ausgeblendet

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kerim AtilganandClaude Opus 5.5 committed 2026-10-25 13:18:40 +01:00
1 parent e41e2b38e3
commit 046e523352
2 files changed
+65 -16

No files matched your search

+34 -11
View File
@@ -103,10 +103,13 @@ async function api(url, options = {}) {
function switchView(id) {
document.querySelectorAll('.view').forEach(v => v.classList.remove('active'));
document.getElementById(id).classList.add('active');
for (const btn of topbarNav.children) btn.classList.toggle('active', btn.dataset.view === id);
}
function showLogin() {
document.getElementById('header').style.display = 'none';
signedInName = null;
renderTopbar();
switchView('loginView');
applyLoginMode();
}
@@ -169,7 +172,8 @@ function renderCurrentUser() {
const el = document.getElementById('currentUser');
el.textContent = name;
el.title = u && u.email ? u.email : 'Angemeldet';
renderTopbarSession(name);
signedInName = name || 'Angemeldet';
renderTopbar();
}
function confirmLogout() {
@@ -194,24 +198,43 @@ async function logout() {
// ---------------------------------------------------------------------------
// topbar.js laeuft per defer erst nach diesem Skript, die Leiste steht also
// fruehestens ab DOMContentLoaded im DOM. Die Sitzungsanzeige wird einmal
// eingehaengt, sobald die Anmeldung steht, danach aendert sich nur ihr Text.
// fruehestens ab DOMContentLoaded im DOM. Navigation (slot="aktionen") und
// Sitzungsanzeige (slot="benutzer") werden einmal eingehaengt, sobald die
// Anmeldung steht. Danach aendern sich nur Text und Sichtbarkeit. Ist die
// Leiste da, blendet das CSS den eigenen Header aus.
const topbarNav = document.createElement('div');
topbarNav.slot = 'aktionen';
topbarNav.className = 'topbar-nav';
for (const [view, icon, label, show] of [
['timerView', '⏱️', 'Timer', () => showTimer()],
['historyView', '📊', 'Historie', () => showHistory()],
['settingsView', '⚙️', 'Einstellungen', () => showSettings()],
]) {
const btn = document.createElement('button');
btn.type = 'button';
btn.dataset.view = view;
btn.title = label;
btn.append(icon, Object.assign(document.createElement('span'), { textContent: label }));
btn.addEventListener('click', show);
topbarNav.append(btn);
}
const topbarSession = document.createElement('div');
topbarSession.slot = 'benutzer';
topbarSession.className = 'topbar-session';
topbarSession.append(Object.assign(document.createElement('span'), { textContent: 'Timer – angemeldet als' }),
document.createElement('strong'));
let topbarSessionName = null; // null = (noch) nicht angemeldet
let signedInName = null; // null = nicht angemeldet
function renderTopbarSession(name) {
topbarSessionName = name || 'Angemeldet';
topbarSession.lastChild.textContent = topbarSessionName;
if (!topbarSession.isConnected) document.querySelector('hi-topbar')?.append(topbarSession);
function renderTopbar() {
const signedIn = signedInName !== null;
topbarNav.hidden = topbarSession.hidden = !signedIn;
if (!signedIn) return;
topbarSession.lastChild.textContent = signedInName;
if (!topbarSession.isConnected) document.querySelector('hi-topbar')?.append(topbarNav, topbarSession);
}
document.addEventListener('DOMContentLoaded', () => {
if (topbarSessionName !== null) renderTopbarSession(topbarSessionName);
});
document.addEventListener('DOMContentLoaded', renderTopbar);
// "Abmelden" in der Leiste: erst die eigene Sitzung beenden, danach meldet
// die Leiste bei Portal und Authentik ab. Abbrechen bei laufenden Timern