Compare commits

...

2 Commits

2 changed files with 63 additions and 6 deletions

View File

@@ -2,6 +2,7 @@ import NavigationWrapper from "@/components/NavigationWrapper";
import EventsPageSection from "@/components/EventsPageSection";
import { prisma } from "@/lib/prisma";
import { getBackgroundImage } from "@/lib/preferences";
import { auth } from "@/lib/auth";
export default async function EventsPage() {
const events = await prisma.event.findMany({
@@ -12,10 +13,41 @@ export default async function EventsPage() {
const backgroundImage = await getBackgroundImage("events", "/got-2.jpg");
// Récupérer les inscriptions côté serveur pour éviter le clignotement
const session = await auth();
const initialRegistrations: Record<string, boolean> = {};
if (session?.user?.id) {
const upcomingEvents = events.filter((e) => e.status === "UPCOMING");
const eventIds = upcomingEvents.map((e) => e.id);
if (eventIds.length > 0) {
const registrations = await prisma.eventRegistration.findMany({
where: {
userId: session.user.id,
eventId: {
in: eventIds,
},
},
select: {
eventId: true,
},
});
registrations.forEach((reg) => {
initialRegistrations[reg.eventId] = true;
});
}
}
return (
<main className="min-h-screen bg-black relative">
<NavigationWrapper />
<EventsPageSection events={events} backgroundImage={backgroundImage} />
<EventsPageSection
events={events}
backgroundImage={backgroundImage}
initialRegistrations={initialRegistrations}
/>
</main>
);
}

View File

@@ -1,6 +1,6 @@
"use client";
import { useState, useEffect } from "react";
import { useState, useEffect, useMemo, useRef } from "react";
import { useSession } from "next-auth/react";
import { useRouter } from "next/navigation";
@@ -16,6 +16,7 @@ interface Event {
interface EventsPageSectionProps {
events: Event[];
backgroundImage: string;
initialRegistrations?: Record<string, boolean>;
}
const getEventTypeColor = (type: Event["type"]) => {
@@ -74,16 +75,25 @@ const getStatusBadge = (status: Event["status"]) => {
export default function EventsPageSection({
events,
backgroundImage,
initialRegistrations = {},
}: EventsPageSectionProps) {
const { data: session } = useSession();
const router = useRouter();
const [registrations, setRegistrations] = useState<Record<string, boolean>>(
{}
);
const [registrations, setRegistrations] =
useState<Record<string, boolean>>(initialRegistrations);
const [loading, setLoading] = useState<Record<string, boolean>>({});
const [error, setError] = useState<string>("");
const [currentMonth, setCurrentMonth] = useState(new Date());
// Déterminer si on a des données initiales valides
const hasInitialData = useMemo(
() => Object.keys(initialRegistrations).length > 0,
[initialRegistrations]
);
// Ref pour tracker si on a déjà utilisé les données initiales
const hasUsedInitialData = useRef(hasInitialData);
// Séparer et trier les événements (du plus récent au plus ancien)
const upcomingEvents = events
.filter((e) => e.status === "UPCOMING" || e.status === "LIVE")
@@ -108,12 +118,27 @@ export default function EventsPageSection({
eventsByDate[dateKey].push(event);
});
// Vérifier les inscriptions au chargement
// Mettre à jour le ref quand on a des données initiales
useEffect(() => {
if (hasInitialData) {
hasUsedInitialData.current = true;
}
}, [hasInitialData]);
// Ne charger depuis l'API que si on n'a pas de données initiales
// (cas où l'utilisateur se connecte après le chargement de la page)
useEffect(() => {
// Si on a déjà des données initiales, ne jamais charger depuis l'API
if (hasUsedInitialData.current) {
return;
}
// Si pas de session, ne rien faire (on garde les données vides)
if (!session?.user?.id) {
return;
}
// Charger les inscriptions depuis l'API seulement si on n'a pas de données initiales
const checkRegistrations = async () => {
const upcomingOnlyEvents = events.filter((e) => e.status === "UPCOMING");
const registrationChecks = upcomingOnlyEvents.map(async (event) => {