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>
152 lines
8.1 KiB
TypeScript
152 lines
8.1 KiB
TypeScript
'use client'
|
|
|
|
/**
|
|
* Welcome/Onboarding tab for the Klausur-Korrektur page.
|
|
* Shows hero, workflow explanation, and action cards.
|
|
*/
|
|
|
|
import type { Klausur } from '../../app/admin/klausur-korrektur/types'
|
|
import type { TabId } from './list-types'
|
|
|
|
interface WillkommenTabProps {
|
|
klausuren: Klausur[]
|
|
onNavigate: (tab: TabId) => void
|
|
markAsVisited: () => void
|
|
}
|
|
|
|
export default function WillkommenTab({ klausuren, onNavigate, markAsVisited }: WillkommenTabProps) {
|
|
const goTo = (tab: TabId) => { markAsVisited(); onNavigate(tab) }
|
|
|
|
return (
|
|
<div className="max-w-4xl mx-auto space-y-8">
|
|
{/* Hero Section */}
|
|
<div className="text-center py-8">
|
|
<div className="inline-flex items-center justify-center w-20 h-20 bg-gradient-to-br from-purple-500 to-purple-700 rounded-2xl mb-6">
|
|
<svg className="w-10 h-10 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
</div>
|
|
<h1 className="text-3xl font-bold text-slate-800 mb-3">Willkommen zur Abiturklausur-Korrektur</h1>
|
|
<p className="text-lg text-slate-600 max-w-2xl mx-auto">
|
|
KI-gestuetzte Korrektur fuer Deutsch-Abiturklausuren nach dem 15-Punkte-System.
|
|
Sparen Sie bis zu 80% Zeit bei der Erstkorrektur.
|
|
</p>
|
|
</div>
|
|
|
|
{/* Workflow Explanation */}
|
|
<div className="bg-gradient-to-r from-blue-50 to-purple-50 border border-blue-200 rounded-xl p-6">
|
|
<h2 className="text-lg font-semibold text-slate-800 mb-4 flex items-center gap-2">
|
|
<svg className="w-5 h-5 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
|
|
</svg>
|
|
So funktioniert es
|
|
</h2>
|
|
<div className="grid md:grid-cols-4 gap-4">
|
|
{[
|
|
{ step: 1, title: 'Arbeiten hochladen', desc: 'Scans der Schuelerarbeiten als PDF oder Bilder hochladen' },
|
|
{ step: 2, title: 'EH bereitstellen', desc: 'Erwartungshorizont hochladen oder aus Vorlage erstellen' },
|
|
{ step: 3, title: 'KI korrigiert', desc: 'Automatische Bewertung und Gutachten-Vorschlaege erhalten' },
|
|
{ step: 4, title: 'Pruefen & Anpassen', desc: 'Vorschlaege pruefen, anpassen und finalisieren' },
|
|
].map(({ step, title, desc }) => (
|
|
<div key={step} className="text-center">
|
|
<div className="text-xs text-blue-600 font-medium mb-1">Schritt {step}</div>
|
|
<div className="font-medium text-slate-800 text-sm">{title}</div>
|
|
<div className="text-xs text-slate-500 mt-1">{desc}</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Action Cards */}
|
|
<div className="grid md:grid-cols-2 gap-6">
|
|
{/* Option 1: Standard Flow */}
|
|
<div className="bg-white border-2 border-slate-200 rounded-xl p-6 hover:border-purple-300 hover:shadow-lg transition-all cursor-pointer"
|
|
onClick={() => goTo('erstellen')}>
|
|
<div className="flex items-start gap-4">
|
|
<div className="w-12 h-12 bg-purple-100 rounded-xl flex items-center justify-center flex-shrink-0">
|
|
<svg className="w-6 h-6 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
|
|
</svg>
|
|
</div>
|
|
<div className="flex-1">
|
|
<h3 className="font-semibold text-slate-800 mb-1">Neue Klausur erstellen</h3>
|
|
<p className="text-sm text-slate-600 mb-3">
|
|
Empfohlen fuer regelmaessige Nutzung. Erstellen Sie eine Klausur mit allen Metadaten,
|
|
laden Sie dann die Arbeiten hoch.
|
|
</p>
|
|
<ul className="text-xs text-slate-500 space-y-1">
|
|
{['Volle Metadaten (Fach, Jahr, Kurs)', 'Zweitkorrektur-Workflow', 'Fairness-Analyse'].map(text => (
|
|
<li key={text} className="flex items-center gap-1">
|
|
<svg className="w-3 h-3 text-green-500" fill="currentColor" viewBox="0 0 20 20"><path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" /></svg>
|
|
{text}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
<div className="mt-4 text-sm text-purple-600 font-medium flex items-center gap-1">
|
|
Klausur erstellen
|
|
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Option 2: Quick Upload */}
|
|
<div className="bg-white border-2 border-slate-200 rounded-xl p-6 hover:border-blue-300 hover:shadow-lg transition-all cursor-pointer"
|
|
onClick={() => goTo('direktupload')}>
|
|
<div className="flex items-start gap-4">
|
|
<div className="w-12 h-12 bg-blue-100 rounded-xl flex items-center justify-center flex-shrink-0">
|
|
<svg className="w-6 h-6 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" />
|
|
</svg>
|
|
</div>
|
|
<div className="flex-1">
|
|
<h3 className="font-semibold text-slate-800 mb-1">Schnellstart - Direkt hochladen</h3>
|
|
<p className="text-sm text-slate-600 mb-3">
|
|
Ideal wenn Sie sofort loslegen moechten. Laden Sie Arbeiten und EH direkt hoch,
|
|
wir erstellen die Klausur automatisch.
|
|
</p>
|
|
<ul className="text-xs text-slate-500 space-y-1">
|
|
{['Schnellster Weg zum Korrigieren', 'Drag & Drop Upload', 'Sofort einsatzbereit'].map(text => (
|
|
<li key={text} className="flex items-center gap-1">
|
|
<svg className="w-3 h-3 text-blue-500" fill="currentColor" viewBox="0 0 20 20"><path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clipRule="evenodd" /></svg>
|
|
{text}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
<div className="mt-4 text-sm text-blue-600 font-medium flex items-center gap-1">
|
|
Schnellstart
|
|
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Already have klausuren? */}
|
|
{klausuren.length > 0 && (
|
|
<div className="bg-slate-50 border border-slate-200 rounded-xl p-4 flex items-center justify-between">
|
|
<div>
|
|
<p className="font-medium text-slate-800">Sie haben {klausuren.length} Klausur{klausuren.length !== 1 ? 'en' : ''}</p>
|
|
<p className="text-sm text-slate-500">Setzen Sie Ihre Arbeit fort oder starten Sie eine neue Korrektur.</p>
|
|
</div>
|
|
<button
|
|
onClick={() => goTo('klausuren')}
|
|
className="px-4 py-2 bg-slate-800 text-white rounded-lg hover:bg-slate-700 text-sm"
|
|
>
|
|
Zu meinen Klausuren
|
|
</button>
|
|
</div>
|
|
)}
|
|
|
|
{/* Help Links */}
|
|
<div className="text-center text-sm text-slate-500">
|
|
<p>Fragen? Lesen Sie unsere <button className="text-purple-600 hover:underline">Dokumentation</button> oder kontaktieren Sie den <button className="text-purple-600 hover:underline">Support</button>.</p>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|