I see this error with the app, reported by NextJS, please fix it. The er

This commit is contained in:
Indigo Tang 2025-07-06 12:25:32 +00:00
parent 38fccc09b7
commit 861ec9280e
2 changed files with 43 additions and 17 deletions

View File

@ -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<User[]>([]);
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'),
@ -51,6 +70,14 @@ export default function AdminUserManagementPage({ users }: { users: User[] }) {
setIsDeleting(false);
};
if (isLoading) {
return (
<div className="flex justify-center items-center h-64">
<Loader2 className="h-12 w-12 animate-spin text-primary" />
</div>
);
}
return (
<div className="space-y-8">
<div className="flex justify-between items-center">
@ -71,7 +98,7 @@ export default function AdminUserManagementPage({ users }: { users: User[] }) {
<CardTitle className="text-xl font-headline">{t('admin.users.title')}</CardTitle>
</CardHeader>
<CardContent>
{allUsers.length > 0 ? (
{users.length > 0 ? (
<Table>
<TableHeader>
<TableRow>
@ -82,7 +109,7 @@ export default function AdminUserManagementPage({ users }: { users: User[] }) {
</TableRow>
</TableHeader>
<TableBody>
{allUsers.map((user) => (
{users.map((user) => (
<TableRow key={user.id}>
<TableCell className="font-medium">{user.name}</TableCell>
<TableCell>{user.email}</TableCell>
@ -133,9 +160,3 @@ export default function AdminUserManagementPage({ users }: { users: User[] }) {
</div>
);
}
// Wrapper component to fetch data on the server and pass to the client component
export default function AdminUserManagementPageWrapper() {
const users = getAllUsers();
return <AdminUserManagementPage users={users} />;
}

View File

@ -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<DeleteUserResult> {
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<User[]> {
return dbGetAllUsers();
}