import { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { useAuth } from '../contexts/AuthContext'; import { listUsers, createUser, updateUser, resetUserPassword } from '../api'; import { AdminUser } from '../types'; import './AdminUsersPage.css'; function AdminUsersPage() { const { user, loading: authLoading } = useAuth(); const navigate = useNavigate(); const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [showCreateForm, setShowCreateForm] = useState(false); const [createUsername, setCreateUsername] = useState(''); const [createPassword, setCreatePassword] = useState(''); const [createEmail, setCreateEmail] = useState(''); const [createIsAdmin, setCreateIsAdmin] = useState(false); const [isCreating, setIsCreating] = useState(false); const [createError, setCreateError] = useState(null); const [resetPasswordUsername, setResetPasswordUsername] = useState(null); const [newPassword, setNewPassword] = useState(''); const [isResetting, setIsResetting] = useState(false); const [togglingUser, setTogglingUser] = useState(null); const [successMessage, setSuccessMessage] = useState(null); useEffect(() => { if (!authLoading && !user) { navigate('/login', { state: { from: '/admin/users' } }); } }, [user, authLoading, navigate]); useEffect(() => { if (user && user.is_admin) { loadUsers(); } }, [user]); useEffect(() => { if (successMessage) { const timer = setTimeout(() => setSuccessMessage(null), 3000); return () => clearTimeout(timer); } }, [successMessage]); async function loadUsers() { setLoading(true); setError(null); try { const data = await listUsers(); setUsers(data); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to load users'); } finally { setLoading(false); } } async function handleCreate(e: React.FormEvent) { e.preventDefault(); if (!createUsername.trim()) { setCreateError('Username is required'); return; } if (!createPassword.trim()) { setCreateError('Password is required'); return; } setIsCreating(true); setCreateError(null); try { await createUser({ username: createUsername.trim(), password: createPassword, email: createEmail.trim() || undefined, is_admin: createIsAdmin, }); setShowCreateForm(false); setCreateUsername(''); setCreatePassword(''); setCreateEmail(''); setCreateIsAdmin(false); setSuccessMessage('User created successfully'); await loadUsers(); } catch (err) { setCreateError(err instanceof Error ? err.message : 'Failed to create user'); } finally { setIsCreating(false); } } async function handleToggleAdmin(targetUser: AdminUser) { setTogglingUser(targetUser.username); try { await updateUser(targetUser.username, { is_admin: !targetUser.is_admin }); setSuccessMessage(`${targetUser.username} is ${!targetUser.is_admin ? 'now' : 'no longer'} an admin`); await loadUsers(); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to update user'); } finally { setTogglingUser(null); } } async function handleToggleActive(targetUser: AdminUser) { setTogglingUser(targetUser.username); try { await updateUser(targetUser.username, { is_active: !targetUser.is_active }); setSuccessMessage(`${targetUser.username} has been ${!targetUser.is_active ? 'enabled' : 'disabled'}`); await loadUsers(); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to update user'); } finally { setTogglingUser(null); } } async function handleResetPassword(e: React.FormEvent) { e.preventDefault(); if (!resetPasswordUsername || !newPassword.trim()) { return; } setIsResetting(true); try { await resetUserPassword(resetPasswordUsername, newPassword); setResetPasswordUsername(null); setNewPassword(''); setSuccessMessage(`Password reset for ${resetPasswordUsername}`); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to reset password'); } finally { setIsResetting(false); } } function formatDate(dateString: string | null): string { if (!dateString) return 'Never'; return new Date(dateString).toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit', }); } if (authLoading) { return (
Loading...
); } if (!user) { return null; } if (!user.is_admin) { return (

Access Denied

You do not have permission to access this page. Admin privileges are required.

); } return (

User Management

Manage user accounts and permissions

{successMessage && (
{successMessage}
)} {error && (
{error}
)} {showCreateForm && (

Create New User

{createError && (
{createError}
)}
setCreateUsername(e.target.value)} placeholder="Enter username" autoFocus disabled={isCreating} />
setCreatePassword(e.target.value)} placeholder="Enter password" disabled={isCreating} />
setCreateEmail(e.target.value)} placeholder="user@example.com" disabled={isCreating} />
)} {resetPasswordUsername && (

Reset Password

Set a new password for {resetPasswordUsername}

setNewPassword(e.target.value)} placeholder="Enter new password" autoFocus disabled={isResetting} />
)}
{loading ? (
Loading users...
) : users.length === 0 ? (

No Users

Create a user to get started

) : (
User Status Created Last Login Actions
{users.map((u) => (
{u.username.charAt(0).toUpperCase()}
{u.username} {u.is_admin && Admin}
{u.email && (
{u.email}
)}
{u.is_active ? 'Active' : 'Disabled'}
{formatDate(u.created_at)}
{formatDate(u.last_login)}
))}
)}
); } export default AdminUsersPage;