import React, { useState, useEffect } from 'react' import api from '../api.js' import { useAuth } from '../AuthContext.jsx' import { Plus, Trash2, Edit2, X, Check, Users, Shield, User, KeyRound } from 'lucide-react' function UserModal({ user, onClose, onSave }) { const [form, setForm] = useState({ username: user?.username || '', password: '', role: user?.role || 'user', }) const [error, setError] = useState('') const [loading, setLoading] = useState(false) const handleSubmit = async (e) => { e.preventDefault() setError('') setLoading(true) try { if (user) { const payload = { role: form.role } if (form.username !== user.username) payload.username = form.username if (form.password) payload.password = form.password const { data } = await api.put(`/users/${user.id}`, payload) onSave(data, 'edit') } else { if (!form.password) return setError('Password is required') const { data } = await api.post('/users', form) onSave(data, 'add') } onClose() } catch (err) { setError(err.response?.data?.error || 'Failed to save user') } finally { setLoading(false) } } return (

{user ? 'Edit User' : 'New User'}

{error &&
{error}
}
setForm({ ...form, username: e.target.value })} required className="w-full bg-slate-800 border border-slate-700 rounded-xl px-4 py-3 text-white focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition" placeholder="Username" />
setForm({ ...form, password: e.target.value })} required={!user} className="w-full bg-slate-800 border border-slate-700 rounded-xl px-4 py-3 text-white focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition" placeholder={user ? '••••••••' : 'Min. 6 characters'} />
{['user', 'admin'].map(role => ( ))}
) } export default function Admin() { const { user: currentUser } = useAuth() const [users, setUsers] = useState([]) const [loading, setLoading] = useState(true) const [modal, setModal] = useState(null) const [deleteConfirm, setDeleteConfirm] = useState(null) const [toast, setToast] = useState('') useEffect(() => { api.get('/users').then(({ data }) => { setUsers(data); setLoading(false) }).catch(() => setLoading(false)) }, []) const showToast = (msg) => { setToast(msg); setTimeout(() => setToast(''), 3000) } const handleSave = (data, type) => { if (type === 'add') setUsers(prev => [data, ...prev]) else setUsers(prev => prev.map(u => u.id === data.id ? data : u)) showToast(type === 'add' ? 'User created' : 'User updated') } const handleDelete = async (id) => { try { await api.delete(`/users/${id}`) setUsers(prev => prev.filter(u => u.id !== id)) setDeleteConfirm(null) showToast('User deleted') } catch (err) { showToast(err.response?.data?.error || 'Failed to delete') } } const adminCount = users.filter(u => u.role === 'admin').length const userCount = users.filter(u => u.role === 'user').length return (
{toast && (
{toast}
)}

Admin Panel

Manage user accounts and permissions

{/* Stats */}
{[ { label: 'Total Users', value: users.length, icon: Users, color: 'indigo' }, { label: 'Admins', value: adminCount, icon: Shield, color: 'amber' }, { label: 'Regular Users', value: userCount, icon: User, color: 'blue' }, ].map(({ label, value, icon: Icon, color }) => (

{value}

{label}

))}
{/* Users table */}
{loading ? (
Loading...
) : ( {users.map(u => ( ))}
Username Role MFA Status Created Actions
{u.role === 'admin' ? : }
{u.username} {u.id === currentUser.id && (you)}
{u.role} {u.mfa_enabled ? 'Enabled' : 'Disabled'} {u.must_change_password ? ( Must change pw ) : ( Active )} {new Date(u.created_at).toLocaleDateString()}
{u.id !== currentUser.id && ( )}
)}
{modal && ( setModal(null)} onSave={handleSave} /> )} {deleteConfirm && (

Delete User

Delete {deleteConfirm.username}? This cannot be undone.

)}
) }