'use client'; import { useEffect, useState } from 'react'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import * as z from 'zod'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; import { Avatar, AvatarFallback } from '@/components/ui/avatar'; import { useUser } from '@/components/user-context'; import { ROLE_LABELS } from '@/lib/constants'; import type { User } from '@/types/database'; import { toast } from 'sonner'; import { getErrorMessage } from '@/lib/error-utils'; import { Plus, Pencil, Trash2, Users, Loader2, Crown, Briefcase, User as UserIcon } from 'lucide-react'; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from '@/components/ui/alert-dialog'; import { fetchApi } from '@/lib/api-client'; const userSchema = z.object({ name: z.string().min(1, '名称不能为空'), role: z.enum(['owner', 'pm', 'member']), username: z.string().min(1, '账号不能为空'), password: z.string().optional(), }); type UserFormValues = z.infer; const roleIcons = { owner: Crown, pm: Briefcase, member: UserIcon, }; export default function AdminUsersPage() { const { currentUser, users, refreshUsers } = useUser(); const [isLoading, setIsLoading] = useState(false); const [isDialogOpen, setIsDialogOpen] = useState(false); const [editingUser, setEditingUser] = useState(null); const [isSubmitting, setIsSubmitting] = useState(false); const [deleteUserId, setDeleteUserId] = useState(null); const [isDeleteOpen, setIsDeleteOpen] = useState(false); const [isDeleting, setIsDeleting] = useState(false); const form = useForm({ resolver: zodResolver(userSchema), defaultValues: { name: '', role: 'member', username: '', password: '', }, }); const onSubmit = async (values: UserFormValues) => { setIsSubmitting(true); try { if (!editingUser && !values.password) { throw new Error('请设置初始密码'); } const url = editingUser ? `/api/users/${editingUser.id}` : '/api/users'; const method = editingUser ? 'PATCH' : 'POST'; const payload = { name: values.name, role: values.role, username: values.username, password: values.password ? values.password : undefined, }; const res = await fetchApi(url, { method, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload), }); if (!res.ok) { const data = await res.json(); throw new Error(data.error || '操作失败'); } toast.success(editingUser ? '用户已更新' : '用户已创建'); setIsDialogOpen(false); setEditingUser(null); form.reset(); refreshUsers(); } catch (error) { toast.error(error instanceof Error ? error.message : '操作失败'); } finally { setIsSubmitting(false); } }; const handleEdit = (user: User) => { setEditingUser(user); form.reset({ name: user.name, role: user.role, username: user.username || '', password: '', }); setIsDialogOpen(true); }; const requestDelete = (userId: string) => { setDeleteUserId(userId); setIsDeleteOpen(true); }; const confirmDelete = async () => { if (!deleteUserId) return; setIsDeleting(true); try { const res = await fetchApi(`/api/users/${deleteUserId}`, { method: 'DELETE' }); const data = await res.json().catch(() => ({})); if (!res.ok) throw new Error(data?.error || '删除失败'); toast.success('用户已删除'); refreshUsers(); } catch (error) { toast.error(getErrorMessage(error)); } finally { setIsDeleting(false); setIsDeleteOpen(false); setDeleteUserId(null); } }; const handleDialogClose = () => { setIsDialogOpen(false); setEditingUser(null); form.reset(); }; if (currentUser?.role !== 'owner') { return (

仅老板可访问此页面

); } return (

用户管理

管理系统用户

{editingUser ? '编辑用户' : '新建用户'}
( 名称 * )} /> ( 账号 * )} /> ( {editingUser ? '重置密码' : '密码 *'} )} /> ( 角色 * )} />
用户 账号 角色 创建时间 操作 {users.map(user => { const RoleIcon = roleIcons[user.role]; return (
{user.name.charAt(0)} {user.name}
{user.username || '-'}
{ROLE_LABELS[user.role]}
{new Date(user.created_at).toLocaleDateString('zh-CN')}
); })}
确认删除用户? 删除后无法恢复。 取消 {isDeleting ? '删除中...' : '确认删除'}
); }