import { Form, useActionData, useLoaderData, useNavigation, redirect, Link, } from "react-router"; import { requireAdmin } from "@/session.server"; import { log } from "@/lib/logger.server"; import prisma from "@/lib/prisma.server"; import bcrypt from "bcryptjs"; import { AlertCircle, ArrowLeft, Trash2 } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; export async function loader({ request, params, }: { request: Request; params: { id: string }; }) { await requireAdmin(request); const user = await prisma.user.findUnique({ where: { id: params.id }, select: { id: true, name: true, username: true, email: true, role: true }, }); if (!user) throw new Response("Nicht gefunden", { status: 404 }); return { user }; } export async function action({ request, params, }: { request: Request; params: { id: string }; }) { const admin = await requireAdmin(request); const formData = await request.formData(); const intent = formData.get("intent") as string; if (intent === "delete") { if (params.id === admin.id) { return { error: "Sie können Ihr eigenes Konto nicht löschen." }; } await prisma.user.delete({ where: { id: params.id } }); await log({ userId: admin.id, action: "DELETE_USER", entity: "User", entityId: params.id, request, }); return redirect("/admin/users"); } // intent === "update" const name = (formData.get("name") as string).trim(); const username = (formData.get("username") as string).trim().toLowerCase(); const email = (formData.get("email") as string).trim().toLowerCase(); const role = formData.get("role") as "USER" | "ADMIN"; const password = (formData.get("password") as string).trim(); if (!name || !username || !email) { return { error: "Name, Benutzername und E-Mail sind Pflichtfelder." }; } const conflict = await prisma.user.findFirst({ where: { AND: [ { id: { not: params.id } }, { OR: [{ email }, { username }] }, ], }, }); if (conflict) { return { error: "E-Mail oder Benutzername bereits von einem anderen Nutzer vergeben." }; } const updateData: Record = { name, username, email, role: role === "ADMIN" ? "ADMIN" : "USER", }; if (password) { if (password.length < 8) { return { error: "Das Passwort muss mindestens 8 Zeichen lang sein." }; } updateData.passwordHash = await bcrypt.hash(password, 12); } await prisma.user.update({ where: { id: params.id }, data: updateData }); await log({ userId: admin.id, action: "UPDATE_USER", entity: "User", entityId: params.id, metadata: { name, username, email, role, passwordChanged: !!password }, request, }); return redirect("/admin/users"); } export default function AdminUserEditPage() { const { user } = useLoaderData(); const actionData = useActionData(); const navigation = useNavigation(); const loading = navigation.state === "submitting"; return (

Benutzer bearbeiten

{user.name}

{actionData?.error && (
{actionData.error}
)}
{/* Delete zone */}

Benutzer löschen

Löscht den Benutzer und alle zugehörigen Firmen, Kunden und Rechnungen unwiderruflich.

); }