From 88d377e7b28094762b72d89d4c6b026be2dce1d8 Mon Sep 17 00:00:00 2001 From: Julien Froidefond Date: Wed, 10 Dec 2025 05:55:52 +0100 Subject: [PATCH] Add user deletion functionality: Implement DELETE API endpoint for user management, allowing admins to remove users while preventing self-deletion. Enhance UserManagement component with delete confirmation and error handling for improved user experience. --- app/api/admin/users/[id]/route.ts | 48 ++++++++++++ app/api/events/[id]/register/route.ts | 4 +- components/UserManagement.tsx | 108 +++++++++++++++++++++----- 3 files changed, 139 insertions(+), 21 deletions(-) diff --git a/app/api/admin/users/[id]/route.ts b/app/api/admin/users/[id]/route.ts index 6233d0b..9ea5010 100644 --- a/app/api/admin/users/[id]/route.ts +++ b/app/api/admin/users/[id]/route.ts @@ -149,3 +149,51 @@ export async function PUT( } } +export async function DELETE( + request: Request, + { params }: { params: Promise<{ id: string }> } +) { + try { + const session = await auth(); + + if (!session?.user || session.user.role !== Role.ADMIN) { + return NextResponse.json({ error: "Accès refusé" }, { status: 403 }); + } + + const { id } = await params; + + // Vérifier que l'utilisateur existe + const user = await prisma.user.findUnique({ + where: { id }, + }); + + if (!user) { + return NextResponse.json( + { error: "Utilisateur non trouvé" }, + { status: 404 } + ); + } + + // Empêcher la suppression de soi-même + if (user.id === session.user.id) { + return NextResponse.json( + { error: "Vous ne pouvez pas supprimer votre propre compte" }, + { status: 400 } + ); + } + + // Supprimer l'utilisateur (les relations seront supprimées en cascade) + await prisma.user.delete({ + where: { id }, + }); + + return NextResponse.json({ success: true }); + } catch (error) { + console.error("Error deleting user:", error); + return NextResponse.json( + { error: "Erreur lors de la suppression de l'utilisateur" }, + { status: 500 } + ); + } +} + diff --git a/app/api/events/[id]/register/route.ts b/app/api/events/[id]/register/route.ts index 0e76f95..8ce4195 100644 --- a/app/api/events/[id]/register/route.ts +++ b/app/api/events/[id]/register/route.ts @@ -1,6 +1,7 @@ import { NextResponse } from "next/server"; import { auth } from "@/lib/auth"; import { prisma } from "@/lib/prisma"; +import { calculateEventStatus } from "@/lib/eventStatus"; export async function POST( request: Request, @@ -30,7 +31,8 @@ export async function POST( ); } - if (event.status !== "UPCOMING") { + const eventStatus = calculateEventStatus(event.date); + if (eventStatus !== "UPCOMING") { return NextResponse.json( { error: "Vous ne pouvez vous inscrire qu'aux événements à venir" }, { status: 400 } diff --git a/components/UserManagement.tsx b/components/UserManagement.tsx index 547c437..4cce8a2 100644 --- a/components/UserManagement.tsx +++ b/components/UserManagement.tsx @@ -31,6 +31,7 @@ export default function UserManagement() { const [loading, setLoading] = useState(true); const [editingUser, setEditingUser] = useState(null); const [saving, setSaving] = useState(false); + const [deletingUserId, setDeletingUserId] = useState(null); useEffect(() => { fetchUsers(); @@ -117,14 +118,41 @@ export default function UserManagement() { setEditingUser(null); }; + const handleDelete = async (userId: string) => { + if ( + !confirm( + "Êtes-vous sûr de vouloir supprimer cet utilisateur ? Cette action est irréversible." + ) + ) { + return; + } + + setDeletingUserId(userId); + try { + const response = await fetch(`/api/admin/users/${userId}`, { + method: "DELETE", + }); + + if (response.ok) { + await fetchUsers(); + } else { + const error = await response.json(); + alert(error.error || "Erreur lors de la suppression"); + } + } catch (error) { + console.error("Error deleting user:", error); + alert("Erreur lors de la suppression"); + } finally { + setDeletingUserId(null); + } + }; + const formatNumber = (num: number) => { return num.toLocaleString("en-US"); }; if (loading) { - return ( -
Chargement...
- ); + return
Chargement...
; } return ( @@ -159,11 +187,17 @@ export default function UserManagement() { className="w-full h-full object-cover" onError={(e) => { e.currentTarget.style.display = "none"; - e.currentTarget.nextElementSibling?.classList.remove("hidden"); + e.currentTarget.nextElementSibling?.classList.remove( + "hidden" + ); }} /> ) : null} -
+
{user.username.charAt(0).toUpperCase()}
@@ -172,22 +206,45 @@ export default function UserManagement() {

{user.username}

- Niveau {user.level} - Score: {formatNumber(user.score)} - + + Niveau {user.level} + + + Score: {formatNumber(user.score)} + + {user.role} -

{user.email}

+

+ {user.email} +

{!isEditing && ( - +
+ + +
)} @@ -264,7 +321,10 @@ export default function UserManagement() {
@@ -341,7 +401,10 @@ export default function UserManagement() {
@@ -522,7 +585,10 @@ export default function UserManagement() {
@@ -538,7 +604,10 @@ export default function UserManagement() {
@@ -552,4 +621,3 @@ export default function UserManagement() { ); } -