'use client' import { useState } from 'react' import { useBannerConsents } from '../_hooks/useBannerConsents' import { BannerConsentRecord, PAGE_SIZE } from '../_types' function formatDate(iso: string | null): string { if (!iso) return '—' return new Date(iso).toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' }) } function shortenFingerprint(fp: string): string { return fp.length > 12 ? fp.slice(0, 12) + '...' : fp } function shortenUA(ua: string | null): string { if (!ua) return '—' const match = ua.match(/(Chrome|Safari|Firefox|Edge|Opera)\/[\d.]+/) if (match) return match[0] return ua.length > 30 ? ua.slice(0, 30) + '...' : ua } const categoryColors: Record = { essential: 'bg-gray-100 text-gray-700', functional: 'bg-blue-100 text-blue-700', analytics: 'bg-purple-100 text-purple-700', marketing: 'bg-pink-100 text-pink-700', } const methodLabels: Record = { accept_all: 'Alle akzeptiert', reject_all: 'Nur notwendige', custom_selection: 'Individuelle Auswahl', } const methodColors: Record = { accept_all: 'bg-green-100 text-green-700', reject_all: 'bg-red-100 text-red-700', custom_selection: 'bg-yellow-100 text-yellow-700', } export default function BannerConsentsTab() { const { records, sites, selectedSite, changeSite, stats, currentPage, setCurrentPage, totalRecords, loading, } = useBannerConsents() const [detail, setDetail] = useState(null) const totalPages = Math.ceil(totalRecords / PAGE_SIZE) return (
{/* Stats + Site Selector */}
{totalRecords} Consents
{stats && Object.keys(stats.category_acceptance).length > 0 && (
{Object.entries(stats.category_acceptance).map(([cat, data]) => ( {cat}: {data.rate}% ))}
)}
{sites.length > 0 && ( )}
{/* Table */}
{loading && records.length === 0 ? ( ) : records.length === 0 ? ( ) : ( records.map(record => ( )) )}
Device Kategorien Methode Erteilt am Ablauf Browser Aktion
Laden...
Keine Consents vorhanden
{shortenFingerprint(record.device_fingerprint)}
{record.categories.length > 0 ? record.categories.map(cat => ( {cat} )) : }
{record.consent_method ? ( {methodLabels[record.consent_method] || record.consent_method} ) : } {formatDate(record.created_at)} {formatDate(record.expires_at)} {shortenUA(record.user_agent)}
{/* Pagination */} {totalPages > 1 && (
Seite {currentPage} von {totalPages} ({totalRecords} Einträge)
)} {/* Detail Modal */} {detail && (
setDetail(null)}>
e.stopPropagation()}>

Consent Details

ID{detail.id}
Site{detail.site_id}
Device{detail.device_fingerprint}
Kategorien
{detail.categories.map(cat => ( {cat} ))}
Methode {detail.consent_method ? ( {methodLabels[detail.consent_method] || detail.consent_method} ) : '—'}
Verknüpft mit {detail.linked_email || '— (anonym)'}
Erteilt{formatDate(detail.created_at)}
Ablauf{formatDate(detail.expires_at)}
Aktualisiert{formatDate(detail.updated_at)}
Geltungsbereich{detail.consent_scope || '—'}
{detail.banner_version && (
Banner-Version{detail.banner_version}
)} {/* Tracking-Kontext */}

Tracking-Kontext

{detail.page_url &&
Seite{detail.page_url}
} {detail.referrer &&
Referrer{detail.referrer}
} {detail.geo_country &&
Land{detail.geo_country}{detail.geo_region ? ` / ${detail.geo_region}` : ''}
}
{/* Device-Informationen */}

Device

Typ{detail.device_type || '—'} Browser{detail.browser || shortenUA(detail.user_agent)} OS{detail.os || '—'} Auflösung{detail.screen_resolution || '—'}
{/* Scripts & Cookies */} {(detail.scripts_released?.length > 0 || detail.cookies_set?.length > 0) && (

Scripts & Cookies

{detail.scripts_released?.length > 0 && (
Freigegebene Scripts {detail.scripts_released.map((s, i) => (

{s.src} {s.category}

))}
)} {detail.scripts_blocked?.length > 0 && (
Blockierte Scripts {detail.scripts_blocked.map((s, i) => (

{s.src} {s.category}

))}
)} {detail.cookies_set?.length > 0 && (
Gesetzte Cookies {detail.cookies_set.map((c, i) => (

{c.name} ({c.domain}) {c.category}

))}
)}
)} {/* Technische Details */}

Technisch

User-Agent

{detail.user_agent || '—'}

{detail.ip_hash &&
IP-Hash

{detail.ip_hash}

} {detail.session_id &&
Session

{detail.session_id}

} {detail.banner_config_hash &&
Config-Hash

{detail.banner_config_hash}

}
)}
) }