"use client"; import { Ban, CheckCircle, Edit, ShieldCheck, Trash2, UserRoundCheck, Users } from "lucide-react"; import { useCallback, useEffect, useState } from "react"; import { ConfirmDialog } from "@/components/confirm-dialog"; import { DataTable, type DataTableColumn } from "@/components/data-table"; import { PageHeader, PageShell, StatePanel } from "@/components/page-layout"; import { SectionCard, TableActions } from "@/components/section-card"; import { StatStrip } from "@/components/stat-strip"; import { StatusBadge } from "@/components/status-badge"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { api } from "@/lib/api-client"; import { getUserApi } from "@/lib/api-helpers"; import { useSession } from "@/lib/auth-client"; type User = { id: string; name: string; email: string; role: string; createdAt: Date; emailVerified: boolean; isSuspended: boolean; suspendedUntil: Date | null; }; export default function UsersPage() { const { data: session } = useSession(); const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [editingUser, setEditingUser] = useState(null); const [suspendingUser, setSuspendingUser] = useState(null); const [deleteUser, setDeleteUser] = useState(null); const fetchUsers = useCallback(async () => { try { const { data, error } = await api.api.users.get(); if (!error && data) { setUsers(data); } } catch (_error) { } finally { setLoading(false); } }, []); useEffect(() => { fetchUsers(); }, [fetchUsers]); const handleEdit = async (e: React.FormEvent) => { e.preventDefault(); if (!editingUser) return; const formData = new FormData(e.currentTarget); const name = formData.get("name") as string; const role = formData.get("role") as string; try { const { error } = await api.api.users({ id: editingUser.id }).patch({ name, role: role as "admin" | "user", }); if (!error) { await fetchUsers(); setEditingUser(null); } } catch (_error) {} }; const handleSuspend = async (e: React.FormEvent) => { e.preventDefault(); if (!suspendingUser) return; const formData = new FormData(e.currentTarget); const suspendedUntil = formData.get("suspendedUntil") as string; try { const { error } = await getUserApi(suspendingUser.id).suspension.patch({ isSuspended: true, suspendedUntil: suspendedUntil || null, }); if (!error) { await fetchUsers(); setSuspendingUser(null); } } catch (_error) {} }; const handleUnsuspend = async (userId: string) => { try { const { error } = await getUserApi(userId).suspension.patch({ isSuspended: false, suspendedUntil: null, }); if (!error) { await fetchUsers(); } } catch (_error) {} }; const handleDelete = async () => { if (!deleteUser) return; try { const { error } = await api.api.users({ id: deleteUser.id }).delete(); if (!error) { await fetchUsers(); setDeleteUser(null); } } catch (_error) {} }; const isUserSuspended = (user: User): boolean => { if (!user.isSuspended) return false; if (user.suspendedUntil && new Date(user.suspendedUntil) <= new Date()) { return false; } return true; }; const columns: readonly DataTableColumn[] = [ { id: "name", header: "Name", cell: (user) => user.name, className: "font-bold" }, { id: "email", header: "Email", cell: (user) => user.email, className: "font-mono text-xs text-muted-foreground", }, { id: "role", header: "Role", cell: (user) => ( {user.role} ), }, { id: "status", header: "Status", cell: (user) => isUserSuspended(user) ? ( Suspended {user.suspendedUntil && ` until ${new Date(user.suspendedUntil).toLocaleDateString()}`} ) : ( {user.emailVerified ? "Active" : "Unverified"} ), }, { id: "created", header: "Created", cell: (user) => new Date(user.createdAt).toLocaleDateString(), className: "text-muted-foreground", }, { id: "actions", header: "Actions", headerClassName: "text-right", className: "text-right", cell: (user) => ( {isUserSuspended(user) ? ( ) : ( )} ), }, ]; return ( user.role === "admin").length, icon: ShieldCheck, }, { label: "Active", value: users.filter((user) => !isUserSuspended(user)).length, icon: UserRoundCheck, tone: "positive", }, ]} /> ) } /> {loading ? ( ) : ( user.id} /> )} setEditingUser(null)}> Edit User Update user information and role
setSuspendingUser(null)}> Suspend User Suspend {suspendingUser?.name} from accessing the system

Leave empty for indefinite suspension

Are you sure you want to delete {deleteUser?.name}? This action cannot be undone. } confirmLabel="Delete" onConfirm={handleDelete} onOpenChange={(open) => !open && setDeleteUser(null)} />
); }