'use client' import { useState, useEffect, useCallback } from 'react' import { useRouter } from 'next/navigation' import { useTheme } from '@/lib/ThemeContext' import { Sidebar } from '@/components/Sidebar' import { ThemeToggle } from '@/components/ThemeToggle' import { LanguageDropdown } from '@/components/LanguageDropdown' import type { UploadedFile } from '@/components/QRCodeUpload' import { korrekturApi, getKorrekturStats, type KorrekturStats } from '@/lib/korrektur/api' import type { Klausur, CreateKlausurData } from './types' import { GlassCard } from './_components/GlassCard' import { StatCard } from './_components/StatCard' import { KlausurCard } from './_components/KlausurCard' import { CreateKlausurModal } from './_components/CreateKlausurModal' import { DirectUploadModal, EHUploadModal, QRCodeModal } from './_components/UploadModals' const SESSION_ID_KEY = 'bp_korrektur_session' export default function KorrekturPage() { const { isDark } = useTheme() const router = useRouter() const [klausuren, setKlausuren] = useState([]) const [stats, setStats] = useState(null) const [isLoading, setIsLoading] = useState(true) const [error, setError] = useState(null) const [showCreateModal, setShowCreateModal] = useState(false) const [isCreating, setIsCreating] = useState(false) const [showQRModal, setShowQRModal] = useState(false) const [uploadSessionId, setUploadSessionId] = useState('') const [showDirectUpload, setShowDirectUpload] = useState(false) const [showEHUpload, setShowEHUpload] = useState(false) const [isDragging, setIsDragging] = useState(false) const [uploadedFiles, setUploadedFiles] = useState([]) const [ehFile, setEhFile] = useState(null) const [isUploading, setIsUploading] = useState(false) useEffect(() => { let sid = localStorage.getItem(SESSION_ID_KEY) if (!sid) { sid = `korrektur-${Date.now()}-${Math.random().toString(36).substr(2, 9)}` localStorage.setItem(SESSION_ID_KEY, sid) } setUploadSessionId(sid) }, []) const loadData = useCallback(async () => { setIsLoading(true); setError(null) try { const [kd, sd] = await Promise.all([korrekturApi.getKlausuren(), getKorrekturStats()]) setKlausuren(kd); setStats(sd) } catch (err) { setError(err instanceof Error ? err.message : 'Laden fehlgeschlagen') } finally { setIsLoading(false) } }, []) useEffect(() => { loadData() }, [loadData]) const handleCreateKlausur = async (data: CreateKlausurData) => { setIsCreating(true) try { const nk = await korrekturApi.createKlausur(data) setKlausuren(prev => [nk, ...prev]); setShowCreateModal(false) router.push(`/korrektur/${nk.id}`) } catch (err) { setError(err instanceof Error ? err.message : 'Erstellung fehlgeschlagen') } finally { setIsCreating(false) } } const handleMobileFileSelect = async (_: UploadedFile) => { setShowQRModal(false) } const handleDragOver = (e: React.DragEvent) => { e.preventDefault(); setIsDragging(true) } const handleDragLeave = (e: React.DragEvent) => { e.preventDefault(); setIsDragging(false) } const handleDrop = (e: React.DragEvent, isEH = false) => { e.preventDefault(); setIsDragging(false) const files = Array.from(e.dataTransfer.files).filter(f => f.type === 'application/pdf' || f.type.startsWith('image/')) if (isEH && files.length > 0) setEhFile(files[0]) else setUploadedFiles(prev => [...prev, ...files]) } const handleFileSelect = (e: React.ChangeEvent, isEH = false) => { if (!e.target.files) return const files = Array.from(e.target.files) if (isEH && files.length > 0) setEhFile(files[0]) else setUploadedFiles(prev => [...prev, ...files]) } const handleDirectUpload = async () => { if (uploadedFiles.length === 0) return setIsUploading(true) try { const nk = await korrekturApi.createKlausur({ title: `Schnellstart ${new Date().toLocaleDateString('de-DE')}`, subject: 'Deutsch', year: new Date().getFullYear(), semester: 'Abitur', modus: 'landes_abitur' }) for (let i = 0; i < uploadedFiles.length; i++) { await korrekturApi.uploadStudentWork(nk.id, uploadedFiles[i], `Arbeit-${i + 1}`) } setShowDirectUpload(false); setUploadedFiles([]) router.push(`/korrektur/${nk.id}`) } catch (err) { setError(err instanceof Error ? err.message : 'Upload fehlgeschlagen') } finally { setIsUploading(false) } } const handleEHUpload = async () => { if (!ehFile) return setIsUploading(true) try { await korrekturApi.uploadEH(ehFile) setShowEHUpload(false); setEhFile(null); loadData() } catch (err) { setError(err instanceof Error ? err.message : 'EH Upload fehlgeschlagen') } finally { setIsUploading(false) } } return (
{/* Background Blobs */}
{/* Header */}

Korrekturplattform

KI-gestuetzte Abiturklausur-Korrektur

{/* Stats */} {stats && (
} color="#f97316" delay={100} isDark={isDark} /> } color="#22c55e" delay={200} isDark={isDark} /> 0 ? `${stats.averageGrade} P` : '-'} icon={} color="#3b82f6" delay={300} isDark={isDark} /> } color="#a78bfa" delay={400} isDark={isDark} />
)} {error && (
{error}
)} {isLoading && (
)} {!isLoading && ( <>

Klausuren

{klausuren.map((k, i) => ( router.push(`/korrektur/${k.id}`)} delay={500 + i * 50} isDark={isDark} /> ))} setShowCreateModal(true)} delay={500 + klausuren.length * 50} className={`min-h-[180px] border-2 border-dashed ${isDark ? 'border-white/20 hover:border-purple-400/50' : 'border-slate-300 hover:border-purple-400'}`} isDark={isDark}>

