function formatTime(now) { return new Intl.DateTimeFormat("de-DE", { hour: "2-digit", minute: "2-digit", hour12: false, }).format(now); } function formatDate(now) { return new Intl.DateTimeFormat("de-DE", { weekday: "long", day: "2-digit", month: "short", year: "numeric", }).format(now).toUpperCase(); } function statusTone(status) { if (status === "offline") return "offline"; if (status === "degraded") return "warning"; return "online"; } function statusLabel(status) { if (status === "offline") return "OFFLINE"; if (status === "degraded") return "DEGRADED"; return "NOMINAL"; } export function renderHeader(state) { const now = new Date(); const { overview, services } = state.data; const refreshNode = document.getElementById("last-refresh"); const overallTile = document.getElementById("overall-status-tile"); const overallLabel = document.getElementById("overall-status-label"); const overallSummary = document.getElementById("overall-status-summary"); const haTile = document.getElementById("home-assistant-tile"); const haLabel = document.getElementById("ha-status-label"); const haSummary = document.getElementById("ha-status-summary"); const heroCopy = document.getElementById("hero-copy"); document.getElementById("clock-time").textContent = formatTime(now); document.getElementById("clock-date").textContent = formatDate(now); if (refreshNode) { if (state.lastRefreshAt) { refreshNode.textContent = `LAST REFRESH ${new Intl.DateTimeFormat("de-DE", { hour: "2-digit", minute: "2-digit", second: "2-digit", hour12: false, }).format(state.lastRefreshAt)} CET`; } else { refreshNode.textContent = "LAST REFRESH PENDING"; } refreshNode.classList.toggle("api-error", Boolean(state.error)); } const overallTone = statusTone(overview.overall_status); overallTile.className = "status-tile"; overallTile.style.borderColor = ""; overallLabel.textContent = statusLabel(overview.overall_status); overallLabel.className = ""; overallSummary.textContent = `${overview.services.online} services online, ${overview.services.degraded} degraded, ${overview.services.offline} offline`; overallTile.classList.toggle("api-error", Boolean(state.error)); overallLabel.classList.add(`value-${overallTone === "warning" ? "warning" : overallTone === "offline" ? "danger" : "online"}`); const haTone = statusTone(overview.home_assistant.status); haLabel.textContent = overview.home_assistant.status === "online" ? "ONLINE" : "OFFLINE"; haLabel.className = ""; haLabel.classList.add(`value-${haTone === "warning" ? "warning" : haTone === "offline" ? "danger" : "online"}`); haSummary.textContent = overview.home_assistant.status === "online" ? `Version ${overview.home_assistant.version ?? "unknown"} / ${overview.home_assistant.response_time_ms ?? "n/a"} ms` : "Basisstatus derzeit nicht erreichbar"; haTile.className = "status-tile"; if (state.error) { heroCopy.textContent = `Aggregator API zuletzt fehlerhaft erreichbar. Letzte gueltige Daten bleiben sichtbar. Fehler: ${state.error.message}`; } else { heroCopy.textContent = `Live angebundenes MVP-v1 Dashboard. ${services.summary.docker.running} Container running, ` + `${services.summary.uptime_kuma.monitors_up} Kuma Monitors up, Home Assistant ${overview.home_assistant.status}.`; } }