Eine React/Vite Single-Page-Anwendung für den Verkauf des Rotteck-Pullis. Der Warenkorb läuft vollständig im Browser, bis der Nutzer auf „Kaufen“ klickt. Anschließend werden die Bestellinformationen über eine Vercel-Serverless-Funktion sicher in einer Supabase-Datenbank gespeichert und es wird ein eindeutiger Bestellcode erzeugt.
- Moderne Produktansicht mit Varianten (Farben, Größen) und Warenkorb-Verwaltung im Local Storage.
- Checkout-Flow mit E-Mail-Eingabe und serverseitiger Validierung.
- Supabase-Integration über eine geschützte API-Funktion (
/api/create-order), die den Service-Role-Key nutzt und einen Hash-basierten Bestellcode erzeugt. - Vollständig konfigurierbar über Umgebungsvariablen – keine geheimen Schlüssel im Browser.
- Node.js ≥ 18
- npm (im Repository bereits verwendet)
- Supabase-Projekt
- Optional: Vercel-Account für das Hosting
npm install
npm run devDie Anwendung ist anschließend unter http://localhost:5173 erreichbar.
Für einen Produktions-Build:
npm run build
npm run preview| Variable | Kontext | Beschreibung |
|---|---|---|
VITE_SUPABASE_URL |
Client (Vite) | Supabase Projekt-URL. |
VITE_SUPABASE_ANON_KEY |
Client (Vite) | Public Anon Key für Lesezugriffe. |
SUPABASE_URL |
Serverless Funktion | Supabase Projekt-URL (identisch zur Client-URL). |
SUPABASE_SERVICE_ROLE_KEY |
Serverless Funktion | Service Role Key für Schreibzugriffe – nur auf dem Server speichern! |
ADMIN_PORTAL_PASSWORD |
Serverless Funktion | Starkes Passwort für das geschützte Admin-Portal. Wird ausschließlich serverseitig geprüft. |
VITE_SUPABASE_URL=<deine-supabase-url>
VITE_SUPABASE_ANON_KEY=<dein-anon-key>Im Vercel-Dashboard unter Settings → Environment Variables hinterlegen:
VITE_SUPABASE_URLVITE_SUPABASE_ANON_KEYSUPABASE_URLSUPABASE_SERVICE_ROLE_KEYADMIN_PORTAL_PASSWORD
Tipp:
SUPABASE_SERVICE_ROLE_KEYniemals im Client ausliefern. Er gehört ausschließlich in die Serverless-Funktion.
-
Tabelle anlegen (
orders):create table if not exists orders ( id uuid primary key default gen_random_uuid(), created_at timestamp with time zone default now(), email text not null, items jsonb not null, order_hash text not null unique, status text not null default 'pending' );
-
Row Level Security aktivieren und Regeln nach Bedarf definieren (z. B. nur für Service-Role Inserts zulassen). Bei ausschließlich serverseitigen Zugriffen kann auch komplett auf RLS verzichtet werden.
-
Service Role Key aus dem Supabase-Dashboard kopieren und als
SUPABASE_SERVICE_ROLE_KEYbei Vercel hinterlegen. -
Optional: E-Mail- oder Storage-Policies ergänzen, wenn zukünftige Features darauf aufbauen.
- Erwartet
POSTmit JSON{ email: string, items: Array<{ product, color, size, quantity }> }. - Validiert E-Mail-Adresse und Produkte, cappt Menge auf 30 pro Eintrag und maximal 50 Einträge.
- Schreibt die Bestellung in Supabase und gibt
{ orderCode, createdAt }zurück. DerorderCodeist ein Hash (12-stellig, Großbuchstaben), den Nutzer bei der Überweisung angeben sollen. - Liefert aussagekräftige Fehlermeldungen und HTTP-Statuscodes (400 für ungültige Daten, 500 bei Serverfehlern).
curl -X POST http://localhost:3000/api/create-order \
-H "Content-Type: application/json" \
-d '{
"email": "max@example.com",
"items": [
{ "color": "rot", "size": "L", "quantity": 2 }
]
}'Hinweis: Bei lokalem Vite-Entwicklungsserver ohne Vercel-Adapter kann die Funktion auch über ein separates Node-Skript oder mit
vercel devgetestet werden.
- Warenkorb und E-Mail leben bis zum Kauf ausschließlich im Browser (Local Storage).
- Erst beim Klick auf „Kaufen“ sendet der Client die Daten an
/api/create-order. - Die Serverless-Funktion nutzt den Service-Role-Key, validiert alle Felder und schreibt in Supabase.
- Der generierte Bestellcode wird sofort an den Client zurückgegeben und zusätzlich in Supabase gespeichert.
- Dank getrenntem Client-/Server-Setup bleiben alle sensiblen Informationen (Keys, Backoffice-Status) serverseitig geschützt.
- Passwort-geschützter Bereich. Zugriff erfolgt über das Formular, wobei das Passwort ausschließlich in der API geprüft wird (
ADMIN_PORTAL_PASSWORD). - Dashboard summiert Bestellungen nach Status, Farbe, Größe und Kombinationen.
- Bestellung kann über den Bestellcode als „bezahlt“ markiert werden.
- Die zugehörigen API-Routen (
/api/admin-summary,/api/mark-order-paid) prüfen das Passwort serverseitig per Timing-safe Vergleich.
- Automatisierte E-Mail-Benachrichtigung über Supabase Functions oder Resend.
- Export (CSV/Excel) für die Schulverwaltung.
Viel Spaß beim Anpassen und Erweitern! 🚀