Add profile and house background preferences to SitePreferences: Extend SitePreferences model and related services to include profileBackground and houseBackground fields. Update API and UI components to support new background settings, enhancing user customization options.

This commit is contained in:
Julien Froidefond
2025-12-22 08:54:51 +01:00
parent 14c767cfc0
commit 9bcafe54d3
18 changed files with 295 additions and 10 deletions

View File

@@ -20,6 +20,8 @@ export async function updateSitePreferences(data: {
eventsBackground?: string | null;
leaderboardBackground?: string | null;
challengesBackground?: string | null;
profileBackground?: string | null;
houseBackground?: string | null;
eventRegistrationPoints?: number;
eventFeedbackPoints?: number;
houseJoinPoints?: number;
@@ -34,6 +36,8 @@ export async function updateSitePreferences(data: {
eventsBackground: data.eventsBackground,
leaderboardBackground: data.leaderboardBackground,
challengesBackground: data.challengesBackground,
profileBackground: data.profileBackground,
houseBackground: data.houseBackground,
eventRegistrationPoints: data.eventRegistrationPoints,
eventFeedbackPoints: data.eventFeedbackPoints,
houseJoinPoints: data.houseJoinPoints,
@@ -46,6 +50,8 @@ export async function updateSitePreferences(data: {
revalidatePath("/events");
revalidatePath("/leaderboard");
revalidatePath("/challenges");
revalidatePath("/profile");
revalidatePath("/houses");
return { success: true, data: preferences };
} catch (error) {

View File

@@ -128,3 +128,4 @@ export async function cancelChallenge(challengeId: string) {
}
}

View File

@@ -28,3 +28,4 @@ export async function GET() {
}
}

View File

@@ -13,6 +13,8 @@ export async function GET() {
eventsBackground: null,
leaderboardBackground: null,
challengesBackground: null,
profileBackground: null,
houseBackground: null,
});
}
@@ -21,6 +23,8 @@ export async function GET() {
eventsBackground: sitePreferences.eventsBackground,
leaderboardBackground: sitePreferences.leaderboardBackground,
challengesBackground: sitePreferences.challengesBackground,
profileBackground: sitePreferences.profileBackground,
houseBackground: sitePreferences.houseBackground,
});
} catch (error) {
console.error("Error fetching preferences:", error);
@@ -30,6 +34,8 @@ export async function GET() {
eventsBackground: null,
leaderboardBackground: null,
challengesBackground: null,
profileBackground: null,
houseBackground: null,
},
{ status: 200 }
);

View File

@@ -40,3 +40,4 @@ export async function GET() {
}
}

View File

@@ -125,7 +125,7 @@ export default async function HousesPage() {
username: "asc",
},
}),
getBackgroundImage("challenges", "/got-2.jpg"),
getBackgroundImage("houses", "/got-2.jpg"),
]);
// Sérialiser les données pour le client

View File

