import React, { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { useAuth } from '../../context/AuthContext'; import api from '../../utils/api'; import { Card } from '../../components/ui/card'; import { Button } from '../../components/ui/button'; import { Input } from '../../components/ui/input'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../components/ui/select'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '../../components/ui/tabs'; import CreateStaffDialog from '../../components/CreateStaffDialog'; import InviteStaffDialog from '../../components/InviteStaffDialog'; import PendingInvitationsTable from '../../components/PendingInvitationsTable'; import { toast } from 'sonner'; import { UserCog, Search, Shield, UserPlus, Mail, Edit, Eye, Trash2, UserCheck, UserX, ShieldIcon } from 'lucide-react'; import StatusBadge from '../../components/StatusBadge'; import { StatCard } from '@/components/StatCard'; import { CircleMinus, CreditCard, Users } from 'lucide-react'; import { useStaff } from '../../hooks/use-users'; const AdminStaff = () => { const navigate = useNavigate(); const { hasPermission, user } = useAuth(); const { users, filteredUsers, loading, searchQuery, setSearchQuery, filterValue: roleFilter, setFilterValue: setRoleFilter, refetch, } = useStaff({ initialFilter: 'all', filterKey: 'role', }); const [createDialogOpen, setCreateDialogOpen] = useState(false); const [inviteDialogOpen, setInviteDialogOpen] = useState(false); const [activeTab, setActiveTab] = useState('staff-list'); const handleToggleStatus = async (userId, currentStatus) => { const newStatus = currentStatus === 'active' ? 'inactive' : 'active'; try { await api.put(`/admin/users/${userId}/status`, { status: newStatus }); toast.success(`User ${newStatus === 'active' ? 'activated' : 'deactivated'} successfully`); refetch(); // Refresh list } catch (error) { toast.error(error.response?.data?.detail || 'Failed to update user status'); } }; const handleDeleteUser = async (userId, userName) => { if (!window.confirm(`Are you sure you want to delete ${userName}? This action cannot be undone.`)) { return; } try { await api.delete(`/admin/users/${userId}`); toast.success('User deleted successfully'); refetch(); // Refresh list } catch (error) { toast.error(error.response?.data?.detail || 'Failed to delete user'); } }; return ( <>

Staff Management

Manage internal team members and their roles.

{hasPermission('users.create') && ( )} {hasPermission('users.create') && ( )}
{/* Stats */}
Quick Overview
['admin', 'superadmin', 'finance', 'staff', 'media'].includes(u.role)).length} icon={Users} iconBgClass="bg-[var(--blue-light)] text-[var(--blue-dark)]" dataTestId="stat-total-members" /> ['admin', 'superadmin'].includes(u.role)).length} icon={Shield} iconBgClass="text-[var(--green-light)]" dataTestId="stat-active-members" /> u.role === 'finance').length} icon={CreditCard} iconBgClass="text-brand-light-orange" dataTestId="stat-payment-pending-members" /> ['admin', 'superadmin'].includes(u.role)).length && users.filter(u => u.status !== 'inactive').length} icon={CircleMinus} iconBgClass=" text-brand-pink" dataTestId="stat-inactive-members" />
{/* Tabs */} Staff Members Pending Invitations {/* Filters */}
setSearchQuery(e.target.value)} className="pl-12 h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple " data-testid="search-staff-input" />
{/* Staff List */} {loading ? (

Loading staff...

) : filteredUsers.length > 0 ? (
{filteredUsers.map((user) => { const joinedDate = user.member_since || user.created_at; return (
{/* Avatar */}
{user.first_name?.[0]}{user.last_name?.[0]}
{/* Info */}

{user.first_name} {user.last_name}

Email: {user.email}

Phone: {user.phone}

Joined: {joinedDate ? new Date(joinedDate).toLocaleDateString() : 'N/A'}

{user.last_login && (

Last Login: {new Date(user.last_login).toLocaleDateString()}

)}
{/* Actions */}
{hasPermission('users.status') && ( )} {hasPermission('users.delete') && ( )}
); })}
) : (

No Staff Found

{searchQuery || roleFilter !== 'all' ? 'Try adjusting your filters' : 'No staff members yet'}

)}
{/* Dialogs */} { // Optionally refresh invitations table setActiveTab('pending-invitations'); }} /> ); }; export default AdminStaff;