From 1b07fe8ae5ef789f88424e1cf5ae24469a722c31 Mon Sep 17 00:00:00 2001 From: Julien Froidefond Date: Wed, 10 Dec 2025 05:32:23 +0100 Subject: [PATCH] Refactor event date handling: Update event model to use DateTime type for date fields in Prisma schema. Modify API routes and UI components to ensure consistent date formatting and handling, improving data integrity and user experience across event management and display. --- app/api/admin/events/[id]/route.ts | 13 ++- app/api/admin/events/route.ts | 4 +- app/events/page.tsx | 10 ++- components/EventsPageSection.tsx | 79 +++++++++++++++---- prisma/generated/prisma/internal/class.ts | 4 +- prisma/generated/prisma/models/Event.ts | 38 ++++----- .../migration.sql | 45 +++++++++++ prisma/schema.prisma | 2 +- prisma/seed.ts | 14 ++-- 9 files changed, 160 insertions(+), 49 deletions(-) create mode 100644 prisma/migrations/20251210043000_change_event_date_to_datetime/migration.sql diff --git a/app/api/admin/events/[id]/route.ts b/app/api/admin/events/[id]/route.ts index 881c8e5..edd6864 100644 --- a/app/api/admin/events/[id]/route.ts +++ b/app/api/admin/events/[id]/route.ts @@ -31,7 +31,7 @@ export async function PUT( } const updateData: { - date?: string; + date?: Date; name?: string; description?: string; type?: EventType; @@ -41,7 +41,16 @@ export async function PUT( maxPlaces?: number | null; } = {}; - if (date !== undefined) updateData.date = date; + if (date !== undefined) { + const eventDate = new Date(date); + if (isNaN(eventDate.getTime())) { + return NextResponse.json( + { error: "Format de date invalide" }, + { status: 400 } + ); + } + updateData.date = eventDate; + } if (name !== undefined) updateData.name = name; if (description !== undefined) updateData.description = description; if (type !== undefined) { diff --git a/app/api/admin/events/route.ts b/app/api/admin/events/route.ts index e804f1e..05ae0e0 100644 --- a/app/api/admin/events/route.ts +++ b/app/api/admin/events/route.ts @@ -38,7 +38,7 @@ export async function GET() { // Transformer les données pour inclure le nombre d'inscriptions const eventsWithCount = events.map((event) => ({ id: event.id, - date: event.date, + date: event.date.toISOString(), name: event.name, description: event.description, type: event.type, @@ -96,7 +96,7 @@ export async function POST(request: Request) { const event = await prisma.event.create({ data: { - date, + date: eventDate, name, description, type: type as EventType, diff --git a/app/events/page.tsx b/app/events/page.tsx index 27c3cf2..6a44c79 100644 --- a/app/events/page.tsx +++ b/app/events/page.tsx @@ -11,6 +11,14 @@ export default async function EventsPage() { }, }); + // Sérialiser les dates pour le client + const serializedEvents = events.map((event) => ({ + ...event, + date: event.date.toISOString(), + createdAt: event.createdAt.toISOString(), + updatedAt: event.updatedAt.toISOString(), + })); + const backgroundImage = await getBackgroundImage("events", "/got-2.jpg"); // Récupérer les inscriptions côté serveur pour éviter le clignotement @@ -44,7 +52,7 @@ export default async function EventsPage() {
diff --git a/components/EventsPageSection.tsx b/components/EventsPageSection.tsx index dfa4da0..5d1c581 100644 --- a/components/EventsPageSection.tsx +++ b/components/EventsPageSection.tsx @@ -6,7 +6,7 @@ import { useRouter } from "next/navigation"; interface Event { id: string; - date: string; + date: string | Date; name: string; description: string; type: "SUMMIT" | "LAUNCH" | "FESTIVAL" | "COMPETITION" | "CODE_KATA"; @@ -107,19 +107,39 @@ export default function EventsPageSection({ .filter((e) => e.status === "UPCOMING" || e.status === "LIVE") .sort((a, b) => { // Trier par date décroissante (du plus récent au plus ancien) - return b.date.localeCompare(a.date); + const dateA = typeof a.date === "string" ? new Date(a.date) : a.date; + const dateB = typeof b.date === "string" ? new Date(b.date) : b.date; + return dateB.getTime() - dateA.getTime(); }); const pastEvents = events .filter((e) => e.status === "PAST") .sort((a, b) => { // Trier par date décroissante (du plus récent au plus ancien) - return b.date.localeCompare(a.date); + const dateA = typeof a.date === "string" ? new Date(a.date) : a.date; + const dateB = typeof b.date === "string" ? new Date(b.date) : b.date; + return dateB.getTime() - dateA.getTime(); }); // Créer un map des événements par date pour le calendrier const eventsByDate: Record = {}; events.forEach((event) => { - const dateKey = event.date; // YYYY-MM-DD + // Convertir la date en string YYYY-MM-DD pour le calendrier + let eventDate: Date; + if (typeof event.date === "string") { + eventDate = new Date(event.date); + } else if (event.date instanceof Date) { + eventDate = event.date; + } else { + // Fallback si c'est déjà un objet Date + eventDate = new Date(event.date); + } + + // Utiliser UTC pour éviter les problèmes de fuseau horaire + const year = eventDate.getUTCFullYear(); + const month = String(eventDate.getUTCMonth() + 1).padStart(2, "0"); + const day = String(eventDate.getUTCDate()).padStart(2, "0"); + const dateKey = `${year}-${month}-${day}`; // YYYY-MM-DD + if (!eventsByDate[dateKey]) { eventsByDate[dateKey] = []; } @@ -173,15 +193,17 @@ export default function EventsPageSection({ // Fonctions pour le calendrier const getDaysInMonth = (date: Date) => { - const year = date.getFullYear(); - const month = date.getMonth(); - return new Date(year, month + 1, 0).getDate(); + // Utiliser UTC pour correspondre au format des événements + const year = date.getUTCFullYear(); + const month = date.getUTCMonth(); + return new Date(Date.UTC(year, month + 1, 0)).getUTCDate(); }; const getFirstDayOfMonth = (date: Date) => { - const year = date.getFullYear(); - const month = date.getMonth(); - return new Date(year, month, 1).getDay(); + // Utiliser UTC pour correspondre au format des événements + const year = date.getUTCFullYear(); + const month = date.getUTCMonth(); + return new Date(Date.UTC(year, month, 1)).getUTCDay(); }; const formatMonthYear = (date: Date) => { @@ -206,8 +228,9 @@ export default function EventsPageSection({ days.push(day); } - const year = currentMonth.getFullYear(); - const month = currentMonth.getMonth() + 1; + // Utiliser UTC pour correspondre au format des événements + const year = currentMonth.getUTCFullYear(); + const month = currentMonth.getUTCMonth() + 1; return (
@@ -267,7 +290,13 @@ export default function EventsPageSection({ day ).padStart(2, "0")}`; const dayEvents = eventsByDate[dateKey] || []; - const isToday = new Date().toISOString().split("T")[0] === dateKey; + + // Vérifier si c'est aujourd'hui en utilisant UTC + const today = new Date(); + const todayKey = `${today.getUTCFullYear()}-${String( + today.getUTCMonth() + 1 + ).padStart(2, "0")}-${String(today.getUTCDate()).padStart(2, "0")}`; + const isToday = todayKey === dateKey; const hasEvents = dayEvents.length > 0; // Déterminer la couleur principale selon le type d'événement @@ -374,7 +403,17 @@ export default function EventsPageSection({ {/* Date */}
- {event.date} + {typeof event.date === "string" + ? new Date(event.date).toLocaleDateString("fr-FR", { + day: "numeric", + month: "long", + year: "numeric", + }) + : event.date.toLocaleDateString("fr-FR", { + day: "numeric", + month: "long", + year: "numeric", + })}
{/* Event Name */} @@ -651,7 +690,17 @@ export default function EventsPageSection({ {/* Date */}
- {selectedEvent.date} + {typeof selectedEvent.date === "string" + ? new Date(selectedEvent.date).toLocaleDateString("fr-FR", { + day: "numeric", + month: "long", + year: "numeric", + }) + : selectedEvent.date.toLocaleDateString("fr-FR", { + day: "numeric", + month: "long", + year: "numeric", + })}
{/* Event Details */} diff --git a/prisma/generated/prisma/internal/class.ts b/prisma/generated/prisma/internal/class.ts index 7cd4501..9f0477a 100644 --- a/prisma/generated/prisma/internal/class.ts +++ b/prisma/generated/prisma/internal/class.ts @@ -20,7 +20,7 @@ const config: runtime.GetPrismaClientConfig = { "clientVersion": "7.1.0", "engineVersion": "ab635e6b9d606fa5c8fb8b1a7f909c3c3c1c98ba", "activeProvider": "sqlite", - "inlineSchema": "// This is your Prisma schema file,\n// learn more about it in the docs: https://pris.ly/d/prisma-schema\n\ngenerator client {\n provider = \"prisma-client\"\n output = \"./generated/prisma\"\n}\n\ndatasource db {\n provider = \"sqlite\"\n}\n\nenum Role {\n USER\n ADMIN\n}\n\nenum EventType {\n SUMMIT\n LAUNCH\n FESTIVAL\n COMPETITION\n CODE_KATA\n}\n\nenum EventStatus {\n UPCOMING\n LIVE\n PAST\n}\n\nenum CharacterClass {\n WARRIOR\n MAGE\n ROGUE\n RANGER\n PALADIN\n ENGINEER\n MERCHANT\n SCHOLAR\n BERSERKER\n NECROMANCER\n}\n\nmodel User {\n id String @id @default(cuid())\n email String @unique\n password String\n username String @unique\n role Role @default(USER)\n score Int @default(0)\n level Int @default(1)\n hp Int @default(1000)\n maxHp Int @default(1000)\n xp Int @default(0)\n maxXp Int @default(5000)\n avatar String?\n bio String?\n characterClass CharacterClass?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n preferences UserPreferences?\n eventRegistrations EventRegistration[]\n\n @@index([score])\n @@index([email])\n}\n\nmodel UserPreferences {\n id String @id @default(cuid())\n userId String @unique\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n // Background images for each page\n homeBackground String?\n eventsBackground String?\n leaderboardBackground String?\n\n // Other UI preferences can be added here\n theme String? @default(\"default\")\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Event {\n id String @id @default(cuid())\n date String\n name String\n description String\n type EventType\n status EventStatus\n room String?\n time String?\n maxPlaces Int?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n registrations EventRegistration[]\n\n @@index([status])\n @@index([date])\n}\n\nmodel EventRegistration {\n id String @id @default(cuid())\n userId String\n eventId String\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)\n createdAt DateTime @default(now())\n\n @@unique([userId, eventId])\n @@index([userId])\n @@index([eventId])\n}\n\nmodel SitePreferences {\n id String @id @default(\"global\")\n homeBackground String?\n eventsBackground String?\n leaderboardBackground String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n", + "inlineSchema": "// This is your Prisma schema file,\n// learn more about it in the docs: https://pris.ly/d/prisma-schema\n\ngenerator client {\n provider = \"prisma-client\"\n output = \"./generated/prisma\"\n}\n\ndatasource db {\n provider = \"sqlite\"\n}\n\nenum Role {\n USER\n ADMIN\n}\n\nenum EventType {\n SUMMIT\n LAUNCH\n FESTIVAL\n COMPETITION\n CODE_KATA\n}\n\nenum EventStatus {\n UPCOMING\n LIVE\n PAST\n}\n\nenum CharacterClass {\n WARRIOR\n MAGE\n ROGUE\n RANGER\n PALADIN\n ENGINEER\n MERCHANT\n SCHOLAR\n BERSERKER\n NECROMANCER\n}\n\nmodel User {\n id String @id @default(cuid())\n email String @unique\n password String\n username String @unique\n role Role @default(USER)\n score Int @default(0)\n level Int @default(1)\n hp Int @default(1000)\n maxHp Int @default(1000)\n xp Int @default(0)\n maxXp Int @default(5000)\n avatar String?\n bio String?\n characterClass CharacterClass?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n preferences UserPreferences?\n eventRegistrations EventRegistration[]\n\n @@index([score])\n @@index([email])\n}\n\nmodel UserPreferences {\n id String @id @default(cuid())\n userId String @unique\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n // Background images for each page\n homeBackground String?\n eventsBackground String?\n leaderboardBackground String?\n\n // Other UI preferences can be added here\n theme String? @default(\"default\")\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Event {\n id String @id @default(cuid())\n date DateTime\n name String\n description String\n type EventType\n status EventStatus\n room String?\n time String?\n maxPlaces Int?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n registrations EventRegistration[]\n\n @@index([status])\n @@index([date])\n}\n\nmodel EventRegistration {\n id String @id @default(cuid())\n userId String\n eventId String\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)\n createdAt DateTime @default(now())\n\n @@unique([userId, eventId])\n @@index([userId])\n @@index([eventId])\n}\n\nmodel SitePreferences {\n id String @id @default(\"global\")\n homeBackground String?\n eventsBackground String?\n leaderboardBackground String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n", "runtimeDataModel": { "models": {}, "enums": {}, @@ -28,7 +28,7 @@ const config: runtime.GetPrismaClientConfig = { } } -config.runtimeDataModel = JSON.parse("{\"models\":{\"User\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"password\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"username\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"role\",\"kind\":\"enum\",\"type\":\"Role\"},{\"name\":\"score\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"level\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"hp\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"maxHp\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"xp\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"maxXp\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"avatar\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"bio\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"characterClass\",\"kind\":\"enum\",\"type\":\"CharacterClass\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"preferences\",\"kind\":\"object\",\"type\":\"UserPreferences\",\"relationName\":\"UserToUserPreferences\"},{\"name\":\"eventRegistrations\",\"kind\":\"object\",\"type\":\"EventRegistration\",\"relationName\":\"EventRegistrationToUser\"}],\"dbName\":null},\"UserPreferences\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"UserToUserPreferences\"},{\"name\":\"homeBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"eventsBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"leaderboardBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"theme\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Event\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"date\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"type\",\"kind\":\"enum\",\"type\":\"EventType\"},{\"name\":\"status\",\"kind\":\"enum\",\"type\":\"EventStatus\"},{\"name\":\"room\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"time\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"maxPlaces\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"registrations\",\"kind\":\"object\",\"type\":\"EventRegistration\",\"relationName\":\"EventToEventRegistration\"}],\"dbName\":null},\"EventRegistration\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"eventId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"EventRegistrationToUser\"},{\"name\":\"event\",\"kind\":\"object\",\"type\":\"Event\",\"relationName\":\"EventToEventRegistration\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"SitePreferences\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"homeBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"eventsBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"leaderboardBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null}},\"enums\":{},\"types\":{}}") +config.runtimeDataModel = JSON.parse("{\"models\":{\"User\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"password\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"username\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"role\",\"kind\":\"enum\",\"type\":\"Role\"},{\"name\":\"score\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"level\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"hp\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"maxHp\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"xp\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"maxXp\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"avatar\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"bio\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"characterClass\",\"kind\":\"enum\",\"type\":\"CharacterClass\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"preferences\",\"kind\":\"object\",\"type\":\"UserPreferences\",\"relationName\":\"UserToUserPreferences\"},{\"name\":\"eventRegistrations\",\"kind\":\"object\",\"type\":\"EventRegistration\",\"relationName\":\"EventRegistrationToUser\"}],\"dbName\":null},\"UserPreferences\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"UserToUserPreferences\"},{\"name\":\"homeBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"eventsBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"leaderboardBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"theme\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Event\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"date\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"type\",\"kind\":\"enum\",\"type\":\"EventType\"},{\"name\":\"status\",\"kind\":\"enum\",\"type\":\"EventStatus\"},{\"name\":\"room\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"time\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"maxPlaces\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"registrations\",\"kind\":\"object\",\"type\":\"EventRegistration\",\"relationName\":\"EventToEventRegistration\"}],\"dbName\":null},\"EventRegistration\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"eventId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"EventRegistrationToUser\"},{\"name\":\"event\",\"kind\":\"object\",\"type\":\"Event\",\"relationName\":\"EventToEventRegistration\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"SitePreferences\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"homeBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"eventsBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"leaderboardBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null}},\"enums\":{},\"types\":{}}") async function decodeBase64AsWasm(wasmBase64: string): Promise { const { Buffer } = await import('node:buffer') diff --git a/prisma/generated/prisma/models/Event.ts b/prisma/generated/prisma/models/Event.ts index f4638e9..7614902 100644 --- a/prisma/generated/prisma/models/Event.ts +++ b/prisma/generated/prisma/models/Event.ts @@ -36,7 +36,7 @@ export type EventSumAggregateOutputType = { export type EventMinAggregateOutputType = { id: string | null - date: string | null + date: Date | null name: string | null description: string | null type: $Enums.EventType | null @@ -50,7 +50,7 @@ export type EventMinAggregateOutputType = { export type EventMaxAggregateOutputType = { id: string | null - date: string | null + date: Date | null name: string | null description: string | null type: $Enums.EventType | null @@ -217,7 +217,7 @@ export type EventGroupByArgs | string - date?: Prisma.StringFilter<"Event"> | string + date?: Prisma.DateTimeFilter<"Event"> | Date | string name?: Prisma.StringFilter<"Event"> | string description?: Prisma.StringFilter<"Event"> | string type?: Prisma.EnumEventTypeFilter<"Event"> | $Enums.EventType @@ -287,7 +287,7 @@ export type EventWhereUniqueInput = Prisma.AtLeast<{ AND?: Prisma.EventWhereInput | Prisma.EventWhereInput[] OR?: Prisma.EventWhereInput[] NOT?: Prisma.EventWhereInput | Prisma.EventWhereInput[] - date?: Prisma.StringFilter<"Event"> | string + date?: Prisma.DateTimeFilter<"Event"> | Date | string name?: Prisma.StringFilter<"Event"> | string description?: Prisma.StringFilter<"Event"> | string type?: Prisma.EnumEventTypeFilter<"Event"> | $Enums.EventType @@ -324,7 +324,7 @@ export type EventScalarWhereWithAggregatesInput = { OR?: Prisma.EventScalarWhereWithAggregatesInput[] NOT?: Prisma.EventScalarWhereWithAggregatesInput | Prisma.EventScalarWhereWithAggregatesInput[] id?: Prisma.StringWithAggregatesFilter<"Event"> | string - date?: Prisma.StringWithAggregatesFilter<"Event"> | string + date?: Prisma.DateTimeWithAggregatesFilter<"Event"> | Date | string name?: Prisma.StringWithAggregatesFilter<"Event"> | string description?: Prisma.StringWithAggregatesFilter<"Event"> | string type?: Prisma.EnumEventTypeWithAggregatesFilter<"Event"> | $Enums.EventType @@ -338,7 +338,7 @@ export type EventScalarWhereWithAggregatesInput = { export type EventCreateInput = { id?: string - date: string + date: Date | string name: string description: string type: $Enums.EventType @@ -353,7 +353,7 @@ export type EventCreateInput = { export type EventUncheckedCreateInput = { id?: string - date: string + date: Date | string name: string description: string type: $Enums.EventType @@ -368,7 +368,7 @@ export type EventUncheckedCreateInput = { export type EventUpdateInput = { id?: Prisma.StringFieldUpdateOperationsInput | string - date?: Prisma.StringFieldUpdateOperationsInput | string + date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string name?: Prisma.StringFieldUpdateOperationsInput | string description?: Prisma.StringFieldUpdateOperationsInput | string type?: Prisma.EnumEventTypeFieldUpdateOperationsInput | $Enums.EventType @@ -383,7 +383,7 @@ export type EventUpdateInput = { export type EventUncheckedUpdateInput = { id?: Prisma.StringFieldUpdateOperationsInput | string - date?: Prisma.StringFieldUpdateOperationsInput | string + date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string name?: Prisma.StringFieldUpdateOperationsInput | string description?: Prisma.StringFieldUpdateOperationsInput | string type?: Prisma.EnumEventTypeFieldUpdateOperationsInput | $Enums.EventType @@ -398,7 +398,7 @@ export type EventUncheckedUpdateInput = { export type EventCreateManyInput = { id?: string - date: string + date: Date | string name: string description: string type: $Enums.EventType @@ -412,7 +412,7 @@ export type EventCreateManyInput = { export type EventUpdateManyMutationInput = { id?: Prisma.StringFieldUpdateOperationsInput | string - date?: Prisma.StringFieldUpdateOperationsInput | string + date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string name?: Prisma.StringFieldUpdateOperationsInput | string description?: Prisma.StringFieldUpdateOperationsInput | string type?: Prisma.EnumEventTypeFieldUpdateOperationsInput | $Enums.EventType @@ -426,7 +426,7 @@ export type EventUpdateManyMutationInput = { export type EventUncheckedUpdateManyInput = { id?: Prisma.StringFieldUpdateOperationsInput | string - date?: Prisma.StringFieldUpdateOperationsInput | string + date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string name?: Prisma.StringFieldUpdateOperationsInput | string description?: Prisma.StringFieldUpdateOperationsInput | string type?: Prisma.EnumEventTypeFieldUpdateOperationsInput | $Enums.EventType @@ -525,7 +525,7 @@ export type EventUpdateOneRequiredWithoutRegistrationsNestedInput = { export type EventCreateWithoutRegistrationsInput = { id?: string - date: string + date: Date | string name: string description: string type: $Enums.EventType @@ -539,7 +539,7 @@ export type EventCreateWithoutRegistrationsInput = { export type EventUncheckedCreateWithoutRegistrationsInput = { id?: string - date: string + date: Date | string name: string description: string type: $Enums.EventType @@ -569,7 +569,7 @@ export type EventUpdateToOneWithWhereWithoutRegistrationsInput = { export type EventUpdateWithoutRegistrationsInput = { id?: Prisma.StringFieldUpdateOperationsInput | string - date?: Prisma.StringFieldUpdateOperationsInput | string + date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string name?: Prisma.StringFieldUpdateOperationsInput | string description?: Prisma.StringFieldUpdateOperationsInput | string type?: Prisma.EnumEventTypeFieldUpdateOperationsInput | $Enums.EventType @@ -583,7 +583,7 @@ export type EventUpdateWithoutRegistrationsInput = { export type EventUncheckedUpdateWithoutRegistrationsInput = { id?: Prisma.StringFieldUpdateOperationsInput | string - date?: Prisma.StringFieldUpdateOperationsInput | string + date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string name?: Prisma.StringFieldUpdateOperationsInput | string description?: Prisma.StringFieldUpdateOperationsInput | string type?: Prisma.EnumEventTypeFieldUpdateOperationsInput | $Enums.EventType @@ -699,7 +699,7 @@ export type $EventPayload - readonly date: Prisma.FieldRef<"Event", 'String'> + readonly date: Prisma.FieldRef<"Event", 'DateTime'> readonly name: Prisma.FieldRef<"Event", 'String'> readonly description: Prisma.FieldRef<"Event", 'String'> readonly type: Prisma.FieldRef<"Event", 'EventType'> diff --git a/prisma/migrations/20251210043000_change_event_date_to_datetime/migration.sql b/prisma/migrations/20251210043000_change_event_date_to_datetime/migration.sql new file mode 100644 index 0000000..00c5a31 --- /dev/null +++ b/prisma/migrations/20251210043000_change_event_date_to_datetime/migration.sql @@ -0,0 +1,45 @@ +-- AlterTable +-- SQLite ne supporte pas directement le changement de type, donc on doit recréer la table +-- On convertit les dates string ISO en datetime + +-- Créer une nouvelle table avec le bon type +CREATE TABLE "Event_new" ( + "id" TEXT NOT NULL PRIMARY KEY, + "date" DATETIME NOT NULL, + "name" TEXT NOT NULL, + "description" TEXT NOT NULL, + "type" TEXT NOT NULL, + "status" TEXT NOT NULL, + "room" TEXT, + "time" TEXT, + "maxPlaces" INTEGER, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" DATETIME NOT NULL +); + +-- Copier les données en convertissant les dates string en datetime +INSERT INTO "Event_new" ("id", "date", "name", "description", "type", "status", "room", "time", "maxPlaces", "createdAt", "updatedAt") +SELECT + "id", + datetime("date") as "date", + "name", + "description", + "type", + "status", + "room", + "time", + "maxPlaces", + "createdAt", + "updatedAt" +FROM "Event"; + +-- Supprimer l'ancienne table +DROP TABLE "Event"; + +-- Renommer la nouvelle table +ALTER TABLE "Event_new" RENAME TO "Event"; + +-- Recréer les index +CREATE INDEX "Event_status_idx" ON "Event"("status"); +CREATE INDEX "Event_date_idx" ON "Event"("date"); + diff --git a/prisma/schema.prisma b/prisma/schema.prisma index b476f9f..3b1dee0 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -85,7 +85,7 @@ model UserPreferences { model Event { id String @id @default(cuid()) - date String + date DateTime name String description String type EventType diff --git a/prisma/seed.ts b/prisma/seed.ts index 557ab7d..f74cecf 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -148,7 +148,7 @@ async function main() { // Créer des événements (vérifier s'ils existent déjà) const eventData = [ { - date: "2023-11-18", + date: new Date("2025-11-18"), name: "Sommet de l'Innovation Tech", description: "Rejoignez les leaders de l'industrie et les innovateurs pour une journée de discussions sur les technologies de pointe, les percées de l'IA et des opportunités de networking.", @@ -156,7 +156,7 @@ async function main() { status: EventStatus.PAST, }, { - date: "2023-12-03", + date: new Date("2025-12-03"), name: "Lancement de la Révolution IA", description: "Assistez au lancement de systèmes d'IA révolutionnaires qui vont remodeler le paysage du gaming. Aperçus exclusifs et opportunités d'accès anticipé.", @@ -164,7 +164,7 @@ async function main() { status: EventStatus.PAST, }, { - date: "2023-12-22", + date: new Date("2025-12-22"), name: "Festival du Code d'Hiver", description: "Une célébration de l'excellence en programmation avec des hackathons, des défis de codage et des prix. Montrez vos compétences et rivalisez avec les meilleurs développeurs.", @@ -172,7 +172,7 @@ async function main() { status: EventStatus.PAST, }, { - date: "2024-01-15", + date: new Date("2025-01-15"), name: "Expo Informatique Quantique", description: "Explorez l'avenir de l'informatique quantique dans le gaming. Démonstrations interactives, conférences d'experts et ateliers pratiques pour tous les niveaux.", @@ -180,7 +180,7 @@ async function main() { status: EventStatus.UPCOMING, }, { - date: "2024-02-08", + date: new Date("2025-02-08"), name: "Championnat Cyber Arena", description: "L'événement de gaming compétitif ultime. Compétissez pour la gloire, des récompenses exclusives et le titre de Champion Cyber Arena. Inscriptions ouvertes.", @@ -188,7 +188,7 @@ async function main() { status: EventStatus.UPCOMING, }, { - date: "2024-03-12", + date: new Date("2025-03-12"), name: "Gala Tech du Printemps", description: "Une soirée élégante célébrant les réalisations technologiques. Cérémonie de remise de prix, networking et annonces exclusives des plus grandes entreprises tech.", @@ -196,7 +196,7 @@ async function main() { status: EventStatus.UPCOMING, }, { - date: "2024-12-15", + date: new Date("2025-12-15"), name: "Builder pattern : construction et refactoring", description: "Lors de cet atelier, nous utiliserons le design pattern Builder pour structurer pas à pas la création d'objets complexes… sans transformer notre code en film digne de Red Is Dead.\n\nVous découvrirez comment ce pattern permet de découpler proprement la logique de construction, d'améliorer la lisibilité et de faciliter l'évolution du code — notamment lors de phases de refactoring où les responsabilités se mélangent plus vite que la foule au Palais des Festivals.\n\nL'objectif : poser les fondations pour introduire un vrai modèle, sans rien casser du comportement existant.\n\nQue vous souhaitiez renforcer vos compétences en conception, préparer votre prochain refactoring, ou simplement coder avec plus de style que Serge Karamazov dansant la carioca, venez construire avec nous.",