8.0 KiB
8.0 KiB
Modul: Kunden-Portal (Supabase Auth + Dashboard)
Vollständiges Kundenkonto-System auf Basis von Supabase Auth: Registrierung mit Email-Bestätigung (signierter Confirmation-Link), Login mit Magic Link oder Passwort, Kundendashboard mit Anfragen-Übersicht (Status, Positionen, Admin-Notizen), Profilverwaltung, Logout.
Enthaltene Dateien
| Ziel im neuen Projekt | Inhalt |
|---|---|
app/kunden/login/page.tsx |
Login-Seite (Supabase Auth, Redirect nach Login) |
app/kunden/registrieren/page.tsx |
Registrierungs-Seite (mit API-Aufruf) |
app/kunden/dashboard/page.tsx |
Kundendashboard (Anfragen, Status-Badges, Positionen) |
app/auth/callback/page.tsx |
OAuth/Magic-Link Callback Handler |
app/api/kunden/anfragen/route.ts |
GET: Anfragen des eingeloggten Kunden |
app/api/kunden/registrieren/route.ts |
POST: Registrierung via Supabase Admin API + Email |
Voraussetzungen
npm install @supabase/supabase-js @supabase/ssr
Benötigt außerdem:
lib/supabase.tsmit Browser-Client und Service-Clientlib/mailer.ts(Modul 01) – für Registrierungs-Bestätigungs-Email (optional, Supabase sendet selbst)- Modul 04 (Reservation System) – wenn Kunden ihre Anfragen sehen sollen
Umgebungsvariablen (.env.local)
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...
SUPABASE_SERVICE_ROLE_KEY=eyJ... # Für Registrierung via Admin API
APP_URL=https://example.com # Basis-URL für Confirmation-Links
Datenbank-Setup (Supabase)
1. Supabase Auth aktivieren
Supabase Dashboard → Authentication → Settings:
- Email-Bestätigung aktivieren
- Redirect URL eintragen:
https://example.com/auth/callback
2. Optional: Kunden-Profil-Tabelle
-- Verknüpft auth.users mit zusätzlichen Kundendaten
CREATE TABLE kunden_profile (
id uuid PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE,
firma text,
telefon text,
erstellt_am timestamptz DEFAULT now()
);
-- Trigger: Profil automatisch beim User-Create anlegen
CREATE OR REPLACE FUNCTION handle_new_user()
RETURNS trigger AS $$
BEGIN
INSERT INTO public.kunden_profile (id)
VALUES (NEW.id);
RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
CREATE TRIGGER on_auth_user_created
AFTER INSERT ON auth.users
FOR EACH ROW EXECUTE PROCEDURE handle_new_user();
3. Row Level Security für Anfragen
-- Kunden sehen nur ihre eigenen Anfragen
ALTER TABLE anfragen ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Kunden sehen eigene Anfragen"
ON anfragen FOR SELECT
USING (auth.uid() = kunde_id);
Einbindung Schritt für Schritt
1. Dateien kopieren
2. Supabase Middleware einrichten (middleware.ts im Projekt-Root)
import { createServerClient } from "@supabase/ssr";
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export async function middleware(request: NextRequest) {
let response = NextResponse.next({ request });
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{ cookies: { /* ... */ } }
);
await supabase.auth.getUser(); // Session refreshen
return response;
}
export const config = { matcher: ["/kunden/:path*"] };
3. Supabase Browser-Client in lib/supabase.ts
import { createBrowserClient } from "@supabase/ssr";
export function createClient() {
return createBrowserClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
);
}
4. Dashboard an eigene Datenstruktur anpassen
app/kunden/dashboard/page.tsx erwartet:
anfragenTabelle mitstatus,firma,erstellt_amanfragen_positionenmitmaschine_name,mietbeginn,mietende,gesamt_preis- RLS-Policy: Kunden sehen nur
anfragen WHERE kunde_id = auth.uid()
5. Navigation ergänzen
<Link href="/kunden/login">Mein Konto</Link>
<Link href="/kunden/dashboard">Meine Anfragen</Link>
Anpassungspunkte
| Was | Wo |
|---|---|
| Registrierungs-Email | lib/mailer.ts → sendeRegistrierungsBestaetigung() |
| Passwort-Mindestlänge (8 Zeichen) | app/api/kunden/registrieren/route.ts → Zod-Schema |
| Dashboard-Felder | app/kunden/dashboard/page.tsx |
| Auth-Provider (Magic Link, OAuth) | Supabase Dashboard → Auth → Providers |
| Session-Cookie-Dauer | Supabase Dashboard → Auth → Settings → JWT Expiry |
| Kunden-Profil-Felder | kunden_profile Tabelle + Profilseite |
Integrations-Prompt
Kopiere diesen Prompt in eine neue KI-Konversation, nachdem du die files/ in dein Projekt kopiert hast. Ersetze alle [PLATZHALTER].
Ich integriere das Kunden-Portal (Supabase Auth, Registrierung, Kundendashboard) in mein Next.js/Supabase-Projekt.
PROJEKT-KONTEXT:
- Modul 01 (Email) ist bereits integriert (mailer.ts verfügbar)
- Modul 04 (Reservierungssystem) ist bereits integriert (anfragen-Tabelle existiert)
- Kundenbereich URL-Prefix: /kunden
- App-URL: [https://beispiel.de]
BEREITS KOPIERTE DATEIEN (aus modules/06-kunden-portal/files/):
- app/kunden/login/page.tsx
- app/kunden/registrieren/page.tsx
- app/kunden/dashboard/page.tsx
- app/auth/callback/page.tsx
- app/api/kunden/anfragen/route.ts
- app/api/kunden/registrieren/route.ts
AUFGABEN – führe sie der Reihe nach aus:
1. SUPABASE AUTH KONFIGURIEREN:
Gehe zu Supabase Dashboard → Authentication → URL Configuration.
Trage ein:
- Site URL: [https://beispiel.de]
- Redirect URLs: [https://beispiel.de]/auth/callback
2. SUPABASE-PAKETE installieren (falls noch nicht vorhanden):
npm install @supabase/supabase-js @supabase/ssr
3. SUPABASE CLIENTS in lib/supabase.ts ergänzen:
Lies lib/supabase.ts. Füge hinzu (falls Browser-Client fehlt):
import { createBrowserClient } from "@supabase/ssr";
export function createBrowserSupabaseClient() {
return createBrowserClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
);
}
4. MIDDLEWARE erstellen: Erstelle middleware.ts im Projekt-Root:
import { createServerClient } from "@supabase/ssr";
import { NextResponse, type NextRequest } from "next/server";
export async function middleware(request: NextRequest) {
let response = NextResponse.next({ request });
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{ cookies: {
getAll() { return request.cookies.getAll(); },
setAll(cookiesToSet) {
cookiesToSet.forEach(({ name, value, options }) =>
response.cookies.set(name, value, options));
},
}}
);
await supabase.auth.getUser();
return response;
}
export const config = { matcher: ["/kunden/:path*", "/auth/:path*"] };
5. RLS-POLICY für Anfragen: Führe im Supabase SQL-Editor aus:
ALTER TABLE anfragen ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Kunden sehen eigene Anfragen"
ON anfragen FOR SELECT USING (auth.uid() = kunde_id);
6. REGISTRIERUNGS-EMAIL anpassen: Lies lib/mailer.ts.
Passe die Funktion sendeRegistrierungsBestaetigung() an (oder erstelle sie falls nicht vorhanden):
- Ersetze "Mietpark Hahn" durch "[PROJEKTNAME]"
- Passe den Betreff an: "Bitte bestätigen Sie Ihre E-Mail – [PROJEKTNAME]"
7. DASHBOARD anpassen: Lies app/kunden/dashboard/page.tsx.
- Ersetze "Mietanfrage/Maschine" durch die eigene Bezeichnung
- Passe angezeigte Felder aus anfragen_positionen an
8. NAVIGATION ergänzen: Füge in den öffentlichen Header hinzu:
<Link href="/kunden/login">Mein Konto</Link>
Nach Login: <Link href="/kunden/dashboard">Meine Anfragen</Link>
9. TEST:
a) /kunden/registrieren → Registrierung abschließen
b) Bestätigungs-Email öffnen, Link klicken → /auth/callback → /kunden/dashboard
c) /kunden/dashboard → Anfragen des Kunden erscheinen
d) /kunden/login → Logout → Redirect zu /kunden/login
Lies jede Datei vor dem Bearbeiten. Melde wenn alle Schritte abgeschlossen sind.