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
+26 -13
View File
@@ -17,10 +17,11 @@ import {
mondayOf,
todayISO,
weekdayIndex,
WEEKDAYS,
WEEKDAYS_SHORT,
} from "@/lib/menu";
import { localized } from "@/lib/types";
import type { MenuEntry, Section } from "@/lib/types";
import { useDict, useLocale } from "@/components/i18n/LocaleProvider";
import LanguageSwitcher from "@/components/i18n/LanguageSwitcher";
export default function PublicMobileMenu({
monday,
@@ -32,9 +33,11 @@ export default function PublicMobileMenu({
entries: MenuEntry[];
}) {
const router = useRouter();
const days = WEEKDAYS.map((weekday, i) => ({
const dict = useDict();
const locale = useLocale();
const days = dict.weekdays.long.map((weekday, i) => ({
weekday,
short: WEEKDAYS_SHORT[i],
short: dict.weekdays.short[i],
iso: addDays(monday, i),
}));
const isCurrentWeek = monday === mondayOf(todayISO());
@@ -58,7 +61,7 @@ export default function PublicMobileMenu({
return (
<div key={day.iso} className="mb-4 last:mb-0">
<h3 className="font-bold text-[var(--c-primary)] mb-2">
{day.weekday} · {formatDateLong(day.iso)}
{day.weekday} · {formatDateLong(day.iso, dict.dateLocale)}
</h3>
<div className="space-y-3">
{sections.map((s) => {
@@ -69,18 +72,20 @@ export default function PublicMobileMenu({
className="rounded-md border border-gray-200 overflow-hidden"
>
<div className="bg-[var(--c-primary)] text-[var(--c-header-text)] px-3 py-1.5 text-sm">
<span className="font-semibold">{s.label}</span>{" "}
<span className="font-semibold">{localized(s, locale)}</span>{" "}
<span className="opacity-80">· {s.time_range}</span>
</div>
<div className="bg-[var(--c-row-bg)] px-3 py-2 text-sm">
{items.length === 0 ? (
<p className="text-gray-500">–</p>
<p className="text-gray-500">{dict.publicMenu.noEntry}</p>
) : (
items.map((e) => {
const codes = dishCodes(e.dish);
return (
<p key={e.id} className="mb-1 last:mb-0">
<span className="font-semibold">{e.dish.name}</span>
<span className="font-semibold">
{localized(e.dish, locale)}
</span>
{codes && <sup className="dish-codes">{codes}</sup>}{" "}
– {formatPrice(e.dish.price)}
</p>
@@ -98,25 +103,29 @@ export default function PublicMobileMenu({
return (
<div className="sm:hidden mb-6">
<div className="flex justify-end mb-3">
<LanguageSwitcher variant="light" />
</div>
<div className="flex gap-2 mb-3">
<Link
href={`/?woche=${addDays(monday, -7)}`}
className="btn btn-add flex-1 justify-center"
>
← Woche
{dict.publicMenu.prevWeekShort}
</Link>
<button
type="button"
onClick={goToday}
className="btn btn-primary flex-1"
>
Heute
{dict.publicMenu.today}
</button>
<Link
href={`/?woche=${addDays(monday, 7)}`}
className="btn btn-add flex-1 justify-center"
>
Woche →
{dict.publicMenu.nextWeekShort}
</Link>
</div>
@@ -128,7 +137,7 @@ export default function PublicMobileMenu({
onClick={() => setTab("tag")}
className={`btn flex-1 ${tab === "tag" ? "btn-primary" : "btn-neutral"}`}
>
Tag
{dict.publicMenu.dayTab}
</button>
<button
type="button"
@@ -137,7 +146,7 @@ export default function PublicMobileMenu({
onClick={() => setTab("woche")}
className={`btn flex-1 ${tab === "woche" ? "btn-primary" : "btn-neutral"}`}
>
Woche
{dict.publicMenu.weekTab}
</button>
</div>
@@ -164,6 +173,10 @@ export default function PublicMobileMenu({
) : (
<div>{days.map((d) => renderDay(d))}</div>
)}
<Link href="/vorschlag" className="btn btn-neutral w-full justify-center mt-2">
{dict.publicMenu.suggestDish}
</Link>
</div>
);
}