'use client' import { useState, useEffect } from 'react' interface IABPurpose { id: number name: string name_de: string } const API = '/api/sdk/v1/compliance/tcf' export function TCFSettings({ siteId, tcfEnabled, onToggle }: { siteId?: string tcfEnabled: boolean onToggle: (enabled: boolean) => void }) { const [purposes, setPurposes] = useState([]) const [categoryMap, setCategoryMap] = useState>({}) const [testResult, setTestResult] = useState(null) const [testing, setTesting] = useState(false) useEffect(() => { Promise.all([ fetch(`${API}/purposes`).then(r => r.ok ? r.json() : []), fetch(`${API}/category-mapping`).then(r => r.ok ? r.json() : {}), ]).then(([p, m]) => { setPurposes(p) setCategoryMap(m) }).catch(() => {}) }, []) const handleTestEncode = async () => { setTesting(true) setTestResult(null) try { const res = await fetch(`${API}/encode-categories`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ categories: ['necessary', 'statistics', 'marketing'] }), }) if (res.ok) { const data = await res.json() setTestResult(`TC String: ${data.tc_string}\nPurposes: ${data.purposes_consented.join(', ')}`) } } catch { setTestResult('Fehler beim Generieren') } setTesting(false) } return (
{/* Enable/Disable */}

IAB TCF 2.2

Transparency & Consent Framework — Standardisierte Einwilligungssignale fuer programmatische Werbung

{!tcfEnabled && (

TCF ist nur erforderlich wenn Sie programmatische Werbung (AdTech) einsetzen. Fuer die meisten Websites reicht das Standard-Cookie-Banner.

)}
{tcfEnabled && ( <> {/* IAB Purposes */}

12 IAB-Zwecke (Purposes)

Diese Zwecke werden automatisch aus Ihren Cookie-Kategorien abgeleitet.

{purposes.map(p => { const activeCats = Object.entries(categoryMap) .filter(([, pids]) => pids.includes(p.id)) .map(([cat]) => cat) return (
0 ? 'bg-green-50' : 'bg-gray-50'}`}> 0 ? 'bg-green-500 text-white' : 'bg-gray-300 text-white'}`}> {p.id}
{p.name_de}
{activeCats.length > 0 && (
via: {activeCats.join(', ')}
)}
) })}
{/* Category Mapping */}

Kategorie → Purpose Zuordnung

{Object.entries(categoryMap).map(([cat, pids]) => (
{cat}
{pids.length === 0 ? ( Keine Einwilligung noetig ) : ( pids.map(pid => ( Purpose {pid} )) )}
))}
{/* TC String Test */}

TC String testen

{testResult && (
                {testResult}
              
)}

Simuliert: necessary + statistics + marketing → generiert base64url-codierten TC String

{/* CMP Registration Info */}

CMP-Registrierung

Fuer den produktiven Einsatz muss Ihr CMP bei der IAB Europe registriert werden. Sie erhalten eine eindeutige CMP-ID die im TC String codiert wird.

Registrierung: iabeurope.eu/tcf-for-cmps

)}
) }