import Link from "next/link"; import { query } from "@/lib/db"; import { loadMenuEntries } from "@/lib/db/menu-entries"; import { loadTranslations } from "@/lib/db/translations"; import { listClosedDays } from "@/lib/db/closed-days"; import { getSettings } from "@/lib/db/settings"; import { addDays, dishCodes, entriesFor, formatDateLong, formatPrice, mondayOf, todayISO, } from "@/lib/menu"; import { getDictionary, getLocale } from "@/lib/i18n"; import { localized, logoUrl, SITE_TITLE } from "@/lib/types"; import type { CodeItem, Section } from "@/lib/types"; import PublicMobileMenu from "@/components/PublicMobileMenu"; import LanguageSwitcher from "@/components/i18n/LanguageSwitcher"; export default async function Home({ searchParams, }: { searchParams: Promise<{ woche?: string }>; }) { const { woche } = await searchParams; const monday = mondayOf(woche); const friday = addDays(monday, 4); const currentWeek = mondayOf(todayISO()); const locale = await getLocale(); const dict = await getDictionary(locale); const days = dict.weekdays.long.map((weekday, i) => ({ weekday, iso: addDays(monday, i), })); const [ sectionRows, entries, allergenRows, additiveRows, settings, sectionTranslations, allergenTranslations, additiveTranslations, closedDays, ] = await Promise.all([ query>("select key, label, time_range, sort from sections order by sort"), loadMenuEntries(monday, friday), query>("select code, name, sort from allergens order by sort"), query>("select code, name, sort from additives order by sort"), getSettings(), loadTranslations("section_translations"), loadTranslations("allergen_translations"), loadTranslations("additive_translations"), listClosedDays(monday, friday), ]); const closedDayFor = (iso: string) => closedDays.find((c) => c.closed_date === iso); const sections: Section[] = sectionRows.map((s) => ({ ...s, translations: sectionTranslations.get(s.key) ?? {}, })); const allergens: CodeItem[] = allergenRows.map((a) => ({ ...a, translations: allergenTranslations.get(a.code) ?? {}, })); const additives: CodeItem[] = additiveRows.map((a) => ({ ...a, translations: additiveTranslations.get(a.code) ?? {}, })); const logo = logoUrl(settings?.logo_path); const labelingDetailed = (settings?.labeling_mode ?? "detailed") !== "notice"; return (
{/* Kopfbereich: Sprache + Login-Link eigene Zeile, Logo zentriert darunter. Kein absolutes Positionieren mehr – ein breites Logo (z. B. ein Banner-Format) konnte sonst mit dem Login-Link kollidieren. */}
{/* Auf Mobilgeräten übernimmt PublicMobileMenu den Sprachumschalter, hier würde er sonst doppelt erscheinen. */}
{dict.common.login}
{logo ? ( // eslint-disable-next-line @next/next/no-img-element Logo ) : (

{SITE_TITLE}

)}
{/* Mobil: Tag (Standard) oder Woche umschaltbar */} {/* Ab "sm": klassische Wochentabelle */}
{dict.publicMenu.prevWeek} {dict.publicMenu.today} {dict.publicMenu.nextWeek} {dict.publicMenu.suggestDish}
))} {sections.map((s, sIdx) => ( {days.map((d) => { const closed = closedDayFor(d.iso); if (closed) { if (sIdx > 0) return null; return ( ); } return ( ); })} ))}
{days.map((d) => ( {d.weekday}
{formatDateLong(d.iso, dict.dateLocale)}
{localized(s, locale)}
{s.time_range}
🔒 {dict.publicMenu.closedLabel} {localized(closed, locale) && ( {localized(closed, locale)} )}
{entriesFor(entries, d.iso, s.key).map((e) => { const codes = dishCodes(e.dish); return (
{localized(e.dish, locale)} {labelingDetailed && codes && ( {codes} )} {" – "} {formatPrice(e.dish.price)}
); })}
{/* Allergene & Zusatzstoffe: entweder Legende zu den Kürzeln bei den Gerichten, oder – falls im Hinweismodus – nur ein Hinweistext. */} {labelingDetailed ? (

{dict.publicMenu.allergens}

    {allergens.map((a) => (
  • {a.code} –{" "} {localized(a, locale)}
  • ))}

{dict.publicMenu.additives}

    {additives.map((a) => (
  • {a.code} –{" "} {localized(a, locale)}
  • ))}
) : ( settings && (

{dict.publicMenu.labelingNoticeTitle}

{localized( { name: settings.labeling_notice, name_en: settings.labeling_notice_en, name_pl: settings.labeling_notice_pl, }, locale )}

) )}
); }