diff --git a/src/app/[locale]/admin/users/page.tsx b/src/app/[locale]/admin/users/page.tsx index 109409c..3ff938a 100644 --- a/src/app/[locale]/admin/users/page.tsx +++ b/src/app/[locale]/admin/users/page.tsx @@ -1,14 +1,13 @@ 'use client'; -import { useState } from 'react'; +import { useState, useEffect } from 'react'; import { useRouter } from 'next/navigation'; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; -import { getAllUsers } from "@/data/operations"; import { useI18n, useCurrentLocale } from "@/locales/client"; -import { UserCog, Trash2, PlusCircle } from "lucide-react"; +import { UserCog, Trash2, PlusCircle, Loader2 } from "lucide-react"; import Link from "next/link"; import { AlertDialog, @@ -23,24 +22,44 @@ import { } from "@/components/ui/alert-dialog"; import type { User } from '@/types'; import { useToast } from '@/hooks/use-toast'; -import { deleteUser } from '@/app/actions/user'; +import { deleteUser, getUsers } from '@/app/actions/user'; -export default function AdminUserManagementPage({ users }: { users: User[] }) { +export default function AdminUserManagementPage() { const t = useI18n(); const locale = useCurrentLocale(); const router = useRouter(); const { toast } = useToast(); + + const [users, setUsers] = useState([]); + const [isLoading, setIsLoading] = useState(true); const [isDeleting, setIsDeleting] = useState(false); - // We receive users as a prop after fetching them in a wrapper component. - const allUsers = users.sort((a, b) => a.name.localeCompare(b.name)); + useEffect(() => { + const fetchUsers = async () => { + try { + const fetchedUsers = await getUsers(); + setUsers(fetchedUsers.sort((a, b) => a.name.localeCompare(b.name))); + } catch (error) { + toast({ + title: t('admin.users.toast_error_title'), + description: "Failed to load user data.", + variant: "destructive", + }); + } finally { + setIsLoading(false); + } + }; + fetchUsers(); + }, [t, toast]); + const handleDeleteUser = async (userId: string) => { setIsDeleting(true); const result = await deleteUser(userId); if (result.success) { toast({ title: t('admin.users.user_deleted_toast') }); - // The page will re-render due to revalidation, no need for router.refresh() + const updatedUsers = await getUsers(); + setUsers(updatedUsers.sort((a, b) => a.name.localeCompare(b.name))); } else { toast({ title: t('admin.users.toast_error_title'), @@ -50,6 +69,14 @@ export default function AdminUserManagementPage({ users }: { users: User[] }) { } setIsDeleting(false); }; + + if (isLoading) { + return ( +
+ +
+ ); + } return (
@@ -71,7 +98,7 @@ export default function AdminUserManagementPage({ users }: { users: User[] }) { {t('admin.users.title')} - {allUsers.length > 0 ? ( + {users.length > 0 ? ( @@ -82,7 +109,7 @@ export default function AdminUserManagementPage({ users }: { users: User[] }) { - {allUsers.map((user) => ( + {users.map((user) => ( {user.name} {user.email} @@ -133,9 +160,3 @@ export default function AdminUserManagementPage({ users }: { users: User[] }) { ); } - -// Wrapper component to fetch data on the server and pass to the client component -export default function AdminUserManagementPageWrapper() { - const users = getAllUsers(); - return ; -} diff --git a/src/app/actions/user.ts b/src/app/actions/user.ts index 571a002..e2465a3 100644 --- a/src/app/actions/user.ts +++ b/src/app/actions/user.ts @@ -5,6 +5,7 @@ import db from '@/lib/db'; import type { User } from '@/types'; import { randomUUID } from 'crypto'; import { revalidatePath } from 'next/cache'; +import { getAllUsers as dbGetAllUsers, getUserById } from '@/data/operations'; interface RegisterUserResult { success: boolean; @@ -114,9 +115,13 @@ export async function deleteUser(id: string): Promise { return { success: true, message: 'User deleted successfully.' }; } catch (error) { console.error('Delete user error:', error); - if (error.code === 'SQLITE_CONSTRAINT_FOREIGNKEY') { + if ((error as any).code === 'SQLITE_CONSTRAINT_FOREIGNKEY') { return { success: false, message: 'Cannot delete user. They still have toys listed in the system.' }; } return { success: false, message: 'An unexpected error occurred during deletion.' }; } } + +export async function getUsers(): Promise { + return dbGetAllUsers(); +}