'use client'; import { useState, useEffect, useCallback } from 'react'; import { type ColumnDef } from '@tanstack/react-table'; import { Pencil, Trash2, Plus, ShieldCheck, ShieldOff } from 'lucide-react'; import { DataTable } from '@/components/shared/data-table'; import { PageHeader } from '@/components/shared/page-header'; import { ConfirmationDialog } from '@/components/shared/confirmation-dialog'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { apiFetch } from '@/lib/api/client'; import { UserCard } from './user-card'; import { UserForm } from './user-form'; interface UserRow { userId: string; displayName: string; email: string; phone: string | null; isActive: boolean; isSuperAdmin: boolean; lastLoginAt: string | null; role: { id: string; name: string }; assignedAt: string; } export function UserList() { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [formOpen, setFormOpen] = useState(false); const [editingUser, setEditingUser] = useState(null); const [deletingId, setDeletingId] = useState(null); const fetchUsers = useCallback(async () => { setLoading(true); try { const res = await apiFetch<{ data: UserRow[] }>('/api/v1/admin/users'); setUsers(res.data); } finally { setLoading(false); } }, []); useEffect(() => { void fetchUsers(); }, [fetchUsers]); function handleNewUser() { setEditingUser(null); setFormOpen(true); } function handleEditUser(user: UserRow) { setEditingUser(user); setFormOpen(true); } async function handleRemoveUser(userId: string) { setDeletingId(userId); try { await apiFetch(`/api/v1/admin/users/${userId}`, { method: 'DELETE' }); await fetchUsers(); } finally { setDeletingId(null); } } const columns: ColumnDef[] = [ { accessorKey: 'displayName', header: 'Name', cell: ({ row }) => (
{row.original.displayName} {row.original.email}
), }, { accessorKey: 'role', header: 'Role', cell: ({ row }) => {row.original.role.name}, }, { accessorKey: 'isActive', header: 'Status', cell: ({ row }) => row.original.isActive ? ( Active ) : ( Disabled ), }, { accessorKey: 'lastLoginAt', header: 'Last Login', cell: ({ row }) => row.original.lastLoginAt ? new Date(row.original.lastLoginAt).toLocaleDateString() : 'Never', }, { id: 'actions', header: '', cell: ({ row }) => (
Remove } title="Remove User" description={`Remove "${row.original.displayName}" from this port? They will lose access but their account remains.`} confirmLabel="Remove" onConfirm={() => handleRemoveUser(row.original.userId)} loading={deletingId === row.original.userId} />
), enableSorting: false, size: 80, }, ]; return (
New User } /> row.userId} cardRender={(row) => ( )} emptyState={

No users assigned to this port.

} />
); }