import { useState, useEffect } from 'react' import { userManagement, type User, type Role, type RoleName, type UserStatus } from '../lib/supabase' import { CreateUserModal } from './CreateUserModal' export function UserManagement() { const [users, setUsers] = useState([]) const [roles, setRoles] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [editingUser, setEditingUser] = useState(null) const [showCreateModal, setShowCreateModal] = useState(false) useEffect(() => { loadData() }, []) const loadData = async () => { try { setLoading(true) setError(null) const [usersData, rolesData] = await Promise.all([ userManagement.getAllUsers(), userManagement.getAllRoles() ]) setUsers(usersData) setRoles(rolesData) } catch (err) { setError('Failed to load user data') console.error('Load data error:', err) } finally { setLoading(false) } } const handleStatusToggle = async (userId: string, currentStatus: UserStatus) => { try { const newStatus: UserStatus = currentStatus === 'active' ? 'disabled' : 'active' await userManagement.updateUserStatus(userId, newStatus) // Update local state setUsers(users.map(user => user.id === userId ? { ...user, status: newStatus } : user )) } catch (err) { console.error('Status update error:', err) alert('Failed to update user status') } } const handleRoleUpdate = async (userId: string, newRoles: RoleName[]) => { try { await userManagement.updateUserRoles(userId, newRoles) // Update local state setUsers(users.map(user => user.id === userId ? { ...user, roles: newRoles } : user )) setEditingUser(null) } catch (err) { console.error('Role update error:', err) alert('Failed to update user roles') } } const handleEmailUpdate = async (userId: string, newEmail: string) => { try { await userManagement.updateUserEmail(userId, newEmail) // Update local state setUsers(users.map(user => user.id === userId ? { ...user, email: newEmail } : user )) setEditingUser(null) } catch (err) { console.error('Email update error:', err) alert('Failed to update user email') } } const handleUserCreated = (newUser: User) => { setUsers([...users, newUser]) setShowCreateModal(false) } const getRoleBadgeColor = (role: string) => { switch (role) { case 'admin': return 'bg-red-100 text-red-800' case 'conductor': return 'bg-blue-100 text-blue-800' case 'analyst': return 'bg-green-100 text-green-800' case 'data recorder': return 'bg-purple-100 text-purple-800' default: return 'bg-gray-100 text-gray-800' } } if (loading) { return (

Loading users...

) } if (error) { return (
{error}
) } return (
{/* Header */}

User Management

Manage user accounts, roles, and permissions

{/* Stats */}
👥
Total Users
{users.length}
Active Users
{users.filter(u => u.status === 'active').length}
🔴
Disabled Users
{users.filter(u => u.status === 'disabled').length}
👑
Admins
{users.filter(u => u.roles.includes('admin')).length}
{/* Users Table */}

Users

Click on any field to edit user details

{users.map((user) => ( setEditingUser(user.id)} onCancel={() => setEditingUser(null)} onStatusToggle={handleStatusToggle} onRoleUpdate={handleRoleUpdate} onEmailUpdate={handleEmailUpdate} getRoleBadgeColor={getRoleBadgeColor} /> ))}
Email Roles Status Created Actions
{/* Create User Modal */} {showCreateModal && ( setShowCreateModal(false)} onUserCreated={handleUserCreated} /> )}
) } // UserRow component for inline editing interface UserRowProps { user: User roles: Role[] isEditing: boolean onEdit: () => void onCancel: () => void onStatusToggle: (userId: string, currentStatus: UserStatus) => void onRoleUpdate: (userId: string, newRoles: RoleName[]) => void onEmailUpdate: (userId: string, newEmail: string) => void getRoleBadgeColor: (role: string) => string } function UserRow({ user, roles, isEditing, onEdit, onCancel, onStatusToggle, onRoleUpdate, onEmailUpdate, getRoleBadgeColor }: UserRowProps) { const [editEmail, setEditEmail] = useState(user.email) const [editRoles, setEditRoles] = useState(user.roles) const handleSave = () => { if (editEmail !== user.email) { onEmailUpdate(user.id, editEmail) } if (JSON.stringify(editRoles.sort()) !== JSON.stringify(user.roles.sort())) { onRoleUpdate(user.id, editRoles) } if (editEmail === user.email && JSON.stringify(editRoles.sort()) === JSON.stringify(user.roles.sort())) { onCancel() } } const handleRoleToggle = (roleName: RoleName) => { if (editRoles.includes(roleName)) { setEditRoles(editRoles.filter(r => r !== roleName)) } else { setEditRoles([...editRoles, roleName]) } } return ( {isEditing ? ( setEditEmail(e.target.value)} className="block w-full border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 sm:text-sm" /> ) : (
{user.email}
)} {isEditing ? (
{roles.map((role) => ( ))}
) : (
{user.roles.map((role) => ( {role.charAt(0).toUpperCase() + role.slice(1)} ))}
)} {new Date(user.created_at).toLocaleDateString()} {isEditing ? (
) : ( )} ) }