Add Phase 1 Pocket Pascal UI: home, pantry, week plan, and plate.

Replace the hello-world shell with the elevated design system, bilingual screens, recipe/extras data, and the interactive Mein Teller view.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Steffi Müller
2026-08-04 12:22:32 +02:00
parent 3785d08e97
commit a482bf5b09
60 changed files with 7366 additions and 72 deletions

148
client/src/i18n/ui.ts Normal file
View File

@@ -0,0 +1,148 @@
import type { Language, LocalizedString } from "@/types/domain"
/**
* Resolve a UI chrome key object (or any LocalizedString) for the active language.
* Mirrors the prototype `t(key)` helper when called as `t(ui.nav.home, lang)`.
*/
export function t(value: LocalizedString, lang: Language): string {
return value[lang]
}
/**
* Resolve a data LocalizedString (`name`, `text`, …) — prototype `tr(obj)`.
*/
export function tr(value: LocalizedString, lang: Language): string {
return value[lang]
}
export const ui = {
appName: { de: "Pocket Pascal", en: "Pocket Pascal" },
nav: {
home: { de: "Start", en: "Home" },
pantry: { de: "Vorrat", en: "Pantry" },
knowledge: { de: "Teller", en: "Plate" },
settings: { de: "Einstellungen", en: "Settings" },
},
home: {
title: { de: "Was esse ich jetzt?", en: "What do I eat now?" },
editLayout: { de: "Layout", en: "Layout" },
doneEdit: { de: "Fertig", en: "Done" },
moveUp: { de: "Nach oben", en: "Move up" },
moveDown: { de: "Nach unten", en: "Move down" },
},
suggestion: {
morning: { de: "Morgen · Protein + Obst", en: "Morning · Protein + fruit" },
midday: { de: "Mittag · Ganzer Teller", en: "Midday · Full plate" },
afternoon: { de: "Nachmittag · Snack-Zeit", en: "Afternoon · Snack time" },
evening: { de: "Abend · Ganzer Teller", en: "Evening · Full plate" },
timeSuffix: { de: "Uhr", en: "" },
pinned: { de: "Fixiert", en: "Pinned" },
pin: { de: "Fixieren", en: "Pin" },
unpin: { de: "Lösen", en: "Unpin" },
reroll: { de: "Was anderes", en: "Something else" },
toBuilder: { de: "In den Builder übernehmen", en: "Send to builder" },
fallbackName: { de: "Dein Teller jetzt", en: "Your plate now" },
},
knowledgeHub: {
plateTitle: { de: "Mein Teller", en: "My Plate" },
plateBody: {
de: "⅓ Protein · ⅓ Gemüse/Obst · ⅓ Fett + Kohlenhydrate",
en: "⅓ protein · ⅓ veg/fruit · ⅓ fat + carbs",
},
pantryTitle: { de: "Vorratskammer", en: "Pantry" },
pantryBody: {
de: "Kategorien, Suche, Pick- & Caution-Markierungen",
en: "Categories, search, pick & caution markers",
},
weekplanTitle: { de: "Wochenplan", en: "Weekly plan" },
weekplanBody: {
de: "Frühstück, Snacks, volle Teller & Rezepte",
en: "Breakfast, snacks, full plates & recipes",
},
},
weekplan: {
title: { de: "Wochenplan", en: "Weekly plan" },
intro: {
de: "Kuratierte Kombinationen aus dem Baukasten — gruppiert nach Mahlzeitentyp.",
en: "Curated building-block combos — grouped by meal type.",
},
breakfast: { de: "Frühstück", en: "Breakfast" },
snack: { de: "Snack", en: "Snack" },
full: { de: "Ganzer Teller", en: "Full plate" },
recipe: { de: "Rezepte", en: "Recipes" },
cooked: { de: "Warm / gekocht", en: "Warm / cooked" },
cold: { de: "Kalt / ohne Kochen", en: "Cold / no cook" },
uses: { de: "Zutaten", en: "Ingredients" },
variations: { de: "Variationen", en: "Variations" },
},
pantry: {
title: { de: "Vorratskammer", en: "Pantry" },
search: { de: "Lebensmittel suchen…", en: "Search foods…" },
pick: { de: "empfohlen", en: "recommended" },
caution: { de: "bewusst genießen", en: "enjoy mindfully" },
noResults: { de: "Keine Treffer.", en: "No results." },
tip: { de: "Tipp", en: "Tip" },
},
plate: {
title: { de: "Mein Teller", en: "My Plate" },
subtitle: {
de: "Baukasten-Reihenfolge: zuerst Protein, dann Obst oder Gemüse, danach Fett und Kohlenhydrate.",
en: "Building-block order: protein first, then fruit or vegetables, then fat and carbohydrates.",
},
mealToggle: { de: "Mahlzeitentyp", en: "Meal type" },
segFull: { de: "Ganze Mahlzeit", en: "Full meal" },
segHalf: { de: "Halbe Mahlzeit", en: "Half meal" },
plateAria: {
de: "Tellerverteilung nach Baukasten",
en: "Plate breakdown by building blocks",
},
rulesTitle: { de: "Grundregeln", en: "Ground rules" },
rule1: {
de: "Jede Mahlzeit beruht auf Protein — egal ob süß, herzhaft, Snack oder Hauptmahlzeit.",
en: "Every meal is built on protein — sweet, savoury, snack, or main.",
},
rule2: {
de: "Jede Mahlzeit enthält eine Portion Gemüse oder Obst.",
en: "Every meal includes a portion of vegetables or fruit.",
},
rule3: {
de: "4 Mahlzeiten am Tag, ca. alle 34 Std.",
en: "4 meals a day, roughly every 34 hours.",
},
rule4: {
de: "2 L Wasser täglich.",
en: "2 L of water daily.",
},
},
builderSlot: {
title: { de: "Teller-Builder", en: "Plate builder" },
body: {
de: "Chips antippen, Kombination sofort gegen die Baukasten-Regeln prüfen.",
en: "Tap chips and check the combo against the building-block rules instantly.",
},
},
stubs: {
pantryTitle: { de: "Vorratskammer", en: "Pantry" },
pantryBody: {
de: "Phase-1-Platzhalter — Suche & Kategorien folgen.",
en: "Phase 1 stub — search & categories coming next.",
},
knowledgeTitle: { de: "Knowledge Base", en: "Knowledge Base" },
knowledgeBody: {
de: "Phase-1-Platzhalter — Teller-Regel & Daumenregeln folgen.",
en: "Phase 1 stub — plate rule & thumb rules coming next.",
},
builderTitle: { de: "Teller-Builder", en: "Plate builder" },
builderBody: {
de: "Phase-1-Platzhalter — Chip-Auswahl & Bewertung folgen.",
en: "Phase 1 stub — chip selection & scoring coming next.",
},
builderHandoff: {
de: "Übernommen aus dem Vorschlag:",
en: "Handed off from suggestion:",
},
settingsTitle: { de: "Einstellungen", en: "Settings" },
language: { de: "Sprache", en: "Language" },
comingSoon: { de: "Demnächst", en: "Coming soon" },
},
} as const