MBO-Tech-IT-Webseite/modules/06-kunden-portal/TEMPLATE.md

8.0 KiB
Raw Blame History

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.ts mit Browser-Client und Service-Client
  • lib/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:

  • anfragen Tabelle mit status, firma, erstellt_am
  • anfragen_positionen mit maschine_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.tssendeRegistrierungsBestaetigung()
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.