'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' import { CookieFindings } from './CookieFindings' export interface CookieFinding { vendor: string cookie: string type: string severity: string declared: string library_purpose: string remediation: string kind?: string control?: { control_id?: string | null; regulation?: string; article?: string } } interface CheckData { summary?: { checked?: number; in_library?: number; findings?: number } findings?: CookieFinding[] storage_inventory?: { total?: number by_type?: Record real_cookies?: number other_storage?: number } drift?: { declared_count?: number browser_count?: number high_findings?: number low_findings?: number } } const STORAGE_LABEL: Record = { cookie: 'Cookies', local_storage: 'Local Storage', session_storage: 'Session Storage', indexeddb: 'IndexedDB', framework_storage: 'Framework-Storage', } // Pure, testbar. export function CookieFindingList({ data }: { data: CheckData }) { const findings = data.findings || [] const s = data.summary || {} const inv = data.storage_inventory const drift = data.drift const driftShown = !!drift && ((drift.declared_count ?? 0) + (drift.browser_count ?? 0)) > 0 return (
{(driftShown || (inv && (inv.total ?? 0) > 0)) && (
{driftShown && (
Richtlinie ↔ Realität:{' '} {drift!.declared_count ?? 0} in der Cookie-Richtlinie dokumentiert · {drift!.browser_count ?? 0} im Browser geladen {(drift!.high_findings ?? 0) > 0 && ( <> · {drift!.high_findings} undokumentiert geladen )} {(drift!.low_findings ?? 0) > 0 && ( <> · {drift!.low_findings} dokumentiert, aber nicht geladen )}
)} {inv && (inv.total ?? 0) > 0 && (
Storage-Inventar:{' '} {inv.total} als „Cookies" gelistet →{' '} {inv.real_cookies} echte Cookies {(inv.other_storage ?? 0) > 0 && ( <> + {inv.other_storage} andere Endgeräte-Speicher )} {inv.by_type && ( ({Object.entries(inv.by_type) .map(([k, n]) => `${n} ${STORAGE_LABEL[k] || k}`) .join(' · ')}) )}
)}
)}
{s.in_library ?? 0}/{s.checked ?? 0} Cookies in der Library erkannt
) } export function CookieLibraryPanel( { snapshotId, data: provided }: { snapshotId: string; data?: CheckData }, ) { const [data, setData] = useState(provided ?? null) const [loading, setLoading] = useState(!provided) useEffect(() => { if (provided) { setData(provided); setLoading(false); return } 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, provided]) if (loading) return
Library-Abgleich läuft…
return }