"use client"; import { useCallback, useEffect, useMemo, useState } from "react"; import { createClient } from "@/lib/supabase/client"; import { formatMessage } from "@/lib/i18n/shared"; import type { Profile, Role } from "@/lib/types"; import { useDict } from "@/components/i18n/LocaleProvider"; interface UserForm { id: string | null; // null = neuer Benutzer email: string; full_name: string; role: Role; password: string; // bei Bearbeitung optional (leer = unverändert) passwordRepeat: string; } const EMPTY_FORM: UserForm = { id: null, email: "", full_name: "", role: "staff", password: "", passwordRepeat: "", }; export default function UserManager() { const supabase = useMemo(() => createClient(), []); const dict = useDict(); const roleLabels: Record = { admin: dict.common.roleAdmin, staff: dict.common.roleStaff, }; const [profiles, setProfiles] = useState([]); const [me, setMe] = useState(null); const [form, setForm] = useState(null); const [error, setError] = useState(null); const [busy, setBusy] = useState(false); const load = useCallback(async () => { const [{ data: profileData, error: profileError }, { data: userData }] = await Promise.all([ supabase.from("profiles").select("*").order("created_at"), supabase.auth.getUser(), ]); if (profileError) setError(formatMessage(dict.userManager.loadError, { message: profileError.message })); else setProfiles(profileData as Profile[]); setMe(userData.user?.id ?? null); }, [supabase, dict]); useEffect(() => { load(); }, [load]); async function callApi(method: string, body: unknown): Promise { setBusy(true); setError(null); try { const res = await fetch("/api/admin/users", { method, headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), }); if (!res.ok) { const data = await res.json().catch(() => null); setError(data?.error ?? `Fehler (${res.status})`); return false; } return true; } catch (err) { setError(err instanceof Error ? err.message : String(err)); return false; } finally { setBusy(false); } } async function save(e: React.FormEvent) { e.preventDefault(); if (!form) return; if (form.password && form.password !== form.passwordRepeat) { setError(dict.userManager.passwordMismatch); return; } const ok = form.id ? await callApi("PATCH", { id: form.id, full_name: form.full_name, role: form.role, password: form.password || undefined, }) : await callApi("POST", { email: form.email, full_name: form.full_name, role: form.role, password: form.password, }); if (ok) { setForm(null); await load(); } } async function remove(profile: Profile) { if ( !window.confirm( formatMessage(dict.userManager.confirmDelete, { email: profile.email }) ) ) return; if (await callApi("DELETE", { id: profile.id })) await load(); } return (

{dict.userManager.title}

{error && (

{error}

)} {form && (

{form.id ? dict.userManager.editUser : dict.userManager.newUser}

{!form.id && (
setForm({ ...form, email: e.target.value })} required />
)}
setForm({ ...form, full_name: e.target.value })} />
setForm({ ...form, password: e.target.value })} minLength={8} required={!form.id} autoComplete="new-password" />
setForm({ ...form, passwordRepeat: e.target.value }) } minLength={8} required={!form.id || !!form.password} autoComplete="new-password" />
)}
    {profiles.map((p) => (
  • {p.full_name || p.email}{" "} – {p.email} – {roleLabels[p.role]} {p.id === me && {dict.common.you}} {p.id !== me && ( )}
  • ))}
); }