diff --git a/CHANGELOG.md b/CHANGELOG.md index c87b380..7e0543e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,9 @@ Versionierung nach [Semantic Versioning](https://semver.org/lang/de/). ## [1.4.0] – 2026-07-18 (Branch `feature/v1.4`, noch nicht gemergt) ### Hinzugefügt -- Bereiche (Brotzeit/Mittagessen/…) vollständig verwaltbar: anlegen, +- Essenszeiten (Brotzeit/Mittagessen/…) vollständig verwaltbar: anlegen, umbenennen (inkl. EN/PL), Uhrzeit ändern, löschen und per Pfeil-Buttons - neu anordnen – neue Seite „Bereiche" im Kantinen-Bereich. Löschen + neu anordnen – neue Seite „Essenszeiten" im Kantinen-Bereich. Löschen entfernt zugewiesene Gerichte automatisch aus allen Wochenplänen. ### Geändert diff --git a/README.md b/README.md index c34d483..ccfca73 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,8 @@ markieren die jeweiligen Versionsstände (`git tag`). | Bereich | Funktionen | | --- | --- | -| Öffentlich (ohne Login) | Wochenplan Mo–Fr mit den Bereichen Brotzeit (09:00–10:00), Mittagessen, Mittagessen vegetarisch und Suppe (je 11:30–13:30); Navigation vorherige/nächste Woche/Heute; auf schmalen Bildschirmen umschaltbare Tages-/Wochenansicht (Tag ist Standard); Logo zentriert über der Karte; Allergen-/Zusatzstoff-Kürzel je Gericht, Legende unterhalb der Karte; Sprachumschalter Deutsch/Englisch/Polnisch; Rezeptvorschläge einreichen | -| Kantinen-Team (`/intern`) | Gerichte anlegen/bearbeiten/löschen (inkl. Live-Suche, Mehrfachauswahl zum Batch-Löschen, englischem/polnischem Namen mit automatischer DeepL-Übersetzung) mit Allergenen/Zusatzstoffen je Gericht; Gerichte Tagen/Bereichen zuweisen (mehrere pro Zelle) und wieder entfernen; globale Allergen-/Zusatzstofflisten pflegen (ebenfalls mehrsprachig); eingereichte Rezeptvorschläge sichten, übernehmen oder ablehnen; eigenes Konto verwalten (Name, E-Mail, Passwort, Passkeys, Passwort-Anmeldung an/aus) | +| Öffentlich (ohne Login) | Wochenplan Mo–Fr mit den Essenszeiten Brotzeit (09:00–10:00), Mittagessen, Mittagessen vegetarisch und Suppe (je 11:30–13:30); Navigation vorherige/nächste Woche/Heute; auf schmalen Bildschirmen umschaltbare Tages-/Wochenansicht (Tag ist Standard); Logo zentriert über der Karte; Allergen-/Zusatzstoff-Kürzel je Gericht, Legende unterhalb der Karte; Sprachumschalter Deutsch/Englisch/Polnisch; Rezeptvorschläge einreichen | +| Kantinen-Team (`/intern`) | Gerichte anlegen/bearbeiten/löschen (inkl. Live-Suche, Mehrfachauswahl zum Batch-Löschen, englischem/polnischem Namen mit automatischer DeepL-Übersetzung) mit Allergenen/Zusatzstoffen je Gericht; Gerichte Tagen/Essenszeiten zuweisen (mehrere pro Zelle) und wieder entfernen; globale Allergen-/Zusatzstofflisten pflegen (ebenfalls mehrsprachig); eingereichte Rezeptvorschläge sichten, übernehmen oder ablehnen; eigenes Konto verwalten (Name, E-Mail, Passwort, Passkeys, Passwort-Anmeldung an/aus) | | Admin (`/admin`) | Kantinenmitarbeiter anlegen/bearbeiten/löschen (inkl. Passwort-Reset mit Wiederholung und Rollenvergabe); Farbgebung der Speisekarte anpassen; Logo und Favicon hochladen/entfernen | Anmeldung mit E-Mail + Passwort oder alternativ per **Passkey** @@ -24,7 +24,7 @@ Passwort-Anmeldung kann pro Konto deaktiviert werden, sobald mindestens ein Passkey registriert ist. Die gesamte Oberfläche ist auf Deutsch, Englisch und Polnisch verfügbar -(Sprachumschalter, Cookie-basiert). Gerichte, Bereiche, Allergene und +(Sprachumschalter, Cookie-basiert). Gerichte, Essenszeiten, Allergene und Zusatzstoffe lassen sich zusätzlich auf Englisch/Polnisch benennen – mit optionaler automatischer Übersetzung über DeepL (siehe `DEEPL_API_KEY` unten) und jederzeit manuell korrigierbar. @@ -136,7 +136,7 @@ ihre Gültigkeit und müssen neu registriert werden. Sicherheitsmodell (Row Level Security): -- `anon` darf ausschließlich lesen (Speisekarte, Bereiche, Allergene, +- `anon` darf ausschließlich lesen (Speisekarte, Essenszeiten, Allergene, Zusatzstoffe, Einstellungen). - `staff`/`admin` (Rolle im `profiles`-Eintrag) pflegen Gerichte, Wochenplan und Kennzeichnungen. diff --git a/app/intern/bereiche/page.tsx b/app/intern/essenszeiten/page.tsx similarity index 66% rename from app/intern/bereiche/page.tsx rename to app/intern/essenszeiten/page.tsx index 57a346d..c92b122 100644 --- a/app/intern/bereiche/page.tsx +++ b/app/intern/essenszeiten/page.tsx @@ -1,5 +1,5 @@ import SectionManager from "@/components/SectionManager"; -export default function BereichePage() { +export default function EssenszeitenPage() { return ; } diff --git a/components/AppHeader.tsx b/components/AppHeader.tsx index 2c89e6f..23b42c5 100644 --- a/components/AppHeader.tsx +++ b/components/AppHeader.tsx @@ -23,7 +23,7 @@ export default function AppHeader({ const menuLinks = [ { href: "/intern", label: dict.header.weekPlan }, - { href: "/intern/bereiche", label: dict.header.sections }, + { href: "/intern/essenszeiten", label: dict.header.sections }, { href: "/intern/gerichte", label: dict.header.dishes }, { href: "/intern/kennzeichnung", label: dict.header.labels }, { href: "/intern/vorschlaege", label: dict.header.suggestions }, diff --git a/components/SectionManager.tsx b/components/SectionManager.tsx index f537be0..2c714e5 100644 --- a/components/SectionManager.tsx +++ b/components/SectionManager.tsx @@ -1,6 +1,6 @@ "use client"; -// Verwaltung der Speiseplan-Bereiche (Brotzeit, Mittagessen, …): +// Verwaltung der Essenszeiten (Brotzeit, Mittagessen, …): // anlegen, umbenennen, Uhrzeit ändern, löschen, Reihenfolge anpassen. import { useCallback, useEffect, useMemo, useState } from "react"; @@ -11,7 +11,7 @@ import type { Section } from "@/lib/types"; import { useDict, useLocale } from "@/components/i18n/LocaleProvider"; interface SectionForm { - key: string | null; // null = neuer Bereich + key: string | null; // null = neue Essenszeit label: string; labelEn: string; labelPl: string; diff --git a/lib/i18n/dictionaries.ts b/lib/i18n/dictionaries.ts index c3082ee..27f5792 100644 --- a/lib/i18n/dictionaries.ts +++ b/lib/i18n/dictionaries.ts @@ -30,7 +30,7 @@ const de = { canteen: "Kantine", menuGroup: "Speiseplan", weekPlan: "Wochenplan", - sections: "Bereiche", + sections: "Essenszeiten", dishes: "Gerichte", labels: "Allergene & Zusatzstoffe", adminGroup: "Verwaltung", @@ -120,9 +120,9 @@ const de = { deleteError: "Löschen fehlgeschlagen: {message}", }, sectionManager: { - title: "Bereiche", - newSection: "Neuer Bereich", - editSection: "Bereich bearbeiten", + title: "Essenszeiten", + newSection: "Neue Essenszeit", + editSection: "Essenszeit bearbeiten", nameLabel: "Bezeichnung", nameEnLabel: "Bezeichnung (Englisch)", namePlLabel: "Bezeichnung (Polnisch)", @@ -130,7 +130,7 @@ const de = { timeTo: "Bis", moveUp: "Nach oben", moveDown: "Nach unten", - empty: "Noch keine Bereiche angelegt.", + empty: "Noch keine Essenszeiten angelegt.", confirmDelete: "„{name}“ wirklich löschen? Zugewiesene Gerichte werden auch aus allen Wochenplänen entfernt.", loadError: "Laden fehlgeschlagen: {message}", @@ -286,7 +286,7 @@ const en: Dict = { canteen: "Canteen", menuGroup: "Menu", weekPlan: "Weekly plan", - sections: "Sections", + sections: "Meal times", dishes: "Dishes", labels: "Allergens & Additives", adminGroup: "Administration", @@ -376,9 +376,9 @@ const en: Dict = { deleteError: "Deleting failed: {message}", }, sectionManager: { - title: "Sections", - newSection: "New section", - editSection: "Edit section", + title: "Meal times", + newSection: "New meal time", + editSection: "Edit meal time", nameLabel: "Name", nameEnLabel: "Name (English)", namePlLabel: "Name (Polish)", @@ -386,7 +386,7 @@ const en: Dict = { timeTo: "To", moveUp: "Move up", moveDown: "Move down", - empty: "No sections yet.", + empty: "No meal times yet.", confirmDelete: "Really delete “{name}”? Assigned dishes will also be removed from all weekly plans.", loadError: "Loading failed: {message}", @@ -540,7 +540,7 @@ const pl: Dict = { canteen: "Stołówka", menuGroup: "Jadłospis", weekPlan: "Plan tygodnia", - sections: "Sekcje", + sections: "Pory posiłków", dishes: "Dania", labels: "Alergeny i dodatki", adminGroup: "Administracja", @@ -630,9 +630,9 @@ const pl: Dict = { deleteError: "Usuwanie nie powiodło się: {message}", }, sectionManager: { - title: "Sekcje", - newSection: "Nowa sekcja", - editSection: "Edytuj sekcję", + title: "Pory posiłków", + newSection: "Nowa pora posiłku", + editSection: "Edytuj porę posiłku", nameLabel: "Nazwa", nameEnLabel: "Nazwa (angielski)", namePlLabel: "Nazwa (polski)", @@ -640,7 +640,7 @@ const pl: Dict = { timeTo: "Do", moveUp: "Przesuń w górę", moveDown: "Przesuń w dół", - empty: "Nie dodano jeszcze żadnych sekcji.", + empty: "Nie dodano jeszcze żadnych pór posiłków.", confirmDelete: "Czy na pewno usunąć „{name}”? Przypisane dania zostaną również usunięte ze wszystkich planów tygodniowych.", loadError: "Wczytywanie nie powiodło się: {message}", diff --git a/lib/menu.ts b/lib/menu.ts index 9cc49fb..5049ec0 100644 --- a/lib/menu.ts +++ b/lib/menu.ts @@ -64,7 +64,7 @@ export function dishCodes(dish: { allergens: string[]; additives: string[] }): s return [...(dish.allergens ?? []), ...(dish.additives ?? [])].join(","); } -/** Einträge eines Tages/Bereichs aus der geladenen Wochenliste herausfiltern. */ +/** Einträge eines Tages/einer Essenszeit aus der geladenen Wochenliste herausfiltern. */ export function entriesFor( entries: MenuEntry[], iso: string, diff --git a/supabase/migrations/0001_init.sql b/supabase/migrations/0001_init.sql index 3201bd3..fea35d6 100644 --- a/supabase/migrations/0001_init.sql +++ b/supabase/migrations/0001_init.sql @@ -49,7 +49,7 @@ create trigger on_auth_user_created after insert on auth.users for each row execute function public.handle_new_user(); --- ---------- Bereiche der Speisekarte ---------- +-- ---------- Essenszeiten der Speisekarte ---------- create table public.sections ( key text primary key, label text not null, @@ -101,7 +101,7 @@ create trigger dishes_touch_updated_at before update on public.dishes for each row execute function public.touch_updated_at(); --- ---------- Zuweisung Gericht -> Tag/Bereich ---------- +-- ---------- Zuweisung Gericht -> Tag/Essenszeit ---------- create table public.menu_entries ( id uuid primary key default gen_random_uuid(), menu_date date not null, diff --git a/supabase/migrations/0006_variable_sections.sql b/supabase/migrations/0006_variable_sections.sql index 629a50f..b636681 100644 --- a/supabase/migrations/0006_variable_sections.sql +++ b/supabase/migrations/0006_variable_sections.sql @@ -1,14 +1,14 @@ -- ============================================================= --- Bereiche (Brotzeit/Mittagessen/…) vollständig verwaltbar machen: +-- Essenszeiten (Brotzeit/Mittagessen/…) vollständig verwaltbar machen: -- anlegen, umbenennen, Uhrzeit ändern, löschen. -- ============================================================= --- Neue Bereiche bekommen einen automatisch generierten Schlüssel +-- Neue Essenszeiten bekommen einen automatisch generierten Schlüssel -- (wie bei dishes.id) statt eines von Hand vergebenen Slugs. alter table public.sections alter column key set default (gen_random_uuid())::text; --- Löscht man einen Bereich, werden seine Wochenplan-Einträge mit +-- Löscht man eine Essenszeit, werden ihre Wochenplan-Einträge mit -- entfernt (analog zu menu_entries_dish_id_fkey bei Gerichten) statt -- die Löschung zu blockieren. alter table public.menu_entries @@ -18,7 +18,7 @@ alter table public.menu_entries foreign key (section_key) references public.sections(key) on delete cascade; -- Bisher gab es nur eine Lesepolicy für sections; jetzt dürfen --- Kantinenmitarbeiter/Admins Bereiche auch anlegen/ändern/löschen. +-- Kantinenmitarbeiter/Admins Essenszeiten auch anlegen/ändern/löschen. create policy "sections_staff_write" on public.sections for all to authenticated using (public.app_role() in ('staff', 'admin'))