Neue Klausur

Klausur erstellen

Schnellaktionen

{[ { onClick: () => setShowQRModal(true), icon: '📱', title: 'QR Upload', sub: 'Mit Handy scannen', bg: 'blue', delay: 700 }, { onClick: () => setShowDirectUpload(true), icon: , title: 'Direkt hochladen', sub: 'Drag & Drop', bg: 'green', delay: 750 }, { onClick: () => setShowCreateModal(true), icon: , title: 'Schnellstart', sub: 'Direkt loslegen', bg: 'purple', delay: 800 }, { onClick: () => setShowEHUpload(true), icon: , title: 'EH hochladen', sub: 'Erwartungshorizont', bg: 'orange', delay: 850 }, { onClick: () => router.push('/korrektur/archiv'), icon: , title: 'Abitur-Archiv', sub: 'EH durchsuchen', bg: 'indigo', delay: 900 }, ].map((action, i) => (
{typeof action.icon === 'string' ? {action.icon} : action.icon}

{action.title}

{action.sub}

))}
)}
setShowCreateModal(false)} onSubmit={handleCreateKlausur} isLoading={isCreating} isDark={isDark} /> {showQRModal && setShowQRModal(false)} onFileUploaded={handleMobileFileSelect} />} {showDirectUpload && handleDrop(e, false)} onFileSelect={(e) => handleFileSelect(e, false)} onRemoveFile={(idx) => setUploadedFiles(prev => prev.filter((_, i) => i !== idx))} onUpload={handleDirectUpload} onClose={() => { setShowDirectUpload(false); setUploadedFiles([]) }} />} {showEHUpload && handleDrop(e, true)} onFileSelect={(e) => handleFileSelect(e, true)} onRemoveFile={() => setEhFile(null)} onUpload={handleEHUpload} onClose={() => { setShowEHUpload(false); setEhFile(null) }} />}
) }