"use client" import { useEffect, useSyncExternalStore } from "react" import Link from "next/link" import { Cookie } from "lucide-react" // Cookie/privacy consent banner. // // The platform only sets strictly-necessary cookies (auth session, CSRF) and // uses cookieless Umami analytics — so this banner is disclosure plus an // analytics opt-out, not a tracking gate. "Essential only" sets the // `umami.disabled` localStorage flag, which the Umami script honors, so the // choice takes effect without a reload for subsequent page views. // // The choice is stored locally for everyone; signed-in users also get a row in // consent_log via /api/gdpr/consent (anonymous visitors are a 204 no-op). const STORAGE_KEY = "pmn-cookie-consent" const CONSENT_VERSION = 1 type StoredConsent = { v: number; analytics: boolean; ts: string } // ── localStorage as an external store (SSR-safe, lint-clean) ──────────────── let listeners: Array<() => void> = [] function subscribe(listener: () => void) { listeners.push(listener) return () => { listeners = listeners.filter((l) => l !== listener) } } function notify() { for (const l of listeners) l() } function readStored(): string | null { try { return localStorage.getItem(STORAGE_KEY) } catch { // Storage unavailable (private mode) — treat as "answered" so the banner // doesn't nag on every render; the choice just can't persist. return "unavailable" } } function hasValidConsent(raw: string | null): boolean { if (raw === null) return false if (raw === "unavailable") return true try { return (JSON.parse(raw) as StoredConsent).v === CONSENT_VERSION } catch { return false } } function applyAnalyticsChoice(analytics: boolean) { try { if (analytics) localStorage.removeItem("umami.disabled") else localStorage.setItem("umami.disabled", "1") } catch { // Storage unavailable — nothing to apply. } } export function CookieConsent() { // Server snapshot says "answered" so nothing renders during SSR/hydration. const raw = useSyncExternalStore(subscribe, readStored, () => "unavailable") const visible = !hasValidConsent(raw) // Re-apply a returning visitor's analytics opt-out (external system only). useEffect(() => { if (raw && raw !== "unavailable") { try { applyAnalyticsChoice((JSON.parse(raw) as StoredConsent).analytics) } catch { // Corrupt value — banner is showing anyway. } } }, [raw]) function choose(analytics: boolean) { const stored: StoredConsent = { v: CONSENT_VERSION, analytics, ts: new Date().toISOString() } try { localStorage.setItem(STORAGE_KEY, JSON.stringify(stored)) } catch { // Private mode — still honor the choice for this page view. } applyAnalyticsChoice(analytics) // Record the choice server-side for signed-in users (fire-and-forget). fetch("/api/gdpr/consent", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ analytics }), }).catch(() => {}) notify() } if (!visible) return null return (

We only use strictly-necessary cookies (sign-in and security) plus cookieless, privacy-friendly analytics. Choose “Essential only” to opt out of analytics. Details in our{" "} Cookie Policy .

) }