import { useState, useEffect, useCallback } from 'react'; import { motion } from 'framer-motion'; import { HiSearch } from 'react-icons/hi'; import { HiArrowPath } from 'react-icons/hi2'; import api from '../../../services/api'; import { formatDate } from '../../../utils/helpers'; import { useAuth } from '../../../contexts/AuthContext'; import toast from 'react-hot-toast'; const ROLES = [ { value: 'citizen', label: 'Citizen', color: '#6B7280' }, { value: 'volunteer_coordinator',label: 'Vol. Coordinator', color: '#3B82F6' }, { value: 'content_manager', label: 'Content Manager', color: '#8B5CF6' }, { value: 'manager', label: 'Manager', color: '#D97706' }, { value: 'admin', label: 'Admin', color: '#EF4444' }, ]; const ROLE_STYLE = Object.fromEntries(ROLES.map(r => [r.value, r])); function RoleChangeModal({ user, onClose, onSave }) { const [newRole, setNewRole] = useState(user.role); const [saving, setSaving] = useState(false); const handle = async () => { if (newRole === user.role) { onClose(); return; } if (!window.confirm(`Change ${user.displayName || user.email}'s role to "${newRole}"?`)) return; setSaving(true); try { await api.put('/auth/role', { userId: user.uid, role: newRole }); toast.success(`Role updated to ${newRole}`); onSave(); onClose(); } catch (e) { toast.error(e.message || 'Update failed.'); } finally { setSaving(false); } }; return (
e.stopPropagation()}>

👤 Change Role

{user.displayName || user.email}

{ROLES.map(r => ( ))}
); } export default function UserManagement() { const { isRole, userProfile } = useAuth(); const [users, setUsers] = useState([]); const [search, setSearch] = useState(''); const [roleFilter, setRoleFilter] = useState(''); const [loading, setLoading] = useState(true); const [editingUser, setEditingUser] = useState(null); const load = useCallback(async () => { setLoading(true); try { const data = await api.get(`/auth/users?limit=200${roleFilter ? '&role=' + roleFilter : ''}`); setUsers(data.users || []); } catch (e) { toast.error(e.message || 'Failed to load users.'); } finally { setLoading(false); } }, [roleFilter]); useEffect(() => { load(); }, [load]); const filtered = users.filter(u => !search || u.displayName?.toLowerCase().includes(search.toLowerCase()) || u.email?.toLowerCase().includes(search.toLowerCase()) ); return (
{editingUser && setEditingUser(null)} onSave={load} />}

👤 User Management

View all users and manage their roles and permissions.

{/* Filters */}
setSearch(e.target.value)} />
{filtered.length} users
{/* Users Table */}
{loading ? (
{[1,2,3,4,5].map(i =>
)}
) : filtered.length === 0 ? (
👤

No users found.

) : (
{isRole('admin') && } {filtered.map((u, i) => { const roleSty = ROLE_STYLE[u.role] || ROLE_STYLE.citizen; const isSelf = u.uid === userProfile?.uid; const initials = (u.displayName || u.email || 'U').split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2); return ( {isRole('admin') && ( )} ); })}
User Email Role Status JoinedActions
{u.profileImage ? ( {u.displayName} ) : (
{initials}
)}
{u.displayName || '—'} {isSelf && (you)}
{u.email} {roleSty.label} {u.status || 'active'} {u.createdAt ? formatDate(u.createdAt) : '—'} {!isSelf && ( )}
)}
); }