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>
113 lines
5.0 KiB
TypeScript
113 lines
5.0 KiB
TypeScript
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>
|
||
);
|
||
}
|