"use client" import {useEffect, useState} 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, SheetContent, SheetTitle} from "@/components/ui/sheet" import {Badge} from "@/components/ui/badge" import {Avatar, AvatarFallback, AvatarImage} from "@/components/ui/avatar" import { ChevronDown, ChevronLeft, ChevronRight, Eye, Filter, Layers, Loader2, Plus, Search, ShieldCheck, UserCheck, UserX, X } from "lucide-react" import {Tooltip, TooltipContent, TooltipProvider, TooltipTrigger} from "@/components/ui/tooltip" import {AdminUser} from "@/lib/services" import {cn, 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 {useAdminUsers} from "@/contexts/admin-users-context" import {CreateUserModal} from "./create-user-modal" 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) const [createModalOpen, setCreateModalOpen] = 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} {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 && (
)} )}
setCreateModalOpen(false)} />
) }