'use client' import { Loader2, UserPlus } from 'lucide-react' 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: { value: number; label: string }[] = [ { value: 1, label: 'User (1)' }, { value: 2, label: 'Bronze (2)' }, { value: 3, label: 'Silver (3)' }, { value: 4, label: 'Gold (4)' }, { value: 5, label: 'Moderator (5)' }, { value: 6, label: 'Admin (6)' }, { value: 7, label: 'Super Admin (7)' }, ] export function CreateUserDialog({ sessionRank }: CreateUserDialogProps) { 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.value < 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('Password generated', { description: out }) } function handleCreate() { const u = username.trim() const m = mail.trim() if (!u || !m || !password) { toast.error('Username, email and password are required') return } if (u.length < 3 || u.length > 20 || !/^[a-zA-Z0-9_-]+$/.test(u)) { toast.error('Invalid username (3-20 chars, letters/digits/_/-)') return } if (password.length < 6) { toast.error('Password must be at least 6 characters') return } run( () => createUser({ username: u, mail: m, password, rank: Number(rank), motto: motto.trim(), }), { successMessage: `User "${u}" created.`, onSuccess: () => { setOpen(false) reset() }, }, ) } return ( { setOpen(next) if (!next) reset() }} > Create User Account is created immediately with default look and 5,000 credits/duckets/diamonds.
setUsername(e.target.value)} placeholder="HabboName" autoComplete="off" maxLength={20} />
setMail(e.target.value)} placeholder="user@example.com" autoComplete="off" />
setPassword(e.target.value)} placeholder="Minimum 6 characters" autoComplete="new-password" className="font-mono" />
setMotto(e.target.value)} maxLength={127} placeholder="I'm new here!" />
) }