'use client'; /** * Profil-Modal: der angemeldete Benutzer kann seinen Anzeigenamen * (Username) aendern. E-Mail und Rolle sind nur lesbar dargestellt. * * Der Username ist optional und eindeutig; beim Speichern prueft der * Server das Format und die Eindeutigkeit. Ein leerer Wert loescht * den Username (das Badge faellt auf die E-Mail zurueck). * * Wird aus der Sidebar ueber das Profil-Badge geoeffnet; nach dem * Speichern aktualisiert router.refresh() die Sidebar sofort. */ import { useCallback, useEffect, useState } from 'react'; import { useRouter } from 'next/navigation'; import { Button, ErrorMessage, Input, Label, Badge } from '@/components/ui/ui'; import { ModalShell } from '@/components/ui/ModalShell'; interface Profile { id: string; email: string; username: string | null; role: 'ADMIN' | 'USER'; } export function ProfileModal({ onClose }: { onClose: () => void }) { const router = useRouter(); const [profile, setProfile] = useState(null); const [isLoading, setIsLoading] = useState(true); const [isSaving, setIsSaving] = useState(false); const [error, setError] = useState(null); const [success, setSuccess] = useState(false); const loadProfile = useCallback(async () => { setIsLoading(true); setError(null); try { const response = await fetch('/api/me/profile', { cache: 'no-store' }); if (!response.ok) { throw new Error('Profil konnte nicht geladen werden.'); } const data = (await response.json()) as { user: Profile }; setProfile(data.user); } catch (loadError) { setError( loadError instanceof Error ? loadError.message : 'Profil konnte nicht geladen werden.', ); } finally { setIsLoading(false); } }, []); useEffect(() => { void loadProfile(); }, [loadProfile]); async function handleSubmit(event: React.FormEvent) { event.preventDefault(); setIsSaving(true); setError(null); setSuccess(false); const formData = new FormData(event.currentTarget); const username = String(formData.get('username') ?? '').trim(); try { const response = await fetch('/api/me/profile', { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: username || null }), }); if (!response.ok) { const data = (await response.json().catch(() => ({}))) as { error?: string }; setError(data.error ?? 'Speichern fehlgeschlagen.'); return; } const data = (await response.json()) as { user: Profile }; setProfile(data.user); setSuccess(true); // Sidebar + Seite aktualisieren, damit der neue Name ueberall // sofort sichtbar wird. router.refresh(); } catch { setError('Netzwerkfehler. Bitte erneut versuchen.'); } finally { setIsSaving(false); } } return ( {isLoading ? (

Profil wird geladen …

) : !profile ? ( ) : (
{success && (

Profil wurde gespeichert.

)}

Die E-Mail-Adresse kann nicht geaendert werden.

2-32 Zeichen; Buchstaben, Ziffern, _ - . erlaubt. Leer lassen, um den Namen zu entfernen (es wird dann die E-Mail angezeigt).

{profile.role === 'ADMIN' ? 'Administrator' : 'Benutzer'}
)}
); }