Files
breakpilot-lehrer/website/app/lehrer/klausur-korrektur/[klausurId]/[studentId]/page.tsx
Benjamin Admin 6811264756 [split-required] Split final batch of monoliths >1000 LOC
Python (6 files in klausur-service):
- rbac.py (1,132 → 4), admin_api.py (1,012 → 4)
- routes/eh.py (1,111 → 4), ocr_pipeline_geometry.py (1,105 → 5)

Python (2 files in backend-lehrer):
- unit_api.py (1,226 → 6), game_api.py (1,129 → 5)

Website (6 page files):
- 4x klausur-korrektur pages (1,249-1,328 LOC each) → shared components
  in website/components/klausur-korrektur/ (17 shared files)
- companion (1,057 → 10), magic-help (1,017 → 8)

All re-export barrels preserve backward compatibility.
Zero import errors verified.

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

141 lines
5.3 KiB
TypeScript

'use client'
/**
* Korrektur-Workspace (Lehrer Route)
*
* Main correction interface with 2/3 - 1/3 layout:
* - Left (2/3): Document viewer with annotation overlay
* - Right (1/3): Criteria scoring, Gutachten editor, Annotations
*/
import { useParams, useRouter } from 'next/navigation'
import AdminLayout from '@/components/admin/AdminLayout'
import { useKorrekturWorkspace } from '@/components/klausur-korrektur/useKorrekturWorkspace'
import WorkspaceTopBar from '@/components/klausur-korrektur/WorkspaceTopBar'
import DocumentViewer from '@/components/klausur-korrektur/DocumentViewer'
import CorrectionPanel from '@/components/klausur-korrektur/CorrectionPanel'
import EinigungModal from '@/components/klausur-korrektur/EinigungModal'
import ErrorBanner from '@/components/klausur-korrektur/ErrorBanner'
import AnnotationLayer from '../../components/AnnotationLayer'
import AnnotationToolbar from '../../components/AnnotationToolbar'
import AnnotationPanel from '../../components/AnnotationPanel'
import EHSuggestionPanel from '../../components/EHSuggestionPanel'
export default function KorrekturWorkspacePage() {
const params = useParams()
const router = useRouter()
const klausurId = params.klausurId as string
const studentId = params.studentId as string
const ws = useKorrekturWorkspace({ klausurId, studentId })
const goToStudent = (direction: 'prev' | 'next') => {
const newIndex = direction === 'prev' ? ws.currentIndex - 1 : ws.currentIndex + 1
if (newIndex >= 0 && newIndex < ws.students.length) {
router.push(`/lehrer/klausur-korrektur/${klausurId}/${ws.students[newIndex].id}`)
}
}
if (ws.loading) {
return (
<AdminLayout title="Laedt..." description="">
<div className="flex items-center justify-center h-[calc(100vh-200px)]">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary-600"></div>
</div>
</AdminLayout>
)
}
return (
<AdminLayout
title={`Korrektur: ${ws.student?.anonym_id || 'Student'}`}
description={ws.klausur?.title || ''}
>
<WorkspaceTopBar
klausurId={klausurId}
backPath={`/lehrer/klausur-korrektur/${klausurId}`}
currentIndex={ws.currentIndex}
studentCount={ws.students.length}
workflow={ws.workflow}
saving={ws.saving}
totals={ws.totals}
onGoToStudent={goToStudent}
/>
{ws.showEinigungModal && ws.workflow && (
<EinigungModal
workflow={ws.workflow}
einigungGrade={ws.einigungGrade}
einigungNotes={ws.einigungNotes}
submittingWorkflow={ws.submittingWorkflow}
onGradeChange={ws.setEinigungGrade}
onNotesChange={ws.setEinigungNotes}
onSubmit={ws.submitEinigung}
onClose={() => ws.setShowEinigungModal(false)}
/>
)}
{ws.error && <ErrorBanner error={ws.error} onDismiss={() => ws.setError(null)} />}
<div className="flex gap-6 h-[calc(100vh-280px)]">
<DocumentViewer
student={ws.student}
documentUrl={ws.documentUrl}
zoom={ws.zoom}
currentPage={ws.currentPage}
totalPages={ws.totalPages}
annotations={ws.annotations}
selectedTool={ws.selectedTool}
selectedAnnotation={ws.selectedAnnotation}
annotationCounts={ws.annotationCounts}
onZoomChange={ws.setZoom}
onPageChange={ws.setCurrentPage}
onSelectTool={ws.setSelectedTool}
onCreateAnnotation={ws.createAnnotation}
onSelectAnnotation={(ann) => {
ws.setSelectedAnnotation(ann)
ws.setActiveTab('annotationen')
}}
AnnotationToolbarComponent={AnnotationToolbar}
AnnotationLayerComponent={AnnotationLayer}
/>
<CorrectionPanel
activeTab={ws.activeTab}
onTabChange={ws.setActiveTab}
annotations={ws.annotations}
gradeInfo={ws.gradeInfo}
criteriaScores={ws.criteriaScores}
gutachten={ws.gutachten}
totals={ws.totals}
workflow={ws.workflow}
saving={ws.saving}
generatingGutachten={ws.generatingGutachten}
exporting={ws.exporting}
submittingWorkflow={ws.submittingWorkflow}
selectedAnnotation={ws.selectedAnnotation}
studentId={studentId}
klausurId={klausurId}
klausurEhId={ws.klausur?.eh_id}
onCriteriaChange={ws.handleCriteriaChange}
onGutachtenChange={ws.setGutachten}
onSaveGutachten={ws.saveGutachten}
onGenerateGutachten={ws.generateGutachten}
onExportGutachtenPDF={ws.exportGutachtenPDF}
onSelectAnnotation={ws.setSelectedAnnotation}
onUpdateAnnotation={ws.updateAnnotation}
onDeleteAnnotation={ws.deleteAnnotation}
onSelectTool={ws.setSelectedTool}
onSetActiveTab={ws.setActiveTab}
onSubmitErstkorrektur={ws.submitErstkorrektur}
onStartZweitkorrektur={ws.startZweitkorrektur}
onSubmitZweitkorrektur={ws.submitZweitkorrektur}
onShowEinigungModal={() => ws.setShowEinigungModal(true)}
AnnotationPanelComponent={AnnotationPanel}
EHSuggestionPanelComponent={EHSuggestionPanel}
/>
</div>
</AdminLayout>
)
}