import React, { useState, useEffect } from 'react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import * as z from 'zod'; import { api } from '../api'; import { toast } from 'sonner'; import { createColumnHelper, flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table'; import { format } from 'date-fns'; import { Button } from '../components/ui/button'; import { Dialog } from '../components/ui/dialog'; import { Input } from '../components/ui/input'; import { Loader2, AlertTriangle, UserPlus, Pencil, Trash2 } from 'lucide-react'; import { cn } from '../lib/utils'; const userSchema = z.object({ fullName: z.string().min(2, 'Full name is required'), email: z.string().email('Invalid email address'), role: z.enum(['admin', 'moderator']), }); type UserFormData = z.infer; type User = UserFormData & { created_at: string }; const columnHelper = createColumnHelper(); const UserForm = ({ user, onClose }: { user: User | null; onClose: () => void }) => { const queryClient = useQueryClient(); const isEditing = !!user; const { register, handleSubmit, formState: { errors }, reset } = useForm({ resolver: zodResolver(userSchema), defaultValues: user ? { fullName: user.fullName, email: user.email, role: user.role } : { role: 'moderator' }, }); const mutation = useMutation({ mutationFn: (data: UserFormData) => { return isEditing ? api.put(`/api/admin/users/${user.email}`, data) : api.post('/api/admin/users', data); }, onSuccess: () => { toast.success(isEditing ? 'User updated successfully' : 'User created successfully'); queryClient.invalidateQueries({ queryKey: ['adminUsers'] }); onClose(); }, onError: (error: any) => { toast.error(error.response?.data?.error || 'An error occurred'); } }); useEffect(() => { reset(user ? { fullName: user.fullName, email: user.email, role: user.role } : { role: 'moderator' }); }, [user, reset]); const onSubmit = (data: UserFormData) => mutation.mutate(data); return (
{errors.fullName &&

{errors.fullName.message}

}
{errors.email &&

{errors.email.message}

}
{errors.role &&

{errors.role.message}

}
); }; const UserManagementPage = () => { const [isFormOpen, setIsFormOpen] = useState(false); const [isDeleteConfirmOpen, setIsDeleteConfirmOpen] = useState(false); const [selectedUser, setSelectedUser] = useState(null); const queryClient = useQueryClient(); const { data: users, isLoading, isError } = useQuery({ queryKey: ['adminUsers'], queryFn: async () => { const res = await api.get('/api/admin/users'); return res.data; }, }); const deleteMutation = useMutation({ mutationFn: (email: string) => api.delete(`/api/admin/users/${email}`), onSuccess: () => { toast.success('User deleted successfully'); queryClient.invalidateQueries({ queryKey: ['adminUsers'] }); setIsDeleteConfirmOpen(false); setSelectedUser(null); }, onError: (error: any) => { toast.error(error.response?.data?.error || 'Failed to delete user'); } }); const columns = [ columnHelper.accessor('fullName', { header: 'User', cell: info => (
{info.getValue()} {info.row.original.email}
) }), columnHelper.accessor('role', { header: 'Role', cell: info => {info.getValue()}, }), columnHelper.accessor('created_at', { header: 'Created', cell: info => {format(new Date(info.getValue()), 'MMM d, yyyy')}, }), columnHelper.accessor('email', { header: 'Actions', id: 'actions', cell: ({ row }) => (
), }), ]; const table = useReactTable({ data: users || [], columns, getCoreRowModel: getCoreRowModel() }); return (
{ setIsFormOpen(false); setSelectedUser(null); }} title={selectedUser ? 'Edit User' : 'Create New User'} showCloseButton={false} > { setIsFormOpen(false); setSelectedUser(null); }} /> { setIsDeleteConfirmOpen(false); setSelectedUser(null); }} title="Confirm Deletion" description={`Are you sure you want to delete the user ${selectedUser?.email}? This action cannot be undone.`} confirmText="Yes, Delete User" onConfirm={() => selectedUser && deleteMutation.mutate(selectedUser.email)} />

User Management

{isLoading ? (
) : isError ? (
Failed to load users.
) : ( {table.getHeaderGroups().map(headerGroup => ( {headerGroup.headers.map(header => ( ))} ))} {table.getRowModel().rows.map(row => ( {row.getVisibleCells().map(cell => ( ))} ))}
{flexRender(header.column.columnDef.header, header.getContext())}
{flexRender(cell.column.columnDef.cell, cell.getContext())}
)}
); }; export default UserManagementPage;