'use client' import { useState } from 'react' import { Zap, X, RefreshCw, History, CheckCircle2 } from 'lucide-react' import { BACKEND_URL, DOMAIN_OPTIONS, COLLECTION_OPTIONS } from './helpers' interface GeneratorModalProps { onClose: () => void onComplete: () => void } export function GeneratorModal({ onClose, onComplete }: GeneratorModalProps) { const [generating, setGenerating] = useState(false) const [genResult, setGenResult] = useState | null>(null) const [genDomain, setGenDomain] = useState('') const [genMaxControls, setGenMaxControls] = useState(10) const [genDryRun, setGenDryRun] = useState(true) const [genCollections, setGenCollections] = useState([]) const [showJobHistory, setShowJobHistory] = useState(false) const [jobHistory, setJobHistory] = useState>>([]) const handleGenerate = async () => { setGenerating(true) setGenResult(null) try { const res = await fetch(`${BACKEND_URL}?endpoint=generate`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ domain: genDomain || null, collections: genCollections.length > 0 ? genCollections : null, max_controls: genMaxControls, dry_run: genDryRun, skip_web_search: false, }), }) if (!res.ok) { const err = await res.json() setGenResult({ status: 'error', message: err.error || err.details || 'Fehler' }) return } const data = await res.json() setGenResult(data) if (!genDryRun) { onComplete() } } catch { setGenResult({ status: 'error', message: 'Netzwerkfehler' }) } finally { setGenerating(false) } } const loadJobHistory = async () => { try { const res = await fetch(`${BACKEND_URL}?endpoint=generate-jobs`) if (res.ok) { const data = await res.json() setJobHistory(data.jobs || []) } } catch { /* ignore */ } } const toggleCollection = (col: string) => { setGenCollections(prev => prev.includes(col) ? prev.filter(c => c !== col) : [...prev, col] ) } return (

Control Generator

{showJobHistory ? (

Letzte Generierungs-Jobs

{jobHistory.length === 0 ? (

Keine Jobs vorhanden.

) : (
{jobHistory.map((job, i) => (
{String(job.status)} {String(job.created_at || '').slice(0, 16)}
Chunks: {String(job.total_chunks_scanned || 0)} Generiert: {String(job.controls_generated || 0)} Verifiziert: {String(job.controls_verified || 0)}
))}
)}
) : (
{COLLECTION_OPTIONS.map(col => ( ))}
{genCollections.length === 0 && (

Keine Auswahl = alle Collections

)}
setGenMaxControls(parseInt(e.target.value))} className="w-full" />
setGenDryRun(e.target.checked)} className="rounded border-gray-300" />
{/* Results */} {genResult && (
{genResult.status !== 'error' && }

{String(genResult.message || genResult.status)}

{genResult.status !== 'error' && (
Chunks gescannt: {String(genResult.total_chunks_scanned)} Controls generiert: {String(genResult.controls_generated)} Verifiziert: {String(genResult.controls_verified)} Review noetig: {String(genResult.controls_needs_review)} Zu aehnlich: {String(genResult.controls_too_close)} Duplikate: {String(genResult.controls_duplicates_found)}
)} {Array.isArray(genResult.errors) && (genResult.errors as string[]).length > 0 && (
{(genResult.errors as string[]).slice(0, 3).map((e, i) =>

{e}

)}
)}
)}
)}
) }