feat: integrate ToastProvider and enhance theme management

- Added `ToastProvider` to `RootLayout` for improved user feedback on theme changes.
- Updated `ThemeProvider` to display toast notifications with theme names and icons upon theme changes.
- Refactored theme-related imports to streamline code and improve maintainability.
- Simplified background cycling logic in `useBackgroundCycle` to utilize centralized background definitions.
- Cleaned up unused background definitions in `BackgroundContext` for better clarity and performance.
This commit is contained in:
Julien Froidefond
2025-10-02 17:24:37 +02:00
parent 99377ee38d
commit 10c1f811ce
10 changed files with 405 additions and 189 deletions

View File

@@ -2,6 +2,7 @@
import { createContext, useContext, useEffect, useState, ReactNode } from 'react';
import { useUserPreferences } from './UserPreferencesContext';
import { PRESET_BACKGROUNDS } from '@/lib/ui-config';
interface BackgroundContextType {
backgroundImage: string | undefined;
@@ -69,37 +70,14 @@ export function BackgroundProvider({ children }: BackgroundProviderProps) {
backgroundElement.style.pointerEvents = 'none';
// Vérifier si c'est une URL d'image ou un preset
const PRESET_BACKGROUNDS = [
'theme-subtle',
'theme-primary',
'theme-accent',
'theme-success',
'theme-purple',
'theme-diagonal',
'theme-radial',
'theme-sunset',
'theme-ocean',
'theme-forest',
'theme-galaxy'
];
if (PRESET_BACKGROUNDS.includes(backgroundImage)) {
// Appliquer le preset basé sur le thème
const presetStyles = {
'theme-subtle': 'linear-gradient(135deg, var(--background) 0%, color-mix(in srgb, var(--primary) 15%, var(--background)) 100%)',
'theme-primary': 'linear-gradient(135deg, var(--background) 0%, color-mix(in srgb, var(--primary) 25%, var(--background)) 100%)',
'theme-accent': 'linear-gradient(135deg, var(--background) 0%, color-mix(in srgb, var(--accent) 25%, var(--background)) 100%)',
'theme-success': 'linear-gradient(135deg, var(--background) 0%, color-mix(in srgb, var(--success) 25%, var(--background)) 100%)',
'theme-purple': 'linear-gradient(135deg, var(--background) 0%, color-mix(in srgb, var(--purple) 25%, var(--background)) 100%)',
'theme-diagonal': 'linear-gradient(45deg, var(--background) 0%, color-mix(in srgb, var(--primary) 20%, var(--background)) 50%, color-mix(in srgb, var(--accent) 20%, var(--background)) 100%)',
'theme-radial': 'radial-gradient(circle at center, var(--background) 0%, color-mix(in srgb, var(--primary) 20%, var(--background)) 100%)',
'theme-sunset': 'linear-gradient(135deg, color-mix(in srgb, var(--accent) 30%, var(--background)) 0%, color-mix(in srgb, var(--destructive) 20%, var(--background)) 100%)',
'theme-ocean': 'linear-gradient(135deg, color-mix(in srgb, var(--blue) 25%, var(--background)) 0%, color-mix(in srgb, var(--primary) 15%, var(--background)) 100%)',
'theme-forest': 'linear-gradient(135deg, color-mix(in srgb, var(--green) 25%, var(--background)) 0%, color-mix(in srgb, var(--success) 15%, var(--background)) 100%)',
'theme-galaxy': 'linear-gradient(135deg, color-mix(in srgb, var(--purple) 25%, var(--background)) 0%, color-mix(in srgb, var(--blue) 20%, var(--background)) 100%)'
};
backgroundElement.style.backgroundImage = presetStyles[backgroundImage as keyof typeof presetStyles];
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) {
backgroundElement.style.backgroundImage = preset.preview;
}
} else {
// Appliquer l'URL d'image personnalisée
backgroundElement.style.backgroundImage = `url(${backgroundImage})`;

View File

@@ -2,8 +2,8 @@
import { createContext, useContext, useEffect, useState, ReactNode } from 'react';
import { updateViewPreferences } from '@/actions/preferences';
import { Theme } from '@/lib/theme-config';
import { THEME_CONFIG, getNextDarkTheme } from '@/lib/theme-config';
import { useToast } from '@/components/ui/Toast';
import { Theme, THEME_CONFIG, getNextDarkTheme, THEME_NAMES, getThemeIcon } from '@/lib/ui-config';
interface ThemeContextType {
theme: Theme;
@@ -25,6 +25,7 @@ export function ThemeProvider({ children, initialTheme = 'dark', userPreferredTh
const [theme, setThemeState] = useState<Theme>(initialTheme);
const [userPreferredTheme, setUserPreferredTheme] = useState<Theme>(initialUserPreferredTheme);
const [mounted, setMounted] = useState(false);
const { showToast } = useToast();
// Hydration safe initialization
useEffect(() => {
@@ -57,6 +58,9 @@ export function ThemeProvider({ children, initialTheme = 'dark', userPreferredTh
} catch (error) {
console.error('Erreur lors de la sauvegarde du thème:', error);
}
// Afficher le toast avec le nom du thème
showToast(`Thème: ${THEME_NAMES[newTheme]}`, 2000, getThemeIcon(newTheme));
};
const setTheme = async (newTheme: Theme) => {
@@ -78,6 +82,9 @@ export function ThemeProvider({ children, initialTheme = 'dark', userPreferredTh
} catch (error) {
console.error('Erreur lors de la sauvegarde du thème:', error);
}
// Afficher le toast avec le nom du thème
showToast(`Thème: ${THEME_NAMES[newTheme]}`, 2000, getThemeIcon(newTheme));
};
const cycleDarkThemes = async () => {