Files
breakpilot-lehrer/studio-v2/app/worksheet-cleanup/_components/PreviewStep.tsx
Benjamin Admin b6983ab1dc [split-required] Split 500-1000 LOC files across all services
backend-lehrer (5 files):
- alerts_agent/db/repository.py (992 → 5), abitur_docs_api.py (956 → 3)
- teacher_dashboard_api.py (951 → 3), services/pdf_service.py (916 → 3)
- mail/mail_db.py (987 → 6)

klausur-service (5 files):
- legal_templates_ingestion.py (942 → 3), ocr_pipeline_postprocess.py (929 → 4)
- ocr_pipeline_words.py (876 → 3), ocr_pipeline_ocr_merge.py (616 → 2)
- KorrekturPage.tsx (956 → 6)

website (5 pages):
- mail (985 → 9), edu-search (958 → 8), mac-mini (950 → 7)
- ocr-labeling (946 → 7), audit-workspace (871 → 4)

studio-v2 (5 files + 1 deleted):
- page.tsx (946 → 5), MessagesContext.tsx (925 → 4)
- korrektur (914 → 6), worksheet-cleanup (899 → 6)
- useVocabWorksheet.ts (888 → 3)
- Deleted dead page-original.tsx (934 LOC)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-24 23:35:37 +02:00

128 lines
5.7 KiB
TypeScript

'use client'
import { GlassCard } from './GlassCard'
import { ProgressRing } from './ProgressRing'
interface PreviewResult {
has_handwriting: boolean
confidence: number
handwriting_ratio: number
image_width: number
image_height: number
estimated_times_ms: {
detection: number
inpainting: number
reconstruction: number
total: number
}
}
interface PreviewStepProps {
previewResult: PreviewResult
previewUrl: string | null
maskUrl: string | null
removeHandwriting: boolean
reconstructLayout: boolean
isProcessing: boolean
onBack: () => void
onCleanup: () => void
onGetMask: () => void
}
export function PreviewStep({
previewResult, previewUrl, maskUrl,
removeHandwriting, reconstructLayout, isProcessing,
onBack, onCleanup, onGetMask
}: PreviewStepProps) {
return (
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
<GlassCard delay={100}>
<h3 className="text-lg font-semibold text-white mb-6">Analyse</h3>
<div className="flex justify-around">
<ProgressRing
progress={previewResult.confidence * 100}
label="Konfidenz"
value={`${Math.round(previewResult.confidence * 100)}%`}
color={previewResult.has_handwriting ? '#f97316' : '#22c55e'}
/>
<ProgressRing
progress={previewResult.handwriting_ratio * 100 * 10}
label="Handschrift"
value={`${(previewResult.handwriting_ratio * 100).toFixed(1)}%`}
color="#a78bfa"
/>
</div>
<div className={`mt-6 p-4 rounded-xl text-center ${
previewResult.has_handwriting ? 'bg-orange-500/20 text-orange-300' : 'bg-green-500/20 text-green-300'
}`}>
{previewResult.has_handwriting ? 'Handschrift erkannt' : 'Keine Handschrift gefunden'}
</div>
</GlassCard>
<GlassCard delay={200}>
<h3 className="text-lg font-semibold text-white mb-4">Geschätzte Zeit</h3>
<div className="space-y-3">
<div className="flex justify-between text-white/70">
<span>Erkennung</span>
<span className="text-white">~{Math.round(previewResult.estimated_times_ms.detection / 1000)}s</span>
</div>
{removeHandwriting && previewResult.has_handwriting && (
<div className="flex justify-between text-white/70">
<span>Bereinigung</span>
<span className="text-white">~{Math.round(previewResult.estimated_times_ms.inpainting / 1000)}s</span>
</div>
)}
{reconstructLayout && (
<div className="flex justify-between text-white/70">
<span>Layout</span>
<span className="text-white">~{Math.round(previewResult.estimated_times_ms.reconstruction / 1000)}s</span>
</div>
)}
<div className="flex justify-between pt-3 border-t border-white/10 font-medium">
<span className="text-white">Gesamt</span>
<span className="text-purple-300">~{Math.round(previewResult.estimated_times_ms.total / 1000)}s</span>
</div>
</div>
</GlassCard>
<GlassCard delay={300}>
<h3 className="text-lg font-semibold text-white mb-4">Bild-Info</h3>
<div className="space-y-3">
<div className="flex justify-between text-white/70"><span>Breite</span><span className="text-white">{previewResult.image_width}px</span></div>
<div className="flex justify-between text-white/70"><span>Höhe</span><span className="text-white">{previewResult.image_height}px</span></div>
<div className="flex justify-between text-white/70"><span>Pixel</span><span className="text-white">{(previewResult.image_width * previewResult.image_height / 1000000).toFixed(1)}MP</span></div>
</div>
<button onClick={onGetMask}
className="w-full mt-4 px-4 py-2 rounded-xl bg-white/10 text-white/70 hover:bg-white/20 hover:text-white transition-all text-sm">
Maske anzeigen
</button>
</GlassCard>
<GlassCard className="col-span-1 lg:col-span-2" delay={400}>
<h3 className="text-lg font-semibold text-white mb-4">Original</h3>
{previewUrl && <img src={previewUrl} alt="Original" className="w-full max-h-96 object-contain rounded-xl" />}
</GlassCard>
{maskUrl && (
<GlassCard delay={500}>
<h3 className="text-lg font-semibold text-white mb-4">Maske</h3>
<img src={maskUrl} alt="Mask" className="w-full max-h-96 object-contain rounded-xl" />
</GlassCard>
)}
<div className="col-span-1 lg:col-span-3 flex justify-center gap-4">
<button onClick={onBack}
className="px-6 py-3 rounded-xl bg-white/10 text-white hover:bg-white/20 transition-all flex items-center gap-2">
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 19l-7-7m0 0l7-7m-7 7h18" /></svg>
Zurück
</button>
<button onClick={onCleanup} disabled={isProcessing}
className="px-8 py-3 rounded-xl font-semibold bg-gradient-to-r from-orange-500 to-red-500 text-white hover:shadow-lg hover:shadow-orange-500/30 transition-all disabled:opacity-50 flex items-center gap-2">
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19.428 15.428a2 2 0 00-1.022-.547l-2.387-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z" /></svg>
Bereinigen starten
</button>
</div>
</div>
)
}