Implement event feedback functionality: Add EventFeedback model to Prisma schema, enabling users to submit ratings and comments for events. Update EventsPageSection and AdminPanel components to support feedback management, including UI for submitting feedback and viewing existing feedbacks. Refactor registration logic to retrieve all user registrations for improved feedback handling.

This commit is contained in:
Julien Froidefond
2025-12-10 06:11:32 +01:00
parent 44be5d2e98
commit 3bd43e777e
19 changed files with 2818 additions and 33 deletions

View File

@@ -0,0 +1,92 @@
import { NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import { Role } from "@/prisma/generated/prisma/client";
export async function GET() {
try {
const session = await auth();
if (!session?.user?.id) {
return NextResponse.json({ error: "Non authentifié" }, { status: 401 });
}
if (session.user.role !== Role.ADMIN) {
return NextResponse.json({ error: "Accès refusé" }, { status: 403 });
}
// Récupérer tous les feedbacks avec les détails de l'événement et de l'utilisateur
const feedbacks = await prisma.eventFeedback.findMany({
include: {
event: {
select: {
id: true,
name: true,
date: true,
type: true,
},
},
user: {
select: {
id: true,
username: true,
email: true,
},
},
},
orderBy: {
createdAt: "desc",
},
});
// Calculer les statistiques par événement
const eventStats = await prisma.eventFeedback.groupBy({
by: ["eventId"],
_avg: {
rating: true,
},
_count: {
id: true,
},
});
// Récupérer les détails des événements pour les stats
const eventIds = eventStats.map((stat) => stat.eventId);
const events = await prisma.event.findMany({
where: {
id: {
in: eventIds,
},
},
select: {
id: true,
name: true,
date: true,
type: true,
},
});
// Combiner les stats avec les détails des événements
const statsWithDetails = eventStats.map((stat) => {
const event = events.find((e) => e.id === stat.eventId);
return {
eventId: stat.eventId,
eventName: event?.name || "Événement supprimé",
eventDate: event?.date || null,
eventType: event?.type || null,
averageRating: stat._avg.rating || 0,
feedbackCount: stat._count.id,
};
});
return NextResponse.json({
feedbacks,
statistics: statsWithDetails,
});
} catch (error) {
console.error("Error fetching feedbacks:", error);
return NextResponse.json(
{ error: "Erreur lors de la récupération des feedbacks" },
{ status: 500 }
);
}
}

View File

@@ -0,0 +1,31 @@
import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
export async function GET(
request: Request,
{ params }: { params: Promise<{ id: string }> }
) {
try {
const { id } = await params;
const event = await prisma.event.findUnique({
where: { id },
});
if (!event) {
return NextResponse.json(
{ error: "Événement introuvable" },
{ status: 404 }
);
}
return NextResponse.json(event);
} catch (error) {
console.error("Error fetching event:", error);
return NextResponse.json(
{ error: "Erreur lors de la récupération de l'événement" },
{ status: 500 }
);
}
}

View File

@@ -0,0 +1,108 @@
import { NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
export async function POST(
request: Request,
{ params }: { params: Promise<{ eventId: string }> }
) {
try {
const session = await auth();
if (!session?.user?.id) {
return NextResponse.json({ error: "Non authentifié" }, { status: 401 });
}
const { eventId } = await params;
const body = await request.json();
const { rating, comment } = body;
// Valider la note (1-5)
if (!rating || rating < 1 || rating > 5) {
return NextResponse.json(
{ error: "La note doit être entre 1 et 5" },
{ status: 400 }
);
}
// Vérifier que l'événement existe
const event = await prisma.event.findUnique({
where: { id: eventId },
});
if (!event) {
return NextResponse.json(
{ error: "Événement introuvable" },
{ status: 404 }
);
}
// Créer ou mettre à jour le feedback (unique par utilisateur/événement)
const feedback = await prisma.eventFeedback.upsert({
where: {
userId_eventId: {
userId: session.user.id,
eventId,
},
},
update: {
rating,
comment: comment || null,
},
create: {
userId: session.user.id,
eventId,
rating,
comment: comment || null,
},
});
return NextResponse.json({ success: true, feedback });
} catch (error) {
console.error("Error saving feedback:", error);
return NextResponse.json(
{ error: "Erreur lors de l'enregistrement du feedback" },
{ status: 500 }
);
}
}
export async function GET(
request: Request,
{ params }: { params: Promise<{ eventId: string }> }
) {
try {
const session = await auth();
if (!session?.user?.id) {
return NextResponse.json({ error: "Non authentifié" }, { status: 401 });
}
const { eventId } = await params;
// Récupérer le feedback de l'utilisateur pour cet événement
const feedback = await prisma.eventFeedback.findUnique({
where: {
userId_eventId: {
userId: session.user.id,
eventId,
},
},
include: {
event: {
select: {
id: true,
name: true,
date: true,
},
},
},
});
return NextResponse.json({ feedback });
} catch (error) {
console.error("Error fetching feedback:", error);
return NextResponse.json(
{ error: "Erreur lors de la récupération du feedback" },
{ status: 500 }
);
}
}