"use client"; import { useState } from "react"; import { clientFetch } from "@/lib/api"; import { toast } from "sonner"; import { User, UserRole } from "@/lib/types"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, } from "@/components/ui/sheet"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog"; import { Loader2, Pencil, Trash2, Check, Users2 } from "lucide-react"; interface Props { initialUsers: User[]; } const roleMeta: Record = { [UserRole.ADMIN]: { label: "Admin", classes: "bg-red-100 text-red-800 border-red-200 dark:bg-red-950 dark:text-red-300", }, [UserRole.MANAGER]: { label: "Manager", classes: "bg-amber-100 text-amber-800 border-amber-200 dark:bg-amber-950 dark:text-amber-300", }, [UserRole.MEMBER]: { label: "Member", classes: "bg-blue-100 text-blue-700 border-blue-200 dark:bg-blue-950 dark:text-blue-300", }, }; function Avatar({ name, email }: { name?: string; email: string }) { const letter = (name || email).charAt(0).toUpperCase(); return (
{letter}
); } export function UsersTable({ initialUsers }: Props) { const [users, setUsers] = useState(initialUsers); const [editingUser, setEditingUser] = useState(null); const [deletingUser, setDeletingUser] = useState(null); const [editName, setEditName] = useState(""); const [editRole, setEditRole] = useState(UserRole.MEMBER); const [loading, setLoading] = useState(false); const [deleteLoading, setDeleteLoading] = useState(false); const openEdit = (user: User) => { setEditingUser(user); setEditName(user.name || ""); setEditRole(user.role); }; const closeEdit = () => setEditingUser(null); const handleUpdate = async () => { if (!editingUser) return; setLoading(true); try { let updated = editingUser; if (editName.trim() !== (editingUser.name || "")) { const res = await clientFetch<{ success: boolean; user: User }>( `/users/${editingUser.id}`, { method: "PATCH", body: JSON.stringify({ name: editName.trim() || undefined }), } ); updated = res.user; } if (editRole !== editingUser.role) { const res = await clientFetch<{ success: boolean; user: User }>( `/users/${editingUser.id}/role`, { method: "PATCH", body: JSON.stringify({ role: editRole }), } ); updated = res.user; } toast.success("User updated."); setUsers((prev) => prev.map((u) => (u.id === editingUser.id ? updated : u)) ); closeEdit(); } catch (err: unknown) { toast.error(err instanceof Error ? err.message : "Update failed"); } finally { setLoading(false); } }; const handleDelete = async () => { if (!deletingUser) return; setDeleteLoading(true); try { await clientFetch(`/users/${deletingUser.id}`, { method: "DELETE" }); toast.success(`User "${deletingUser.email}" deleted.`); setUsers((prev) => prev.filter((u) => u.id !== deletingUser.id)); setDeletingUser(null); } catch (err: unknown) { toast.error(err instanceof Error ? err.message : "Delete failed"); } finally { setDeleteLoading(false); } }; if (users.length === 0) { return (
No users found.
); } return ( <>
{users.map((user) => { const role = roleMeta[user.role]; return (

{user.name || ( No name )}

{role.label} {!user.isActive && ( Inactive )}

{user.email}

{new Date(user.createdAt).toLocaleDateString()}
); })}
{/* ── Edit sheet ───────────────────────────────────────────────────── */} !o && closeEdit()}> Edit User {editingUser?.email}
{/* Avatar preview */}
{(editName || editingUser?.email || "?").charAt(0).toUpperCase()}

{editName || "No name"}

{editingUser?.email}

setEditName(e.target.value)} placeholder="Full name" />

{editRole === UserRole.ADMIN ? "Full access: create, edit, delete posts and manage users." : editRole === UserRole.MANAGER ? "Can create posts (saved as draft for review)." : "Read-only access to the dashboard."}

{/* ── Delete confirmation dialog ────────────────────────────────────── */} !o && setDeletingUser(null)}> Delete user? This will permanently delete{" "} {deletingUser?.name || deletingUser?.email} . This action cannot be undone. Cancel {deleteLoading ? ( ) : ( )} Delete ); }