import { IconArrowsUpDown as ArrowUpDown, IconBuilding as Building2, IconCircleCheck as CheckCircle, IconChevronLeft as ChevronLeft, IconChevronRight as ChevronRight, IconLoader2 as Loader2, IconLogin as LogIn, IconSearch as Search, IconShield as Shield, IconCircleX as XCircle, } from '@tabler/icons-react'; import { useQuery } from '@tanstack/react-query'; import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router'; import { useAuth } from '@/components/auth/AuthProvider'; import { PageHeader } from '@/components/PageHeader'; import { Avatar, AvatarFallback } from '@/components/ui/avatar'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Input } from '@/components/ui/input'; import { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table'; import { apiJson } from '@/lib/api'; import { ContentPanel } from '../../components/ContentPanel'; type User = { id: string; email: string; name: string | null; avatar: string | null; role: string | null; emailVerified: boolean; organizationCount: number; lastSignIn: string | null; createdAt: string; }; type SortField = 'email' | 'name' | 'created_at'; type SortOrder = 'asc' | 'desc'; async function fetchUsers(params: { search: string; sortBy: SortField; sortOrder: SortOrder; page: number; limit: number; }): Promise<{ users: User[]; pagination: { total: number; totalPages: number } }> { const queryParams = new URLSearchParams({ search: params.search, sortBy: params.sortBy, sortOrder: params.sortOrder, page: params.page.toString(), limit: params.limit.toString(), }); return apiJson<{ users: User[]; pagination: { total: number; totalPages: number } }>( `/api/v1/admin/users?${queryParams}`, {}, 'Failed to fetch users' ); } function getUserInitials(user: User) { if (user.name) { return user.name .split(' ') .map((n) => n[0]) .join('') .toUpperCase() .slice(0, 2); } return user.email?.[0]?.toUpperCase() || '?'; } export default function AdminUsers() { const { t } = useTranslation(); const navigate = useNavigate(); const { impersonateUser, user: currentUser } = useAuth(); const [search, setSearch] = useState(''); const [sortBy, setSortBy] = useState('created_at'); const [sortOrder, setSortOrder] = useState('desc'); const [page, setPage] = useState(1); const [impersonating, setImpersonating] = useState(null); const limit = 20; const handleImpersonate = async (userId: string) => { setImpersonating(userId); try { await impersonateUser(userId); navigate('/dashboard'); } catch { setImpersonating(null); } }; const { data, isLoading, error } = useQuery({ queryKey: ['admin-users', search, sortBy, sortOrder, page], queryFn: () => fetchUsers({ search, sortBy, sortOrder, page, limit }), }); const users = data?.users || []; const totalPages = data?.pagination.totalPages || 1; const total = data?.pagination.total || 0; const toggleSort = (field: SortField) => { if (sortBy === field) { setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc'); } else { setSortBy(field); setSortOrder('asc'); } setPage(1); }; const handleSearch = (value: string) => { setSearch(value); setPage(1); }; const sortOptions: Record = { 'created_at-desc': 'Newest first', 'created_at-asc': 'Oldest first', 'email-asc': 'Email A-Z', 'email-desc': 'Email Z-A', 'name-asc': 'Name A-Z', 'name-desc': 'Name Z-A', }; const sortValue = `${sortBy}-${sortOrder}`; return ( <>
Users ({total}) A list of all registered users in the system.
handleSearch(e.target.value)} className="pl-8 w-64" />
{isLoading ? (
) : error ? (
{error instanceof Error ? error.message : 'Failed to load users'}
) : users.length === 0 ? (
{search ? 'No users match your search.' : 'No users found.'}
) : ( <> Role Verified Organizations Last Sign In {users.map((user) => (
{getUserInitials(user)} {user.name || -}
{user.email} {user.role === 'super_admin' ? ( Super Admin ) : ( - )} {user.emailVerified ? ( ) : ( )}
{user.organizationCount}
{user.lastSignIn ? new Date(user.lastSignIn).toLocaleDateString() : 'Never'} {new Date(user.createdAt).toLocaleDateString()} {user.id !== currentUser?.id && user.role !== 'super_admin' && ( )}
))}
{/* Pagination */} {totalPages > 1 && (

Page {page} of {totalPages}

)} )}
); }