'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 */} Original { 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 */}
) }