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 ROLE_OPTIONS = ["", "sysadmin", "admin", "editor", "user"]; const ROLE_COLORS = { sysadmin: { bg: "var(--danger-bg)", text: "var(--danger-text)" }, admin: { bg: "#3b2a0a", text: "#f6ad55" }, editor: { bg: "var(--badge-blue-bg)", text: "var(--badge-blue-text)" }, user: { bg: "var(--bg-card-hover)", text: "var(--text-muted)" }, }; function RoleBadge({ role }) { const colors = ROLE_COLORS[role] || ROLE_COLORS.user; return ( {role} ); } export default function StaffList() { const [staff, setStaff] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(""); const [search, setSearch] = useState(""); const [roleFilter, setRoleFilter] = useState(""); const [deleteTarget, setDeleteTarget] = useState(null); const navigate = useNavigate(); const { user } = useAuth(); const fetchStaff = async () => { setLoading(true); setError(""); try { const params = new URLSearchParams(); if (search) params.set("search", search); if (roleFilter) params.set("role", roleFilter); const qs = params.toString(); const data = await api.get(`/staff${qs ? `?${qs}` : ""}`); setStaff(data.staff); } catch (err) { setError(err.message); } finally { setLoading(false); } }; useEffect(() => { fetchStaff(); }, [search, roleFilter]); const handleDelete = async () => { if (!deleteTarget) return; try { await api.delete(`/staff/${deleteTarget.id}`); setDeleteTarget(null); fetchStaff(); } catch (err) { setError(err.message); setDeleteTarget(null); } }; const canDeleteStaff = (staffMember) => { if (staffMember.id === user?.sub) return false; if (user?.role === "admin" && staffMember.role === "sysadmin") return false; return true; }; const canEditStaff = (staffMember) => { if (user?.role === "admin" && staffMember.role === "sysadmin") return false; return true; }; const selectClass = "px-3 py-2 rounded-md text-sm cursor-pointer border"; const selectStyle = { backgroundColor: "var(--bg-card)", color: "var(--text-primary)", borderColor: "var(--border-primary)", }; return (
| Name | Role | Status | ||
|---|---|---|---|---|
| {member.name} | {member.email} | {member.is_active ? "Active" : "Inactive"} |
e.stopPropagation()}>
{canEditStaff(member) && (
)}
{canDeleteStaff(member) && (
)}
|