feat: enhance login page with random theme and background features
- Added RandomThemeApplier to apply a random theme on login. - Introduced RandomBackground component for setting a random background from presets. - Updated GlobalKeyboardShortcuts import in RootLayout for consistent keyboard shortcut handling. - Refactored BackgroundContext to include cycleBackground functionality for dynamic background changes. - Removed deprecated useBackgroundCycle hook to streamline background management.
This commit is contained in:
@@ -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<BackgroundContextType | undefined>(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<string | undefined>(
|
||||
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 (
|
||||
<BackgroundContext.Provider value={{ backgroundImage, setBackgroundImage }}>
|
||||
<BackgroundContext.Provider value={{ backgroundImage, setBackgroundImage, cycleBackground }}>
|
||||
{children}
|
||||
</BackgroundContext.Provider>
|
||||
);
|
||||
|
||||
@@ -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<Theme>(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
|
||||
|
||||
Reference in New Issue
Block a user