'use client' import React, { useState } from 'react' import { ChecklistView } from './ChecklistView' interface CheckItem { id: string; label: string; passed: boolean; severity: string matched_text: string; level?: number; parent?: string | null skipped?: boolean; hint?: string } export function ImpressumCheckTab() { const [url, setUrl] = useState(() => typeof window !== 'undefined' ? localStorage.getItem('impressum-check-url') || '' : '' ) const [loading, setLoading] = useState(false) const [progress, setProgress] = useState('') const [error, setError] = useState(null) const [results, setResults] = useState(() => { if (typeof window === 'undefined') return null try { const s = localStorage.getItem('impressum-check-results'); return s ? JSON.parse(s) : null } catch { return null } }) const [history, setHistory] = useState<{ url: string; date: string; findings: number; pct: number; resultKey: string }[]>(() => { if (typeof window === 'undefined') return [] try { return JSON.parse(localStorage.getItem('impressum-check-history') || '[]') } catch { return [] } }) const [useAgent, setUseAgent] = useState(false) React.useEffect(() => { localStorage.setItem('impressum-check-url', url) }, [url]) const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() if (!url.trim()) return setLoading(true) setError(null) setResults(null) setProgress('Impressum wird geprueft...') try { const startRes = await fetch('/api/sdk/v1/agent/doc-check', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ entries: [{ doc_type: 'impressum', label: 'Impressum', url: url.trim() }], recipient: 'dsb@breakpilot.local', use_agent: useAgent, }), }) if (!startRes.ok) throw new Error(`Fehler: ${startRes.status}`) const { check_id } = await startRes.json() if (!check_id) throw new Error('Keine Check-ID erhalten') let attempts = 0 while (attempts < 120) { await new Promise(r => setTimeout(r, 3000)) const pollRes = await fetch(`/api/sdk/v1/agent/doc-check?check_id=${check_id}`) if (!pollRes.ok) { attempts++; continue } const pollData = await pollRes.json() if (pollData.progress) setProgress(pollData.progress) if (pollData.status === 'completed' && pollData.result) { setResults(pollData.result) setProgress('') localStorage.setItem('impressum-check-results', JSON.stringify(pollData.result)) const resultKey = `impressum-result-${Date.now()}` try { localStorage.setItem(resultKey, JSON.stringify(pollData.result)) } catch {} const total = pollData.result.total_findings || 0 const pct = pollData.result.results?.[0]?.completeness_pct || 0 const entry = { url: url.trim(), date: new Date().toISOString(), findings: total, pct, resultKey } const updated = [entry, ...history].slice(0, 30) setHistory(updated) localStorage.setItem('impressum-check-history', JSON.stringify(updated)) break } if (pollData.status === 'failed') throw new Error(pollData.error || 'Pruefung fehlgeschlagen') attempts++ } } catch (e) { setError(e instanceof Error ? e.message : 'Unbekannter Fehler') setProgress('') } finally { setLoading(false) } } return (

Impressum-Check (§5 TMG / §18 MStV)

Prueft 16 Pflichtangaben: Anbietername, Anschrift, Kontaktdaten, Handelsregister, USt-IdNr., Vertretungsberechtigte, V.i.S.d.P., Streitbeilegung.

setUrl(e.target.value)} placeholder="https://www.example.com/impressum" className="flex-1 px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent text-sm" disabled={loading} required />
{progress && (
{progress}
)} {error &&
{error}
} {results?.results && (
{results.email_status && (
E-Mail: {results.email_status === 'sent' ? 'Gesendet' : results.email_status}
)}
)} {history.length > 0 && (

Letzte Impressum-Checks

{history.map((h, i) => ( ))}
)}
) }