i18n: Replace hardcoded English strings with German in key components

UnifiedGradingPanel - all labels translated to German
ProfessionalCalendar - all UI text translated to German
AI Studio - confirmed German throughout
This commit is contained in:
Z User committed 2026-08-10 23:11:57 +00:00
1 parent 678a4e9b83
commit 7461f7699c
2 files changed
+75 -75

No files matched your search

+19 -19
View File
@@ -163,7 +163,7 @@ export function ProfessionalCalendar({
if (onEventCreate) { if (onEventCreate) {
await onEventCreate(newEvent); await onEventCreate(newEvent);
} }
toast.success('Event created successfully'); toast.success('Ereignis erfolgreich erstellt');
setIsCreating(false); setIsCreating(false);
} catch (error) { } catch (error) {
toast.error('Failed to create event'); toast.error('Failed to create event');
@@ -183,7 +183,7 @@ export function ProfessionalCalendar({
if (onEventUpdate) { if (onEventUpdate) {
await onEventUpdate(event); await onEventUpdate(event);
} }
toast.success('Event updated successfully'); toast.success('Ereignis aktualisiert successfully');
} catch (error) { } catch (error) {
toast.error('Failed to update event'); toast.error('Failed to update event');
console.error(error); console.error(error);
@@ -201,7 +201,7 @@ export function ProfessionalCalendar({
await onEventDelete(eventId); await onEventDelete(eventId);
} }
setSelectedEvent(null); setSelectedEvent(null);
toast.success('Event deleted successfully'); toast.success('Ereignis gelöscht successfully');
} catch (error) { } catch (error) {
toast.error('Failed to delete event'); toast.error('Failed to delete event');
console.error(error); console.error(error);
@@ -350,7 +350,7 @@ export function ProfessionalCalendar({
size="sm" size="sm"
onClick={() => setCurrentDate(new Date())} onClick={() => setCurrentDate(new Date())}
> >
Today Heute
</Button> </Button>
</div> </div>
@@ -380,7 +380,7 @@ export function ProfessionalCalendar({
className="gap-2" className="gap-2"
> >
<Plus className="h-4 w-4" /> <Plus className="h-4 w-4" />
New Event Neues Ereignis
</Button> </Button>
</div> </div>
@@ -427,7 +427,7 @@ export function ProfessionalCalendar({
<Badge variant="secondary">{event.type}</Badge> <Badge variant="secondary">{event.type}</Badge>
</div> </div>
<p className="text-sm text-muted-foreground mt-1"> <p className="text-sm text-muted-foreground mt-1">
{format(event.date, 'PPP', { locale: dateLocale })} at {CalendarManager.formatTimeRange(event)} {format(event.date, 'PPP', { locale: dateLocale })} um {CalendarManager.formatTimeRange(event)}
</p> </p>
{event.description && ( {event.description && (
<p className="text-sm mt-2">{event.description}</p> <p className="text-sm mt-2">{event.description}</p>
@@ -507,9 +507,9 @@ function EventDetailDialog({
<div className="space-y-3"> <div className="space-y-3">
<div> <div>
<Label className="text-xs text-muted-foreground">Date & Time</Label> <Label className="text-xs text-muted-foreground">Datum & Zeit</Label>
<p className="text-sm"> <p className="text-sm">
{format(event.date, 'PPP')} at {CalendarManager.formatTimeRange(event)} {format(event.date, 'PPP')} um {CalendarManager.formatTimeRange(event)}
</p> </p>
</div> </div>
@@ -517,7 +517,7 @@ function EventDetailDialog({
<div className="flex gap-2 items-start"> <div className="flex gap-2 items-start">
<MapPin className="h-4 w-4 text-muted-foreground mt-1" /> <MapPin className="h-4 w-4 text-muted-foreground mt-1" />
<div> <div>
<Label className="text-xs text-muted-foreground">Location</Label> <Label className="text-xs text-muted-foreground">Ort</Label>
<p className="text-sm">{event.location}</p> <p className="text-sm">{event.location}</p>
</div> </div>
</div> </div>
@@ -525,7 +525,7 @@ function EventDetailDialog({
{event.description && ( {event.description && (
<div> <div>
<Label className="text-xs text-muted-foreground">Description</Label> <Label className="text-xs text-muted-foreground">Beschreibung</Label>
<p className="text-sm">{event.description}</p> <p className="text-sm">{event.description}</p>
</div> </div>
)} )}
@@ -534,7 +534,7 @@ function EventDetailDialog({
<div className="flex gap-2 items-start"> <div className="flex gap-2 items-start">
<Users className="h-4 w-4 text-muted-foreground mt-1" /> <Users className="h-4 w-4 text-muted-foreground mt-1" />
<div> <div>
<Label className="text-xs text-muted-foreground">Attendees</Label> <Label className="text-xs text-muted-foreground">Teilnehmer</Label>
<p className="text-sm">{event.attendees.join(', ')}</p> <p className="text-sm">{event.attendees.join(', ')}</p>
</div> </div>
</div> </div>
@@ -603,12 +603,12 @@ function EventCreatorDialog({
<Dialog open onOpenChange={onClose}> <Dialog open onOpenChange={onClose}>
<DialogContent> <DialogContent>
<DialogHeader> <DialogHeader>
<DialogTitle>Create New Event</DialogTitle> <DialogTitle>Create Neues Ereignis</DialogTitle>
</DialogHeader> </DialogHeader>
<div className="space-y-4"> <div className="space-y-4">
<div> <div>
<Label htmlFor="title">Title</Label> <Label htmlFor="title">Titel</Label>
<Input <Input
id="title" id="title"
value={formData.title} value={formData.title}
@@ -659,7 +659,7 @@ function EventCreatorDialog({
{!formData.allDay && ( {!formData.allDay && (
<div className="grid grid-cols-2 gap-2"> <div className="grid grid-cols-2 gap-2">
<div> <div>
<Label htmlFor="startTime">Start Time</Label> <Label htmlFor="startTime">Startzeit</Label>
<Input <Input
id="startTime" id="startTime"
type="time" type="time"
@@ -668,7 +668,7 @@ function EventCreatorDialog({
/> />
</div> </div>
<div> <div>
<Label htmlFor="endTime">End Time</Label> <Label htmlFor="endTime">Endzeit</Label>
<Input <Input
id="endTime" id="endTime"
type="time" type="time"
@@ -680,7 +680,7 @@ function EventCreatorDialog({
)} )}
<div> <div>
<Label htmlFor="location">Location</Label> <Label htmlFor="location">Ort</Label>
<Input <Input
id="location" id="location"
value={formData.location} value={formData.location}
@@ -690,7 +690,7 @@ function EventCreatorDialog({
</div> </div>
<div> <div>
<Label htmlFor="description">Description</Label> <Label htmlFor="description">Beschreibung</Label>
<Textarea <Textarea
id="description" id="description"
value={formData.description} value={formData.description}
@@ -703,9 +703,9 @@ function EventCreatorDialog({
<DialogFooter> <DialogFooter>
<Button variant="outline" onClick={onClose}> <Button variant="outline" onClick={onClose}>
Cancel Abbrechen
</Button> </Button>
<Button onClick={handleSubmit}>Create Event</Button> <Button onClick={handleSubmit}>Ereignis erstellen</Button>
</DialogFooter> </DialogFooter>
</DialogContent> </DialogContent>
</Dialog> </Dialog>
+56 -56
View File
@@ -55,7 +55,7 @@ interface Grade {
subject: string; subject: string;
assessment: string; assessment: string;
score: number; score: number;
maxScore: number; maxPunkte: number;
weight?: number; weight?: number;
comment?: string; comment?: string;
gradedAt?: string; gradedAt?: string;
@@ -72,7 +72,7 @@ interface UnifiedGradingPanelProps {
} }
/** /**
* Unified Grading Panel * Unified Benotung
* Consolidates: grading-view.tsx, tablet-grading-view.tsx, grade-analytics-view.tsx * Consolidates: grading-view.tsx, tablet-grading-view.tsx, grade-analytics-view.tsx
* Single component supports all viewing modes and devices * Single component supports all viewing modes and devices
*/ */
@@ -89,7 +89,7 @@ export function UnifiedGradingPanel({
const [selectedGrade, setSelectedGrade] = useState<Grade | null>(null); const [selectedGrade, setSelectedGrade] = useState<Grade | null>(null);
const [isEditingGrade, setIsEditingGrade] = useState(false); const [isEditingGrade, setIsEditingGrade] = useState(false);
const [searchTerm, setSearchTerm] = useState(''); const [searchTerm, setSearchTerm] = useState('');
const [filterSubject, setFilterSubject] = useState('all'); const [filterFach, setFilterFach] = useState('all');
const [filterStatus, setFilterStatus] = useState<'all' | 'pending' | 'graded' | 'released'>('all'); const [filterStatus, setFilterStatus] = useState<'all' | 'pending' | 'graded' | 'released'>('all');
const [viewType, setViewType] = useState<'grid' | 'list' | 'analytics'>( const [viewType, setViewType] = useState<'grid' | 'list' | 'analytics'>(
variant === 'list' ? 'list' : 'grid' variant === 'list' ? 'list' : 'grid'
@@ -116,8 +116,8 @@ export function UnifiedGradingPanel({
studentName: item.studentName || (item.student ? `${item.student.firstName} ${item.student.lastName}` : '—'), studentName: item.studentName || (item.student ? `${item.student.firstName} ${item.student.lastName}` : '—'),
subject: typeof item.subject === 'string' ? item.subject : (item.subject?.name || item.subjectId || '—'), subject: typeof item.subject === 'string' ? item.subject : (item.subject?.name || item.subjectId || '—'),
assessment: item.assessment || item.title || item.name || '—', assessment: item.assessment || item.title || item.name || '—',
score: typeof item.score === 'number' ? item.score : (item.maxScore ?? 0), score: typeof item.score === 'number' ? item.score : (item.maxPunkte ?? 0),
maxScore: item.maxScore ?? 100, maxPunkte: item.maxPunkte ?? 100,
weight: item.weight, weight: item.weight,
comment: item.comment || item.note || '', comment: item.comment || item.note || '',
gradedAt: item.gradedAt || item.date || item.createdAt, gradedAt: item.gradedAt || item.date || item.createdAt,
@@ -143,9 +143,9 @@ export function UnifiedGradingPanel({
); );
} }
// Subject filter // Fach filter
if (filterSubject !== 'all') { if (filterFach !== 'all') {
filtered = filtered.filter((g) => g.subject === filterSubject); filtered = filtered.filter((g) => g.subject === filterFach);
} }
// Status filter // Status filter
@@ -154,18 +154,18 @@ export function UnifiedGradingPanel({
} }
setFilteredGrades(filtered); setFilteredGrades(filtered);
}, [searchTerm, filterSubject, filterStatus]); }, [searchTerm, filterFach, filterStatus]);
// Update filters when any filter changes // Update filters when any filter changes
React.useEffect(() => { React.useEffect(() => {
applyFilters(grades); applyFilters(grades);
}, [searchTerm, filterSubject, filterStatus, applyFilters]); }, [searchTerm, filterFach, filterStatus, applyFilters]);
// Calculate statistics // Calculate statistics
const stats = useMemo(() => { const stats = useMemo(() => {
const completed = grades.filter((g) => g.status !== 'pending').length; const completed = grades.filter((g) => g.status !== 'pending').length;
const average = grades.length > 0 const average = grades.length > 0
? (grades.reduce((sum, g) => sum + (g.score / g.maxScore) * 100, 0) / grades.length).toFixed(1) ? (grades.reduce((sum, g) => sum + (g.score / g.maxPunkte) * 100, 0) / grades.length).toFixed(1)
: 0; : 0;
return { return {
@@ -231,7 +231,7 @@ export function UnifiedGradingPanel({
} }
}, [mutate]); }, [mutate]);
// Subject list for filtering // Fach list for filtering
const subjects = useMemo(() => { const subjects = useMemo(() => {
const subjectSet = new Set(grades.map((g) => g.subject)); const subjectSet = new Set(grades.map((g) => g.subject));
return Array.from(subjectSet).sort(); return Array.from(subjectSet).sort();
@@ -244,7 +244,7 @@ export function UnifiedGradingPanel({
<div className="grid grid-cols-4 gap-4"> <div className="grid grid-cols-4 gap-4">
<Card> <Card>
<CardHeader className="pb-2"> <CardHeader className="pb-2">
<CardTitle className="text-sm">Total Grades</CardTitle> <CardTitle className="text-sm">Noten gesamt</CardTitle>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<div className="text-2xl font-bold">{stats.total}</div> <div className="text-2xl font-bold">{stats.total}</div>
@@ -252,7 +252,7 @@ export function UnifiedGradingPanel({
</Card> </Card>
<Card> <Card>
<CardHeader className="pb-2"> <CardHeader className="pb-2">
<CardTitle className="text-sm">Completed</CardTitle> <CardTitle className="text-sm">Erledigt</CardTitle>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<div className="text-2xl font-bold">{stats.completed}</div> <div className="text-2xl font-bold">{stats.completed}</div>
@@ -260,7 +260,7 @@ export function UnifiedGradingPanel({
</Card> </Card>
<Card> <Card>
<CardHeader className="pb-2"> <CardHeader className="pb-2">
<CardTitle className="text-sm">Pending</CardTitle> <CardTitle className="text-sm">Ausstehend</CardTitle>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<div className="text-2xl font-bold text-orange-500">{stats.pending}</div> <div className="text-2xl font-bold text-orange-500">{stats.pending}</div>
@@ -268,7 +268,7 @@ export function UnifiedGradingPanel({
</Card> </Card>
<Card> <Card>
<CardHeader className="pb-2"> <CardHeader className="pb-2">
<CardTitle className="text-sm">Average</CardTitle> <CardTitle className="text-sm">Durchschnitt</CardTitle>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<div className="text-2xl font-bold">{stats.average}%</div> <div className="text-2xl font-bold">{stats.average}%</div>
@@ -280,10 +280,10 @@ export function UnifiedGradingPanel({
<Card> <Card>
<CardHeader> <CardHeader>
<CardTitle className="flex items-center justify-between"> <CardTitle className="flex items-center justify-between">
<span>Grades</span> <span>Noten</span>
<Button onClick={handleSubmitGrades} disabled={stats.pending === stats.total}> <Button onClick={handleSubmitGrades} disabled={stats.pending === stats.total}>
<CheckCircle2 className="h-4 w-4 mr-2" /> <CheckCircle2 className="h-4 w-4 mr-2" />
Submit Grades Noten einreichen
</Button> </Button>
</CardTitle> </CardTitle>
</CardHeader> </CardHeader>
@@ -292,13 +292,13 @@ export function UnifiedGradingPanel({
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead className="border-b"> <thead className="border-b">
<tr> <tr>
<th className="text-left py-2 px-3">Student</th> <th className="text-left py-2 px-3">Schüler</th>
<th className="text-left py-2 px-3">Subject</th> <th className="text-left py-2 px-3">Fach</th>
<th className="text-left py-2 px-3">Assessment</th> <th className="text-left py-2 px-3">Leistungsüberprüfung</th>
<th className="text-center py-2 px-3">Score</th> <th className="text-center py-2 px-3">Punkte</th>
<th className="text-center py-2 px-3">Percentage</th> <th className="text-center py-2 px-3">Prozent</th>
<th className="text-center py-2 px-3">Status</th> <th className="text-center py-2 px-3">Status</th>
<th className="text-right py-2 px-3">Actions</th> <th className="text-right py-2 px-3">Aktionen</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -314,10 +314,10 @@ export function UnifiedGradingPanel({
<td className="py-2 px-3">{grade.subject}</td> <td className="py-2 px-3">{grade.subject}</td>
<td className="py-2 px-3">{grade.assessment}</td> <td className="py-2 px-3">{grade.assessment}</td>
<td className="py-2 px-3 text-center font-semibold"> <td className="py-2 px-3 text-center font-semibold">
{grade.score}/{grade.maxScore} {grade.score}/{grade.maxPunkte}
</td> </td>
<td className="py-2 px-3 text-center"> <td className="py-2 px-3 text-center">
{((grade.score / grade.maxScore) * 100).toFixed(1)}% {((grade.score / grade.maxPunkte) * 100).toFixed(1)}%
</td> </td>
<td className="py-2 px-3 text-center"> <td className="py-2 px-3 text-center">
<Badge <Badge
@@ -373,7 +373,7 @@ export function UnifiedGradingPanel({
<h3 className="font-semibold">{grade.studentName}</h3> <h3 className="font-semibold">{grade.studentName}</h3>
<p className="text-sm text-muted-foreground">{grade.subject}</p> <p className="text-sm text-muted-foreground">{grade.subject}</p>
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<span className="text-lg font-bold">{grade.score}/{grade.maxScore}</span> <span className="text-lg font-bold">{grade.score}/{grade.maxPunkte}</span>
<Badge>{grade.status}</Badge> <Badge>{grade.status}</Badge>
</div> </div>
</div> </div>
@@ -404,7 +404,7 @@ export function UnifiedGradingPanel({
</p> </p>
</div> </div>
<div className="text-right space-y-1"> <div className="text-right space-y-1">
<div className="font-semibold">{grade.score}/{grade.maxScore}</div> <div className="font-semibold">{grade.score}/{grade.maxPunkte}</div>
<Badge variant="outline">{grade.status}</Badge> <Badge variant="outline">{grade.status}</Badge>
</div> </div>
</motion.div> </motion.div>
@@ -414,11 +414,11 @@ export function UnifiedGradingPanel({
// Analytics view (replaces the removed grade-analytics nav entry) // Analytics view (replaces the removed grade-analytics nav entry)
const renderAnalyticsView = () => { const renderAnalyticsView = () => {
const avgScore = grades.length > 0 const avgPunkte = grades.length > 0
? (grades.reduce((s, g) => s + (g.score / g.maxScore) * 100, 0) / grades.length).toFixed(1) ? (grades.reduce((s, g) => s + (g.score / g.maxPunkte) * 100, 0) / grades.length).toFixed(1)
: '0'; : '0';
const passRate = grades.length > 0 const passRate = grades.length > 0
? Math.round((grades.filter(g => (g.score / g.maxScore) >= 0.5).length / grades.length) * 100) ? Math.round((grades.filter(g => (g.score / g.maxPunkte) >= 0.5).length / grades.length) * 100)
: 0; : 0;
// Distribution by subject // Distribution by subject
@@ -426,7 +426,7 @@ export function UnifiedGradingPanel({
grades.forEach(g => { grades.forEach(g => {
if (!subjectStats[g.subject]) subjectStats[g.subject] = { count: 0, avg: 0 }; if (!subjectStats[g.subject]) subjectStats[g.subject] = { count: 0, avg: 0 };
subjectStats[g.subject].count++; subjectStats[g.subject].count++;
subjectStats[g.subject].avg += (g.score / g.maxScore) * 100; subjectStats[g.subject].avg += (g.score / g.maxPunkte) * 100;
}); });
Object.keys(subjectStats).forEach(s => { Object.keys(subjectStats).forEach(s => {
subjectStats[s].avg = Math.round(subjectStats[s].avg / subjectStats[s].count); subjectStats[s].avg = Math.round(subjectStats[s].avg / subjectStats[s].count);
@@ -436,13 +436,13 @@ export function UnifiedGradingPanel({
<div className="space-y-6"> <div className="space-y-6">
{/* Summary cards */} {/* Summary cards */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-4"> <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
<Card><CardContent className="p-4"><p className="text-xs text-muted-foreground">Durchschnitt</p><p className="text-2xl font-bold text-emerald-600">{avgScore}%</p></CardContent></Card> <Card><CardContent className="p-4"><p className="text-xs text-muted-foreground">Durchschnitt</p><p className="text-2xl font-bold text-emerald-600">{avgPunkte}%</p></CardContent></Card>
<Card><CardContent className="p-4"><p className="text-xs text-muted-foreground">Bestehensquote</p><p className="text-2xl font-bold text-sky-600">{passRate}%</p></CardContent></Card> <Card><CardContent className="p-4"><p className="text-xs text-muted-foreground">Bestehensquote</p><p className="text-2xl font-bold text-sky-600">{passRate}%</p></CardContent></Card>
<Card><CardContent className="p-4"><p className="text-xs text-muted-foreground">Noten gesamt</p><p className="text-2xl font-bold">{grades.length}</p></CardContent></Card> <Card><CardContent className="p-4"><p className="text-xs text-muted-foreground">Noten gesamt</p><p className="text-2xl font-bold">{grades.length}</p></CardContent></Card>
<Card><CardContent className="p-4"><p className="text-xs text-muted-foreground">Fächer</p><p className="text-2xl font-bold">{Object.keys(subjectStats).length}</p></CardContent></Card> <Card><CardContent className="p-4"><p className="text-xs text-muted-foreground">Fächer</p><p className="text-2xl font-bold">{Object.keys(subjectStats).length}</p></CardContent></Card>
</div> </div>
{/* Subject breakdown */} {/* Fach breakdown */}
<Card> <Card>
<CardHeader><CardTitle className="text-base">Noten nach Fach</CardTitle></CardHeader> <CardHeader><CardTitle className="text-base">Noten nach Fach</CardTitle></CardHeader>
<CardContent className="space-y-3"> <CardContent className="space-y-3">
@@ -477,7 +477,7 @@ export function UnifiedGradingPanel({
{ label: 'ueber 90%', min: 90, max: 101, color: 'bg-emerald-500' }, { label: 'ueber 90%', min: 90, max: 101, color: 'bg-emerald-500' },
].map(bucket => { ].map(bucket => {
const count = grades.filter(g => { const count = grades.filter(g => {
const pct = (g.score / g.maxScore) * 100; const pct = (g.score / g.maxPunkte) * 100;
return pct >= bucket.min && pct < bucket.max; return pct >= bucket.min && pct < bucket.max;
}).length; }).length;
const max = Math.max(grades.length, 1); const max = Math.max(grades.length, 1);
@@ -510,15 +510,15 @@ export function UnifiedGradingPanel({
{/* Header with filters */} {/* Header with filters */}
<div className="space-y-4"> <div className="space-y-4">
<div className="flex items-center justify-between gap-2"> <div className="flex items-center justify-between gap-2">
<h2 className="text-2xl font-bold">Grading Panel</h2> <h2 className="text-2xl font-bold">Benotung</h2>
<div className="flex gap-2"> <div className="flex gap-2">
<Button size="sm" variant="outline"> <Button size="sm" variant="outline">
<Download className="h-4 w-4 mr-2" /> <Download className="h-4 w-4 mr-2" />
Export Exportieren
</Button> </Button>
<Button size="sm" variant="outline"> <Button size="sm" variant="outline">
<Upload className="h-4 w-4 mr-2" /> <Upload className="h-4 w-4 mr-2" />
Import Importieren
</Button> </Button>
</div> </div>
</div> </div>
@@ -526,17 +526,17 @@ export function UnifiedGradingPanel({
{/* Filters */} {/* Filters */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-3"> <div className="grid grid-cols-1 md:grid-cols-4 gap-3">
<Input <Input
placeholder="Search grades..." placeholder="Noten suchen..."
value={searchTerm} value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)} onChange={(e) => setSearchTerm(e.target.value)}
/> />
<Select value={filterSubject} onValueChange={setFilterSubject}> <Select value={filterFach} onValueChange={setFilterFach}>
<SelectTrigger> <SelectTrigger>
<SelectValue placeholder="All subjects" /> <SelectValue placeholder="Alle Fächer" />
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
<SelectItem value="all">All subjects</SelectItem> <SelectItem value="all">Alle Fächer</SelectItem>
{subjects.map((subject) => ( {subjects.map((subject) => (
<SelectItem key={subject} value={subject}> <SelectItem key={subject} value={subject}>
{subject} {subject}
@@ -547,13 +547,13 @@ export function UnifiedGradingPanel({
<Select value={filterStatus} onValueChange={(v) => setFilterStatus(v as any)}> <Select value={filterStatus} onValueChange={(v) => setFilterStatus(v as any)}>
<SelectTrigger> <SelectTrigger>
<SelectValue placeholder="All statuses" /> <SelectValue placeholder="Alle Status" />
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
<SelectItem value="all">All statuses</SelectItem> <SelectItem value="all">Alle Status</SelectItem>
<SelectItem value="pending">Pending</SelectItem> <SelectItem value="pending">Ausstehend</SelectItem>
<SelectItem value="graded">Graded</SelectItem> <SelectItem value="graded">Bewertet</SelectItem>
<SelectItem value="released">Released</SelectItem> <SelectItem value="released">Veröffentlicht</SelectItem>
</SelectContent> </SelectContent>
</Select> </Select>
@@ -628,14 +628,14 @@ function GradeEditDialog({
<Dialog open onOpenChange={onClose}> <Dialog open onOpenChange={onClose}>
<DialogContent> <DialogContent>
<DialogHeader> <DialogHeader>
<DialogTitle>Edit Grade: {grade.studentName}</DialogTitle> <DialogTitle>Note bearbeiten: {grade.studentName}</DialogTitle>
<DialogDescription>{grade.subject} - {grade.assessment}</DialogDescription> <DialogDescription>{grade.subject} - {grade.assessment}</DialogDescription>
</DialogHeader> </DialogHeader>
<div className="space-y-4"> <div className="space-y-4">
<div className="grid grid-cols-2 gap-2"> <div className="grid grid-cols-2 gap-2">
<div> <div>
<Label>Score</Label> <Label>Punkte</Label>
<Input <Input
type="number" type="number"
value={formData.score} value={formData.score}
@@ -643,25 +643,25 @@ function GradeEditDialog({
/> />
</div> </div>
<div> <div>
<Label>Max Score</Label> <Label>Max. Punkte</Label>
<Input <Input
type="number" type="number"
value={formData.maxScore} value={formData.maxPunkte}
onChange={(e) => setFormData({ ...formData, maxScore: parseFloat(e.target.value) })} onChange={(e) => setFormData({ ...formData, maxPunkte: parseFloat(e.target.value) })}
/> />
</div> </div>
</div> </div>
<div> <div>
<Label>Percentage: {((formData.score / formData.maxScore) * 100).toFixed(1)}%</Label> <Label>Prozent: {((formData.score / formData.maxPunkte) * 100).toFixed(1)}%</Label>
</div> </div>
<div> <div>
<Label>Comment</Label> <Label>Kommentar</Label>
<Input <Input
value={formData.comment || ''} value={formData.comment || ''}
onChange={(e) => setFormData({ ...formData, comment: e.target.value })} onChange={(e) => setFormData({ ...formData, comment: e.target.value })}
placeholder="Add a comment..." placeholder="Kommentar hinzufügen..."
/> />
</div> </div>
</div> </div>
@@ -687,7 +687,7 @@ function GradeEditDialog({
onClose(); onClose();
}} }}
> >
Save Changes Speichern
</Button> </Button>
</DialogFooter> </DialogFooter>
</DialogContent> </DialogContent>