"use client" import { useState, useEffect } from "react" import { Button } from "@/components/ui/button" import { Switch } from "@/components/ui/switch" import { Separator } from "@/components/ui/separator" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" import { Sheet, SheetTitle, SheetContent } from "@/components/ui/sheet" import { Badge } from "@/components/ui/badge" import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" import { Layers, Search, UserX, UserCheck, Eye, ShieldCheck, Filter, X, ChevronDown, ChevronLeft, ChevronRight, Loader2 } from "lucide-react" import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip" import { AdminUser, AdminService } from "@/lib/services" import { toast } from "sonner" import { formatDateTime } from "@/lib/utils" import { EmptyStateWithBorder } from "@/components/layout/empty" import { LoadingStateWithBorder } from "@/components/layout/loading" import { ErrorInline } from "@/components/layout/error" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu" import { cn } from "@/lib/utils" import { useAdminUsers } from "@/contexts/admin-users-context" export function UsersManager() { const { users, total, loading, error, page, pageSize, searchUserId, searchUsername, statusFilter, setPage, setPageSize, setSearchUserId, setSearchUsername, setStatusFilter, fetchUsers, updateUserStatus } = useAdminUsers() const [selectedUser, setSelectedUser] = useState(null) const [detailOpen, setDetailOpen] = useState(false) useEffect(() => { fetchUsers() }, [fetchUsers]) const handleStatusToggle = async (user: AdminUser) => { await updateUserStatus(user) if (selectedUser?.id === user.id) { setSelectedUser(prev => prev ? { ...prev, is_active: !prev.is_active } : null) } } const handleShowDetail = (user: AdminUser) => { setSelectedUser(user) setDetailOpen(true) } const totalPages = Math.ceil(total / pageSize) const hasSearchFilter = Boolean(searchUserId || searchUsername) const renderFilterBar = () => (
setSearchUserId(e.target.value)} /> setSearchUsername(e.target.value)} /> {hasSearchFilter && ( )}
{ e.preventDefault(); setStatusFilter('all') }} >
全部状态 { e.preventDefault(); setStatusFilter('active') }} >
正常 { e.preventDefault(); setStatusFilter('inactive') }} >
禁用 {(hasSearchFilter || statusFilter !== 'all') && ( <> )}
{total} 条记录
{page}/{totalPages}
{[20, 50, 100].map(size => ( setPageSize(size)} className={cn("font-mono text-xs", pageSize === size && "bg-accent")} > {size}条/页 ))}
) return (
用户管理
{renderFilterBar()} {error ? (
fetchUsers(true)} className="justify-center" />
) : loading && users.length === 0 ? ( ) : users.length === 0 ? ( ) : (
ID 用户 上次登陆 注册时间 上次更新 操作 {users.map((user) => ( handleShowDetail(user)} > {user.id}
{user.username.substring(0, 2).toUpperCase()}
{user.nickname} {user.is_admin && ( ADM )}
@{user.username}
{formatDateTime(user.last_login_at)} {formatDateTime(user.created_at)} {formatDateTime(user.updated_at)} e.stopPropagation()}>
handleStatusToggle(user)} disabled={user.is_admin} className="scale-75 data-[state=checked]:bg-green-600 h-4 w-7" />
{user.is_admin ? '管理员账户' : user.is_active ? '禁用账户' : '启用账户'}
查看详情
))}
)} 用户档案 {selectedUser && ( <>
{selectedUser.username.substring(0, 2).toUpperCase()}

{selectedUser.nickname}

@{selectedUser.username} UID: {selectedUser.id} Lv.{selectedUser.trust_level} {selectedUser.is_admin && ( Admin )}
注册时间 {formatDateTime(selectedUser.created_at).split(' ')[0]}

系统记录

最后登录 {formatDateTime(selectedUser.last_login_at)}
注册时间 {formatDateTime(selectedUser.created_at)}
最后更新 {formatDateTime(selectedUser.updated_at)}
{!selectedUser.is_admin && (
)} )}
) }