import React, { useEffect, 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 { Badge } from '../../components/ui/badge'; 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 } from 'lucide-react'; const AdminStaff = () => { const navigate = useNavigate(); const { hasPermission } = useAuth(); const [users, setUsers] = useState([]); const [filteredUsers, setFilteredUsers] = useState([]); const [loading, setLoading] = useState(true); const [searchQuery, setSearchQuery] = useState(''); const [roleFilter, setRoleFilter] = useState('all'); const [createDialogOpen, setCreateDialogOpen] = useState(false); const [inviteDialogOpen, setInviteDialogOpen] = useState(false); const [activeTab, setActiveTab] = useState('staff-list'); // Staff roles (non-guest, non-member) - includes all admin-type roles const STAFF_ROLES = ['admin', 'superadmin', 'finance']; useEffect(() => { fetchStaff(); }, []); useEffect(() => { filterUsers(); }, [users, searchQuery, roleFilter]); const fetchStaff = async () => { try { const response = await api.get('/admin/users'); // Filter to only staff roles const staffUsers = response.data.filter(user => STAFF_ROLES.includes(user.role) ); setUsers(staffUsers); } catch (error) { toast.error('Failed to fetch staff'); } finally { setLoading(false); } }; const filterUsers = () => { let filtered = users; if (roleFilter && roleFilter !== 'all') { filtered = filtered.filter(user => user.role === roleFilter); } if (searchQuery) { const query = searchQuery.toLowerCase(); filtered = filtered.filter(user => user.first_name.toLowerCase().includes(query) || user.last_name.toLowerCase().includes(query) || user.email.toLowerCase().includes(query) ); } setFilteredUsers(filtered); }; const getRoleBadge = (role) => { const config = { superadmin: { label: 'Superadmin', className: 'bg-[#664fa3] text-white' }, admin: { label: 'Admin', className: 'bg-[#81B29A] text-white' }, moderator: { label: 'Moderator', className: 'bg-[#DDD8EB] text-[#422268]' }, staff: { label: 'Staff', className: 'bg-gray-200 text-gray-700' }, media: { label: 'Media', className: 'bg-gray-400 text-white' } }; const roleConfig = config[role] || { label: role, className: 'bg-gray-500 text-white' }; return ( {roleConfig.label} ); }; const getStatusBadge = (status) => { const config = { active: { label: 'Active', className: 'bg-[#81B29A] text-white' }, inactive: { label: 'Inactive', className: 'bg-gray-400 text-white' } }; const statusConfig = config[status] || config.inactive; return ( {statusConfig.label} ); }; return ( <>

Staff Management

Manage internal team members and their roles.

{hasPermission('users.invite') && ( )} {hasPermission('users.create') && ( )}
{/* Stats */}

Total Staff

{users.length}

Admins

{users.filter(u => ['admin', 'superadmin'].includes(u.role)).length}

Moderators

{users.filter(u => u.role === 'moderator').length}

Active

{users.filter(u => u.status === 'active').length}

{/* Tabs */} Staff Members Pending Invitations {/* Filters */}
setSearchQuery(e.target.value)} className="pl-12 h-14 rounded-xl border-2 border-[#ddd8eb] focus:border-[#664fa3]" data-testid="search-staff-input" />
{/* Staff List */} {loading ? (

Loading staff...

) : filteredUsers.length > 0 ? (
{filteredUsers.map((user) => (
{/* Avatar */}
{user.first_name?.[0]}{user.last_name?.[0]}
{/* Info */}

{user.first_name} {user.last_name}

{getRoleBadge(user.role)} {getStatusBadge(user.status)}

Email: {user.email}

Phone: {user.phone}

Joined: {new Date(user.created_at).toLocaleDateString()}

{user.last_login && (

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

)}
{/* Actions */}
))}
) : (

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;