'use client'; import { useEffect, useState } from 'react'; import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Switch } from '@/components/ui/switch'; import { useAdminUsers } from '@/contexts/admin-users-context'; import { useAuth } from '@/components/providers/auth-provider'; import type { AdminUser } from '@/lib/services/admin'; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from '@/components/ui/alert-dialog'; import { Loader2 } from 'lucide-react'; interface EditUserForm { nickname: string; email: string; is_admin: boolean; password?: string; } export function EditUserModal({ isOpen, onClose, user, }: { isOpen: boolean; onClose: () => void; user: AdminUser | null; }) { const { updateUser, deleteUser, getUserDetail } = useAdminUsers(); const { user: currentUser } = useAuth(); const isSelf = currentUser && user && currentUser.id.toString() === user.id.toString(); const [form, setForm] = useState({ nickname: '', email: '', is_admin: false, password: '', }); const [saving, setSaving] = useState(false); const [errors, setErrors] = useState>({}); const [showDeleteConfirm, setShowDeleteConfirm] = useState(false); useEffect(() => { let active = true; if (isOpen && user) { setForm({ nickname: user.nickname || '', email: user.email || '', is_admin: user.is_admin || false, password: '', }); setErrors({}); getUserDetail(user.id) .then((detail) => { if (active && detail) { setForm({ nickname: detail.nickname || '', email: detail.email || '', is_admin: detail.is_admin || false, password: '', }); } }) .catch(() => { // ignore fetching error }); } else { setSaving(false); } return () => { active = false; }; }, [isOpen, user, getUserDetail]); const validate = () => { const newErrors: Record = {}; if (!form.email.trim()) { newErrors.email = '邮箱不能为空'; } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email.trim())) { newErrors.email = '邮箱格式不正确'; } if (form.password && form.password.length < 8) { newErrors.password = '密码长度不能少于 8 位'; } setErrors(newErrors); return Object.keys(newErrors).length === 0; }; const handleSave = async (e: React.FormEvent) => { e.preventDefault(); if (!user || !validate()) return; setSaving(true); try { await updateUser(user.id, { nickname: form.nickname.trim() || undefined, email: form.email.trim(), is_admin: form.is_admin, password: form.password?.trim() || undefined, }); onClose(); } catch { // Errors are handled by context toast notifications } finally { setSaving(false); } }; const handleDelete = async () => { if (!user) return; setSaving(true); try { await deleteUser(user); onClose(); } catch { // Errors are handled by context toast notifications } finally { setSaving(false); setShowDeleteConfirm(false); } }; if (!user) return null; return ( <> !open && onClose()}> 编辑用户 修改用户档案、授予/撤销管理权限或重置其密码。
setForm((prev) => ({ ...prev, nickname: e.target.value })) } placeholder='请输入昵称' />
setForm((prev) => ({ ...prev, email: e.target.value })) } placeholder='请输入邮箱地址' /> {errors.email && (

{errors.email}

)}
setForm((prev) => ({ ...prev, password: e.target.value })) } placeholder='留空表示保持当前密码,输入则重置 (至少 8 位)' /> {errors.password && (

{errors.password}

)}
管理员权限
{isSelf ? '不能撤销当前登录用户的管理员权限。' : '开启后此账号将拥有后台管理权限。'}
{ setForm((prev) => ({ ...prev, is_admin: checked })); setSaving(true); try { await updateUser(user.id, { nickname: form.nickname.trim() || undefined, email: form.email.trim(), is_admin: checked, }); } catch { setForm((prev) => ({ ...prev, is_admin: !checked })); } finally { setSaving(false); } }} />
{!user.is_admin && ( )}
确认删除用户 确定要删除用户 {user.nickname || user.username}{' '} 吗?该操作会移除用户账号,删除后无法撤销。 取消 { e.preventDefault(); handleDelete(); }} disabled={saving} > {saving && } 确认删除 ); }