diff --git a/services/user-preferences.ts b/services/user-preferences.ts index f0b1be5..a4f4149 100644 --- a/services/user-preferences.ts +++ b/services/user-preferences.ts @@ -147,6 +147,20 @@ class UserPreferencesService { // === MÉTHODES GLOBALES === + /** + * Récupère uniquement le thème pour le SSR (optimisé) + */ + async getTheme(): Promise<'light' | 'dark'> { + try { + const userPrefs = await this.getOrCreateUserPreferences(); + const viewPrefs = userPrefs.viewPreferences as ViewPreferences; + return viewPrefs.theme; + } catch (error) { + console.error('Erreur lors de la récupération du thème:', error); + return DEFAULT_PREFERENCES.viewPreferences.theme; // Fallback + } + } + /** * Récupère toutes les préférences utilisateur */ diff --git a/src/app/layout.tsx b/src/app/layout.tsx index bf6f397..d764bc3 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -2,6 +2,7 @@ import type { Metadata } from "next"; import { Geist, Geist_Mono } from "next/font/google"; import "./globals.css"; import { ThemeProvider } from "@/contexts/ThemeContext"; +import { userPreferencesService } from "@/services/user-preferences"; const geistSans = Geist({ variable: "--font-geist-sans", @@ -18,17 +19,20 @@ export const metadata: Metadata = { description: "Tour de controle (Kanban, tache, daily, ...)", }; -export default function RootLayout({ +export default async function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) { + // Récupérer uniquement le thème côté serveur pour le SSR (optimisé) + const initialTheme = await userPreferencesService.getTheme(); + return ( - + - + {children} diff --git a/src/contexts/ThemeContext.tsx b/src/contexts/ThemeContext.tsx index b944f32..e370e5e 100644 --- a/src/contexts/ThemeContext.tsx +++ b/src/contexts/ThemeContext.tsx @@ -1,6 +1,7 @@ 'use client'; import { createContext, useContext, useEffect, useState, ReactNode } from 'react'; +import { userPreferencesClient } from '@/clients/user-preferences-client'; type Theme = 'light' | 'dark'; @@ -33,12 +34,31 @@ export function ThemeProvider({ children, initialTheme = 'dark' }: ThemeProvider } }, [theme, mounted]); - const toggleTheme = () => { - setThemeState(prev => prev === 'dark' ? 'light' : 'dark'); + const toggleTheme = async () => { + const newTheme = theme === 'dark' ? 'light' : 'dark'; + setThemeState(newTheme); + + // Sauvegarder en base de façon asynchrone via le client + try { + await userPreferencesClient.updateViewPreferences({ + theme: newTheme + }); + } catch (error) { + console.error('Erreur lors de la sauvegarde du thème:', error); + } }; - const setTheme = (newTheme: Theme) => { + const setTheme = async (newTheme: Theme) => { setThemeState(newTheme); + + // Sauvegarder en base de façon asynchrone via le client + try { + await userPreferencesClient.updateViewPreferences({ + theme: newTheme + }); + } catch (error) { + console.error('Erreur lors de la sauvegarde du thème:', error); + } }; return (