'use client' import { useEffect, useState } from 'react' import type { DeskewResult, DewarpResult, DewarpGroundTruth } from '@/app/(admin)/ai/ocr-kombi/types' import { METHOD_LABELS, SHEAR_METHOD_KEYS } from './dewarp-constants' import { FineTuneSlider } from './FineTuneSlider' interface DewarpFineTunePanelProps { dewarpResult: DewarpResult deskewResult?: DeskewResult | null showFineTune: boolean onToggleFineTune: () => void onCombinedAdjust: (rotationDegrees: number, shearDegrees: number) => void onGroundTruth: (gt: DewarpGroundTruth) => void isApplying: boolean gtSaved: boolean onGtSaved: () => void } export function DewarpFineTunePanel({ dewarpResult, deskewResult, showFineTune, onToggleFineTune, onCombinedAdjust, onGroundTruth, isApplying, gtSaved, onGtSaved, }: DewarpFineTunePanelProps) { // Fine-tuning rotation sliders (3 passes) const [p1Iterative, setP1Iterative] = useState(0) const [p2Residual, setP2Residual] = useState(0) const [p3Textline, setP3Textline] = useState(0) // Fine-tuning shear sliders (4 methods) + selected method const [shearValues, setShearValues] = useState>({ vertical_edge: 0, projection: 0, hough_lines: 0, text_lines: 0, }) const [selectedShearMethod, setSelectedShearMethod] = useState('vertical_edge') // Initialize fine-tuning sliders from deskew result useEffect(() => { if (deskewResult) { setP1Iterative(deskewResult.angle_iterative ?? 0) setP2Residual(deskewResult.angle_residual ?? 0) setP3Textline(deskewResult.angle_textline ?? 0) } }, [deskewResult]) // Initialize shear sliders from dewarp detections useEffect(() => { if (dewarpResult?.detections) { const newValues = { ...shearValues } let bestMethod = selectedShearMethod let bestConf = -1 for (const d of dewarpResult.detections) { if (d.method in newValues) { newValues[d.method] = d.shear_degrees if (d.confidence > bestConf) { bestConf = d.confidence bestMethod = d.method } } } setShearValues(newValues) // Select the method that was actually used, or the highest confidence if (dewarpResult.method_used && dewarpResult.method_used in newValues) { setSelectedShearMethod(dewarpResult.method_used) } else { setSelectedShearMethod(bestMethod) } } // eslint-disable-next-line react-hooks/exhaustive-deps }, [dewarpResult?.detections]) const rotationSum = p1Iterative + p2Residual + p3Textline const activeShear = shearValues[selectedShearMethod] ?? 0 const handleShearValueChange = (method: string, value: number) => { setShearValues((prev) => ({ ...prev, [method]: value })) } const handleFineTunePreview = () => { onCombinedAdjust(rotationSum, activeShear) } return (
{showFineTune && (
{/* Rotation section */}
Rotation (Begradigung)
Summe Rotation {rotationSum >= 0 ? '+' : ''}{rotationSum.toFixed(2)}\u00B0
{/* Shear section */}
Scherung (Entzerrung) — einen Wert waehlen
{SHEAR_METHOD_KEYS.map((method) => ( handleShearValueChange(method, v)} min={-5} max={5} step={0.05} radioName="shear-method" radioChecked={selectedShearMethod === method} onRadioChange={() => setSelectedShearMethod(method)} /> ))}
Gewaehlte Scherung {activeShear >= 0 ? '+' : ''}{activeShear.toFixed(2)}\u00B0 ({METHOD_LABELS[selectedShearMethod]})
{/* Preview + Save */}
Rotation: {rotationSum >= 0 ? '+' : ''}{rotationSum.toFixed(2)}\u00B0 + Scherung: {activeShear >= 0 ? '+' : ''}{activeShear.toFixed(2)}\u00B0
)}
) }