import { useState, useEffect } from "react"; import { useNavigate } from "react-router-dom"; import api from "../api/client"; import { useAuth } from "../auth/AuthContext"; import SearchBar from "../components/SearchBar"; import ConfirmDialog from "../components/ConfirmDialog"; const STATUS_OPTIONS = ["", "active", "blocked"]; export default function UserList() { const [users, setUsers] = useState([]); const [total, setTotal] = useState(0); const [loading, setLoading] = useState(true); const [error, setError] = useState(""); const [search, setSearch] = useState(""); const [statusFilter, setStatusFilter] = useState(""); const [deleteTarget, setDeleteTarget] = useState(null); const [hoveredRow, setHoveredRow] = useState(null); const navigate = useNavigate(); const { hasPermission } = useAuth(); const canEdit = hasPermission("app_users", "edit"); const fetchUsers = async () => { setLoading(true); setError(""); try { const params = new URLSearchParams(); if (search) params.set("search", search); if (statusFilter) params.set("status", statusFilter); const qs = params.toString(); const data = await api.get(`/users${qs ? `?${qs}` : ""}`); setUsers(data.users); setTotal(data.total); } catch (err) { setError(err.message); } finally { setLoading(false); } }; useEffect(() => { fetchUsers(); }, [search, statusFilter]); const handleDelete = async () => { if (!deleteTarget) return; try { await api.delete(`/users/${deleteTarget.id}`); setDeleteTarget(null); fetchUsers(); } catch (err) { setError(err.message); setDeleteTarget(null); } }; return (

User Management

{canEdit && ( )}
{total} {total === 1 ? "user" : "users"}
{error && (
{error}
)} {loading ? (
Loading...
) : users.length === 0 ? (
No users found.
) : (
{canEdit && ( {users.map((user, index) => ( navigate(`/users/${user.id}`)} className="cursor-pointer" style={{ borderBottom: index < users.length - 1 ? "1px solid var(--border-primary)" : "none", backgroundColor: hoveredRow === user.id ? "var(--bg-card-hover)" : "transparent", }} onMouseEnter={() => setHoveredRow(user.id)} onMouseLeave={() => setHoveredRow(null)} > {canEdit && ( )} ))}
Status Name Email Phone Title Last Active )}
{user.status || "unknown"} {user.display_name || "Unnamed User"} {user.email || "-"} {user.phone_number || "-"} {user.userTitle || "-"} {user.lastActive || "-"}
e.stopPropagation()} >
)} setDeleteTarget(null)} />
); }