diff --git a/src/app/layout.tsx b/src/app/layout.tsx index a976092..8e931f2 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -58,8 +58,8 @@ export default async function RootLayout({ - + {children} diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index dc66ef1..b7b161e 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -8,8 +8,56 @@ import { Button } from '@/components/ui/Button' import { Input } from '@/components/ui/Input' import { TowerLogo } from '@/components/TowerLogo' import { TowerBackground } from '@/components/TowerBackground' +import { THEME_CONFIG } from '@/lib/theme-config' +import { useTheme } from '@/contexts/ThemeContext' +import { PRESET_BACKGROUNDS } from '@/lib/ui-config' -export default function LoginPage() { +function RandomThemeApplier() { + const { setTheme } = useTheme(); + const [applied, setApplied] = useState(false); + + useEffect(() => { + if (!applied) { + // Sélectionner un thème aléatoire côté client seulement + const randomTheme = THEME_CONFIG.allThemes[Math.floor(Math.random() * THEME_CONFIG.allThemes.length)]; + console.log('Applying random theme:', randomTheme); + + // Utiliser setTheme du ThemeContext pour forcer le changement + setTheme(randomTheme); + setApplied(true); + } + }, [applied, setTheme]); + + return null; +} + +function RandomBackground() { + const [background, setBackground] = useState('var(--background)'); + const [mounted, setMounted] = useState(false); + + useEffect(() => { + // Sélectionner un background aléatoire parmi les presets (sauf 'none') + const availableBackgrounds = PRESET_BACKGROUNDS.filter(bg => bg.id !== 'none'); + const randomBackground = availableBackgrounds[Math.floor(Math.random() * availableBackgrounds.length)]; + setBackground(randomBackground.preview); + setMounted(true); + }, []); + + return ( +
+ {/* Effet de profondeur */} +
+ + {/* Effet de lumière */} +
+
+ ); +} + +function LoginPageContent() { const [email, setEmail] = useState('') const [password, setPassword] = useState('') const [error, setError] = useState('') @@ -71,7 +119,8 @@ export default function LoginPage() { return (
- + + {/* Contenu principal */}
@@ -150,3 +199,7 @@ export default function LoginPage() {
) } + +export default function LoginPage() { + return +} diff --git a/src/components/GlobalKeyboardShortcuts.tsx b/src/components/GlobalKeyboardShortcuts.tsx index cf007d9..b620b06 100644 --- a/src/components/GlobalKeyboardShortcuts.tsx +++ b/src/components/GlobalKeyboardShortcuts.tsx @@ -1,10 +1,10 @@ 'use client'; import { useGlobalKeyboardShortcuts } from '@/hooks/useGlobalKeyboardShortcuts'; -import { useBackgroundCycle } from '@/hooks/useBackgroundCycle'; +import { useBackground } from '@/contexts/BackgroundContext'; export function GlobalKeyboardShortcuts() { - const { cycleBackground } = useBackgroundCycle(); + const { cycleBackground } = useBackground(); useGlobalKeyboardShortcuts({ onCycleBackground: cycleBackground diff --git a/src/contexts/BackgroundContext.tsx b/src/contexts/BackgroundContext.tsx index b7fee1d..702e3c6 100644 --- a/src/contexts/BackgroundContext.tsx +++ b/src/contexts/BackgroundContext.tsx @@ -2,11 +2,14 @@ import { createContext, useContext, useEffect, useState, ReactNode } from 'react'; import { useUserPreferences } from './UserPreferencesContext'; -import { PRESET_BACKGROUNDS } from '@/lib/ui-config'; +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); @@ -16,7 +19,9 @@ interface BackgroundProviderProps { } export function BackgroundProvider({ children }: BackgroundProviderProps) { - const { preferences } = useUserPreferences(); + const { preferences, updateViewPreferences } = useUserPreferences(); + const { data: session } = useSession(); + const { showToast } = useToast(); const [backgroundImage, setBackgroundImageState] = useState( preferences?.viewPreferences?.backgroundImage ); @@ -33,9 +38,10 @@ export function BackgroundProvider({ children }: BackgroundProviderProps) { setMounted(true); }, []); - // Sync with preferences + // Sync with preferences (only for authenticated users) useEffect(() => { - if (preferences?.viewPreferences?.backgroundImage !== backgroundImage) { + // Only sync if user is authenticated + if (session?.user?.id && preferences?.viewPreferences?.backgroundImage !== backgroundImage) { setBackgroundImageState(preferences?.viewPreferences?.backgroundImage); } if (preferences?.viewPreferences?.backgroundBlur !== backgroundBlur) { @@ -44,7 +50,7 @@ export function BackgroundProvider({ children }: BackgroundProviderProps) { if (preferences?.viewPreferences?.backgroundOpacity !== backgroundOpacity) { setBackgroundOpacityState(preferences?.viewPreferences?.backgroundOpacity || 100); } - }, [preferences?.viewPreferences?.backgroundImage, preferences?.viewPreferences?.backgroundBlur, preferences?.viewPreferences?.backgroundOpacity, backgroundImage, backgroundBlur, backgroundOpacity]); + }, [preferences?.viewPreferences?.backgroundImage, preferences?.viewPreferences?.backgroundBlur, preferences?.viewPreferences?.backgroundOpacity, backgroundImage, backgroundBlur, backgroundOpacity, session?.user?.id]); // Apply background image to document body useEffect(() => { @@ -58,6 +64,7 @@ export function BackgroundProvider({ children }: BackgroundProviderProps) { } 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'; @@ -76,11 +83,15 @@ export function BackgroundProvider({ children }: BackgroundProviderProps) { // Trouver le preset correspondant const preset = PRESET_BACKGROUNDS.find(p => p.id === backgroundImage); if (preset) { - backgroundElement.style.backgroundImage = preset.preview; + // 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 @@ -104,8 +115,27 @@ export function BackgroundProvider({ children }: BackgroundProviderProps) { 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} ); diff --git a/src/contexts/ThemeContext.tsx b/src/contexts/ThemeContext.tsx index dd41980..dcc0e20 100644 --- a/src/contexts/ThemeContext.tsx +++ b/src/contexts/ThemeContext.tsx @@ -4,6 +4,7 @@ import { createContext, useContext, useEffect, useState, ReactNode } from 'react import { updateViewPreferences } from '@/actions/preferences'; import { useToast } from '@/components/ui/Toast'; import { Theme, THEME_CONFIG, getNextDarkTheme, THEME_NAMES, getThemeIcon } from '@/lib/ui-config'; +import { useSession } from 'next-auth/react'; interface ThemeContextType { theme: Theme; @@ -26,6 +27,7 @@ export function ThemeProvider({ children, initialTheme = 'dark', userPreferredTh const [userPreferredTheme, setUserPreferredTheme] = useState(initialUserPreferredTheme); const [mounted, setMounted] = useState(false); const { showToast } = useToast(); + const { data: session } = useSession(); // Hydration safe initialization useEffect(() => { @@ -47,16 +49,18 @@ export function ThemeProvider({ children, initialTheme = 'dark', userPreferredTh const newTheme = theme === 'light' ? userPreferredTheme : 'light'; setThemeState(newTheme); - // Sauvegarder en base de façon asynchrone via server action - try { - const result = await updateViewPreferences({ - theme: newTheme - }); - if (!result.success) { - console.error('Erreur lors de la sauvegarde du thème:', result.error); + // Sauvegarder en base seulement si l'utilisateur est authentifié + if (session?.user?.id) { + try { + const result = await updateViewPreferences({ + theme: newTheme + }); + if (!result.success) { + console.error('Erreur lors de la sauvegarde du thème:', result.error); + } + } catch (error) { + console.error('Erreur lors de la sauvegarde du thème:', error); } - } catch (error) { - console.error('Erreur lors de la sauvegarde du thème:', error); } // Afficher le toast avec le nom du thème @@ -71,16 +75,18 @@ export function ThemeProvider({ children, initialTheme = 'dark', userPreferredTh setUserPreferredTheme(newTheme); } - // Sauvegarder en base de façon asynchrone via server action - try { - const result = await updateViewPreferences({ - theme: newTheme - }); - if (!result.success) { - console.error('Erreur lors de la sauvegarde du thème:', result.error); + // Sauvegarder en base seulement si l'utilisateur est authentifié + if (session?.user?.id) { + try { + const result = await updateViewPreferences({ + theme: newTheme + }); + if (!result.success) { + console.error('Erreur lors de la sauvegarde du thème:', result.error); + } + } catch (error) { + console.error('Erreur lors de la sauvegarde du thème:', error); } - } catch (error) { - console.error('Erreur lors de la sauvegarde du thème:', error); } // Afficher le toast avec le nom du thème diff --git a/src/hooks/useBackgroundCycle.ts b/src/hooks/useBackgroundCycle.ts deleted file mode 100644 index 75fd90e..0000000 --- a/src/hooks/useBackgroundCycle.ts +++ /dev/null @@ -1,28 +0,0 @@ -'use client'; - -import { useUserPreferences } from '@/contexts/UserPreferencesContext'; -import { useToast } from '@/components/ui/Toast'; -import { BACKGROUND_NAMES, TOAST_ICONS, getNextBackground } from '@/lib/ui-config'; - -export function useBackgroundCycle() { - const { preferences, updateViewPreferences } = useUserPreferences(); - const { showToast } = useToast(); - - const cycleBackground = () => { - const currentBackground = preferences?.viewPreferences?.backgroundImage; - const customImages = preferences?.viewPreferences?.customImages || []; - - const nextBackground = getNextBackground(currentBackground || 'none', customImages); - const backgroundImage = nextBackground === 'none' ? undefined : nextBackground; - - updateViewPreferences({ backgroundImage }); - - // Afficher le toast avec le nom du background - const backgroundName = BACKGROUND_NAMES[nextBackground] || 'Image personnalisée'; - showToast(`Background: ${backgroundName}`, 2000, TOAST_ICONS.background); - }; - - return { - cycleBackground - }; -}