Files
pocket-pascal/handover/component-library/ComponentShowcase.tsx
Steffi Müller a482bf5b09 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>
2026-08-04 12:22:32 +02:00

113 lines
5.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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>
);
}