Mehrsprachige Oberfläche + lokalisierte Gericht-/Bereichsnamen

Alle Seiten und Komponenten (öffentliche Speisekarte, Login, Kantinen-
und Admin-Bereich, eigenes Konto) verwenden jetzt die Wörterbücher aus
lib/i18n statt fest codierter deutscher Texte. Gerichte/Bereiche/
Allergene/Zusatzstoffe zeigen den Namen zur aktuell gewählten Sprache;
Gerichte- und Kennzeichnungs-Formulare bekommen Englisch-/Polnisch-
Felder mit Übersetzen-Button (siehe vorherigen Commit). Datumsformat-
ierung (formatDateLong) nimmt jetzt ein locale-Argument statt fix
'de-DE'.
This commit is contained in:
2026-07-18 02:08:03 +02:00
parent 30a02ba7b7
commit a6165de10c
14 changed files with 586 additions and 328 deletions
+25 -21
View File
@@ -8,17 +8,8 @@
import Link from "next/link";
import { usePathname } from "next/navigation";
import type { Role } from "@/lib/types";
const MENU_LINKS = [
{ href: "/intern", label: "Wochenplan" },
{ href: "/intern/gerichte", label: "Gerichte" },
{ href: "/intern/kennzeichnung", label: "Allergene & Zusatzstoffe" },
];
const ADMIN_LINKS = [
{ href: "/admin", label: "Benutzer" },
{ href: "/admin/design", label: "Design" },
];
import { useDict } from "@/components/i18n/LocaleProvider";
import LanguageSwitcher from "@/components/i18n/LanguageSwitcher";
export default function AppHeader({
role,
@@ -28,6 +19,18 @@ export default function AppHeader({
displayName: string;
}) {
const pathname = usePathname();
const dict = useDict();
const menuLinks = [
{ href: "/intern", label: dict.header.weekPlan },
{ href: "/intern/gerichte", label: dict.header.dishes },
{ href: "/intern/kennzeichnung", label: dict.header.labels },
{ href: "/intern/vorschlaege", label: dict.header.suggestions },
];
const adminLinks = [
{ href: "/admin", label: dict.header.users },
{ href: "/admin/design", label: dict.header.design },
];
const linkClass = (href: string) =>
`rounded px-2 py-0.5 transition-colors hover:bg-white/10 ${
@@ -37,16 +40,16 @@ export default function AppHeader({
return (
<header className="bg-[var(--c-primary-dark)] text-white">
<div className="max-w-[1600px] mx-auto w-full px-4 py-3 flex flex-wrap items-center gap-x-6 gap-y-2 text-sm">
<span className="font-bold text-base">Kantine</span>
<span className="font-bold text-base">{dict.header.canteen}</span>
<nav
className="flex flex-wrap items-center gap-x-1 gap-y-1"
aria-label="Speiseplan"
aria-label={dict.header.menuGroup}
>
<span className="mr-1 text-xs uppercase tracking-wider text-white/50">
Speiseplan
{dict.header.menuGroup}
</span>
{MENU_LINKS.map((l) => (
{menuLinks.map((l) => (
<Link key={l.href} href={l.href} className={linkClass(l.href)}>
{l.label}
</Link>
@@ -56,12 +59,12 @@ export default function AppHeader({
{role === "admin" && (
<nav
className="flex flex-wrap items-center gap-x-1 gap-y-1"
aria-label="Verwaltung"
aria-label={dict.header.adminGroup}
>
<span className="mr-1 text-xs uppercase tracking-wider text-white/50">
Verwaltung
{dict.header.adminGroup}
</span>
{ADMIN_LINKS.map((l) => (
{adminLinks.map((l) => (
<Link key={l.href} href={l.href} className={linkClass(l.href)}>
{l.label}
</Link>
@@ -73,13 +76,14 @@ export default function AppHeader({
href="/"
className="rounded px-2 py-0.5 text-white/70 hover:bg-white/10"
>
Speisekarte ansehen
{dict.header.viewMenu}
</Link>
<div className="ml-auto flex items-center gap-3">
<LanguageSwitcher />
<Link
href="/konto"
title="Mein Konto"
title={dict.header.myAccount}
className={`rounded px-2 py-0.5 hover:bg-white/10 ${
pathname === "/konto"
? "bg-white/20 font-semibold"
@@ -90,7 +94,7 @@ export default function AppHeader({
</Link>
<form action="/logout" method="post">
<button type="submit" className="btn btn-del">
Abmelden
{dict.common.logout}
</button>
</form>
</div>