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

@@ -1,66 +1,30 @@
import { useCallback, useEffect, useState } from "react"
import { RefreshCw } from "lucide-react"
import { BrowserRouter, Navigate, Route, Routes } from "react-router-dom"
import { Button } from "@/components/ui/button"
import { fetchHello, type HelloResponse } from "@/lib/api"
import { HomeScreen } from "@/components/home/HomeScreen"
import { AppShell } from "@/components/layout/AppShell"
import { LanguageProvider } from "@/lib/language"
import { BuilderScreen } from "@/screens/BuilderScreen"
import { PantryScreen } from "@/screens/PantryScreen"
import { PlateScreen } from "@/screens/PlateScreen"
import { SettingsScreen } from "@/screens/SettingsScreen"
import { WeekPlanScreen } from "@/screens/WeekPlanScreen"
export default function App() {
const [data, setData] = useState<HelloResponse | null>(null)
const [error, setError] = useState<string | null>(null)
const [loading, setLoading] = useState(true)
const load = useCallback(async () => {
setLoading(true)
setError(null)
try {
setData(await fetchHello())
} catch (err) {
setError(err instanceof Error ? err.message : "Something went wrong")
} finally {
setLoading(false)
}
}, [])
useEffect(() => {
void load()
}, [load])
return (
<main className="dark:bg-background dark:text-foreground flex min-h-svh flex-col items-center justify-center bg-background gap-6 p-6 text-center">
<div className="flex max-w-sm flex-col items-center gap-6">
<span className="bg-primary/10 text-primary rounded-full px-3 py-1 text-xs font-medium">
Pocket Pascal
</span>
<h1 className="text-4xl font-bold tracking-tight sm:text-5xl">
{data?.message ?? "Hello, World!"}
</h1>
<p className="text-muted-foreground text-sm">
A minimal installable PWA. React + shadcn/ui on the front, Express +
SQLite on the back.
</p>
<div className="bg-muted text-muted-foreground flex w-full flex-col gap-1 rounded-lg border p-4 text-sm">
{loading ? (
<span>Asking the server</span>
) : error ? (
<span className="text-destructive">{error}</span>
) : (
<>
<span className="text-foreground text-2xl font-semibold">
{data?.visits.toLocaleString()}
</span>
<span>times this hello has been said</span>
</>
)}
</div>
<Button onClick={() => void load()} disabled={loading}>
<RefreshCw className={loading ? "animate-spin" : undefined} />
Say it again
</Button>
</div>
</main>
<LanguageProvider>
<BrowserRouter>
<Routes>
<Route element={<AppShell />}>
<Route index element={<HomeScreen />} />
<Route path="pantry" element={<PantryScreen />} />
<Route path="knowledge" element={<PlateScreen />} />
<Route path="weekplan" element={<WeekPlanScreen />} />
<Route path="builder" element={<BuilderScreen />} />
<Route path="settings" element={<SettingsScreen />} />
<Route path="*" element={<Navigate to="/" replace />} />
</Route>
</Routes>
</BrowserRouter>
</LanguageProvider>
)
}