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'; 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: '', role: 'viewer' }); 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 handleSubmit = async (e) => { e.preventDefault(); setFormError(''); setFormSuccess(''); 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: '', role: 'viewer' }); setFormSuccess(''); }, 1500); } catch (err) { setFormError(err.message); } }; const handleEdit = (user) => { setEditingUser(user); setFormData({ username: user.username, email: user.email, password: '', role: user.role }); 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); } }; const getRoleBadgeColor = (role) => { switch (role) { case 'admin': return 'bg-red-100 text-red-800'; case 'editor': return 'bg-blue-100 text-blue-800'; default: return 'bg-gray-100 text-gray-800'; } }; return (
Manage user accounts and permissions
Loading users...
{error}
| User | Role | Status | Last Login | Actions |
|---|---|---|---|---|
|
{user.username} {user.email} |
{user.role.charAt(0).toUpperCase() + user.role.slice(1)} | {user.last_login ? new Date(user.last_login).toLocaleString() : 'Never'} |
|