'use client' /** * CookieLibraryPanel — Pro-Cookie-Abgleich gegen die Knowledge-Library: * findet als „notwendig" deklarierte Tracker + fehlende Zwecke und zeigt je * Befund die Abstellmaßnahme. Lädt aus dem Snapshot (kein Re-Crawl). */ import React, { useEffect, useState } from 'react' export interface CookieFinding { vendor: string cookie: string type: string severity: string declared: string library_purpose: string remediation: string control?: { control_id?: string | null; regulation?: string; article?: string } } interface CheckData { summary?: { checked?: number; in_library?: number; findings?: number } findings?: CookieFinding[] } const SEV_COLOR: Record = { HIGH: 'bg-red-100 text-red-700', MEDIUM: 'bg-amber-100 text-amber-700', LOW: 'bg-blue-100 text-blue-700', } const TYPE_LABEL: Record = { tracker_as_necessary: 'Tracker als „notwendig" deklariert', missing_purpose: 'Zweck fehlt', excessive_lifetime: 'Speicherdauer zu lang', vague_duration: 'Speicherdauer nicht konkret', third_country: 'Drittland-Transfer', eu_alternative: 'EU-Alternative verfügbar', } // Pure, testbar. export function CookieFindingList({ data }: { data: CheckData }) { const findings = data.findings || [] const s = data.summary || {} return (
Library-Abgleich — {findings.length} Befund{findings.length !== 1 ? 'e' : ''} {s.in_library ?? 0}/{s.checked ?? 0} Cookies in der Library erkannt
{findings.length === 0 ? (
Keine Abweichungen gegen die Library.
) : (
{findings.map((f, i) => (
{f.severity} {f.cookie} · {f.vendor} {TYPE_LABEL[f.type] || f.type}
{f.library_purpose && (
Library-Zweck: {f.library_purpose}
)}
{f.remediation}
{f.control?.regulation && f.control.regulation !== '—' && (
Rechtsgrundlage: {f.control.regulation} {f.control.article} {f.control.control_id && ` · Control ${f.control.control_id}`}
)}
))}
)}
) } export function CookieLibraryPanel({ snapshotId }: { snapshotId: string }) { const [data, setData] = useState(null) const [loading, setLoading] = useState(true) useEffect(() => { let cancelled = false fetch(`/api/sdk/v1/agent/snapshots/${snapshotId}/cookie-check`) .then(r => r.json()) .then(d => { if (!cancelled) setData(d) }) .catch(() => { if (!cancelled) setData({ findings: [] }) }) .finally(() => { if (!cancelled) setLoading(false) }) return () => { cancelled = true } }, [snapshotId]) if (loading) return
Library-Abgleich läuft…
return }