Website (14 monoliths split): - compliance/page.tsx (1,519 → 9), docs/audit (1,262 → 20) - quality (1,231 → 16), alerts (1,203 → 10), docs (1,202 → 11) - i18n.ts (1,173 → 8 language files) - unity-bridge (1,094 → 12), backlog (1,087 → 6) - training (1,066 → 8), rag (1,063 → 8) - Deleted index_original.ts (4,899 LOC dead backup) Studio-v2 (5 monoliths split): - meet/page.tsx (1,481 → 9), messages (1,166 → 9) - AlertsB2BContext.tsx (1,165 → 5 modules) - alerts-b2b/page.tsx (1,019 → 6), korrektur/archiv (1,001 → 6) All existing imports preserved. Zero new TypeScript errors. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
131 lines
4.8 KiB
TypeScript
131 lines
4.8 KiB
TypeScript
'use client'
|
|
|
|
import { useState } from 'react'
|
|
import { GlassCard } from './GlassCard'
|
|
import type { AbiturDokument } from './DokumentCard'
|
|
|
|
interface CreateKlausurFromTemplateModalProps {
|
|
template: AbiturDokument
|
|
onClose: () => void
|
|
onCreate: (title: string) => void
|
|
onFallback: () => void
|
|
isLoading: boolean
|
|
error: string | null
|
|
isDark: boolean
|
|
}
|
|
|
|
export function CreateKlausurFromTemplateModal({
|
|
template,
|
|
onClose,
|
|
onCreate,
|
|
onFallback,
|
|
isLoading,
|
|
error,
|
|
isDark,
|
|
}: CreateKlausurFromTemplateModalProps) {
|
|
const [title, setTitle] = useState(
|
|
`${template.fach} ${template.aufgabentyp || ''} ${template.jahr}`.trim()
|
|
)
|
|
|
|
const handleSubmit = (e: React.FormEvent) => {
|
|
e.preventDefault()
|
|
onCreate(title)
|
|
}
|
|
|
|
return (
|
|
<div className="fixed inset-0 z-50 flex items-center justify-center p-4">
|
|
<div className="absolute inset-0 bg-black/50 backdrop-blur-sm" onClick={onClose} />
|
|
<GlassCard className="relative w-full max-w-md" size="lg" delay={0} isDark={isDark}>
|
|
<h2 className={`text-xl font-bold mb-2 ${isDark ? 'text-white' : 'text-slate-900'}`}>
|
|
Klausur aus Vorlage erstellen
|
|
</h2>
|
|
<p className={`text-sm mb-6 ${isDark ? 'text-white/60' : 'text-slate-600'}`}>
|
|
Basierend auf: {template.thema || template.dateiname}
|
|
</p>
|
|
|
|
{error && (
|
|
<div className="mb-4 p-3 rounded-lg bg-red-500/20 border border-red-500/30 text-sm">
|
|
<p className="text-red-300 mb-2">{error}</p>
|
|
<button
|
|
onClick={onFallback}
|
|
className="text-purple-400 hover:text-purple-300 underline text-xs"
|
|
>
|
|
Zur Korrektur-Uebersicht (ohne Klausur erstellen)
|
|
</button>
|
|
</div>
|
|
)}
|
|
|
|
<form onSubmit={handleSubmit} className="space-y-4">
|
|
<div>
|
|
<label className={`block text-sm mb-2 ${isDark ? 'text-white/60' : 'text-slate-600'}`}>
|
|
Klausur-Titel
|
|
</label>
|
|
<input
|
|
type="text"
|
|
value={title}
|
|
onChange={(e) => setTitle(e.target.value)}
|
|
placeholder="z.B. Deutsch LK Q4 - Kafka"
|
|
className={`w-full p-3 rounded-xl border focus:ring-2 focus:ring-purple-500 focus:border-transparent ${
|
|
isDark
|
|
? 'bg-white/10 border-white/20 text-white placeholder-white/40'
|
|
: 'bg-slate-100 border-slate-300 text-slate-900 placeholder-slate-400'
|
|
}`}
|
|
required
|
|
autoFocus
|
|
/>
|
|
</div>
|
|
|
|
{/* Template Info */}
|
|
<div className={`p-4 rounded-xl ${isDark ? 'bg-white/5' : 'bg-slate-100'}`}>
|
|
<div className="grid grid-cols-2 gap-3 text-sm">
|
|
{[
|
|
{ label: 'Fach', value: template.fach },
|
|
{ label: 'Jahr', value: String(template.jahr) },
|
|
{ label: 'Niveau', value: template.niveau },
|
|
{ label: 'Typ', value: template.aufgabentyp || '-' },
|
|
].map(({ label, value }) => (
|
|
<div key={label}>
|
|
<span className={isDark ? 'text-white/50' : 'text-slate-500'}>{label}:</span>
|
|
<span className={`ml-2 ${isDark ? 'text-white' : 'text-slate-900'}`}>{value}</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex gap-3 pt-2">
|
|
<button
|
|
type="button"
|
|
onClick={onClose}
|
|
disabled={isLoading}
|
|
className={`flex-1 px-4 py-3 rounded-xl transition-colors ${
|
|
isDark
|
|
? 'bg-white/10 text-white hover:bg-white/20'
|
|
: 'bg-slate-200 text-slate-700 hover:bg-slate-300'
|
|
} disabled:opacity-50`}
|
|
>
|
|
Abbrechen
|
|
</button>
|
|
<button
|
|
type="submit"
|
|
disabled={isLoading || !title.trim()}
|
|
className="flex-1 px-4 py-3 rounded-xl bg-gradient-to-r from-purple-500 to-pink-500 text-white font-semibold hover:shadow-lg hover:shadow-purple-500/30 transition-all disabled:opacity-50"
|
|
>
|
|
{isLoading ? (
|
|
<span className="flex items-center justify-center gap-2">
|
|
<svg className="w-4 h-4 animate-spin" fill="none" viewBox="0 0 24 24">
|
|
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
|
|
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" />
|
|
</svg>
|
|
Erstelle...
|
|
</span>
|
|
) : (
|
|
'Klausur erstellen'
|
|
)}
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</GlassCard>
|
|
</div>
|
|
)
|
|
}
|