@@ -29,7 +29,7 @@ export default async function ProfilePage() {
score: true,
createdAt: true,
}),
getBackgroundImage("home", "/got-background.jpg"),
getBackgroundImage("profile", "/got-background.jpg"),
]);
if (!user) {

View File

@@ -11,6 +11,8 @@ interface SitePreferences {
eventsBackground: string | null;
leaderboardBackground: string | null;
challengesBackground: string | null;
profileBackground: string | null;
houseBackground: string | null;
eventRegistrationPoints?: number;
}
@@ -23,6 +25,8 @@ const DEFAULT_IMAGES = {
events: "/got-2.jpg",
leaderboard: "/leaderboard-bg.jpg",
challenges: "/got-2.jpg",
profile: "/got-background.jpg",
houses: "/got-2.jpg",
};
export default function BackgroundPreferences({
@@ -64,6 +68,14 @@ export default function BackgroundPreferences({
initialPreferences.challengesBackground,
DEFAULT_IMAGES.challenges
),
profileBackground: getFormValue(
initialPreferences.profileBackground,
DEFAULT_IMAGES.profile
),
houseBackground: getFormValue(
initialPreferences.houseBackground,
DEFAULT_IMAGES.houses
),
}),
[initialPreferences]
);
@@ -101,6 +113,14 @@ export default function BackgroundPreferences({
formData.challengesBackground,
DEFAULT_IMAGES.challenges
),
profileBackground: getApiValue(
formData.profileBackground,
DEFAULT_IMAGES.profile
),
houseBackground: getApiValue(
formData.houseBackground,
DEFAULT_IMAGES.houses
),
};
const result = await updateSitePreferences(apiData);
@@ -125,6 +145,14 @@ export default function BackgroundPreferences({
result.data.challengesBackground,
DEFAULT_IMAGES.challenges
),
profileBackground: getFormValue(
result.data.profileBackground,
DEFAULT_IMAGES.profile
),
houseBackground: getFormValue(
result.data.houseBackground,
DEFAULT_IMAGES.houses
),
});
setIsEditing(false);
} else {
@@ -157,6 +185,14 @@ export default function BackgroundPreferences({
preferences.challengesBackground,
DEFAULT_IMAGES.challenges
),
profileBackground: getFormValue(
preferences.profileBackground,
DEFAULT_IMAGES.profile
),
houseBackground: getFormValue(
preferences.houseBackground,
DEFAULT_IMAGES.houses
),
});
}
};
@@ -226,6 +262,26 @@ export default function BackgroundPreferences({
}
label="Background Challenges"
/>
<ImageSelector
value={formData.profileBackground}
onChange={(url) =>
setFormData({
...formData,
profileBackground: url,
})
}
label="Background Profile"
/>
<ImageSelector
value={formData.houseBackground}
onChange={(url) =>
setFormData({
...formData,
houseBackground: url,
})
}
label="Background Houses"
/>
<div className="flex flex-col sm:flex-row gap-2 pt-4">
<Button onClick={handleSave} variant="success" size="md">
Enregistrer
@@ -461,6 +517,118 @@ export default function BackgroundPreferences({
);
})()}
</div>
<div className="flex flex-col sm:flex-row sm:items-center gap-2 sm:gap-4">
<span className="text-pixel-gold font-bold text-sm sm:text-base min-w-0 sm:min-w-[120px] flex-shrink-0">
Profile:
</span>
{(() => {
const currentImage =
preferences?.profileBackground &&
preferences.profileBackground.trim() !== ""
? preferences.profileBackground
: DEFAULT_IMAGES.profile;
const isDefault =
!preferences?.profileBackground ||
preferences.profileBackground.trim() === "";
return (
<div className="flex items-center gap-2 sm:gap-3 min-w-0 flex-1">
<div className="relative w-16 h-10 sm:w-20 sm:h-12 rounded border border-pixel-gold/30 overflow-hidden bg-black/60 flex-shrink-0">
<img
src={currentImage}
alt="Profile background"
className="w-full h-full object-cover"
onError={(e) => {
const target = e.currentTarget;
const currentSrc = target.src;
const fallbackSrc = "/got-background.jpg";
if (!currentSrc.includes(fallbackSrc)) {
target.src = fallbackSrc;
} else {
target.style.display = "none";
const fallbackDiv =
target.nextElementSibling as HTMLElement;
if (fallbackDiv) {
fallbackDiv.classList.remove("hidden");
}
}
}}
/>
<div className="absolute inset-0 flex items-center justify-center bg-black/60 text-gray-500 text-xs hidden">
No image
</div>
</div>
<div className="flex flex-col min-w-0 flex-1">
<span className="text-xs text-gray-400 truncate min-w-0">
{isDefault ? "Par défaut: " : ""}
{currentImage}
</span>
{isDefault && (
<span className="text-[10px] text-gray-500 italic">
(Image par défaut)
</span>
)}
</div>
</div>
);
})()}
</div>
<div className="flex flex-col sm:flex-row sm:items-center gap-2 sm:gap-4">
<span className="text-pixel-gold font-bold text-sm sm:text-base min-w-0 sm:min-w-[120px] flex-shrink-0">
Houses:
</span>
{(() => {
const currentImage =
preferences?.houseBackground &&
preferences.houseBackground.trim() !== ""
? preferences.houseBackground
: DEFAULT_IMAGES.houses;
const isDefault =
!preferences?.houseBackground ||
preferences.houseBackground.trim() === "";
return (
<div className="flex items-center gap-2 sm:gap-3 min-w-0 flex-1">
<div className="relative w-16 h-10 sm:w-20 sm:h-12 rounded border border-pixel-gold/30 overflow-hidden bg-black/60 flex-shrink-0">
<img
src={currentImage}
alt="Houses background"
className="w-full h-full object-cover"
onError={(e) => {
const target = e.currentTarget;
const currentSrc = target.src;
const fallbackSrc = "/got-2.jpg";
if (!currentSrc.includes(fallbackSrc)) {
target.src = fallbackSrc;
} else {
target.style.display = "none";
const fallbackDiv =
target.nextElementSibling as HTMLElement;
if (fallbackDiv) {
fallbackDiv.classList.remove("hidden");
}
}
}}
/>
<div className="absolute inset-0 flex items-center justify-center bg-black/60 text-gray-500 text-xs hidden">
No image
</div>
</div>
<div className="flex flex-col min-w-0 flex-1">
<span className="text-xs text-gray-400 truncate min-w-0">
{isDefault ? "Par défaut: " : ""}
{currentImage}
</span>
{isDefault && (
<span className="text-[10px] text-gray-500 italic">
(Image par défaut)
</span>
)}
</div>
</div>
);
})()}
</div>
</div>
)}
</Card>

