'use client'
import type { OverlayReconstructionProps } from './overlay-reconstruction-types'
import { KLAUSUR_API } from './overlay-reconstruction-types'
import { useOverlayReconstructionState } from './useOverlayReconstructionState'
import { OverlayToolbar } from './OverlayToolbar'
import { OverlayCellRenderer } from './OverlayCellRenderer'
export function OverlayReconstruction({ sessionId, onNext, wordResultOverride }: OverlayReconstructionProps) {
const state = useOverlayReconstructionState(sessionId, wordResultOverride)
const {
status,
error,
cells,
rows,
imageNaturalSize,
textOpacity,
textColor,
changedCount,
medianCellHeightPx,
fontScale,
globalBold,
cellWordPositions,
reconRef,
handleTextChange,
handleKeyDown,
getDisplayText,
isEdited,
resetCell,
saveReconstruction,
loadSessionData,
setError,
setImageNaturalSize,
} = state
if (!sessionId) {
return
Bitte zuerst eine Session auswaehlen.
}
if (status === 'loading') {
return (
Overlay-Daten werden geladen...
)
}
if (status === 'error') {
return (
⚠️
Fehler
{error}
)
}
if (status === 'saved') {
return (
✅
Overlay gespeichert
{changedCount > 0 ? `${changedCount} Zellen wurden aktualisiert.` : 'Keine Aenderungen vorgenommen.'}
)
}
const imgW = imageNaturalSize?.w || 1
const imgH = imageNaturalSize?.h || 1
const colorValue = textColor === 'black' ? '#1a1a1a' : textColor
const dewarpedUrl = sessionId
? `${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/image/cropped`
: ''
return (
{/* Toolbar */}
{/* True overlay: text layer on top of original image */}
{/* Background: original image */}
{/* eslint-disable-next-line @next/next/no-img-element */}

{
const img = e.target as HTMLImageElement
setImageNaturalSize({ w: img.naturalWidth, h: img.naturalHeight })
}}
/>
{/* Text overlay layer */}
{/* Row lines */}
{rows.map((row, i) => (
))}
{/* Cells */}
{cells.map((cell) => (
))}
{/* Bottom action */}
)
}