[split-required] Split final 43 files (500-668 LOC) to complete refactoring
klausur-service (11 files): - cv_gutter_repair, ocr_pipeline_regression, upload_api - ocr_pipeline_sessions, smart_spell, nru_worksheet_generator - ocr_pipeline_overlays, mail/aggregator, zeugnis_api - cv_syllable_detect, self_rag backend-lehrer (17 files): - classroom_engine/suggestions, generators/quiz_generator - worksheets_api, llm_gateway/comparison, state_engine_api - classroom/models (→ 4 submodules), services/file_processor - alerts_agent/api/wizard+digests+routes, content_generators/pdf - classroom/routes/sessions, llm_gateway/inference - classroom_engine/analytics, auth/keycloak_auth - alerts_agent/processing/rule_engine, ai_processor/print_versions agent-core (5 files): - brain/memory_store, brain/knowledge_graph, brain/context_manager - orchestrator/supervisor, sessions/session_manager admin-lehrer (5 components): - GridOverlay, StepGridReview, DevOpsPipelineSidebar - DataFlowDiagram, sbom/wizard/page website (2 files): - DependencyMap, lehrer/abitur-archiv Other: nibis_ingestion, grid_detection_service, export-doclayout-onnx Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -474,76 +474,5 @@ export function GridOverlay({
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* GridStats Component
|
||||
*/
|
||||
interface GridStatsProps {
|
||||
stats: GridData['stats']
|
||||
deskewAngle?: number
|
||||
source?: string
|
||||
className?: string
|
||||
}
|
||||
|
||||
export function GridStats({ stats, deskewAngle, source, className }: GridStatsProps) {
|
||||
const coveragePercent = Math.round(stats.coverage * 100)
|
||||
|
||||
return (
|
||||
<div className={cn('flex flex-wrap gap-3', className)}>
|
||||
<div className="px-3 py-1.5 bg-green-50 text-green-700 rounded-lg text-sm font-medium">
|
||||
Erkannt: {stats.recognized}
|
||||
</div>
|
||||
{(stats.manual ?? 0) > 0 && (
|
||||
<div className="px-3 py-1.5 bg-blue-50 text-blue-700 rounded-lg text-sm font-medium">
|
||||
Manuell: {stats.manual}
|
||||
</div>
|
||||
)}
|
||||
{stats.problematic > 0 && (
|
||||
<div className="px-3 py-1.5 bg-orange-50 text-orange-700 rounded-lg text-sm font-medium">
|
||||
Problematisch: {stats.problematic}
|
||||
</div>
|
||||
)}
|
||||
<div className="px-3 py-1.5 bg-slate-50 text-slate-600 rounded-lg text-sm font-medium">
|
||||
Leer: {stats.empty}
|
||||
</div>
|
||||
<div className="px-3 py-1.5 bg-indigo-50 text-indigo-700 rounded-lg text-sm font-medium">
|
||||
Abdeckung: {coveragePercent}%
|
||||
</div>
|
||||
{deskewAngle !== undefined && deskewAngle !== 0 && (
|
||||
<div className="px-3 py-1.5 bg-purple-50 text-purple-700 rounded-lg text-sm font-medium">
|
||||
Begradigt: {deskewAngle.toFixed(1)}
|
||||
</div>
|
||||
)}
|
||||
{source && (
|
||||
<div className="px-3 py-1.5 bg-cyan-50 text-cyan-700 rounded-lg text-sm font-medium">
|
||||
Quelle: {source === 'tesseract+grid_service' ? 'Tesseract' : 'Vision LLM'}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Legend Component for GridOverlay
|
||||
*/
|
||||
export function GridLegend({ className }: { className?: string }) {
|
||||
return (
|
||||
<div className={cn('flex flex-wrap gap-4 text-sm', className)}>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-4 h-4 rounded border-2 border-green-500 bg-green-500/20" />
|
||||
<span className="text-slate-600">Erkannt</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-4 h-4 rounded border-2 border-orange-500 bg-orange-500/30" />
|
||||
<span className="text-slate-600">Problematisch</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-4 h-4 rounded border-2 border-blue-500 bg-blue-500/20" />
|
||||
<span className="text-slate-600">Manuell korrigiert</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-4 h-4 rounded border-2 border-slate-300 bg-transparent" />
|
||||
<span className="text-slate-600">Leer</span>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
// Re-export widgets from sibling file for backwards compatibility
|
||||
export { GridStats, GridLegend } from './GridOverlayWidgets'
|
||||
|
||||
84
admin-lehrer/components/ocr/GridOverlayWidgets.tsx
Normal file
84
admin-lehrer/components/ocr/GridOverlayWidgets.tsx
Normal file
@@ -0,0 +1,84 @@
|
||||
'use client'
|
||||
|
||||
/**
|
||||
* GridOverlay Widgets - GridStats and GridLegend
|
||||
*
|
||||
* Extracted from GridOverlay.tsx to keep each file under 500 LOC.
|
||||
*/
|
||||
|
||||
import { cn } from '@/lib/utils'
|
||||
import type { GridData } from './GridOverlay'
|
||||
|
||||
/**
|
||||
* GridStats Component
|
||||
*/
|
||||
interface GridStatsProps {
|
||||
stats: GridData['stats']
|
||||
deskewAngle?: number
|
||||
source?: string
|
||||
className?: string
|
||||
}
|
||||
|
||||
export function GridStats({ stats, deskewAngle, source, className }: GridStatsProps) {
|
||||
const coveragePercent = Math.round(stats.coverage * 100)
|
||||
|
||||
return (
|
||||
<div className={cn('flex flex-wrap gap-3', className)}>
|
||||
<div className="px-3 py-1.5 bg-green-50 text-green-700 rounded-lg text-sm font-medium">
|
||||
Erkannt: {stats.recognized}
|
||||
</div>
|
||||
{(stats.manual ?? 0) > 0 && (
|
||||
<div className="px-3 py-1.5 bg-blue-50 text-blue-700 rounded-lg text-sm font-medium">
|
||||
Manuell: {stats.manual}
|
||||
</div>
|
||||
)}
|
||||
{stats.problematic > 0 && (
|
||||
<div className="px-3 py-1.5 bg-orange-50 text-orange-700 rounded-lg text-sm font-medium">
|
||||
Problematisch: {stats.problematic}
|
||||
</div>
|
||||
)}
|
||||
<div className="px-3 py-1.5 bg-slate-50 text-slate-600 rounded-lg text-sm font-medium">
|
||||
Leer: {stats.empty}
|
||||
</div>
|
||||
<div className="px-3 py-1.5 bg-indigo-50 text-indigo-700 rounded-lg text-sm font-medium">
|
||||
Abdeckung: {coveragePercent}%
|
||||
</div>
|
||||
{deskewAngle !== undefined && deskewAngle !== 0 && (
|
||||
<div className="px-3 py-1.5 bg-purple-50 text-purple-700 rounded-lg text-sm font-medium">
|
||||
Begradigt: {deskewAngle.toFixed(1)}
|
||||
</div>
|
||||
)}
|
||||
{source && (
|
||||
<div className="px-3 py-1.5 bg-cyan-50 text-cyan-700 rounded-lg text-sm font-medium">
|
||||
Quelle: {source === 'tesseract+grid_service' ? 'Tesseract' : 'Vision LLM'}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Legend Component for GridOverlay
|
||||
*/
|
||||
export function GridLegend({ className }: { className?: string }) {
|
||||
return (
|
||||
<div className={cn('flex flex-wrap gap-4 text-sm', className)}>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-4 h-4 rounded border-2 border-green-500 bg-green-500/20" />
|
||||
<span className="text-slate-600">Erkannt</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-4 h-4 rounded border-2 border-orange-500 bg-orange-500/30" />
|
||||
<span className="text-slate-600">Problematisch</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-4 h-4 rounded border-2 border-blue-500 bg-blue-500/20" />
|
||||
<span className="text-slate-600">Manuell korrigiert</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-4 h-4 rounded border-2 border-slate-300 bg-transparent" />
|
||||
<span className="text-slate-600">Leer</span>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user