'use client' import { RefObject } from 'react' import type { GridResult, GridCell } from '@/app/(admin)/ai/ocr-kombi/types' import { colTypeLabel, colTypeColor, confColor, CellCrop } from './WordRecognitionUtils' const KLAUSUR_API = '/klausur-api' interface WordRecognitionLabelingProps { sessionId: string gridResult: GridResult | null editedCells: GridCell[] activeIndex: number setActiveIndex: (idx: number) => void columnsUsed: GridResult['columns_used'] getUniqueRowCount: () => number getRowCells: (rowPosition: number) => GridCell[] updateCell: (cellId: string, value: string) => void confirmEntry: () => void skipEntry: () => void enRef: RefObject /** cellsByRow map + sorted row indices, pre-computed by parent */ cellsByRow: Map sortedRowIndices: number[] } export function WordRecognitionLabeling({ sessionId, gridResult, editedCells, activeIndex, setActiveIndex, columnsUsed, getUniqueRowCount, getRowCells, updateCell, confirmEntry, skipEntry, enRef, cellsByRow, sortedRowIndices, }: WordRecognitionLabelingProps) { if (editedCells.length === 0) return null const overlayUrl = `${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/image/words-overlay` const dewarpedUrl = `${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/image/cropped` return (
{/* Left 2/3: Image with highlighted active row */}
Zeile {activeIndex + 1} von {getUniqueRowCount()}
{/* eslint-disable-next-line @next/next/no-img-element */} Wort-Overlay {/* Highlight overlay for active row */} {(() => { const rowCells = getRowCells(activeIndex) return rowCells.map(cell => (
)) })()}
{/* Right 1/3: Editable fields */}
{/* Navigation */}
{activeIndex + 1} / {getUniqueRowCount()}
{/* Status badge */}
{(() => { const rowCells = getRowCells(activeIndex) const avgConf = rowCells.length ? Math.round(rowCells.reduce((s, c) => s + c.confidence, 0) / rowCells.length) : 0 return ( {avgConf}% Konfidenz ) })()}
{/* Editable fields -- one per column, driven by columns_used */}
{(() => { const rowCells = getRowCells(activeIndex) return columnsUsed.map((col, colIdx) => { const cell = rowCells.find(c => c.col_index === col.index) if (!cell) return null return (
{cell.cell_id}
{/* Cell crop */}