import Link from "next/link"; import { createClient } from "@/lib/supabase/server"; 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, MenuEntry, 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 = getDictionary(locale); const days = dict.weekdays.long.map((weekday, i) => ({ weekday, iso: addDays(monday, i), })); const supabase = await createClient(); const [sectionsRes, entriesRes, allergensRes, additivesRes, settingsRes] = await Promise.all([ supabase.from("sections").select("*").order("sort"), supabase .from("menu_entries") .select( "id, menu_date, section_key, position, dish:dishes(id, name, name_en, name_pl, price, allergens, additives)" ) .gte("menu_date", monday) .lte("menu_date", friday) .order("position") .order("created_at"), supabase.from("allergens").select("*").order("sort"), supabase.from("additives").select("*").order("sort"), supabase.from("settings").select("logo_path").eq("id", 1).maybeSingle(), ]); const sections = (sectionsRes.data ?? []) as Section[]; const entries = (entriesRes.data ?? []) as unknown as MenuEntry[]; const allergens = (allergensRes.data ?? []) as CodeItem[]; const additives = (additivesRes.data ?? []) as CodeItem[]; const logo = logoUrl(settingsRes.data?.logo_path); 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) => ( {days.map((d) => ( ))} ))}
{days.map((d) => ( {d.weekday}
{formatDateLong(d.iso, dict.dateLocale)}
{localized(s, locale)}
{s.time_range}
{entriesFor(entries, d.iso, s.key).map((e) => { const codes = dishCodes(e.dish); return (
{localized(e.dish, locale)} {codes && {codes}} {" – "} {formatPrice(e.dish.price)}
); })}
{/* Allergene & Zusatzstoffe: Legende zu den Kürzeln bei den Gerichten */}

{dict.publicMenu.allergens}

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

{dict.publicMenu.additives}

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