import React, { useState, useEffect } from 'react'; import { X, Plus, Edit2, Trash2, Loader, AlertCircle, CheckCircle, User, Mail, Shield } from 'lucide-react'; import { useAuth } from '../contexts/AuthContext'; const API_BASE = process.env.REACT_APP_API_BASE || 'http://localhost:3001/api'; const VALID_GROUPS = ['Admin', 'Standard_User', 'Leadership', 'Read_Only']; const GROUP_LABELS = { Admin: 'Admin (full access)', Standard_User: 'Standard User (create, edit, limited delete)', Leadership: 'Leadership (read-only + exports)', Read_Only: 'Read Only (view only)' }; const GROUP_BADGE_STYLES = { Admin: { backgroundColor: '#FEE2E2', color: '#991B1B' }, Standard_User: { backgroundColor: '#DBEAFE', color: '#1E40AF' }, Leadership: { backgroundColor: '#F3E8FF', color: '#6B21A8' }, Read_Only: { backgroundColor: '#F3F4F6', color: '#374151' } }; export default function UserManagement({ onClose }) { const { user: currentUser } = useAuth(); const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [showAddUser, setShowAddUser] = useState(false); const [editingUser, setEditingUser] = useState(null); const [formData, setFormData] = useState({ username: '', email: '', password: '', group: 'Read_Only' }); const [formError, setFormError] = useState(''); const [formSuccess, setFormSuccess] = useState(''); useEffect(() => { fetchUsers(); }, []); const fetchUsers = async () => { try { const response = await fetch(`${API_BASE}/users`, { credentials: 'include' }); if (!response.ok) throw new Error('Failed to fetch users'); const data = await response.json(); setUsers(data); } catch (err) { setError(err.message); } finally { setLoading(false); } }; const confirmGroupChange = (targetUser, newGroup) => { let message = `Are you sure you want to change ${targetUser.username}'s group from ${targetUser.group} to ${newGroup}?`; // Extra warning when downgrading an Admin user if (targetUser.group === 'Admin' && newGroup !== 'Admin') { message += `\n\n⚠️ WARNING: You are removing Admin privileges from ${targetUser.username}. They will lose full system access.`; } return window.confirm(message); }; const handleSubmit = async (e) => { e.preventDefault(); setFormError(''); setFormSuccess(''); // If editing and group changed, show confirmation dialog if (editingUser && formData.group !== editingUser.group) { if (!confirmGroupChange(editingUser, formData.group)) { return; } } try { const url = editingUser ? `${API_BASE}/users/${editingUser.id}` : `${API_BASE}/users`; const method = editingUser ? 'PATCH' : 'POST'; const body = { ...formData }; if (editingUser && !body.password) { delete body.password; } const response = await fetch(url, { method, headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify(body) }); const data = await response.json(); if (!response.ok) { throw new Error(data.error || 'Operation failed'); } setFormSuccess(editingUser ? 'User updated successfully' : 'User created successfully'); fetchUsers(); setTimeout(() => { setShowAddUser(false); setEditingUser(null); setFormData({ username: '', email: '', password: '', group: 'Read_Only' }); setFormSuccess(''); }, 1500); } catch (err) { setFormError(err.message); } }; const handleEdit = (user) => { setEditingUser(user); setFormData({ username: user.username, email: user.email, password: '', group: user.group }); setShowAddUser(true); setFormError(''); setFormSuccess(''); }; const handleDelete = async (userId) => { if (!window.confirm('Are you sure you want to delete this user?')) { return; } try { const response = await fetch(`${API_BASE}/users/${userId}`, { method: 'DELETE', credentials: 'include' }); const data = await response.json(); if (!response.ok) { throw new Error(data.error || 'Delete failed'); } fetchUsers(); } catch (err) { alert(err.message); } }; const handleToggleActive = async (user) => { try { const response = await fetch(`${API_BASE}/users/${user.id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify({ is_active: !user.is_active }) }); const data = await response.json(); if (!response.ok) { throw new Error(data.error || 'Update failed'); } fetchUsers(); } catch (err) { alert(err.message); } }; // Check if group dropdown should be disabled for self-demotion prevention const isGroupDropdownDisabled = (targetUser) => { if (!targetUser || !currentUser) return false; return targetUser.id === currentUser.id && currentUser.group === 'Admin'; }; return (

User Management

Manage user accounts and permissions

{!showAddUser && ( )} {showAddUser && (

{editingUser ? 'Edit User' : 'Add New User'}

{formError && (
{formError}
)} {formSuccess && (
{formSuccess}
)}
setFormData({ ...formData, username: e.target.value })} className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-[#0476D9] focus:border-transparent" />
setFormData({ ...formData, email: e.target.value })} className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-[#0476D9] focus:border-transparent" />
setFormData({ ...formData, password: e.target.value })} className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-[#0476D9] focus:border-transparent" />
{isGroupDropdownDisabled(editingUser) && (

You cannot change your own Admin group.

)}
)} {loading ? (

Loading users...

) : error ? (

{error}

) : (
{users.map((user) => ( ))}
User Group Status Last Login Actions

{user.username}

{user.email}

{user.group ? user.group.replace('_', ' ') : 'Read Only'} {user.last_login ? new Date(user.last_login).toLocaleString() : 'Never'}
)}
); }