'use client'; import { createContext, useContext, useEffect, useState, ReactNode } from 'react'; import { useUserPreferences } from './UserPreferencesContext'; import { PRESET_BACKGROUNDS, BACKGROUND_NAMES, TOAST_ICONS, getNextBackground } from '@/lib/ui-config'; import { useSession } from 'next-auth/react'; import { useToast } from '@/components/ui/Toast'; interface BackgroundContextType { backgroundImage: string | undefined; setBackgroundImage: (image: string | undefined) => void; cycleBackground: () => void; } const BackgroundContext = createContext(undefined); interface BackgroundProviderProps { children: ReactNode; } export function BackgroundProvider({ children }: BackgroundProviderProps) { const { preferences, updateViewPreferences } = useUserPreferences(); const { data: session } = useSession(); const { showToast } = useToast(); const [backgroundImage, setBackgroundImageState] = useState( preferences?.viewPreferences?.backgroundImage ); const [backgroundBlur, setBackgroundBlurState] = useState( preferences?.viewPreferences?.backgroundBlur || 0 ); const [backgroundOpacity, setBackgroundOpacityState] = useState( preferences?.viewPreferences?.backgroundOpacity || 100 ); const [mounted, setMounted] = useState(false); // Hydration safe initialization useEffect(() => { setMounted(true); }, []); // Sync with preferences (only for authenticated users) useEffect(() => { // Only sync if user is authenticated if (session?.user?.id && preferences?.viewPreferences?.backgroundImage !== backgroundImage) { setBackgroundImageState(preferences?.viewPreferences?.backgroundImage); } if (preferences?.viewPreferences?.backgroundBlur !== backgroundBlur) { setBackgroundBlurState(preferences?.viewPreferences?.backgroundBlur || 0); } if (preferences?.viewPreferences?.backgroundOpacity !== backgroundOpacity) { setBackgroundOpacityState(preferences?.viewPreferences?.backgroundOpacity || 100); } }, [preferences?.viewPreferences?.backgroundImage, preferences?.viewPreferences?.backgroundBlur, preferences?.viewPreferences?.backgroundOpacity, backgroundImage, backgroundBlur, backgroundOpacity, session?.user?.id]); // Apply background image to document body useEffect(() => { if (mounted) { const body = document.body; // Supprimer l'ancien élément de fond s'il existe const existingBackground = document.getElementById('custom-background'); if (existingBackground) { existingBackground.remove(); } if (backgroundImage) { console.log('Creating background element for:', backgroundImage); // Créer un élément div pour l'image de fond avec les effets const backgroundElement = document.createElement('div'); backgroundElement.id = 'custom-background'; backgroundElement.style.position = 'fixed'; backgroundElement.style.top = '0'; backgroundElement.style.left = '0'; backgroundElement.style.width = '100%'; backgroundElement.style.height = '100%'; backgroundElement.style.zIndex = '-1'; backgroundElement.style.pointerEvents = 'none'; // Vérifier si c'est une URL d'image ou un preset const presetIds = PRESET_BACKGROUNDS.map(preset => preset.id); if (backgroundImage && presetIds.includes(backgroundImage as typeof presetIds[number])) { // Trouver le preset correspondant const preset = PRESET_BACKGROUNDS.find(p => p.id === backgroundImage); if (preset) { // Appliquer le gradient directement backgroundElement.style.background = preset.preview; // Ajouter une classe pour identifier le type de background backgroundElement.className = `preset-background preset-${preset.id}`; } } else { // Appliquer l'URL d'image personnalisée backgroundElement.style.backgroundImage = `url(${backgroundImage})`; backgroundElement.className = 'custom-background'; } // Appliquer les propriétés communes backgroundElement.style.backgroundSize = 'cover'; backgroundElement.style.backgroundPosition = 'center'; backgroundElement.style.backgroundRepeat = 'no-repeat'; backgroundElement.style.filter = `blur(${backgroundBlur}px)`; backgroundElement.style.opacity = `${backgroundOpacity / 100}`; // Ajouter l'élément au body body.appendChild(backgroundElement); body.classList.add('has-background-image'); } else { // Supprimer l'image de fond body.classList.remove('has-background-image'); } } }, [backgroundImage, backgroundBlur, backgroundOpacity, mounted]); const setBackgroundImage = (image: string | undefined) => { setBackgroundImageState(image); }; const cycleBackground = () => { const currentBackground = backgroundImage; // Utiliser le state local au lieu des préférences const customImages = preferences?.viewPreferences?.customImages || []; const nextBackground = getNextBackground(currentBackground || 'none', customImages); const newBackgroundImage = nextBackground === 'none' ? undefined : nextBackground; setBackgroundImageState(newBackgroundImage); // Sauvegarder seulement si l'utilisateur est authentifié if (session?.user?.id) { updateViewPreferences({ backgroundImage: newBackgroundImage }); } // Afficher le toast avec le nom du background const backgroundName = BACKGROUND_NAMES[nextBackground] || 'Image personnalisée'; showToast(`Background: ${backgroundName}`, 2000, TOAST_ICONS.background); }; return ( {children} ); } export function useBackground() { const context = useContext(BackgroundContext); if (context === undefined) { throw new Error('useBackground must be used within a BackgroundProvider'); } return context; }