"use client" import { useCallback, useEffect, useState } from "react" import { AlertCircle, Eye, EyeOff, MoreHorizontal, Pencil, Plus, Trash2 } from "lucide-react" import { toast } from "sonner" import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog" import { Avatar, AvatarFallback } from "@/components/ui/avatar" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { Dialog, DialogBody, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select" import { Skeleton } from "@/components/ui/skeleton" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table" import { formatDateTime, initials } from "@/lib/format" interface User { id: number email: string name: string | null role: string isActive: boolean createdAt: string updatedAt: string createdByUser?: { email: string name: string | null } | null } interface UserFormData { email: string name: string password: string role: string } interface UserManagementProps { isOpen: boolean onClose: () => void } const emptyForm: UserFormData = { email: "", name: "", password: "", role: "ADMIN", } export function UserManagement({ isOpen, onClose }: UserManagementProps) { const [users, setUsers] = useState([]) const [isLoading, setIsLoading] = useState(false) const [error, setError] = useState("") const [isFormOpen, setIsFormOpen] = useState(false) const [editingUser, setEditingUser] = useState(null) const [userToDelete, setUserToDelete] = useState(null) const [isSubmitting, setIsSubmitting] = useState(false) const [showPassword, setShowPassword] = useState(false) const [formData, setFormData] = useState(emptyForm) const loadUsers = useCallback(async () => { setIsLoading(true) setError("") try { const response = await fetch("/api/users") if (!response.ok) throw new Error("Fehler beim Laden der Benutzer") setUsers(await response.json()) } catch (err) { setError(err instanceof Error ? err.message : "Ein Fehler ist aufgetreten") } finally { setIsLoading(false) } }, []) useEffect(() => { if (isOpen) loadUsers() }, [isOpen, loadUsers]) const openCreateForm = () => { setEditingUser(null) setFormData(emptyForm) setShowPassword(false) setIsFormOpen(true) } const openEditForm = (user: User) => { setEditingUser(user) setFormData({ email: user.email, name: user.name || "", password: "", role: user.role, }) setShowPassword(false) setIsFormOpen(true) } const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() setIsSubmitting(true) setError("") try { const response = await fetch( editingUser ? `/api/users/${editingUser.id}` : "/api/users", { method: editingUser ? "PUT" : "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(formData), } ) if (!response.ok) { const errorData = await response.json().catch(() => ({})) throw new Error(errorData.error || "Fehler beim Speichern") } toast.success(editingUser ? "Benutzer aktualisiert" : "Benutzer erstellt") setIsFormOpen(false) await loadUsers() } catch (err) { const message = err instanceof Error ? err.message : "Ein Fehler ist aufgetreten" setError(message) toast.error(message) } finally { setIsSubmitting(false) } } const handleDelete = async () => { if (!userToDelete) return setIsSubmitting(true) try { const response = await fetch(`/api/users/${userToDelete.id}`, { method: "DELETE", }) if (!response.ok) { const errorData = await response.json().catch(() => ({})) throw new Error(errorData.error || "Fehler beim Löschen") } toast.success("Benutzer gelöscht") setUserToDelete(null) await loadUsers() } catch (err) { toast.error(err instanceof Error ? err.message : "Fehler beim Löschen") } finally { setIsSubmitting(false) } } return ( <> !open && onClose()}>
Benutzerverwaltung {users.length} {users.length === 1 ? "Konto" : "Konten"} mit Zugriff auf das Admin-Portal
{error && (
{error}
)} {isLoading ? (
{Array.from({ length: 3 }).map((_, index) => ( ))}
) : (
Benutzer Rolle Erstellt {users.map((user) => (
{initials(user.name || user.email)}
{user.name || user.email} {!user.isActive && ( Inaktiv )}
{user.name && ( {user.email} )}
{user.role === "SUPER_ADMIN" ? "Super Admin" : "Admin"} {formatDateTime(user.createdAt)} openEditForm(user)}> Bearbeiten setUserToDelete(user)} > Löschen
))}
)}
{editingUser ? "Benutzer bearbeiten" : "Neuer Benutzer"} {editingUser ? "Passwortfeld leer lassen, um das Passwort beizubehalten." : "Zugang für das Admin-Portal anlegen."}
{error &&

{error}

}
setFormData((prev) => ({ ...prev, email: e.target.value })) } placeholder="benutzer@beispiel.de" required disabled={isSubmitting} />
setFormData((prev) => ({ ...prev, name: e.target.value })) } placeholder="Max Mustermann" disabled={isSubmitting} />
setFormData((prev) => ({ ...prev, password: e.target.value })) } placeholder="••••••••" required={!editingUser} disabled={isSubmitting} className="pr-10" />
!open && setUserToDelete(null)} > Benutzer löschen? „{userToDelete?.name || userToDelete?.email}“ verliert damit sofort den Zugang zum Admin-Portal. Abbrechen { e.preventDefault() handleDelete() }} disabled={isSubmitting} className="bg-destructive text-destructive-foreground hover:bg-destructive/90" > {isSubmitting ? "Löschen…" : "Löschen"} ) }