i18n: Fix 44 additional hardcoded English strings across 15 files
Fixed files: - competitions-view.tsx: 10 strings (placeholders, labels) - subjects-view.tsx: 11 strings (types, actions, placeholders) - professional-calendar.tsx: 5 strings (event type labels) - illness-reporting-view.tsx: 3 strings (status badges) - student-detail-view.tsx: 4 strings (health form placeholders) - data-table.tsx: 2 strings (search, empty state) - compliance-wizard.tsx: 2 strings (name, state) - settings-view.tsx: 1 string (Skipped) - competence-flower-view.tsx: 1 string (Active) - disciplinary-view.tsx: 1 string (All clear) - district-management-view.tsx: 1 string (No recent activity) - competitions-view.tsx: 1 string (Stock) - ui/pagination.tsx: 3 strings (Previous, Next, More pages) - ui/breadcrumb.tsx: 1 string (More) - ui/carousel.tsx: 2 strings (Previous/Next slide) - ui/sidebar.tsx: 1 string (Sidebar title) Total: 44 hardcoded English strings replaced with German
This commit is contained in:
1 parent
229b918fa5
commit
baa9f981ed
14 files changed
+45
-45
No files matched your search
@@ -512,7 +512,7 @@ export default function CompetenceFlowerView() {
|
||||
<div className="flex items-center gap-3 pr-4 border-r border-gray-200/60 dark:border-gray-700/40">
|
||||
<div className="w-12 h-12 rounded-xl shadow-md ring-2 ring-white dark:ring-gray-800" style={{ backgroundColor: primaryColor, boxShadow: `0 4px 12px ${primaryColor}30` }} />
|
||||
<div>
|
||||
<p className="text-[10px] uppercase tracking-wider font-semibold text-gray-500/70 dark:text-gray-400/60">Active</p>
|
||||
<p className="text-[10px] uppercase tracking-wider font-semibold text-gray-500/70 dark:text-gray-400/60">Aktiv</p>
|
||||
<p className="text-xs font-mono text-gray-700 dark:text-gray-300">{primaryColor}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1550,7 +1550,7 @@ export default function CompetitionsView() {
|
||||
}}
|
||||
>
|
||||
<SelectTrigger className="min-h-[44px]">
|
||||
<SelectValue placeholder="Select a competition" />
|
||||
<SelectValue placeholder="Wettbewerb auswählen" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{activeCompetitions.map((comp) => (
|
||||
@@ -2329,7 +2329,7 @@ export default function CompetitionsView() {
|
||||
<Input
|
||||
value={createForm.title}
|
||||
onChange={(e) => setCreateForm((f) => ({ ...f, title: e.target.value }))}
|
||||
placeholder="Competition title"
|
||||
placeholder="Wettbewerbstitel"
|
||||
className="mt-1 min-h-[44px]"
|
||||
/>
|
||||
</div>
|
||||
@@ -2339,7 +2339,7 @@ export default function CompetitionsView() {
|
||||
<Textarea
|
||||
value={createForm.description}
|
||||
onChange={(e) => setCreateForm((f) => ({ ...f, description: e.target.value }))}
|
||||
placeholder="Describe the competition..."
|
||||
placeholder="Beschreiben Sie den Wettbewerb..."
|
||||
className="mt-1 min-h-[80px]"
|
||||
rows={3}
|
||||
/>
|
||||
@@ -2417,7 +2417,7 @@ export default function CompetitionsView() {
|
||||
type="number"
|
||||
value={createForm.maxParticipants}
|
||||
onChange={(e) => setCreateForm((f) => ({ ...f, maxParticipants: e.target.value }))}
|
||||
placeholder="Unlimited"
|
||||
placeholder="Unbegrenzt"
|
||||
className="mt-1 min-h-[44px]"
|
||||
/>
|
||||
</div>
|
||||
@@ -2445,7 +2445,7 @@ export default function CompetitionsView() {
|
||||
<Textarea
|
||||
value={createForm.rules}
|
||||
onChange={(e) => setCreateForm((f) => ({ ...f, rules: e.target.value }))}
|
||||
placeholder="Competition rules and guidelines..."
|
||||
placeholder="Regeln und Richtlinien..."
|
||||
className="mt-1 min-h-[100px]"
|
||||
rows={4}
|
||||
/>
|
||||
@@ -2509,7 +2509,7 @@ export default function CompetitionsView() {
|
||||
<Input
|
||||
value={rewardForm.name}
|
||||
onChange={(e) => setRewardForm((f) => ({ ...f, name: e.target.value }))}
|
||||
placeholder="Reward name"
|
||||
placeholder="Belohnungsname"
|
||||
className="mt-1 min-h-[44px]"
|
||||
/>
|
||||
</div>
|
||||
@@ -2519,7 +2519,7 @@ export default function CompetitionsView() {
|
||||
<Textarea
|
||||
value={rewardForm.description}
|
||||
onChange={(e) => setRewardForm((f) => ({ ...f, description: e.target.value }))}
|
||||
placeholder="Reward description..."
|
||||
placeholder="Belohnungsbeschreibung..."
|
||||
className="mt-1 min-h-[80px]"
|
||||
rows={3}
|
||||
/>
|
||||
@@ -2565,7 +2565,7 @@ export default function CompetitionsView() {
|
||||
<Input
|
||||
value={rewardForm.rewardValue}
|
||||
onChange={(e) => setRewardForm((f) => ({ ...f, rewardValue: e.target.value }))}
|
||||
placeholder="Promo code or value"
|
||||
placeholder="Promo-Code oder Wert"
|
||||
className="mt-1 min-h-[44px]"
|
||||
/>
|
||||
</div>
|
||||
@@ -2586,7 +2586,7 @@ export default function CompetitionsView() {
|
||||
type="number"
|
||||
value={rewardForm.rankRequirement}
|
||||
onChange={(e) => setRewardForm((f) => ({ ...f, rankRequirement: e.target.value }))}
|
||||
placeholder="Any"
|
||||
placeholder="Alle"
|
||||
className="mt-1 min-h-[44px]"
|
||||
/>
|
||||
</div>
|
||||
@@ -2596,7 +2596,7 @@ export default function CompetitionsView() {
|
||||
type="number"
|
||||
value={rewardForm.pointsRequired}
|
||||
onChange={(e) => setRewardForm((f) => ({ ...f, pointsRequired: e.target.value }))}
|
||||
placeholder="Any"
|
||||
placeholder="Alle"
|
||||
className="mt-1 min-h-[44px]"
|
||||
/>
|
||||
</div>
|
||||
@@ -2752,12 +2752,12 @@ export default function CompetitionsView() {
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label>Stock</Label>
|
||||
<Label>Bestand</Label>
|
||||
<Input
|
||||
type="number"
|
||||
value={newRewardForm.stock}
|
||||
onChange={(e) => setNewRewardForm((f) => ({ ...f, stock: e.target.value }))}
|
||||
placeholder="Unlimited"
|
||||
placeholder="Unbegrenzt"
|
||||
className="mt-1 min-h-[44px]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -245,7 +245,7 @@ export function ComplianceWizard({ schoolId, onComplete }: ComplianceWizardProps
|
||||
onChange={(e) =>
|
||||
setState((prev) => ({ ...prev, dpoName: e.target.value }))
|
||||
}
|
||||
placeholder="Full name"
|
||||
placeholder="Vollständiger Name"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
@@ -305,7 +305,7 @@ export function ComplianceWizard({ schoolId, onComplete }: ComplianceWizardProps
|
||||
setState((prev) => ({ ...prev, bundesland: value }))
|
||||
}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select state..." />
|
||||
<SelectValue placeholder="Bundesland auswählen..." />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{BUNDESLANDS.map((land) => (
|
||||
|
||||
@@ -103,7 +103,7 @@ export function DataTable<T extends Record<string, any>>({
|
||||
<div className="relative">
|
||||
<Search className="absolute left-3 top-2.5 h-5 w-5 text-gray-400" />
|
||||
<Input
|
||||
placeholder="Search..."
|
||||
placeholder="Suchen..."
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
className="pl-10"
|
||||
@@ -191,7 +191,7 @@ export function DataTable<T extends Record<string, any>>({
|
||||
</div>
|
||||
|
||||
{sortedData.length === 0 && (
|
||||
<div className="text-center py-8 text-gray-500">No data found</div>
|
||||
<div className="text-center py-8 text-gray-500">Keine Daten gefunden</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -371,7 +371,7 @@ export default function DisciplinaryView() {
|
||||
</div>
|
||||
</motion.div>
|
||||
<p className="text-gray-500 dark:text-gray-400 text-lg font-medium">{t('disciplinary.no_cases')}</p>
|
||||
<p className="text-gray-400 text-sm mt-1">All clear</p>
|
||||
<p className="text-gray-400 text-sm mt-1">Alles in Ordnung</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
) : (
|
||||
|
||||
@@ -894,7 +894,7 @@ export default function DistrictManagementView() {
|
||||
{activityLog.length === 0 ? (
|
||||
<div className="text-center py-8">
|
||||
<Activity className="h-12 w-12 text-emerald-300 dark:text-emerald-700 mx-auto mb-3" />
|
||||
<p className="text-gray-500 dark:text-gray-400">No recent activity</p>
|
||||
<p className="text-gray-500 dark:text-gray-400">Keine aktuellen Aktivitäten</p>
|
||||
</div>
|
||||
) : (
|
||||
<ScrollArea className="max-h-96">
|
||||
|
||||
@@ -340,13 +340,13 @@ function ReportCard({
|
||||
|
||||
const getStatusBadge = () => {
|
||||
if (report.adminApprovalStatus === 'approved') {
|
||||
return <Badge variant="outline" className="bg-emerald-50 text-emerald-700 border-emerald-300 dark:bg-emerald-950/30 dark:text-emerald-300 dark:border-emerald-800"><CheckCircle2 className="h-3 w-3 mr-1" />Approved and on calendar</Badge>;
|
||||
return <Badge variant="outline" className="bg-emerald-50 text-emerald-700 border-emerald-300 dark:bg-emerald-950/30 dark:text-emerald-300 dark:border-emerald-800"><CheckCircle2 className="h-3 w-3 mr-1" />Genehmigt und im Kalender</Badge>;
|
||||
}
|
||||
if (report.adminApprovalStatus === 'rejected') {
|
||||
return <Badge variant="outline" className="bg-rose-50 text-rose-700 border-rose-300 dark:bg-rose-950/30 dark:text-rose-300 dark:border-rose-800"><XCircle className="h-3 w-3 mr-1" />Rejected by administration</Badge>;
|
||||
return <Badge variant="outline" className="bg-rose-50 text-rose-700 border-rose-300 dark:bg-rose-950/30 dark:text-rose-300 dark:border-rose-800"><XCircle className="h-3 w-3 mr-1" />Von der Verwaltung abgelehnt</Badge>;
|
||||
}
|
||||
if (report.parentApprovalStatus === 'approved') {
|
||||
return <Badge variant="outline" className="bg-blue-50 text-blue-700 border-blue-300 dark:bg-blue-950/30 dark:text-blue-300 dark:border-blue-800"><Clock className="h-3 w-3 mr-1" />Awaiting administration</Badge>;
|
||||
return <Badge variant="outline" className="bg-blue-50 text-blue-700 border-blue-300 dark:bg-blue-950/30 dark:text-blue-300 dark:border-blue-800"><Clock className="h-3 w-3 mr-1" />Wartet auf Verwaltung</Badge>;
|
||||
}
|
||||
switch (report.parentApprovalStatus) {
|
||||
case 'pending':
|
||||
|
||||
@@ -619,18 +619,18 @@ function EventCreatorDialog({
|
||||
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<div>
|
||||
<Label htmlFor="type">Type</Label>
|
||||
<Label htmlFor="type">Typ</Label>
|
||||
<select
|
||||
id="type"
|
||||
value={formData.type}
|
||||
onChange={(e) => setFormData({ ...formData, type: e.target.value as CalendarEventType })}
|
||||
className="w-full px-3 py-2 border rounded-md"
|
||||
>
|
||||
<option value="exam">Exam</option>
|
||||
<option value="lesson">Lesson</option>
|
||||
<option value="assignment">Assignment</option>
|
||||
<option value="exam">Prüfung</option>
|
||||
<option value="lesson">Unterricht</option>
|
||||
<option value="assignment">Hausaufgabe</option>
|
||||
<option value="school_event">School Event</option>
|
||||
<option value="custom">Custom</option>
|
||||
<option value="custom">Sonstiges</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -3930,7 +3930,7 @@ export default function SettingsView() {
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<p className="text-xl font-bold text-amber-600 dark:text-amber-400">{importResult.skipped}</p>
|
||||
<p className="text-[10px] text-gray-500 dark:text-gray-400">Skipped</p>
|
||||
<p className="text-[10px] text-gray-500 dark:text-gray-400">Übersprungen</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<p className="text-xl font-bold text-red-600 dark:text-red-400">{importResult.errorCount}</p>
|
||||
|
||||
@@ -2320,7 +2320,7 @@ export default function SubjectsView() {
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label>Icon</Label>
|
||||
<Label>Symbol</Label>
|
||||
<Select
|
||||
value={categoryForm.icon}
|
||||
onValueChange={(v) => setCategoryForm({ ...categoryForm, icon: v })}
|
||||
@@ -2392,11 +2392,11 @@ export default function SubjectsView() {
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="topic">Topic</SelectItem>
|
||||
<SelectItem value="exercise">Exercise</SelectItem>
|
||||
<SelectItem value="lesson">Lesson</SelectItem>
|
||||
<SelectItem value="topic">Thema</SelectItem>
|
||||
<SelectItem value="exercise">Übung</SelectItem>
|
||||
<SelectItem value="lesson">Lektion</SelectItem>
|
||||
<SelectItem value="quiz">Quiz</SelectItem>
|
||||
<SelectItem value="vocabulary">Vocabulary</SelectItem>
|
||||
<SelectItem value="vocabulary">Wortschatz</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
@@ -2418,7 +2418,7 @@ export default function SubjectsView() {
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Label>Icon</Label>
|
||||
<Label>Symbol</Label>
|
||||
<Select
|
||||
value={contentForm.icon}
|
||||
onValueChange={(v) => setContentForm({ ...contentForm, icon: v })}
|
||||
@@ -2446,7 +2446,7 @@ export default function SubjectsView() {
|
||||
checked={contentForm.isPublic}
|
||||
onCheckedChange={(v) => setContentForm({ ...contentForm, isPublic: v })}
|
||||
/>
|
||||
<Label>Public</Label>
|
||||
<Label>Öffentlich</Label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2481,9 +2481,9 @@ export default function SubjectsView() {
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="edit">Edit</SelectItem>
|
||||
<SelectItem value="add">Add</SelectItem>
|
||||
<SelectItem value="delete">Delete</SelectItem>
|
||||
<SelectItem value="edit">Bearbeiten</SelectItem>
|
||||
<SelectItem value="add">Hinzufügen</SelectItem>
|
||||
<SelectItem value="delete">Löschen</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
@@ -93,7 +93,7 @@ function BreadcrumbEllipsis({
|
||||
{...props}
|
||||
>
|
||||
<MoreHorizontal className="size-4" />
|
||||
<span className="sr-only">More</span>
|
||||
<span className="sr-only">Mehr</span>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ function CarouselPrevious({
|
||||
{...props}
|
||||
>
|
||||
<ArrowLeft />
|
||||
<span className="sr-only">Previous slide</span>
|
||||
<span className="sr-only">Vorherige Folie</span>
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
@@ -226,7 +226,7 @@ function CarouselNext({
|
||||
{...props}
|
||||
>
|
||||
<ArrowRight />
|
||||
<span className="sr-only">Next slide</span>
|
||||
<span className="sr-only">Nächste Folie</span>
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ function PaginationPrevious({
|
||||
{...props}
|
||||
>
|
||||
<ChevronLeftIcon />
|
||||
<span className="hidden sm:block">Previous</span>
|
||||
<span className="hidden sm:block">Zurück</span>
|
||||
</PaginationLink>
|
||||
)
|
||||
}
|
||||
@@ -93,7 +93,7 @@ function PaginationNext({
|
||||
className={cn("gap-1 px-2.5 sm:pr-2.5", className)}
|
||||
{...props}
|
||||
>
|
||||
<span className="hidden sm:block">Next</span>
|
||||
<span className="hidden sm:block">Weiter</span>
|
||||
<ChevronRightIcon />
|
||||
</PaginationLink>
|
||||
)
|
||||
@@ -111,7 +111,7 @@ function PaginationEllipsis({
|
||||
{...props}
|
||||
>
|
||||
<MoreHorizontalIcon className="size-4" />
|
||||
<span className="sr-only">More pages</span>
|
||||
<span className="sr-only">Weitere Seiten</span>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ function Sidebar({
|
||||
side={side}
|
||||
>
|
||||
<SheetHeader className="sr-only">
|
||||
<SheetTitle>Sidebar</SheetTitle>
|
||||
<SheetTitle>Seitenleiste</SheetTitle>
|
||||
<SheetDescription>Displays the mobile sidebar.</SheetDescription>
|
||||
</SheetHeader>
|
||||
<div className="flex h-full w-full flex-col">{children}</div>
|
||||
|
||||
Reference in new issue
Block a user