View File

@@ -6,6 +6,8 @@ interface Preferences {
eventsBackground: string | null;
leaderboardBackground: string | null;
challengesBackground: string | null;
profileBackground: string | null;
houseBackground: string | null;
}
export function usePreferences() {
@@ -23,6 +25,8 @@ export function usePreferences() {
eventsBackground: null,
leaderboardBackground: null,
challengesBackground: null,
profileBackground: null,
houseBackground: null,
}
);
setLoading(false);
@@ -33,6 +37,8 @@ export function usePreferences() {
eventsBackground: null,
leaderboardBackground: null,
challengesBackground: null,
profileBackground: null,
houseBackground: null,
});
setLoading(false);
});
@@ -42,7 +48,7 @@ export function usePreferences() {
}
export function useBackgroundImage(
page: "home" | "events" | "leaderboard" | "challenges",
page: "home" | "events" | "leaderboard" | "challenges" | "profile" | "houses",
defaultImage: string
) {
const { preferences } = usePreferences();
@@ -51,7 +57,9 @@ export function useBackgroundImage(
useEffect(() => {
if (preferences) {
const imageKey = `${page}Background` as keyof Preferences;
// Mapping spécial pour "houses" -> "house" (car la colonne est houseBackground)
const dbPage = page === "houses" ? "house" : page;
const imageKey = `${dbPage}Background` as keyof Preferences;
const customImage = preferences[imageKey];
const rawImage = customImage || defaultImage;
// Normaliser l'URL pour utiliser l'API si nécessaire

View File

@@ -1,7 +1,7 @@
import { sitePreferencesService } from "@/services/preferences/site-preferences.service";
export async function getBackgroundImage(
page: "home" | "events" | "leaderboard" | "challenges",
page: "home" | "events" | "leaderboard" | "challenges" | "profile" | "houses",
defaultImage: string
): Promise<string> {
return sitePreferencesService.getBackgroundImage(page, defaultImage);

File diff suppressed because one or more lines are too long

View File

@@ -1349,6 +1349,8 @@ export const SitePreferencesScalarFieldEnum = {
eventsBackground: 'eventsBackground',
leaderboardBackground: 'leaderboardBackground',
challengesBackground: 'challengesBackground',
profileBackground: 'profileBackground',
houseBackground: 'houseBackground',
eventRegistrationPoints: 'eventRegistrationPoints',
eventFeedbackPoints: 'eventFeedbackPoints',
houseJoinPoints: 'houseJoinPoints',

View File

@@ -162,6 +162,8 @@ export const SitePreferencesScalarFieldEnum = {
eventsBackground: 'eventsBackground',
leaderboardBackground: 'leaderboardBackground',
challengesBackground: 'challengesBackground',
profileBackground: 'profileBackground',
houseBackground: 'houseBackground',
eventRegistrationPoints: 'eventRegistrationPoints',
eventFeedbackPoints: 'eventFeedbackPoints',
houseJoinPoints: 'houseJoinPoints',

View File

@@ -48,6 +48,8 @@ export type SitePreferencesMinAggregateOutputType = {
eventsBackground: string | null
leaderboardBackground: string | null
challengesBackground: string | null
profileBackground: string | null
houseBackground: string | null
eventRegistrationPoints: number | null
eventFeedbackPoints: number | null
houseJoinPoints: number | null
@@ -63,6 +65,8 @@ export type SitePreferencesMaxAggregateOutputType = {
eventsBackground: string | null
leaderboardBackground: string | null
challengesBackground: string | null
profileBackground: string | null
houseBackground: string | null
eventRegistrationPoints: number | null
eventFeedbackPoints: number | null
houseJoinPoints: number | null
@@ -78,6 +82,8 @@ export type SitePreferencesCountAggregateOutputType = {
eventsBackground: number
leaderboardBackground: number
challengesBackground: number
profileBackground: number
houseBackground: number
eventRegistrationPoints: number
eventFeedbackPoints: number
houseJoinPoints: number
@@ -111,6 +117,8 @@ export type SitePreferencesMinAggregateInputType = {
eventsBackground?: true
leaderboardBackground?: true
challengesBackground?: true
profileBackground?: true
houseBackground?: true
eventRegistrationPoints?: true
eventFeedbackPoints?: true
houseJoinPoints?: true
@@ -126,6 +134,8 @@ export type SitePreferencesMaxAggregateInputType = {
eventsBackground?: true
leaderboardBackground?: true
challengesBackground?: true
profileBackground?: true
houseBackground?: true
eventRegistrationPoints?: true
eventFeedbackPoints?: true
houseJoinPoints?: true
@@ -141,6 +151,8 @@ export type SitePreferencesCountAggregateInputType = {
eventsBackground?: true
leaderboardBackground?: true
challengesBackground?: true
profileBackground?: true
houseBackground?: true
eventRegistrationPoints?: true
eventFeedbackPoints?: true
houseJoinPoints?: true
@@ -243,6 +255,8 @@ export type SitePreferencesGroupByOutputType = {
eventsBackground: string | null
leaderboardBackground: string | null
challengesBackground: string | null
profileBackground: string | null
houseBackground: string | null
eventRegistrationPoints: number
eventFeedbackPoints: number
houseJoinPoints: number
@@ -281,6 +295,8 @@ export type SitePreferencesWhereInput = {
eventsBackground?: Prisma.StringNullableFilter<"SitePreferences"> | string | null
leaderboardBackground?: Prisma.StringNullableFilter<"SitePreferences"> | string | null
challengesBackground?: Prisma.StringNullableFilter<"SitePreferences"> | string | null
profileBackground?: Prisma.StringNullableFilter<"SitePreferences"> | string | null
houseBackground?: Prisma.StringNullableFilter<"SitePreferences"> | string | null
eventRegistrationPoints?: Prisma.IntFilter<"SitePreferences"> | number
eventFeedbackPoints?: Prisma.IntFilter<"SitePreferences"> | number
houseJoinPoints?: Prisma.IntFilter<"SitePreferences"> | number
@@ -296,6 +312,8 @@ export type SitePreferencesOrderByWithRelationInput = {
eventsBackground?: Prisma.SortOrderInput | Prisma.SortOrder
leaderboardBackground?: Prisma.SortOrderInput | Prisma.SortOrder
challengesBackground?: Prisma.SortOrderInput | Prisma.SortOrder
profileBackground?: Prisma.SortOrderInput | Prisma.SortOrder
houseBackground?: Prisma.SortOrderInput | Prisma.SortOrder
eventRegistrationPoints?: Prisma.SortOrder
eventFeedbackPoints?: Prisma.SortOrder
houseJoinPoints?: Prisma.SortOrder
@@ -314,6 +332,8 @@ export type SitePreferencesWhereUniqueInput = Prisma.AtLeast<{
eventsBackground?: Prisma.StringNullableFilter<"SitePreferences"> | string | null
leaderboardBackground?: Prisma.StringNullableFilter<"SitePreferences"> | string | null
challengesBackground?: Prisma.StringNullableFilter<"SitePreferences"> | string | null
profileBackground?: Prisma.StringNullableFilter<"SitePreferences"> | string | null
houseBackground?: Prisma.StringNullableFilter<"SitePreferences"> | string | null
eventRegistrationPoints?: Prisma.IntFilter<"SitePreferences"> | number
eventFeedbackPoints?: Prisma.IntFilter<"SitePreferences"> | number
houseJoinPoints?: Prisma.IntFilter<"SitePreferences"> | number
@@ -329,6 +349,8 @@ export type SitePreferencesOrderByWithAggregationInput = {
eventsBackground?: Prisma.SortOrderInput | Prisma.SortOrder
leaderboardBackground?: Prisma.SortOrderInput | Prisma.SortOrder
challengesBackground?: Prisma.SortOrderInput | Prisma.SortOrder
profileBackground?: Prisma.SortOrderInput | Prisma.SortOrder
houseBackground?: Prisma.SortOrderInput | Prisma.SortOrder
eventRegistrationPoints?: Prisma.SortOrder
eventFeedbackPoints?: Prisma.SortOrder
houseJoinPoints?: Prisma.SortOrder
@@ -352,6 +374,8 @@ export type SitePreferencesScalarWhereWithAggregatesInput = {
eventsBackground?: Prisma.StringNullableWithAggregatesFilter<"SitePreferences"> | string | null
leaderboardBackground?: Prisma.StringNullableWithAggregatesFilter<"SitePreferences"> | string | null
challengesBackground?: Prisma.StringNullableWithAggregatesFilter<"SitePreferences"> | string | null
profileBackground?: Prisma.StringNullableWithAggregatesFilter<"SitePreferences"> | string | null
houseBackground?: Prisma.StringNullableWithAggregatesFilter<"SitePreferences"> | string | null
eventRegistrationPoints?: Prisma.IntWithAggregatesFilter<"SitePreferences"> | number
eventFeedbackPoints?: Prisma.IntWithAggregatesFilter<"SitePreferences"> | number
houseJoinPoints?: Prisma.IntWithAggregatesFilter<"SitePreferences"> | number
@@ -367,6 +391,8 @@ export type SitePreferencesCreateInput = {
eventsBackground?: string | null
leaderboardBackground?: string | null
challengesBackground?: string | null
profileBackground?: string | null
houseBackground?: string | null
eventRegistrationPoints?: number
eventFeedbackPoints?: number
houseJoinPoints?: number
@@ -382,6 +408,8 @@ export type SitePreferencesUncheckedCreateInput = {
eventsBackground?: string | null
leaderboardBackground?: string | null
challengesBackground?: string | null
profileBackground?: string | null
houseBackground?: string | null
eventRegistrationPoints?: number
eventFeedbackPoints?: number
houseJoinPoints?: number
@@ -397,6 +425,8 @@ export type SitePreferencesUpdateInput = {
eventsBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
leaderboardBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
challengesBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
profileBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
houseBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
eventRegistrationPoints?: Prisma.IntFieldUpdateOperationsInput | number
eventFeedbackPoints?: Prisma.IntFieldUpdateOperationsInput | number
houseJoinPoints?: Prisma.IntFieldUpdateOperationsInput | number
@@ -412,6 +442,8 @@ export type SitePreferencesUncheckedUpdateInput = {
eventsBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
leaderboardBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
challengesBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
profileBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
houseBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
eventRegistrationPoints?: Prisma.IntFieldUpdateOperationsInput | number
eventFeedbackPoints?: Prisma.IntFieldUpdateOperationsInput | number
houseJoinPoints?: Prisma.IntFieldUpdateOperationsInput | number
@@ -427,6 +459,8 @@ export type SitePreferencesCreateManyInput = {
eventsBackground?: string | null
leaderboardBackground?: string | null
challengesBackground?: string | null
profileBackground?: string | null
houseBackground?: string | null
eventRegistrationPoints?: number
eventFeedbackPoints?: number
houseJoinPoints?: number
@@ -442,6 +476,8 @@ export type SitePreferencesUpdateManyMutationInput = {
eventsBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
leaderboardBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
challengesBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
profileBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
houseBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
eventRegistrationPoints?: Prisma.IntFieldUpdateOperationsInput | number
eventFeedbackPoints?: Prisma.IntFieldUpdateOperationsInput | number
houseJoinPoints?: Prisma.IntFieldUpdateOperationsInput | number
@@ -457,6 +493,8 @@ export type SitePreferencesUncheckedUpdateManyInput = {
eventsBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
leaderboardBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
challengesBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
profileBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
houseBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
eventRegistrationPoints?: Prisma.IntFieldUpdateOperationsInput | number
eventFeedbackPoints?: Prisma.IntFieldUpdateOperationsInput | number
houseJoinPoints?: Prisma.IntFieldUpdateOperationsInput | number
@@ -472,6 +510,8 @@ export type SitePreferencesCountOrderByAggregateInput = {
eventsBackground?: Prisma.SortOrder
leaderboardBackground?: Prisma.SortOrder
challengesBackground?: Prisma.SortOrder
profileBackground?: Prisma.SortOrder
houseBackground?: Prisma.SortOrder
eventRegistrationPoints?: Prisma.SortOrder
eventFeedbackPoints?: Prisma.SortOrder
houseJoinPoints?: Prisma.SortOrder
@@ -495,6 +535,8 @@ export type SitePreferencesMaxOrderByAggregateInput = {
eventsBackground?: Prisma.SortOrder
leaderboardBackground?: Prisma.SortOrder
challengesBackground?: Prisma.SortOrder
profileBackground?: Prisma.SortOrder
houseBackground?: Prisma.SortOrder
eventRegistrationPoints?: Prisma.SortOrder
eventFeedbackPoints?: Prisma.SortOrder
houseJoinPoints?: Prisma.SortOrder
@@ -510,6 +552,8 @@ export type SitePreferencesMinOrderByAggregateInput = {
eventsBackground?: Prisma.SortOrder
leaderboardBackground?: Prisma.SortOrder
challengesBackground?: Prisma.SortOrder
profileBackground?: Prisma.SortOrder
houseBackground?: Prisma.SortOrder
eventRegistrationPoints?: Prisma.SortOrder
eventFeedbackPoints?: Prisma.SortOrder
houseJoinPoints?: Prisma.SortOrder
@@ -535,6 +579,8 @@ export type SitePreferencesSelect<ExtArgs extends runtime.Types.Extensions.Inter
eventsBackground?: boolean
leaderboardBackground?: boolean
challengesBackground?: boolean
profileBackground?: boolean
houseBackground?: boolean
eventRegistrationPoints?: boolean
eventFeedbackPoints?: boolean
houseJoinPoints?: boolean
@@ -550,6 +596,8 @@ export type SitePreferencesSelectCreateManyAndReturn<ExtArgs extends runtime.Typ
eventsBackground?: boolean
leaderboardBackground?: boolean
challengesBackground?: boolean
profileBackground?: boolean
houseBackground?: boolean
eventRegistrationPoints?: boolean
eventFeedbackPoints?: boolean
houseJoinPoints?: boolean
@@ -565,6 +613,8 @@ export type SitePreferencesSelectUpdateManyAndReturn<ExtArgs extends runtime.Typ
eventsBackground?: boolean
leaderboardBackground?: boolean
challengesBackground?: boolean
profileBackground?: boolean
houseBackground?: boolean
eventRegistrationPoints?: boolean
eventFeedbackPoints?: boolean
houseJoinPoints?: boolean
@@ -580,6 +630,8 @@ export type SitePreferencesSelectScalar = {
eventsBackground?: boolean
leaderboardBackground?: boolean
challengesBackground?: boolean
profileBackground?: boolean
houseBackground?: boolean
eventRegistrationPoints?: boolean
eventFeedbackPoints?: boolean
houseJoinPoints?: boolean
@@ -589,7 +641,7 @@ export type SitePreferencesSelectScalar = {
updatedAt?: boolean
}
export type SitePreferencesOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "homeBackground" | "eventsBackground" | "leaderboardBackground" | "challengesBackground" | "eventRegistrationPoints" | "eventFeedbackPoints" | "houseJoinPoints" | "houseLeavePoints" | "houseCreatePoints" | "createdAt" | "updatedAt", ExtArgs["result"]["sitePreferences"]>
export type SitePreferencesOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "homeBackground" | "eventsBackground" | "leaderboardBackground" | "challengesBackground" | "profileBackground" | "houseBackground" | "eventRegistrationPoints" | "eventFeedbackPoints" | "houseJoinPoints" | "houseLeavePoints" | "houseCreatePoints" | "createdAt" | "updatedAt", ExtArgs["result"]["sitePreferences"]>
export type $SitePreferencesPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
name: "SitePreferences"
@@ -600,6 +652,8 @@ export type $SitePreferencesPayload<ExtArgs extends runtime.Types.Extensions.Int
eventsBackground: string | null
leaderboardBackground: string | null
challengesBackground: string | null
profileBackground: string | null
houseBackground: string | null
eventRegistrationPoints: number
eventFeedbackPoints: number
houseJoinPoints: number
@@ -1035,6 +1089,8 @@ export interface SitePreferencesFieldRefs {
readonly eventsBackground: Prisma.FieldRef<"SitePreferences", 'String'>
readonly leaderboardBackground: Prisma.FieldRef<"SitePreferences", 'String'>
readonly challengesBackground: Prisma.FieldRef<"SitePreferences", 'String'>
readonly profileBackground: Prisma.FieldRef<"SitePreferences", 'String'>
readonly houseBackground: Prisma.FieldRef<"SitePreferences", 'String'>
readonly eventRegistrationPoints: Prisma.FieldRef<"SitePreferences", 'Int'>
readonly eventFeedbackPoints: Prisma.FieldRef<"SitePreferences", 'Int'>
readonly houseJoinPoints: Prisma.FieldRef<"SitePreferences", 'Int'>

View File

@@ -0,0 +1,3 @@
-- AlterTable
ALTER TABLE "SitePreferences" ADD COLUMN "profileBackground" TEXT;

View File

@@ -0,0 +1,3 @@
-- AlterTable
ALTER TABLE "SitePreferences" ADD COLUMN "houseBackground" TEXT;

View File

@@ -107,6 +107,8 @@ model SitePreferences {
eventsBackground String?
leaderboardBackground String?
challengesBackground String?
profileBackground String?
houseBackground String?
eventRegistrationPoints Int @default(100)
eventFeedbackPoints Int @default(100)
houseJoinPoints Int @default(100)

View File

@@ -14,6 +14,8 @@ export interface UpdateSitePreferencesInput {
eventsBackground?: string | null;
leaderboardBackground?: string | null;
challengesBackground?: string | null;
profileBackground?: string | null;
houseBackground?: string | null;
eventRegistrationPoints?: number;
eventFeedbackPoints?: number;
houseJoinPoints?: number;
@@ -50,6 +52,8 @@ export class SitePreferencesService {
eventsBackground: null,
leaderboardBackground: null,
challengesBackground: null,
profileBackground: null,
houseBackground: null,
eventRegistrationPoints: 100,
eventFeedbackPoints: 100,
houseJoinPoints: 100,
@@ -93,6 +97,14 @@ export class SitePreferencesService {
data.challengesBackground === ""
? null
: (data.challengesBackground ?? undefined),
profileBackground:
data.profileBackground === ""
? null
: (data.profileBackground ?? undefined),
houseBackground:
data.houseBackground === ""
? null
: (data.houseBackground ?? undefined),
eventRegistrationPoints:
data.eventRegistrationPoints !== undefined
? data.eventRegistrationPoints
@@ -126,6 +138,12 @@ export class SitePreferencesService {
data.challengesBackground === ""
? null
: (data.challengesBackground ?? null),
profileBackground:
data.profileBackground === ""
? null
: (data.profileBackground ?? null),
houseBackground:
data.houseBackground === "" ? null : (data.houseBackground ?? null),
eventRegistrationPoints: data.eventRegistrationPoints ?? 100,
eventFeedbackPoints: data.eventFeedbackPoints ?? 100,
houseJoinPoints: data.houseJoinPoints ?? 100,
@@ -139,7 +157,13 @@ export class SitePreferencesService {
* Récupère l'image de fond pour une page donnée
*/
async getBackgroundImage(
page: "home" | "events" | "leaderboard" | "challenges",
page:
| "home"
| "events"
| "leaderboard"
| "challenges"
| "profile"
| "houses",
defaultImage: string
): Promise<string> {
try {
@@ -151,7 +175,9 @@ export class SitePreferencesService {
return defaultImage;
}
const imageKey = `${page}Background` as keyof typeof sitePreferences;
// Mapping spécial pour "houses" -> "house" (car la colonne est houseBackground)
const dbPage = page === "houses" ? "house" : page;
const imageKey = `${dbPage}Background` as keyof typeof sitePreferences;
const customImage = sitePreferences[imageKey];
const imageUrl = (customImage as string | null) || defaultImage;