Implement event registration functionality: Add EventRegistration model to Prisma schema, enabling user event registrations. Enhance EventsPageSection component with registration checks, calendar view, and improved event display. Refactor event rendering logic to separate upcoming and past events, improving user experience.

This commit is contained in:
Julien Froidefond
2025-12-09 21:53:10 +01:00
parent 5ae6cde14e
commit 50a2eaf109
13 changed files with 2483 additions and 61 deletions

View File

@@ -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}\n\nenum EventStatus {\n UPCOMING\n LIVE\n PAST\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 createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n preferences UserPreferences?\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 createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([status])\n @@index([date])\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}\n\nenum EventStatus {\n UPCOMING\n LIVE\n PAST\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 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 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\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"preferences\",\"kind\":\"object\",\"type\":\"UserPreferences\",\"relationName\":\"UserToUserPreferences\"}],\"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\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"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\":\"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\":\"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<WebAssembly.Module> {
const { Buffer } = await import('node:buffer')
@@ -204,6 +204,16 @@ export interface PrismaClient<
*/
get event(): Prisma.EventDelegate<ExtArgs, { omit: OmitOpts }>;
/**
* `prisma.eventRegistration`: Exposes CRUD operations for the **EventRegistration** model.
* Example usage:
* ```ts
* // Fetch zero or more EventRegistrations
* const eventRegistrations = await prisma.eventRegistration.findMany()
* ```
*/
get eventRegistration(): Prisma.EventRegistrationDelegate<ExtArgs, { omit: OmitOpts }>;
/**
* `prisma.sitePreferences`: Exposes CRUD operations for the **SitePreferences** model.
* Example usage:

View File

@@ -387,6 +387,7 @@ export const ModelName = {
User: 'User',
UserPreferences: 'UserPreferences',
Event: 'Event',
EventRegistration: 'EventRegistration',
SitePreferences: 'SitePreferences'
} as const
@@ -403,7 +404,7 @@ export type TypeMap<ExtArgs extends runtime.Types.Extensions.InternalArgs = runt
omit: GlobalOmitOptions
}
meta: {
modelProps: "user" | "userPreferences" | "event" | "sitePreferences"
modelProps: "user" | "userPreferences" | "event" | "eventRegistration" | "sitePreferences"
txIsolationLevel: TransactionIsolationLevel
}
model: {
@@ -629,6 +630,80 @@ export type TypeMap<ExtArgs extends runtime.Types.Extensions.InternalArgs = runt
}
}
}
EventRegistration: {
payload: Prisma.$EventRegistrationPayload<ExtArgs>
fields: Prisma.EventRegistrationFieldRefs
operations: {
findUnique: {
args: Prisma.EventRegistrationFindUniqueArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$EventRegistrationPayload> | null
}
findUniqueOrThrow: {
args: Prisma.EventRegistrationFindUniqueOrThrowArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$EventRegistrationPayload>
}
findFirst: {
args: Prisma.EventRegistrationFindFirstArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$EventRegistrationPayload> | null
}
findFirstOrThrow: {
args: Prisma.EventRegistrationFindFirstOrThrowArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$EventRegistrationPayload>
}
findMany: {
args: Prisma.EventRegistrationFindManyArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$EventRegistrationPayload>[]
}
create: {
args: Prisma.EventRegistrationCreateArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$EventRegistrationPayload>
}
createMany: {
args: Prisma.EventRegistrationCreateManyArgs<ExtArgs>
result: BatchPayload
}
createManyAndReturn: {
args: Prisma.EventRegistrationCreateManyAndReturnArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$EventRegistrationPayload>[]
}
delete: {
args: Prisma.EventRegistrationDeleteArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$EventRegistrationPayload>
}
update: {
args: Prisma.EventRegistrationUpdateArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$EventRegistrationPayload>
}
deleteMany: {
args: Prisma.EventRegistrationDeleteManyArgs<ExtArgs>
result: BatchPayload
}
updateMany: {
args: Prisma.EventRegistrationUpdateManyArgs<ExtArgs>
result: BatchPayload
}
updateManyAndReturn: {
args: Prisma.EventRegistrationUpdateManyAndReturnArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$EventRegistrationPayload>[]
}
upsert: {
args: Prisma.EventRegistrationUpsertArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$EventRegistrationPayload>
}
aggregate: {
args: Prisma.EventRegistrationAggregateArgs<ExtArgs>
result: runtime.Types.Utils.Optional<Prisma.AggregateEventRegistration>
}
groupBy: {
args: Prisma.EventRegistrationGroupByArgs<ExtArgs>
result: runtime.Types.Utils.Optional<Prisma.EventRegistrationGroupByOutputType>[]
}
count: {
args: Prisma.EventRegistrationCountArgs<ExtArgs>
result: runtime.Types.Utils.Optional<Prisma.EventRegistrationCountAggregateOutputType> | number
}
}
}
SitePreferences: {
payload: Prisma.$SitePreferencesPayload<ExtArgs>
fields: Prisma.SitePreferencesFieldRefs
@@ -787,6 +862,16 @@ export const EventScalarFieldEnum = {
export type EventScalarFieldEnum = (typeof EventScalarFieldEnum)[keyof typeof EventScalarFieldEnum]
export const EventRegistrationScalarFieldEnum = {
id: 'id',
userId: 'userId',
eventId: 'eventId',
createdAt: 'createdAt'
} as const
export type EventRegistrationScalarFieldEnum = (typeof EventRegistrationScalarFieldEnum)[keyof typeof EventRegistrationScalarFieldEnum]
export const SitePreferencesScalarFieldEnum = {
id: 'id',
homeBackground: 'homeBackground',
@@ -967,6 +1052,7 @@ export type GlobalOmitConfig = {
user?: Prisma.UserOmit
userPreferences?: Prisma.UserPreferencesOmit
event?: Prisma.EventOmit
eventRegistration?: Prisma.EventRegistrationOmit
sitePreferences?: Prisma.SitePreferencesOmit
}

View File

@@ -54,6 +54,7 @@ export const ModelName = {
User: 'User',
UserPreferences: 'UserPreferences',
Event: 'Event',
EventRegistration: 'EventRegistration',
SitePreferences: 'SitePreferences'
} as const
@@ -118,6 +119,16 @@ export const EventScalarFieldEnum = {
export type EventScalarFieldEnum = (typeof EventScalarFieldEnum)[keyof typeof EventScalarFieldEnum]
export const EventRegistrationScalarFieldEnum = {
id: 'id',
userId: 'userId',
eventId: 'eventId',
createdAt: 'createdAt'
} as const
export type EventRegistrationScalarFieldEnum = (typeof EventRegistrationScalarFieldEnum)[keyof typeof EventRegistrationScalarFieldEnum]
export const SitePreferencesScalarFieldEnum = {
id: 'id',
homeBackground: 'homeBackground',