'use client'; import { useState, useCallback } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; import { AdminUsersTemplate } from '@/templates/AdminUsersTemplate'; import { AdminUsersViewData } from '@/lib/view-data/AdminUsersViewData'; import { updateUserStatus, deleteUser } from '@/app/actions/adminActions'; import { routes } from '@/lib/routing/RouteConfig'; import { ConfirmDialog } from '@/ui/ConfirmDialog'; interface AdminUsersWrapperProps { initialViewData: AdminUsersViewData; } export function AdminUsersWrapper({ initialViewData }: AdminUsersWrapperProps) { const router = useRouter(); const searchParams = useSearchParams(); // UI state (not business logic) const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [deletingUser, setDeletingUser] = useState(null); const [userToDelete, setUserToDelete] = useState(null); const [selectedUserIds, setSelectedUserIds] = useState([]); // Current filter values from URL const search = searchParams.get('search') || ''; const roleFilter = searchParams.get('role') || ''; const statusFilter = searchParams.get('status') || ''; // Selection handlers const handleSelectUser = useCallback((userId: string) => { setSelectedUserIds(prev => prev.includes(userId) ? prev.filter(id => id !== userId) : [...prev, userId] ); }, []); const handleSelectAll = useCallback(() => { if (selectedUserIds.length === initialViewData.users.length) { setSelectedUserIds([]); } else { setSelectedUserIds(initialViewData.users.map(u => u.id)); } }, [selectedUserIds.length, initialViewData.users]); const handleClearSelection = useCallback(() => { setSelectedUserIds([]); }, []); // Callbacks that update URL (triggers RSC re-render) const handleSearch = useCallback((newSearch: string) => { const params = new URLSearchParams(searchParams); if (newSearch) params.set('search', newSearch); else params.delete('search'); params.delete('page'); // Reset to page 1 router.push(`${routes.admin.users}?${params.toString()}`); }, [router, searchParams]); const handleFilterRole = useCallback((role: string) => { const params = new URLSearchParams(searchParams); if (role) params.set('role', role); else params.delete('role'); params.delete('page'); router.push(`${routes.admin.users}?${params.toString()}`); }, [router, searchParams]); const handleFilterStatus = useCallback((status: string) => { const params = new URLSearchParams(searchParams); if (status) params.set('status', status); else params.delete('status'); params.delete('page'); router.push(`${routes.admin.users}?${params.toString()}`); }, [router, searchParams]); const handleClearFilters = useCallback(() => { router.push(routes.admin.users); }, [router]); const handleRefresh = useCallback(() => { router.refresh(); }, [router]); // Mutation callbacks (call Server Actions) const handleUpdateStatus = useCallback(async (userId: string, newStatus: string) => { try { setLoading(true); const result = await updateUserStatus(userId, newStatus); if (result.isErr()) { setError(result.getError()); return; } // Revalidate data router.refresh(); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to update status'); } finally { setLoading(false); } }, [router]); const handleDeleteUser = useCallback(async (userId: string) => { setUserToDelete(userId); }, []); const confirmDeleteUser = useCallback(async () => { if (!userToDelete) return; try { setDeletingUser(userToDelete); setError(null); const result = await deleteUser(userToDelete); if (result.isErr()) { setError(result.getError()); return; } // Revalidate data router.refresh(); setUserToDelete(null); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to delete user'); } finally { setDeletingUser(null); } }, [router, userToDelete]); return ( <> setUserToDelete(null)} onConfirm={confirmDeleteUser} title="Delete User" description="Are you sure you want to delete this user? This action cannot be undone and will permanently remove the user's access." confirmLabel="Delete User" variant="danger" isLoading={!!deletingUser} /> ); }