diff --git a/actions/admin/preferences.ts b/actions/admin/preferences.ts
index b41add5..0dd64f5 100644
--- a/actions/admin/preferences.ts
+++ b/actions/admin/preferences.ts
@@ -20,6 +20,8 @@ export async function updateSitePreferences(data: {
eventsBackground?: string | null;
leaderboardBackground?: string | null;
challengesBackground?: string | null;
+ eventRegistrationPoints?: number;
+ eventFeedbackPoints?: number;
}) {
try {
await checkAdminAccess()();
@@ -29,6 +31,8 @@ export async function updateSitePreferences(data: {
eventsBackground: data.eventsBackground,
leaderboardBackground: data.leaderboardBackground,
challengesBackground: data.challengesBackground,
+ eventRegistrationPoints: data.eventRegistrationPoints,
+ eventFeedbackPoints: data.eventFeedbackPoints,
});
revalidatePath("/admin");
diff --git a/app/feedback/[eventId]/FeedbackPageClient.tsx b/app/feedback/[eventId]/FeedbackPageClient.tsx
index aec711c..d4069ff 100644
--- a/app/feedback/[eventId]/FeedbackPageClient.tsx
+++ b/app/feedback/[eventId]/FeedbackPageClient.tsx
@@ -128,6 +128,9 @@ export default function FeedbackPageClient({
});
}
+ // Rafraîchir le score dans le header
+ window.dispatchEvent(new Event("refreshUserScore"));
+
// Rediriger après 2 secondes
setTimeout(() => {
router.push("/events");
diff --git a/components/admin/AdminPanel.tsx b/components/admin/AdminPanel.tsx
index 72e597c..4f585dc 100644
--- a/components/admin/AdminPanel.tsx
+++ b/components/admin/AdminPanel.tsx
@@ -6,6 +6,8 @@ import EventManagement from "@/components/admin/EventManagement";
import FeedbackManagement from "@/components/admin/FeedbackManagement";
import ChallengeManagement from "@/components/admin/ChallengeManagement";
import BackgroundPreferences from "@/components/admin/BackgroundPreferences";
+import EventPointsPreferences from "@/components/admin/EventPointsPreferences";
+import EventFeedbackPointsPreferences from "@/components/admin/EventFeedbackPointsPreferences";
import { Button, Card, SectionTitle } from "@/components/ui";
interface SitePreferences {
@@ -14,6 +16,8 @@ interface SitePreferences {
eventsBackground: string | null;
leaderboardBackground: string | null;
challengesBackground: string | null;
+ eventRegistrationPoints: number;
+ eventFeedbackPoints: number;
}
interface AdminPanelProps {
@@ -93,6 +97,8 @@ export default function AdminPanel({ initialPreferences }: AdminPanelProps) {
+
+
)}
diff --git a/components/admin/BackgroundPreferences.tsx b/components/admin/BackgroundPreferences.tsx
index 6cf1b9a..bb56c11 100644
--- a/components/admin/BackgroundPreferences.tsx
+++ b/components/admin/BackgroundPreferences.tsx
@@ -11,6 +11,7 @@ interface SitePreferences {
eventsBackground: string | null;
leaderboardBackground: string | null;
challengesBackground: string | null;
+ eventRegistrationPoints?: number;
}
interface BackgroundPreferencesProps {
diff --git a/components/admin/EventFeedbackPointsPreferences.tsx b/components/admin/EventFeedbackPointsPreferences.tsx
new file mode 100644
index 0000000..08c8722
--- /dev/null
+++ b/components/admin/EventFeedbackPointsPreferences.tsx
@@ -0,0 +1,166 @@
+"use client";
+
+import { useState, useEffect } from "react";
+import { updateSitePreferences } from "@/actions/admin/preferences";
+import { Button, Card, Input } from "@/components/ui";
+
+interface SitePreferences {
+ id: string;
+ eventFeedbackPoints: number;
+}
+
+interface EventFeedbackPointsPreferencesProps {
+ initialPreferences: SitePreferences;
+}
+
+export default function EventFeedbackPointsPreferences({
+ initialPreferences,
+}: EventFeedbackPointsPreferencesProps) {
+ const [preferences, setPreferences] = useState(
+ initialPreferences
+ );
+ const [isEditing, setIsEditing] = useState(false);
+ const [formData, setFormData] = useState({
+ eventFeedbackPoints: initialPreferences.eventFeedbackPoints.toString(),
+ });
+ const [isSaving, setIsSaving] = useState(false);
+
+ // Synchroniser les préférences quand initialPreferences change
+ useEffect(() => {
+ setPreferences(initialPreferences);
+ setFormData({
+ eventFeedbackPoints: initialPreferences.eventFeedbackPoints.toString(),
+ });
+ }, [initialPreferences]);
+
+ const handleEdit = () => {
+ setIsEditing(true);
+ };
+
+ const handleSave = async () => {
+ const points = parseInt(formData.eventFeedbackPoints, 10);
+
+ if (isNaN(points) || points < 0) {
+ alert("Le nombre de points doit être un nombre positif");
+ return;
+ }
+
+ setIsSaving(true);
+ try {
+ const result = await updateSitePreferences({
+ eventFeedbackPoints: points,
+ });
+
+ if (result.success && result.data) {
+ setPreferences(result.data);
+ setFormData({
+ eventFeedbackPoints: result.data.eventFeedbackPoints.toString(),
+ });
+ setIsEditing(false);
+ } else {
+ console.error("Error updating preferences:", result.error);
+ alert(result.error || "Erreur lors de la mise à jour");
+ }
+ } catch (error) {
+ console.error("Error updating preferences:", error);
+ alert("Erreur lors de la mise à jour");
+ } finally {
+ setIsSaving(false);
+ }
+ };
+
+ const handleCancel = () => {
+ setIsEditing(false);
+ if (preferences) {
+ setFormData({
+ eventFeedbackPoints: preferences.eventFeedbackPoints.toString(),
+ });
+ }
+ };
+
+ return (
+
+
+
+
+ Points de feedback sur les événements
+
+
+ Nombre de points attribués lorsqu'un utilisateur donne un feedback à un événement (première fois uniquement)
+
+
+ {!isEditing && (
+
+ )}
+
+
+ {isEditing ? (
+
+
+
+
+ setFormData({
+ ...formData,
+ eventFeedbackPoints: e.target.value,
+ })
+ }
+ placeholder="100"
+ className="w-full"
+ />
+
+ Les utilisateurs gagneront ce nombre de points lors de leur premier feedback sur un événement
+
+
+
+
+
+
+
+ ) : (
+
+
+ Points actuels:
+
+
+
+ {preferences?.eventFeedbackPoints ?? 100}
+
+ points
+
+
+ )}
+
+ );
+}
+
diff --git a/components/admin/EventPointsPreferences.tsx b/components/admin/EventPointsPreferences.tsx
new file mode 100644
index 0000000..921aa55
--- /dev/null
+++ b/components/admin/EventPointsPreferences.tsx
@@ -0,0 +1,166 @@
+"use client";
+
+import { useState, useEffect } from "react";
+import { updateSitePreferences } from "@/actions/admin/preferences";
+import { Button, Card, Input } from "@/components/ui";
+
+interface SitePreferences {
+ id: string;
+ eventRegistrationPoints: number;
+}
+
+interface EventPointsPreferencesProps {
+ initialPreferences: SitePreferences;
+}
+
+export default function EventPointsPreferences({
+ initialPreferences,
+}: EventPointsPreferencesProps) {
+ const [preferences, setPreferences] = useState(
+ initialPreferences
+ );
+ const [isEditing, setIsEditing] = useState(false);
+ const [formData, setFormData] = useState({
+ eventRegistrationPoints: initialPreferences.eventRegistrationPoints.toString(),
+ });
+ const [isSaving, setIsSaving] = useState(false);
+
+ // Synchroniser les préférences quand initialPreferences change
+ useEffect(() => {
+ setPreferences(initialPreferences);
+ setFormData({
+ eventRegistrationPoints: initialPreferences.eventRegistrationPoints.toString(),
+ });
+ }, [initialPreferences]);
+
+ const handleEdit = () => {
+ setIsEditing(true);
+ };
+
+ const handleSave = async () => {
+ const points = parseInt(formData.eventRegistrationPoints, 10);
+
+ if (isNaN(points) || points < 0) {
+ alert("Le nombre de points doit être un nombre positif");
+ return;
+ }
+
+ setIsSaving(true);
+ try {
+ const result = await updateSitePreferences({
+ eventRegistrationPoints: points,
+ });
+
+ if (result.success && result.data) {
+ setPreferences(result.data);
+ setFormData({
+ eventRegistrationPoints: result.data.eventRegistrationPoints.toString(),
+ });
+ setIsEditing(false);
+ } else {
+ console.error("Error updating preferences:", result.error);
+ alert(result.error || "Erreur lors de la mise à jour");
+ }
+ } catch (error) {
+ console.error("Error updating preferences:", error);
+ alert("Erreur lors de la mise à jour");
+ } finally {
+ setIsSaving(false);
+ }
+ };
+
+ const handleCancel = () => {
+ setIsEditing(false);
+ if (preferences) {
+ setFormData({
+ eventRegistrationPoints: preferences.eventRegistrationPoints.toString(),
+ });
+ }
+ };
+
+ return (
+
+
+
+
+ Points d'inscription aux événements
+
+
+ Nombre de points attribués lorsqu'un utilisateur s'inscrit à un événement
+
+
+ {!isEditing && (
+
+ )}
+
+
+ {isEditing ? (
+
+
+
+
+ setFormData({
+ ...formData,
+ eventRegistrationPoints: e.target.value,
+ })
+ }
+ placeholder="100"
+ className="w-full"
+ />
+
+ Les utilisateurs gagneront ce nombre de points lors de leur inscription à un événement
+
+
+
+
+
+
+
+ ) : (
+
+
+ Points actuels:
+
+
+
+ {preferences?.eventRegistrationPoints ?? 100}
+
+ points
+
+
+ )}
+
+ );
+}
+
diff --git a/components/events/EventsPageSection.tsx b/components/events/EventsPageSection.tsx
index d64b4fb..d3158d4 100644
--- a/components/events/EventsPageSection.tsx
+++ b/components/events/EventsPageSection.tsx
@@ -564,6 +564,8 @@ export default function EventsPageSection({
...prev,
[eventId]: true,
}));
+ // Rafraîchir le score dans le header
+ window.dispatchEvent(new Event("refreshUserScore"));
} else {
setError(result.error || "Une erreur est survenue");
}
@@ -583,6 +585,8 @@ export default function EventsPageSection({
...prev,
[eventId]: false,
}));
+ // Rafraîchir le score dans le header
+ window.dispatchEvent(new Event("refreshUserScore"));
} else {
setError(result.error || "Une erreur est survenue");
}
diff --git a/components/feedback/FeedbackModal.tsx b/components/feedback/FeedbackModal.tsx
index e4163e1..25ef858 100644
--- a/components/feedback/FeedbackModal.tsx
+++ b/components/feedback/FeedbackModal.tsx
@@ -155,6 +155,9 @@ export default function FeedbackModal({
});
}
+ // Rafraîchir le score dans le header
+ window.dispatchEvent(new Event("refreshUserScore"));
+
// Fermer la modale après 1.5 secondes
setTimeout(() => {
onClose();
diff --git a/components/profile/PlayerStats.tsx b/components/profile/PlayerStats.tsx
index 81c95eb..43251cd 100644
--- a/components/profile/PlayerStats.tsx
+++ b/components/profile/PlayerStats.tsx
@@ -1,6 +1,6 @@
"use client";
-import { useEffect, useState } from "react";
+import { useEffect, useState, useCallback } from "react";
import { useSession } from "next-auth/react";
import Link from "next/link";
import { Avatar } from "@/components/ui";
@@ -42,6 +42,31 @@ export default function PlayerStats({ initialUserData }: PlayerStatsProps) {
initialUserData || defaultUserData
);
+ const refreshUserData = useCallback(async () => {
+ if (!session?.user?.id) return;
+
+ try {
+ const res = await fetch(`/api/users/${session.user.id}`);
+ const data = await res.json();
+ if (data) {
+ requestAnimationFrame(() => {
+ setUserData({
+ username: data.username || "Guest",
+ avatar: data.avatar,
+ hp: data.hp || 1000,
+ maxHp: data.maxHp || 1000,
+ xp: data.xp || 0,
+ maxXp: data.maxXp || 5000,
+ level: data.level || 1,
+ score: data.score || 0,
+ });
+ });
+ }
+ } catch (error) {
+ console.error("Error refreshing user data:", error);
+ }
+ }, [session]);
+
useEffect(() => {
// Si on a déjà des données initiales, ne rien faire (déjà initialisé dans useState)
if (initialUserData) {
@@ -92,6 +117,18 @@ export default function PlayerStats({ initialUserData }: PlayerStatsProps) {
}
}, [session, initialUserData]);
+ // Écouter les événements de refresh du score
+ useEffect(() => {
+ const handleRefreshScore = () => {
+ refreshUserData();
+ };
+
+ window.addEventListener("refreshUserScore", handleRefreshScore);
+ return () => {
+ window.removeEventListener("refreshUserScore", handleRefreshScore);
+ };
+ }, [refreshUserData]);
+
const { username, avatar, level, score } = userData;
return (
@@ -136,7 +173,6 @@ export default function PlayerStats({ initialUserData }: PlayerStatsProps) {
-
);
}
diff --git a/prisma/generated/prisma/internal/class.ts b/prisma/generated/prisma/internal/class.ts
index 8085cd8..c2455be 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": "generator client {\n provider = \"prisma-client\"\n output = \"./generated/prisma\"\n}\n\ndatasource db {\n provider = \"sqlite\"\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 bio String?\n characterClass CharacterClass?\n eventFeedbacks EventFeedback[]\n eventRegistrations EventRegistration[]\n preferences UserPreferences?\n challengesAsChallenger Challenge[] @relation(\"Challenger\")\n challengesAsChallenged Challenge[] @relation(\"Challenged\")\n challengesAsAdmin Challenge[] @relation(\"AdminValidator\")\n challengesAsWinner Challenge[] @relation(\"ChallengeWinner\")\n\n @@index([score])\n @@index([email])\n}\n\nmodel UserPreferences {\n id String @id @default(cuid())\n userId String @unique\n homeBackground String?\n eventsBackground String?\n leaderboardBackground String?\n theme String? @default(\"default\")\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n}\n\nmodel Event {\n id String @id @default(cuid())\n date DateTime\n name String\n description String\n type EventType\n room String?\n time String?\n maxPlaces Int?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n feedbacks EventFeedback[]\n registrations EventRegistration[]\n\n @@index([date])\n}\n\nmodel EventRegistration {\n id String @id @default(cuid())\n userId String\n eventId String\n createdAt DateTime @default(now())\n event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n @@unique([userId, eventId])\n @@index([userId])\n @@index([eventId])\n}\n\nmodel EventFeedback {\n id String @id @default(cuid())\n userId String\n eventId String\n rating Int\n comment String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\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 challengesBackground String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nenum Role {\n USER\n ADMIN\n}\n\nenum EventType {\n ATELIER\n KATA\n PRESENTATION\n LEARNING_HOUR\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\nenum ChallengeStatus {\n PENDING\n ACCEPTED\n COMPLETED\n REJECTED\n CANCELLED\n}\n\nmodel Challenge {\n id String @id @default(cuid())\n challengerId String // Joueur qui lance le défi\n challengedId String // Joueur qui reçoit le défi\n challenger User @relation(\"Challenger\", fields: [challengerId], references: [id], onDelete: Cascade)\n challenged User @relation(\"Challenged\", fields: [challengedId], references: [id], onDelete: Cascade)\n title String // Titre du défi\n description String // Description détaillée du défi\n pointsReward Int @default(100) // Points à gagner pour le gagnant\n status ChallengeStatus @default(PENDING)\n adminId String? // Admin qui valide le défi\n admin User? @relation(\"AdminValidator\", fields: [adminId], references: [id], onDelete: SetNull)\n adminComment String? // Commentaire de l'admin lors de la validation/rejet\n winnerId String? // ID du gagnant (challengerId ou challengedId)\n winner User? @relation(\"ChallengeWinner\", fields: [winnerId], references: [id], onDelete: SetNull)\n createdAt DateTime @default(now())\n acceptedAt DateTime? // Date d'acceptation du défi\n completedAt DateTime? // Date de validation par l'admin\n updatedAt DateTime @updatedAt\n\n @@index([challengerId])\n @@index([challengedId])\n @@index([status])\n @@index([adminId])\n}\n",
+ "inlineSchema": "generator client {\n provider = \"prisma-client\"\n output = \"./generated/prisma\"\n}\n\ndatasource db {\n provider = \"sqlite\"\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 bio String?\n characterClass CharacterClass?\n eventFeedbacks EventFeedback[]\n eventRegistrations EventRegistration[]\n preferences UserPreferences?\n challengesAsChallenger Challenge[] @relation(\"Challenger\")\n challengesAsChallenged Challenge[] @relation(\"Challenged\")\n challengesAsAdmin Challenge[] @relation(\"AdminValidator\")\n challengesAsWinner Challenge[] @relation(\"ChallengeWinner\")\n\n @@index([score])\n @@index([email])\n}\n\nmodel UserPreferences {\n id String @id @default(cuid())\n userId String @unique\n homeBackground String?\n eventsBackground String?\n leaderboardBackground String?\n theme String? @default(\"default\")\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n}\n\nmodel Event {\n id String @id @default(cuid())\n date DateTime\n name String\n description String\n type EventType\n room String?\n time String?\n maxPlaces Int?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n feedbacks EventFeedback[]\n registrations EventRegistration[]\n\n @@index([date])\n}\n\nmodel EventRegistration {\n id String @id @default(cuid())\n userId String\n eventId String\n createdAt DateTime @default(now())\n event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n @@unique([userId, eventId])\n @@index([userId])\n @@index([eventId])\n}\n\nmodel EventFeedback {\n id String @id @default(cuid())\n userId String\n eventId String\n rating Int\n comment String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\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 challengesBackground String?\n eventRegistrationPoints Int @default(100)\n eventFeedbackPoints Int @default(50)\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nenum Role {\n USER\n ADMIN\n}\n\nenum EventType {\n ATELIER\n KATA\n PRESENTATION\n LEARNING_HOUR\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\nenum ChallengeStatus {\n PENDING\n ACCEPTED\n COMPLETED\n REJECTED\n CANCELLED\n}\n\nmodel Challenge {\n id String @id @default(cuid())\n challengerId String // Joueur qui lance le défi\n challengedId String // Joueur qui reçoit le défi\n challenger User @relation(\"Challenger\", fields: [challengerId], references: [id], onDelete: Cascade)\n challenged User @relation(\"Challenged\", fields: [challengedId], references: [id], onDelete: Cascade)\n title String // Titre du défi\n description String // Description détaillée du défi\n pointsReward Int @default(100) // Points à gagner pour le gagnant\n status ChallengeStatus @default(PENDING)\n adminId String? // Admin qui valide le défi\n admin User? @relation(\"AdminValidator\", fields: [adminId], references: [id], onDelete: SetNull)\n adminComment String? // Commentaire de l'admin lors de la validation/rejet\n winnerId String? // ID du gagnant (challengerId ou challengedId)\n winner User? @relation(\"ChallengeWinner\", fields: [winnerId], references: [id], onDelete: SetNull)\n createdAt DateTime @default(now())\n acceptedAt DateTime? // Date d'acceptation du défi\n completedAt DateTime? // Date de validation par l'admin\n updatedAt DateTime @updatedAt\n\n @@index([challengerId])\n @@index([challengedId])\n @@index([status])\n @@index([adminId])\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\":\"bio\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"characterClass\",\"kind\":\"enum\",\"type\":\"CharacterClass\"},{\"name\":\"eventFeedbacks\",\"kind\":\"object\",\"type\":\"EventFeedback\",\"relationName\":\"EventFeedbackToUser\"},{\"name\":\"eventRegistrations\",\"kind\":\"object\",\"type\":\"EventRegistration\",\"relationName\":\"EventRegistrationToUser\"},{\"name\":\"preferences\",\"kind\":\"object\",\"type\":\"UserPreferences\",\"relationName\":\"UserToUserPreferences\"},{\"name\":\"challengesAsChallenger\",\"kind\":\"object\",\"type\":\"Challenge\",\"relationName\":\"Challenger\"},{\"name\":\"challengesAsChallenged\",\"kind\":\"object\",\"type\":\"Challenge\",\"relationName\":\"Challenged\"},{\"name\":\"challengesAsAdmin\",\"kind\":\"object\",\"type\":\"Challenge\",\"relationName\":\"AdminValidator\"},{\"name\":\"challengesAsWinner\",\"kind\":\"object\",\"type\":\"Challenge\",\"relationName\":\"ChallengeWinner\"}],\"dbName\":null},\"UserPreferences\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"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\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"UserToUserPreferences\"}],\"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\":\"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\":\"feedbacks\",\"kind\":\"object\",\"type\":\"EventFeedback\",\"relationName\":\"EventToEventFeedback\"},{\"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\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"event\",\"kind\":\"object\",\"type\":\"Event\",\"relationName\":\"EventToEventRegistration\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"EventRegistrationToUser\"}],\"dbName\":null},\"EventFeedback\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"eventId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"rating\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"comment\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"event\",\"kind\":\"object\",\"type\":\"Event\",\"relationName\":\"EventToEventFeedback\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"EventFeedbackToUser\"}],\"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\":\"challengesBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Challenge\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"challengerId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"challengedId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"challenger\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"Challenger\"},{\"name\":\"challenged\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"Challenged\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"pointsReward\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"status\",\"kind\":\"enum\",\"type\":\"ChallengeStatus\"},{\"name\":\"adminId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"admin\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"AdminValidator\"},{\"name\":\"adminComment\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"winnerId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"winner\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"ChallengeWinner\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"acceptedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"completedAt\",\"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\":\"bio\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"characterClass\",\"kind\":\"enum\",\"type\":\"CharacterClass\"},{\"name\":\"eventFeedbacks\",\"kind\":\"object\",\"type\":\"EventFeedback\",\"relationName\":\"EventFeedbackToUser\"},{\"name\":\"eventRegistrations\",\"kind\":\"object\",\"type\":\"EventRegistration\",\"relationName\":\"EventRegistrationToUser\"},{\"name\":\"preferences\",\"kind\":\"object\",\"type\":\"UserPreferences\",\"relationName\":\"UserToUserPreferences\"},{\"name\":\"challengesAsChallenger\",\"kind\":\"object\",\"type\":\"Challenge\",\"relationName\":\"Challenger\"},{\"name\":\"challengesAsChallenged\",\"kind\":\"object\",\"type\":\"Challenge\",\"relationName\":\"Challenged\"},{\"name\":\"challengesAsAdmin\",\"kind\":\"object\",\"type\":\"Challenge\",\"relationName\":\"AdminValidator\"},{\"name\":\"challengesAsWinner\",\"kind\":\"object\",\"type\":\"Challenge\",\"relationName\":\"ChallengeWinner\"}],\"dbName\":null},\"UserPreferences\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"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\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"UserToUserPreferences\"}],\"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\":\"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\":\"feedbacks\",\"kind\":\"object\",\"type\":\"EventFeedback\",\"relationName\":\"EventToEventFeedback\"},{\"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\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"event\",\"kind\":\"object\",\"type\":\"Event\",\"relationName\":\"EventToEventRegistration\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"EventRegistrationToUser\"}],\"dbName\":null},\"EventFeedback\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"eventId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"rating\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"comment\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"event\",\"kind\":\"object\",\"type\":\"Event\",\"relationName\":\"EventToEventFeedback\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"EventFeedbackToUser\"}],\"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\":\"challengesBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"eventRegistrationPoints\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"eventFeedbackPoints\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Challenge\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"challengerId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"challengedId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"challenger\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"Challenger\"},{\"name\":\"challenged\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"Challenged\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"pointsReward\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"status\",\"kind\":\"enum\",\"type\":\"ChallengeStatus\"},{\"name\":\"adminId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"admin\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"AdminValidator\"},{\"name\":\"adminComment\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"winnerId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"winner\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"ChallengeWinner\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"acceptedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"completedAt\",\"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/internal/prismaNamespace.ts b/prisma/generated/prisma/internal/prismaNamespace.ts
index 2ccf43a..d868283 100644
--- a/prisma/generated/prisma/internal/prismaNamespace.ts
+++ b/prisma/generated/prisma/internal/prismaNamespace.ts
@@ -1045,6 +1045,8 @@ export const SitePreferencesScalarFieldEnum = {
eventsBackground: 'eventsBackground',
leaderboardBackground: 'leaderboardBackground',
challengesBackground: 'challengesBackground',
+ eventRegistrationPoints: 'eventRegistrationPoints',
+ eventFeedbackPoints: 'eventFeedbackPoints',
createdAt: 'createdAt',
updatedAt: 'updatedAt'
} as const
diff --git a/prisma/generated/prisma/internal/prismaNamespaceBrowser.ts b/prisma/generated/prisma/internal/prismaNamespaceBrowser.ts
index faa805f..63d8c82 100644
--- a/prisma/generated/prisma/internal/prismaNamespaceBrowser.ts
+++ b/prisma/generated/prisma/internal/prismaNamespaceBrowser.ts
@@ -154,6 +154,8 @@ export const SitePreferencesScalarFieldEnum = {
eventsBackground: 'eventsBackground',
leaderboardBackground: 'leaderboardBackground',
challengesBackground: 'challengesBackground',
+ eventRegistrationPoints: 'eventRegistrationPoints',
+ eventFeedbackPoints: 'eventFeedbackPoints',
createdAt: 'createdAt',
updatedAt: 'updatedAt'
} as const
diff --git a/prisma/generated/prisma/models/SitePreferences.ts b/prisma/generated/prisma/models/SitePreferences.ts
index 170f0d3..52aecfb 100644
--- a/prisma/generated/prisma/models/SitePreferences.ts
+++ b/prisma/generated/prisma/models/SitePreferences.ts
@@ -20,16 +20,30 @@ export type SitePreferencesModel = runtime.Types.Result.DefaultSelection | string | null
leaderboardBackground?: Prisma.StringNullableFilter<"SitePreferences"> | string | null
challengesBackground?: Prisma.StringNullableFilter<"SitePreferences"> | string | null
+ eventRegistrationPoints?: Prisma.IntFilter<"SitePreferences"> | number
+ eventFeedbackPoints?: Prisma.IntFilter<"SitePreferences"> | number
createdAt?: Prisma.DateTimeFilter<"SitePreferences"> | Date | string
updatedAt?: Prisma.DateTimeFilter<"SitePreferences"> | Date | string
}
@@ -206,6 +260,8 @@ export type SitePreferencesOrderByWithRelationInput = {
eventsBackground?: Prisma.SortOrderInput | Prisma.SortOrder
leaderboardBackground?: Prisma.SortOrderInput | Prisma.SortOrder
challengesBackground?: Prisma.SortOrderInput | Prisma.SortOrder
+ eventRegistrationPoints?: Prisma.SortOrder
+ eventFeedbackPoints?: Prisma.SortOrder
createdAt?: Prisma.SortOrder
updatedAt?: Prisma.SortOrder
}
@@ -219,6 +275,8 @@ export type SitePreferencesWhereUniqueInput = Prisma.AtLeast<{
eventsBackground?: Prisma.StringNullableFilter<"SitePreferences"> | string | null
leaderboardBackground?: Prisma.StringNullableFilter<"SitePreferences"> | string | null
challengesBackground?: Prisma.StringNullableFilter<"SitePreferences"> | string | null
+ eventRegistrationPoints?: Prisma.IntFilter<"SitePreferences"> | number
+ eventFeedbackPoints?: Prisma.IntFilter<"SitePreferences"> | number
createdAt?: Prisma.DateTimeFilter<"SitePreferences"> | Date | string
updatedAt?: Prisma.DateTimeFilter<"SitePreferences"> | Date | string
}, "id">
@@ -229,11 +287,15 @@ export type SitePreferencesOrderByWithAggregationInput = {
eventsBackground?: Prisma.SortOrderInput | Prisma.SortOrder
leaderboardBackground?: Prisma.SortOrderInput | Prisma.SortOrder
challengesBackground?: Prisma.SortOrderInput | Prisma.SortOrder
+ eventRegistrationPoints?: Prisma.SortOrder
+ eventFeedbackPoints?: Prisma.SortOrder
createdAt?: Prisma.SortOrder
updatedAt?: Prisma.SortOrder
_count?: Prisma.SitePreferencesCountOrderByAggregateInput
+ _avg?: Prisma.SitePreferencesAvgOrderByAggregateInput
_max?: Prisma.SitePreferencesMaxOrderByAggregateInput
_min?: Prisma.SitePreferencesMinOrderByAggregateInput
+ _sum?: Prisma.SitePreferencesSumOrderByAggregateInput
}
export type SitePreferencesScalarWhereWithAggregatesInput = {
@@ -245,6 +307,8 @@ export type SitePreferencesScalarWhereWithAggregatesInput = {
eventsBackground?: Prisma.StringNullableWithAggregatesFilter<"SitePreferences"> | string | null
leaderboardBackground?: Prisma.StringNullableWithAggregatesFilter<"SitePreferences"> | string | null
challengesBackground?: Prisma.StringNullableWithAggregatesFilter<"SitePreferences"> | string | null
+ eventRegistrationPoints?: Prisma.IntWithAggregatesFilter<"SitePreferences"> | number
+ eventFeedbackPoints?: Prisma.IntWithAggregatesFilter<"SitePreferences"> | number
createdAt?: Prisma.DateTimeWithAggregatesFilter<"SitePreferences"> | Date | string
updatedAt?: Prisma.DateTimeWithAggregatesFilter<"SitePreferences"> | Date | string
}
@@ -255,6 +319,8 @@ export type SitePreferencesCreateInput = {
eventsBackground?: string | null
leaderboardBackground?: string | null
challengesBackground?: string | null
+ eventRegistrationPoints?: number
+ eventFeedbackPoints?: number
createdAt?: Date | string
updatedAt?: Date | string
}
@@ -265,6 +331,8 @@ export type SitePreferencesUncheckedCreateInput = {
eventsBackground?: string | null
leaderboardBackground?: string | null
challengesBackground?: string | null
+ eventRegistrationPoints?: number
+ eventFeedbackPoints?: number
createdAt?: Date | string
updatedAt?: Date | string
}
@@ -275,6 +343,8 @@ export type SitePreferencesUpdateInput = {
eventsBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
leaderboardBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
challengesBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
+ eventRegistrationPoints?: Prisma.IntFieldUpdateOperationsInput | number
+ eventFeedbackPoints?: Prisma.IntFieldUpdateOperationsInput | number
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
}
@@ -285,6 +355,8 @@ export type SitePreferencesUncheckedUpdateInput = {
eventsBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
leaderboardBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
challengesBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
+ eventRegistrationPoints?: Prisma.IntFieldUpdateOperationsInput | number
+ eventFeedbackPoints?: Prisma.IntFieldUpdateOperationsInput | number
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
}
@@ -295,6 +367,8 @@ export type SitePreferencesCreateManyInput = {
eventsBackground?: string | null
leaderboardBackground?: string | null
challengesBackground?: string | null
+ eventRegistrationPoints?: number
+ eventFeedbackPoints?: number
createdAt?: Date | string
updatedAt?: Date | string
}
@@ -305,6 +379,8 @@ export type SitePreferencesUpdateManyMutationInput = {
eventsBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
leaderboardBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
challengesBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
+ eventRegistrationPoints?: Prisma.IntFieldUpdateOperationsInput | number
+ eventFeedbackPoints?: Prisma.IntFieldUpdateOperationsInput | number
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
}
@@ -315,6 +391,8 @@ export type SitePreferencesUncheckedUpdateManyInput = {
eventsBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
leaderboardBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
challengesBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
+ eventRegistrationPoints?: Prisma.IntFieldUpdateOperationsInput | number
+ eventFeedbackPoints?: Prisma.IntFieldUpdateOperationsInput | number
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
}
@@ -325,16 +403,25 @@ export type SitePreferencesCountOrderByAggregateInput = {
eventsBackground?: Prisma.SortOrder
leaderboardBackground?: Prisma.SortOrder
challengesBackground?: Prisma.SortOrder
+ eventRegistrationPoints?: Prisma.SortOrder
+ eventFeedbackPoints?: Prisma.SortOrder
createdAt?: Prisma.SortOrder
updatedAt?: Prisma.SortOrder
}
+export type SitePreferencesAvgOrderByAggregateInput = {
+ eventRegistrationPoints?: Prisma.SortOrder
+ eventFeedbackPoints?: Prisma.SortOrder
+}
+
export type SitePreferencesMaxOrderByAggregateInput = {
id?: Prisma.SortOrder
homeBackground?: Prisma.SortOrder
eventsBackground?: Prisma.SortOrder
leaderboardBackground?: Prisma.SortOrder
challengesBackground?: Prisma.SortOrder
+ eventRegistrationPoints?: Prisma.SortOrder
+ eventFeedbackPoints?: Prisma.SortOrder
createdAt?: Prisma.SortOrder
updatedAt?: Prisma.SortOrder
}
@@ -345,10 +432,17 @@ export type SitePreferencesMinOrderByAggregateInput = {
eventsBackground?: Prisma.SortOrder
leaderboardBackground?: Prisma.SortOrder
challengesBackground?: Prisma.SortOrder
+ eventRegistrationPoints?: Prisma.SortOrder
+ eventFeedbackPoints?: Prisma.SortOrder
createdAt?: Prisma.SortOrder
updatedAt?: Prisma.SortOrder
}
+export type SitePreferencesSumOrderByAggregateInput = {
+ eventRegistrationPoints?: Prisma.SortOrder
+ eventFeedbackPoints?: Prisma.SortOrder
+}
+
export type SitePreferencesSelect = runtime.Types.Extensions.GetSelect<{
@@ -357,6 +451,8 @@ export type SitePreferencesSelect
@@ -367,6 +463,8 @@ export type SitePreferencesSelectCreateManyAndReturn
@@ -377,6 +475,8 @@ export type SitePreferencesSelectUpdateManyAndReturn
@@ -387,11 +487,13 @@ export type SitePreferencesSelectScalar = {
eventsBackground?: boolean
leaderboardBackground?: boolean
challengesBackground?: boolean
+ eventRegistrationPoints?: boolean
+ eventFeedbackPoints?: boolean
createdAt?: boolean
updatedAt?: boolean
}
-export type SitePreferencesOmit = runtime.Types.Extensions.GetOmit<"id" | "homeBackground" | "eventsBackground" | "leaderboardBackground" | "challengesBackground" | "createdAt" | "updatedAt", ExtArgs["result"]["sitePreferences"]>
+export type SitePreferencesOmit = runtime.Types.Extensions.GetOmit<"id" | "homeBackground" | "eventsBackground" | "leaderboardBackground" | "challengesBackground" | "eventRegistrationPoints" | "eventFeedbackPoints" | "createdAt" | "updatedAt", ExtArgs["result"]["sitePreferences"]>
export type $SitePreferencesPayload = {
name: "SitePreferences"
@@ -402,6 +504,8 @@ export type $SitePreferencesPayload
@@ -832,6 +936,8 @@ export interface SitePreferencesFieldRefs {
readonly eventsBackground: Prisma.FieldRef<"SitePreferences", 'String'>
readonly leaderboardBackground: Prisma.FieldRef<"SitePreferences", 'String'>
readonly challengesBackground: Prisma.FieldRef<"SitePreferences", 'String'>
+ readonly eventRegistrationPoints: Prisma.FieldRef<"SitePreferences", 'Int'>
+ readonly eventFeedbackPoints: Prisma.FieldRef<"SitePreferences", 'Int'>
readonly createdAt: Prisma.FieldRef<"SitePreferences", 'DateTime'>
readonly updatedAt: Prisma.FieldRef<"SitePreferences", 'DateTime'>
}
diff --git a/prisma/migrations/20251216153031_add_event_registration_points/migration.sql b/prisma/migrations/20251216153031_add_event_registration_points/migration.sql
new file mode 100644
index 0000000..ef95838
--- /dev/null
+++ b/prisma/migrations/20251216153031_add_event_registration_points/migration.sql
@@ -0,0 +1,18 @@
+-- RedefineTables
+PRAGMA defer_foreign_keys=ON;
+PRAGMA foreign_keys=OFF;
+CREATE TABLE "new_SitePreferences" (
+ "id" TEXT NOT NULL PRIMARY KEY DEFAULT 'global',
+ "homeBackground" TEXT,
+ "eventsBackground" TEXT,
+ "leaderboardBackground" TEXT,
+ "challengesBackground" TEXT,
+ "eventRegistrationPoints" INTEGER NOT NULL DEFAULT 100,
+ "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" DATETIME NOT NULL
+);
+INSERT INTO "new_SitePreferences" ("challengesBackground", "createdAt", "eventsBackground", "homeBackground", "id", "leaderboardBackground", "updatedAt") SELECT "challengesBackground", "createdAt", "eventsBackground", "homeBackground", "id", "leaderboardBackground", "updatedAt" FROM "SitePreferences";
+DROP TABLE "SitePreferences";
+ALTER TABLE "new_SitePreferences" RENAME TO "SitePreferences";
+PRAGMA foreign_keys=ON;
+PRAGMA defer_foreign_keys=OFF;
diff --git a/prisma/migrations/20251216153510_add_event_feedback_points/migration.sql b/prisma/migrations/20251216153510_add_event_feedback_points/migration.sql
new file mode 100644
index 0000000..9d0f861
--- /dev/null
+++ b/prisma/migrations/20251216153510_add_event_feedback_points/migration.sql
@@ -0,0 +1,19 @@
+-- RedefineTables
+PRAGMA defer_foreign_keys=ON;
+PRAGMA foreign_keys=OFF;
+CREATE TABLE "new_SitePreferences" (
+ "id" TEXT NOT NULL PRIMARY KEY DEFAULT 'global',
+ "homeBackground" TEXT,
+ "eventsBackground" TEXT,
+ "leaderboardBackground" TEXT,
+ "challengesBackground" TEXT,
+ "eventRegistrationPoints" INTEGER NOT NULL DEFAULT 100,
+ "eventFeedbackPoints" INTEGER NOT NULL DEFAULT 50,
+ "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" DATETIME NOT NULL
+);
+INSERT INTO "new_SitePreferences" ("challengesBackground", "createdAt", "eventRegistrationPoints", "eventsBackground", "homeBackground", "id", "leaderboardBackground", "updatedAt") SELECT "challengesBackground", "createdAt", "eventRegistrationPoints", "eventsBackground", "homeBackground", "id", "leaderboardBackground", "updatedAt" FROM "SitePreferences";
+DROP TABLE "SitePreferences";
+ALTER TABLE "new_SitePreferences" RENAME TO "SitePreferences";
+PRAGMA foreign_keys=ON;
+PRAGMA defer_foreign_keys=OFF;
diff --git a/prisma/migrations/20251216153605_change_feedback_points_default_to_100/migration.sql b/prisma/migrations/20251216153605_change_feedback_points_default_to_100/migration.sql
new file mode 100644
index 0000000..a6b3005
--- /dev/null
+++ b/prisma/migrations/20251216153605_change_feedback_points_default_to_100/migration.sql
@@ -0,0 +1,19 @@
+-- RedefineTables
+PRAGMA defer_foreign_keys=ON;
+PRAGMA foreign_keys=OFF;
+CREATE TABLE "new_SitePreferences" (
+ "id" TEXT NOT NULL PRIMARY KEY DEFAULT 'global',
+ "homeBackground" TEXT,
+ "eventsBackground" TEXT,
+ "leaderboardBackground" TEXT,
+ "challengesBackground" TEXT,
+ "eventRegistrationPoints" INTEGER NOT NULL DEFAULT 100,
+ "eventFeedbackPoints" INTEGER NOT NULL DEFAULT 100,
+ "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" DATETIME NOT NULL
+);
+INSERT INTO "new_SitePreferences" ("challengesBackground", "createdAt", "eventFeedbackPoints", "eventRegistrationPoints", "eventsBackground", "homeBackground", "id", "leaderboardBackground", "updatedAt") SELECT "challengesBackground", "createdAt", "eventFeedbackPoints", "eventRegistrationPoints", "eventsBackground", "homeBackground", "id", "leaderboardBackground", "updatedAt" FROM "SitePreferences";
+DROP TABLE "SitePreferences";
+ALTER TABLE "new_SitePreferences" RENAME TO "SitePreferences";
+PRAGMA foreign_keys=ON;
+PRAGMA defer_foreign_keys=OFF;
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index b239421..23fa4a1 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -100,6 +100,8 @@ model SitePreferences {
eventsBackground String?
leaderboardBackground String?
challengesBackground String?
+ eventRegistrationPoints Int @default(100)
+ eventFeedbackPoints Int @default(100)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
diff --git a/services/events/event-feedback.service.ts b/services/events/event-feedback.service.ts
index 635cf0f..933f88a 100644
--- a/services/events/event-feedback.service.ts
+++ b/services/events/event-feedback.service.ts
@@ -2,6 +2,7 @@ import { prisma } from "../database";
import type { EventFeedback, Prisma } from "@/prisma/generated/prisma/client";
import { ValidationError, NotFoundError } from "../errors";
import { eventService } from "./event.service";
+import { sitePreferencesService } from "../preferences/site-preferences.service";
export interface CreateOrUpdateFeedbackInput {
rating: number;
@@ -168,11 +169,34 @@ export class EventFeedbackService {
throw new NotFoundError("Événement");
}
- // Créer ou mettre à jour le feedback
- return this.createOrUpdateFeedback(userId, eventId, {
- rating: data.rating,
- comment: data.comment || null,
- });
+ // Vérifier si c'est un nouveau feedback ou une mise à jour
+ const existingFeedback = await this.getUserFeedback(userId, eventId);
+ const isNewFeedback = !existingFeedback;
+
+ // Récupérer les points à attribuer depuis les préférences du site
+ const sitePreferences = await sitePreferencesService.getOrCreateSitePreferences();
+ const pointsToAward = sitePreferences.eventFeedbackPoints || 100;
+
+ // Créer ou mettre à jour le feedback et attribuer les points (seulement pour nouveau feedback)
+ const [feedback] = await Promise.all([
+ this.createOrUpdateFeedback(userId, eventId, {
+ rating: data.rating,
+ comment: data.comment || null,
+ }),
+ // Attribuer les points seulement si c'est un nouveau feedback
+ isNewFeedback
+ ? prisma.user.update({
+ where: { id: userId },
+ data: {
+ score: {
+ increment: pointsToAward,
+ },
+ },
+ })
+ : Promise.resolve(null),
+ ]);
+
+ return feedback;
}
}
diff --git a/services/events/event-registration.service.ts b/services/events/event-registration.service.ts
index f0c1c93..04825b5 100644
--- a/services/events/event-registration.service.ts
+++ b/services/events/event-registration.service.ts
@@ -3,6 +3,7 @@ import type { EventRegistration } from "@/prisma/generated/prisma/client";
import { ValidationError, NotFoundError, ConflictError } from "../errors";
import { eventService } from "./event.service";
import { calculateEventStatus } from "@/lib/eventStatus";
+import { sitePreferencesService } from "../preferences/site-preferences.service";
/**
* Service de gestion des inscriptions aux événements
@@ -24,18 +25,39 @@ export class EventRegistrationService {
}
/**
- * Désinscrit un utilisateur d'un événement
+ * Désinscrit un utilisateur d'un événement et retire les points attribués
*/
async unregisterUserFromEvent(
userId: string,
eventId: string
): Promise {
- await prisma.eventRegistration.deleteMany({
- where: {
- userId,
- eventId,
- },
- });
+ // Vérifier que l'utilisateur est bien inscrit avant de retirer les points
+ const isRegistered = await this.checkUserRegistration(userId, eventId);
+ if (!isRegistered) {
+ return; // Pas d'inscription, rien à faire
+ }
+
+ // Récupérer les points à retirer depuis les préférences du site
+ const sitePreferences = await sitePreferencesService.getOrCreateSitePreferences();
+ const pointsToRemove = sitePreferences.eventRegistrationPoints || 100;
+
+ // Supprimer l'inscription et retirer les points en parallèle
+ await Promise.all([
+ prisma.eventRegistration.deleteMany({
+ where: {
+ userId,
+ eventId,
+ },
+ }),
+ prisma.user.update({
+ where: { id: userId },
+ data: {
+ score: {
+ decrement: pointsToRemove,
+ },
+ },
+ }),
+ ]);
}
/**
@@ -123,8 +145,24 @@ export class EventRegistrationService {
throw new ConflictError("Vous êtes déjà inscrit à cet événement");
}
- // Créer l'inscription
- return this.registerUserToEvent(userId, eventId);
+ // Récupérer les points à attribuer depuis les préférences du site
+ const sitePreferences = await sitePreferencesService.getOrCreateSitePreferences();
+ const pointsToAward = sitePreferences.eventRegistrationPoints || 100;
+
+ // Créer l'inscription et attribuer les points en parallèle
+ const [registration] = await Promise.all([
+ this.registerUserToEvent(userId, eventId),
+ prisma.user.update({
+ where: { id: userId },
+ data: {
+ score: {
+ increment: pointsToAward,
+ },
+ },
+ }),
+ ]);
+
+ return registration;
}
}
diff --git a/services/preferences/site-preferences.service.ts b/services/preferences/site-preferences.service.ts
index 5d9e424..531e2fb 100644
--- a/services/preferences/site-preferences.service.ts
+++ b/services/preferences/site-preferences.service.ts
@@ -7,6 +7,8 @@ export interface UpdateSitePreferencesInput {
eventsBackground?: string | null;
leaderboardBackground?: string | null;
challengesBackground?: string | null;
+ eventRegistrationPoints?: number;
+ eventFeedbackPoints?: number;
}
/**
@@ -38,6 +40,8 @@ export class SitePreferencesService {
eventsBackground: null,
leaderboardBackground: null,
challengesBackground: null,
+ eventRegistrationPoints: 100,
+ eventFeedbackPoints: 100,
},
});
}
@@ -70,6 +74,14 @@ export class SitePreferencesService {
data.challengesBackground === ""
? null
: (data.challengesBackground ?? undefined),
+ eventRegistrationPoints:
+ data.eventRegistrationPoints !== undefined
+ ? data.eventRegistrationPoints
+ : undefined,
+ eventFeedbackPoints:
+ data.eventFeedbackPoints !== undefined
+ ? data.eventFeedbackPoints
+ : undefined,
},
create: {
id: "global",
@@ -85,6 +97,8 @@ export class SitePreferencesService {
data.challengesBackground === ""
? null
: (data.challengesBackground ?? null),
+ eventRegistrationPoints: data.eventRegistrationPoints ?? 100,
+ eventFeedbackPoints: data.eventFeedbackPoints ?? 100,
},
});
}