- Klicken Sie auf das Bild, um vertikale Trennlinien zu setzen.
- {dividers.length > 0 && (
-
- {dividers.length} Linien = {dividers.length + 1} Spalten
-
+ {/* Two-column layout: image (left) + controls (right) */}
+
+ {/* Left: Interactive image */}
+
+
+
+ Klicken um Trennlinien zu setzen
+
+
+
+
+ {/* eslint-disable-next-line @next/next/no-img-element */}
+

setImageLoaded(true)}
+ />
+
+ {imageLoaded && (
+ <>
+ {/* Column overlays */}
+ {columnRegions.map((region, i) => (
+
+
+ {i + 1}
+
+
+ ))}
+
+ {/* Divider lines */}
+ {sorted.map((xPct, i) => (
+
handleDividerMouseDown(e, i)}
+ >
+ {/* Visible line */}
+
+ {/* Delete button */}
+
+
+ ))}
+ >
+ )}
+
+
+
+ {/* Right: Column type assignment + actions */}
+
+
+ Spaltentypen
+
+
+ {dividers.length === 0 ? (
+
+
👆
+
+ Klicken Sie auf das Bild links, um vertikale Trennlinien zwischen den Spalten zu setzen.
+
+
+ Linien koennen per Drag verschoben und per Hover geloescht werden.
+
+
+ ) : (
+
+
+
+ {dividers.length} Linien = {dividers.length + 1} Spalten
+
+
+
+ {columnRegions.map((region, i) => (
+
+
+ Spalte {i + 1}
+
+
+
+ {Math.round(region.rightPct - region.leftPct)}%
+
+
+ ))}
+
+
)}
-
-
-
- {/* Interactive image area */}
-
- {/* eslint-disable-next-line @next/next/no-img-element */}
-

setImageLoaded(true)}
- />
-
- {imageLoaded && (
- <>
- {/* Column overlays */}
- {columnRegions.map((region, i) => (
-
-
- {i + 1}
-
-
- ))}
-
- {/* Divider lines */}
- {sorted.map((xPct, i) => (
-
handleDividerMouseDown(e, i)}
- >
- {/* Visible line */}
-
- {/* Delete button */}
-
-
- ))}
- >
- )}
-
-
- {/* Column type assignment */}
- {dividers.length > 0 && (
-
-
- Spaltentypen zuweisen
-
-
- {columnRegions.map((region, i) => (
-
-
- Spalte {i + 1}
-
-
-
- {Math.round(region.rightPct - region.leftPct)}%
-
-
- ))}
+ {/* Action buttons */}
+
+
+
- )}
-
- {/* Action buttons */}
-
-
-
)
diff --git a/admin-lehrer/components/ocr-pipeline/StepColumnDetection.tsx b/admin-lehrer/components/ocr-pipeline/StepColumnDetection.tsx
index 5f14fbb..fe31287 100644
--- a/admin-lehrer/components/ocr-pipeline/StepColumnDetection.tsx
+++ b/admin-lehrer/components/ocr-pipeline/StepColumnDetection.tsx
@@ -20,15 +20,12 @@ export function StepColumnDetection({ sessionId, onNext }: StepColumnDetectionPr
const [applying, setApplying] = useState(false)
const [imageDimensions, setImageDimensions] = useState<{ width: number; height: number } | null>(null)
- // Auto-trigger column detection on mount
+ // Fetch session info (image dimensions) + check for cached column result
useEffect(() => {
- if (!sessionId || columnResult) return
+ if (!sessionId || imageDimensions) return
- const runDetection = async () => {
- setDetecting(true)
- setError(null)
+ const fetchSessionInfo = async () => {
try {
- // First check if columns already detected (reload case)
const infoRes = await fetch(`${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}`)
if (infoRes.ok) {
const info = await infoRes.json()
@@ -37,32 +34,22 @@ export function StepColumnDetection({ sessionId, onNext }: StepColumnDetectionPr
}
if (info.column_result) {
setColumnResult(info.column_result)
- setDetecting(false)
return
}
}
-
- // Run detection
- const res = await fetch(`${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/columns`, {
- method: 'POST',
- })
- if (!res.ok) {
- const err = await res.json().catch(() => ({ detail: res.statusText }))
- throw new Error(err.detail || 'Spaltenerkennung fehlgeschlagen')
- }
- const data: ColumnResult = await res.json()
- setColumnResult(data)
} catch (e) {
- setError(e instanceof Error ? e.message : 'Unbekannter Fehler')
- } finally {
- setDetecting(false)
+ console.error('Failed to fetch session info:', e)
}
+
+ // No cached result - run auto-detection
+ runAutoDetection()
}
- runDetection()
- }, [sessionId, columnResult])
+ fetchSessionInfo()
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [sessionId])
- const handleRerun = useCallback(async () => {
+ const runAutoDetection = useCallback(async () => {
if (!sessionId) return
setDetecting(true)
setError(null)
@@ -70,16 +57,23 @@ export function StepColumnDetection({ sessionId, onNext }: StepColumnDetectionPr
const res = await fetch(`${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/columns`, {
method: 'POST',
})
- if (!res.ok) throw new Error('Spaltenerkennung fehlgeschlagen')
+ if (!res.ok) {
+ const err = await res.json().catch(() => ({ detail: res.statusText }))
+ throw new Error(err.detail || 'Spaltenerkennung fehlgeschlagen')
+ }
const data: ColumnResult = await res.json()
setColumnResult(data)
} catch (e) {
- setError(e instanceof Error ? e.message : 'Fehler')
+ setError(e instanceof Error ? e.message : 'Unbekannter Fehler')
} finally {
setDetecting(false)
}
}, [sessionId])
+ const handleRerun = useCallback(() => {
+ runAutoDetection()
+ }, [runAutoDetection])
+
const handleGroundTruth = useCallback(async (gt: ColumnGroundTruth) => {
if (!sessionId) return
try {