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

View File

@@ -0,0 +1,112 @@
import { useState } from "react";
import { GlassCard } from "./components/GlassCard";
import { Button } from "./components/Button";
import { BottomNav, type NavItem } from "./components/BottomNav";
import { PlateChart } from "./components/PlateChart";
/**
* Demo page — every component rendered over a few different background
* gradients so the backdrop-blur actually has something to refract.
* Drop this on a route in Cursor (e.g. /showcase) to sanity-check the
* system before wiring it into real screens.
*/
export default function ComponentShowcase() {
const [dark, setDark] = useState(false);
const [active, setActive] = useState("plate");
const [loading, setLoading] = useState(false);
const navItems: NavItem[] = [
{ key: "plate", icon: "🍽️", label: "Teller", active: active === "plate", onClick: () => setActive("plate") },
{ key: "pantry", icon: "🧺", label: "Vorrat", active: active === "pantry", onClick: () => setActive("pantry") },
{ key: "builder", icon: "🧩", label: "Builder", active: active === "builder", onClick: () => setActive("builder") },
{ key: "settings", icon: "⚙️", label: "Mehr", active: active === "settings", onClick: () => setActive("settings") },
];
return (
<div className={dark ? "dark" : ""}>
<div
className="min-h-screen font-body"
style={{ background: "var(--page-gradient)", color: "var(--ink)" }}
>
<div className="mx-auto max-w-md space-y-10 px-5 pb-32 pt-10">
<header className="flex items-center justify-between">
<div>
<p className="text-[10px] font-bold uppercase tracking-widest text-[var(--ink-faint)]">
Pocket Pascal · Component Showcase
</p>
<h1 className="font-display text-3xl font-black">Elevated Surfaces</h1>
</div>
<Button variant="secondary" onClick={() => setDark((d) => !d)}>
{dark ? "☀️ Light" : "🌙 Dark"}
</Button>
</header>
{/* GlassCard variants */}
<section className="space-y-3">
<h2 className="font-display text-sm font-bold uppercase tracking-wide text-[var(--ink-faint)]">
Card
</h2>
<GlassCard className="p-5">
<p className="font-display text-lg font-bold">Default</p>
<p className="mt-1 text-sm text-[var(--ink-soft)]">
Static container low-transparency surface, real elevation shadow, raised bevel edge.
</p>
</GlassCard>
<GlassCard variant="interactive" className="p-5" onClick={() => {}}>
<p className="font-display text-lg font-bold">Interactive</p>
<p className="mt-1 text-sm text-[var(--ink-soft)]">Tap me settles down 1px, shadow softens.</p>
</GlassCard>
</section>
{/* Dining Plate chart inside a GlassCard */}
<section className="space-y-3">
<h2 className="font-display text-sm font-bold uppercase tracking-wide text-[var(--ink-faint)]">
Dining Plate Chart
</h2>
<GlassCard className="flex flex-col items-center gap-4 p-6">
<PlateChart
size={220}
centerValue="420"
centerLabel="kcal"
slices={[
{ id: "protein", label: "Protein", value: 30, colors: ["#D9F227", "#B8CE1E"] },
{ id: "obstgem", label: "Obst/Gemüse", value: 30, colors: ["#FF6A3D", "#FF8F6B"] },
{ id: "fett", label: "Fett", value: 15, colors: ["#FFB300", "#FFC94A"] },
{ id: "kh", label: "KH", value: 25, colors: ["#1FD9C4", "#5FE0C4"] },
]}
/>
<div className="flex flex-wrap justify-center gap-x-4 gap-y-1 text-xs font-bold text-[var(--ink-soft)]">
<span>🟡 Protein 30%</span>
<span>🟠 Obst/Gemüse 30%</span>
<span>🟨 Fett 15%</span>
<span>🟢 KH 25%</span>
</div>
</GlassCard>
</section>
{/* Buttons */}
<section className="space-y-3">
<h2 className="font-display text-sm font-bold uppercase tracking-wide text-[var(--ink-faint)]">
Buttons
</h2>
<div className="flex flex-wrap items-center gap-3">
<Button variant="primary">Guter Teller!</Button>
<Button variant="secondary">Details</Button>
<Button variant="fab" icon="" aria-label="Hinzufügen" />
</div>
<div className="flex flex-wrap items-center gap-3">
<Button variant="primary" loading={loading} onClick={() => setLoading((l) => !l)}>
{loading ? "Speichert…" : "Speichern (Loading toggle)"}
</Button>
<Button variant="secondary" disabled>
Disabled
</Button>
</div>
</section>
</div>
<BottomNav items={navItems} />
</div>
</div>
);
}