'use client' import { useCallback, useEffect, useState } from 'react' import type { ExcludeRegion, StructureResult } from '@/app/(admin)/ai/ocr-kombi/types' import { KLAUSUR_API, type DetectionMethod } from './structure-detection-utils' import { StructureImageComparison } from './StructureImageComparison' import { StructureResultDetails } from './StructureResultDetails' import { ExcludeRegionsList } from './ExcludeRegionsList' interface StepStructureDetectionProps { sessionId: string | null onNext: () => void } export function StepStructureDetection({ sessionId, onNext }: StepStructureDetectionProps) { const [result, setResult] = useState(null) const [detecting, setDetecting] = useState(false) const [error, setError] = useState(null) const [hasRun, setHasRun] = useState(false) const [overlayTs, setOverlayTs] = useState(0) const [detectionMethod, setDetectionMethod] = useState('auto') // Exclude region state const [excludeRegions, setExcludeRegions] = useState([]) const [saving, setSaving] = useState(false) const [drawMode, setDrawMode] = useState(false) // Auto-trigger detection on mount useEffect(() => { if (!sessionId || hasRun) return setHasRun(true) const runDetection = async () => { setDetecting(true) setError(null) try { const params = detectionMethod !== 'auto' ? `?method=${detectionMethod}` : '' const res = await fetch(`${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/detect-structure${params}`, { method: 'POST', }) if (!res.ok) { throw new Error('Strukturerkennung fehlgeschlagen') } const data = await res.json() setResult(data) setExcludeRegions(data.exclude_regions || []) setOverlayTs(Date.now()) } catch (e) { setError(e instanceof Error ? e.message : 'Unbekannter Fehler') } finally { setDetecting(false) } } runDetection() }, [sessionId, hasRun]) const handleRerun = async () => { if (!sessionId) return setDetecting(true) setError(null) try { const params = detectionMethod !== 'auto' ? `?method=${detectionMethod}` : '' const res = await fetch(`${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/detect-structure${params}`, { method: 'POST', }) if (!res.ok) throw new Error('Erneute Erkennung fehlgeschlagen') const data = await res.json() setResult(data) setExcludeRegions(data.exclude_regions || []) setOverlayTs(Date.now()) } catch (e) { setError(e instanceof Error ? e.message : 'Unbekannter Fehler') } finally { setDetecting(false) } } // Save exclude regions to backend const saveExcludeRegions = useCallback(async (regions: ExcludeRegion[]) => { if (!sessionId) return setSaving(true) try { const res = await fetch(`${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/exclude-regions`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ regions }), }) if (!res.ok) throw new Error('Speichern fehlgeschlagen') } catch (e) { setError(e instanceof Error ? e.message : 'Speichern fehlgeschlagen') } finally { setSaving(false) } }, [sessionId]) const handleAddRegion = useCallback((region: ExcludeRegion) => { const updated = [...excludeRegions, region] setExcludeRegions(updated) saveExcludeRegions(updated) }, [excludeRegions, saveExcludeRegions]) const handleDeleteRegion = useCallback(async (index: number) => { if (!sessionId) return setSaving(true) try { const res = await fetch(`${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/exclude-regions/${index}`, { method: 'DELETE', }) if (!res.ok) throw new Error('Loeschen fehlgeschlagen') const updated = excludeRegions.filter((_, i) => i !== index) setExcludeRegions(updated) } catch (e) { setError(e instanceof Error ? e.message : 'Loeschen fehlgeschlagen') } finally { setSaving(false) } }, [sessionId, excludeRegions]) if (!sessionId) { return
Keine Session ausgewaehlt.
} return (
{/* Loading indicator */} {detecting && (
Dokumentstruktur wird analysiert...
)} {/* Detection method toggle */}
Methode: {(['auto', 'opencv', 'ppdoclayout'] as DetectionMethod[]).map((method) => ( ))} {detectionMethod === 'auto' ? 'PP-DocLayout wenn verfuegbar, sonst OpenCV' : detectionMethod === 'ppdoclayout' ? 'ONNX-basierte Layouterkennung mit Klassifikation' : 'Klassische OpenCV-Konturerkennung'}
{/* Draw mode toggle */} {result && (
{drawMode && ( Rechteck auf dem Bild zeichnen um Bereiche von der OCR-Erkennung auszuschliessen )} {saving && ( Speichern... )}
)} {/* Two-column image comparison */} {result && ( )} {/* Exclude regions list */} {/* Result info */} {result && ( )} {/* Action buttons */} {result && (
)} {error && (
{error}
)}
) }