"use client"; import { Loader2, UserPlus } from "lucide-react"; import { useTranslations } from "next-intl"; import { useState } from "react"; import { toast } from "sonner"; import { createUser } from "@/actions/users"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { useServerAction } from "@/hooks/use-server-action"; interface CreateUserDialogProps { sessionRank: number; } const RANK_OPTIONS = [1, 2, 3, 4, 5, 6, 7]; export function CreateUserDialog({ sessionRank }: CreateUserDialogProps) { const t = useTranslations("pages.admin.users.create"); const { run, isPending } = useServerAction(); const [open, setOpen] = useState(false); const [username, setUsername] = useState(""); const [mail, setMail] = useState(""); const [password, setPassword] = useState(""); const [rank, setRank] = useState("1"); const [motto, setMotto] = useState(""); const allowedRanks = RANK_OPTIONS.filter((r) => sessionRank >= 7 ? true : r < sessionRank, ); function reset() { setUsername(""); setMail(""); setPassword(""); setRank("1"); setMotto(""); } function generatePassword() { const charset = "abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789"; let out = ""; const buf = new Uint32Array(12); crypto.getRandomValues(buf); for (let i = 0; i < buf.length; i++) out += charset[buf[i] % charset.length]; setPassword(out); toast.message(t("passwordGenerated")); } function handleCreate() { const u = username.trim(); const m = mail.trim(); if (!u || !m || !password) { toast.error(t("required")); return; } if (u.length < 3 || u.length > 20 || !/^[a-zA-Z0-9_-]+$/.test(u)) { toast.error(t("invalidUsername")); return; } if (password.length < 6) { toast.error(t("passwordLength")); return; } run( () => createUser({ username: u, mail: m, password, rank: Number(rank), motto: motto.trim(), }), { successMessage: t("created", { username: u }), onSuccess: () => { setOpen(false); reset(); }, }, ); } return ( { setOpen(next); if (!next) reset(); }} > {t("title")} {t("description")}
setUsername(e.target.value)} placeholder={t("usernamePlaceholder")} autoComplete="off" maxLength={20} />
setMail(e.target.value)} placeholder="user@example.com" autoComplete="off" />
setPassword(e.target.value)} placeholder={t("passwordPlaceholder")} autoComplete="new-password" className="font-mono" />
setMotto(e.target.value)} maxLength={127} placeholder={t("mottoPlaceholder")} />
); }