// Users.jsx — Admin User Management function UsersPage() { const [search, setSearch] = React.useState(''); const [catFilter, setCatFilter] = React.useState('All'); const [showAdd, setShowAdd] = React.useState(false); const filtered = USERS.filter(u => (catFilter === 'All' || userCategory(u) === catFilter) && (u.name.toLowerCase().includes(search.toLowerCase()) || u.email.toLowerCase().includes(search.toLowerCase())) ); // Group filtered users into the tidy categories, preserving category order. const grouped = USER_CATEGORIES .map(cat => ({ cat, rows: filtered.filter(u => userCategory(u) === cat) })) .filter(g => g.rows.length > 0); const roleColor = { Admin: '#7C3AED', Operation: '#2563EB', Operator: '#F59E0B', Rigger: '#0891B2', Mechanic: '#DC2626', Finance: '#059669', Management: '#0B1F3A', }; const catColor = { 'Super Admin': '#7C3AED', 'Management': '#0B1F3A', 'Account and Finance': '#059669', 'Dispatch': '#0EA5E9', 'Mechanic': '#DC2626', 'Operator': '#F59E0B', 'Rigger': '#0891B2', }; const statusBadge = (s) => s === 'On Job' ? 'orange' : s === 'Standby' ? 'gray' : 'green'; return (
Team Members
{USERS.length} staff across {USER_CATEGORIES.length} categories
setSearch(e.target.value)} placeholder="Search by name or email..." style={{paddingLeft: 38, width: '100%'}}/>
{grouped.map(g => ( {g.rows.map(u => { const initials = u.name === 'N/A' ? '—' : u.name.replace(/\(.*?\)/g, '').trim().split(/\s+/).map(p => p[0]).slice(0, 2).join(''); return ( ); })} ))} {grouped.length === 0 ? ( ) : null}
Name Role Email Phone Status Last Active
{g.cat} · {g.rows.length}
{initials}
{u.name}
{u.role} {u.email} {u.phone} {u.status} {u.last}
No team members match your search.
{showAdd ? (
setShowAdd(false)}>
e.stopPropagation()} style={{maxWidth: 520}}>
Add User
The new user receives a password-setup link by email. Their permissions are determined by the role you select — see Role Permissions for the full matrix.
) : null}
); } Object.assign(window, { UsersPage });