import { useState } from 'react'; import { useAdminUsers, useUpdateUser, useDisableUser, useEnableUser, useCreateUser, useResetPassword } from '@/hooks/useAdminUsers'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog'; import { Label } from '@/components/ui/label'; import { Loader2, Search, UserCog, Ban, CheckCircle, UserPlus } from 'lucide-react'; interface User { _id: string; username: string; email: string; role: string; is_active?: boolean; override_quota?: boolean; quota?: { monthly_usd?: number }; cost_mtd?: number; } export default function UsersTab() { const [search, setSearch] = useState(''); const [roleFilter, setRoleFilter] = useState(''); const [editUser, setEditUser] = useState(null); const [editRole, setEditRole] = useState('user'); const [editQuota, setEditQuota] = useState(''); const [editOverride, setEditOverride] = useState(false); const [resetPassword, setResetPassword] = useState(''); // Create user dialog state const [showCreateDialog, setShowCreateDialog] = useState(false); const [newUsername, setNewUsername] = useState(''); const [newEmail, setNewEmail] = useState(''); const [newPassword, setNewPassword] = useState(''); const [newRole, setNewRole] = useState('user'); const { data, isLoading } = useAdminUsers({ q: search, role: roleFilter || undefined }); const updateUser = useUpdateUser(); const disableUser = useDisableUser(); const enableUser = useEnableUser(); const createUser = useCreateUser(); const resetPasswordMutation = useResetPassword(); const users: User[] = data?.users || []; const openEdit = (u: User) => { setEditUser(u); setEditRole(u.role); setEditQuota(u.quota?.monthly_usd?.toString() ?? ''); setEditOverride(u.override_quota ?? false); setResetPassword(''); }; const handleCreate = () => { createUser.mutate( { username: newUsername, email: newEmail, password: newPassword, role: newRole }, { onSuccess: () => { setShowCreateDialog(false); setNewUsername(''); setNewEmail(''); setNewPassword(''); setNewRole('user'); }, } ); }; const handleResetPassword = () => { if (!editUser || !resetPassword) return; resetPasswordMutation.mutate({ id: editUser._id, password: resetPassword }, { onSuccess: () => setResetPassword(''), }); }; const handleSave = () => { if (!editUser) return; const payload: any = { role: editRole, override_quota: editOverride }; if (editQuota) { payload.quota = { monthly_usd: parseFloat(editQuota) }; } else { payload.quota = {}; } updateUser.mutate({ id: editUser._id, data: payload }, { onSuccess: () => setEditUser(null), }); }; return (
{/* Filters */}
setSearch(e.target.value)} />
{/* Table */} {isLoading ? (
) : (
User Role Status MTD Cost Monthly Quota Actions {users.length === 0 && ( No users found )} {users.map(u => (
{u.username}
{u.email}
{u.role} {u.override_quota && ( no quota )} {u.is_active === false ? 'Disabled' : 'Active'} ${(u.cost_mtd ?? 0).toFixed(4)} {u.quota?.monthly_usd ? `$${u.quota.monthly_usd}/mo` : '—'}
{u.is_active === false ? ( ) : ( )}
))}
)} {/* Edit Dialog */} !open && setEditUser(null)}> Edit User — {editUser?.username}
setEditQuota(e.target.value)} />
setEditOverride(e.target.checked)} className="h-4 w-4 rounded border-slate-300" />
setResetPassword(e.target.value)} />
{/* Create User Dialog */} !open && setShowCreateDialog(false)}> New User
setNewUsername(e.target.value)} />
setNewEmail(e.target.value)} />
setNewPassword(e.target.value)} />
); }