"use client"; import Link from "next/link"; import { usePathname } from "next/navigation"; import { useEffect, useState } from "react"; import { signIn, signOut, useSession } from "next-auth/react"; export default function NavBar() { const { data } = useSession(); const pathname = usePathname(); const isAdmin = data?.user?.role === "ADMIN" || data?.user?.role === "SUPERADMIN"; const isSuperAdmin = data?.user?.role === "SUPERADMIN"; const [logoUrl, setLogoUrl] = useState(null); const [logoBrightness, setLogoBrightness] = useState(null); const [isDarkTheme, setIsDarkTheme] = useState(false); const [isScrolled, setIsScrolled] = useState(false); const [mobileOpen, setMobileOpen] = useState(false); const [appName, setAppName] = useState("Vereinskalender"); const hideLoginPaths = new Set(["/login", "/register", "/reset"]); const showLoginButton = !data?.user && !hideLoginPaths.has(pathname); const linkClass = (href: string) => pathname === href ? "nav-link-active rounded-full px-3 py-1" : "nav-link rounded-full px-3 py-1"; useEffect(() => { const loadLogo = async () => { try { const response = await fetch("/api/branding/logo", { method: "HEAD", cache: "no-store" }); if (response.ok) { setLogoUrl(`/api/branding/logo?ts=${Date.now()}`); } else { setLogoUrl(null); } } catch { setLogoUrl(null); } }; loadLogo(); }, []); useEffect(() => { const loadAppName = async () => { try { const response = await fetch("/api/settings/app-name"); if (!response.ok) return; const payload = await response.json(); setAppName(payload.name || "Vereinskalender"); } catch { // ignore } }; loadAppName(); }, []); useEffect(() => { if (typeof document === "undefined") return; const root = document.documentElement; const updateTheme = () => { setIsDarkTheme(root.dataset.theme === "dark"); }; updateTheme(); const observer = new MutationObserver(updateTheme); observer.observe(root, { attributes: true, attributeFilter: ["data-theme"] }); return () => observer.disconnect(); }, []); useEffect(() => { const onScroll = () => { setIsScrolled(window.scrollY > 12); }; onScroll(); window.addEventListener("scroll", onScroll, { passive: true }); return () => window.removeEventListener("scroll", onScroll); }, []); useEffect(() => { setMobileOpen(false); }, [pathname]); useEffect(() => { if (!logoUrl) return; let cancelled = false; const img = new Image(); img.crossOrigin = "anonymous"; img.src = logoUrl; img.onload = () => { if (cancelled) return; const canvas = document.createElement("canvas"); const size = 32; canvas.width = size; canvas.height = size; const ctx = canvas.getContext("2d"); if (!ctx) return; ctx.drawImage(img, 0, 0, size, size); const data = ctx.getImageData(0, 0, size, size).data; let total = 0; let count = 0; for (let i = 0; i < data.length; i += 4) { const alpha = data[i + 3]; if (alpha === 0) continue; const r = data[i]; const g = data[i + 1]; const b = data[i + 2]; total += 0.2126 * r + 0.7152 * g + 0.0722 * b; count += 1; } if (count > 0) { setLogoBrightness(total / count); } }; return () => { cancelled = true; }; }, [logoUrl]); const shouldInvertLogo = logoBrightness !== null && ((isDarkTheme && logoBrightness > 140) || (!isDarkTheme && logoBrightness < 200)); return (
{logoUrl && ( Vereinskalender Logo setLogoUrl(null)} /> )} {appName}
{mobileOpen && (
setMobileOpen(false)} /> )}
{data?.user && ( <> {isAdmin && ( <> Admin Registrierungen )} Einstellungen )} {data?.user ? ( ) : showLoginButton ? ( ) : null}
); }