From c650c676270ca19b0d5bbee59d537ec97f042d65 Mon Sep 17 00:00:00 2001 From: Julien Froidefond Date: Sun, 21 Sep 2025 15:03:19 +0200 Subject: [PATCH] feat: integrate UserPreferencesContext for improved preference management - Added `UserPreferencesProvider` to `RootLayout` for centralized user preferences handling. - Updated components to remove direct user preferences fetching, relying on context instead. - Enhanced SSR data fetching by consolidating user preferences retrieval into a single service call. - Cleaned up unused props in various components to streamline the codebase. --- src/app/kanban/KanbanPageClient.tsx | 21 +++---- src/app/kanban/page.tsx | 7 +-- src/app/layout.tsx | 18 +++--- src/app/page.tsx | 5 +- src/app/settings/advanced/page.tsx | 5 +- src/app/settings/general/page.tsx | 8 +-- src/app/settings/integrations/page.tsx | 3 +- src/app/settings/page.tsx | 7 +-- .../WeeklyManagerPageClient.tsx | 21 +++---- src/app/weekly-manager/page.tsx | 7 +-- src/components/HomePageClient.tsx | 22 +++---- .../settings/AdvancedSettingsPageClient.tsx | 8 +-- .../settings/GeneralSettingsPageClient.tsx | 58 +++++++++---------- .../IntegrationsSettingsPageClient.tsx | 9 +-- .../settings/SettingsIndexPageClient.tsx | 21 +++---- src/services/analytics.ts | 2 +- src/services/jira-analytics.ts | 2 +- 17 files changed, 86 insertions(+), 138 deletions(-) diff --git a/src/app/kanban/KanbanPageClient.tsx b/src/app/kanban/KanbanPageClient.tsx index 3c39cd1..62d6351 100644 --- a/src/app/kanban/KanbanPageClient.tsx +++ b/src/app/kanban/KanbanPageClient.tsx @@ -4,8 +4,8 @@ import { useState } from 'react'; import { KanbanBoardContainer } from '@/components/kanban/BoardContainer'; import { Header } from '@/components/ui/Header'; import { TasksProvider, useTasksContext } from '@/contexts/TasksContext'; -import { UserPreferencesProvider, useUserPreferences } from '@/contexts/UserPreferencesContext'; -import { Task, Tag, UserPreferences } from '@/lib/types'; +import { useUserPreferences } from '@/contexts/UserPreferencesContext'; +import { Task, Tag } from '@/lib/types'; import { CreateTaskData } from '@/clients/tasks-client'; import { CreateTaskForm } from '@/components/forms/CreateTaskForm'; import { Button } from '@/components/ui/Button'; @@ -15,7 +15,6 @@ import { FontSizeToggle } from '@/components/ui/FontSizeToggle'; interface KanbanPageClientProps { initialTasks: Task[]; initialTags: (Tag & { usage: number })[]; - initialPreferences: UserPreferences; } function KanbanPageContent() { @@ -179,15 +178,13 @@ function KanbanPageContent() { ); } -export function KanbanPageClient({ initialTasks, initialTags, initialPreferences }: KanbanPageClientProps) { +export function KanbanPageClient({ initialTasks, initialTags }: KanbanPageClientProps) { return ( - - - - - + + + ); } diff --git a/src/app/kanban/page.tsx b/src/app/kanban/page.tsx index 54be739..1f6f4ea 100644 --- a/src/app/kanban/page.tsx +++ b/src/app/kanban/page.tsx @@ -1,6 +1,5 @@ import { tasksService } from '@/services/tasks'; import { tagsService } from '@/services/tags'; -import { userPreferencesService } from '@/services/user-preferences'; import { KanbanPageClient } from './KanbanPageClient'; // Force dynamic rendering (no static generation) @@ -8,17 +7,15 @@ export const dynamic = 'force-dynamic'; export default async function KanbanPage() { // SSR - Récupération des données côté serveur - const [initialTasks, initialTags, initialPreferences] = await Promise.all([ + const [initialTasks, initialTags] = await Promise.all([ tasksService.getTasks(), - tagsService.getTags(), - userPreferencesService.getAllPreferences() + tagsService.getTags() ]); return ( ); } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 553d5e4..3d9e37b 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -3,6 +3,7 @@ import { Geist, Geist_Mono } from "next/font/google"; import "./globals.css"; import { ThemeProvider } from "@/contexts/ThemeContext"; import { JiraConfigProvider } from "@/contexts/JiraConfigContext"; +import { UserPreferencesProvider } from "@/contexts/UserPreferencesContext"; import { userPreferencesService } from "@/services/user-preferences"; const geistSans = Geist({ @@ -25,20 +26,19 @@ export default async function RootLayout({ }: Readonly<{ children: React.ReactNode; }>) { - // Récupérer les données côté serveur pour le SSR - const [initialTheme, jiraConfig] = await Promise.all([ - userPreferencesService.getTheme(), - userPreferencesService.getJiraConfig() - ]); + // Récupérer toutes les préférences côté serveur pour le SSR + const initialPreferences = await userPreferencesService.getAllPreferences(); return ( - + - - - {children} + + + + {children} + diff --git a/src/app/page.tsx b/src/app/page.tsx index 56c0896..75d3491 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,6 +1,5 @@ import { tasksService } from '@/services/tasks'; import { tagsService } from '@/services/tags'; -import { userPreferencesService } from '@/services/user-preferences'; import { HomePageClient } from '@/components/HomePageClient'; // Force dynamic rendering (no static generation) @@ -8,10 +7,9 @@ export const dynamic = 'force-dynamic'; export default async function HomePage() { // SSR - Récupération des données côté serveur - const [initialTasks, initialTags, initialPreferences, initialStats] = await Promise.all([ + const [initialTasks, initialTags, initialStats] = await Promise.all([ tasksService.getTasks(), tagsService.getTags(), - userPreferencesService.getAllPreferences(), tasksService.getTaskStats() ]); @@ -19,7 +17,6 @@ export default async function HomePage() { ); diff --git a/src/app/settings/advanced/page.tsx b/src/app/settings/advanced/page.tsx index 1b4be6b..dc3bab4 100644 --- a/src/app/settings/advanced/page.tsx +++ b/src/app/settings/advanced/page.tsx @@ -1,4 +1,3 @@ -import { userPreferencesService } from '@/services/user-preferences'; import { tasksService } from '@/services/tasks'; import { tagsService } from '@/services/tags'; import { backupService } from '@/services/backup'; @@ -10,8 +9,7 @@ export const dynamic = 'force-dynamic'; export default async function AdvancedSettingsPage() { // Fetch all data server-side - const [preferences, taskStats, tags] = await Promise.all([ - userPreferencesService.getAllPreferences(), + const [taskStats, tags] = await Promise.all([ tasksService.getTaskStats(), tagsService.getTags() ]); @@ -38,7 +36,6 @@ export default async function AdvancedSettingsPage() { return ( diff --git a/src/app/settings/general/page.tsx b/src/app/settings/general/page.tsx index 2594b75..41051a1 100644 --- a/src/app/settings/general/page.tsx +++ b/src/app/settings/general/page.tsx @@ -1,4 +1,3 @@ -import { userPreferencesService } from '@/services/user-preferences'; import { tagsService } from '@/services/tags'; import { GeneralSettingsPageClient } from '@/components/settings/GeneralSettingsPageClient'; @@ -7,10 +6,7 @@ export const dynamic = 'force-dynamic'; export default async function GeneralSettingsPage() { // Fetch data server-side - const [preferences, tags] = await Promise.all([ - userPreferencesService.getAllPreferences(), - tagsService.getTags() - ]); + const tags = await tagsService.getTags(); - return ; + return ; } diff --git a/src/app/settings/integrations/page.tsx b/src/app/settings/integrations/page.tsx index 97f54e7..13aba65 100644 --- a/src/app/settings/integrations/page.tsx +++ b/src/app/settings/integrations/page.tsx @@ -6,12 +6,11 @@ export const dynamic = 'force-dynamic'; export default async function IntegrationsSettingsPage() { // Fetch data server-side - const preferences = await userPreferencesService.getAllPreferences(); + // Preferences are now available via context const jiraConfig = await userPreferencesService.getJiraConfig(); return ( ); diff --git a/src/app/settings/page.tsx b/src/app/settings/page.tsx index 3bc1414..c8e52cb 100644 --- a/src/app/settings/page.tsx +++ b/src/app/settings/page.tsx @@ -1,4 +1,3 @@ -import { userPreferencesService } from '@/services/user-preferences'; import { SystemInfoService } from '@/services/system-info'; import { SettingsIndexPageClient } from '@/components/settings/SettingsIndexPageClient'; @@ -7,14 +6,10 @@ export const dynamic = 'force-dynamic'; export default async function SettingsPage() { // Fetch data in parallel for better performance - const [preferences, systemInfo] = await Promise.all([ - userPreferencesService.getAllPreferences(), - SystemInfoService.getSystemInfo() - ]); + const systemInfo = await SystemInfoService.getSystemInfo(); return ( ); diff --git a/src/app/weekly-manager/WeeklyManagerPageClient.tsx b/src/app/weekly-manager/WeeklyManagerPageClient.tsx index da3000f..a640399 100644 --- a/src/app/weekly-manager/WeeklyManagerPageClient.tsx +++ b/src/app/weekly-manager/WeeklyManagerPageClient.tsx @@ -1,32 +1,27 @@ 'use client'; import { TasksProvider } from '@/contexts/TasksContext'; -import { UserPreferencesProvider } from '@/contexts/UserPreferencesContext'; import ManagerWeeklySummary from '@/components/dashboard/ManagerWeeklySummary'; import { ManagerSummary } from '@/services/manager-summary'; -import { Task, Tag, UserPreferences } from '@/lib/types'; +import { Task, Tag } from '@/lib/types'; interface WeeklyManagerPageClientProps { initialSummary: ManagerSummary; initialTasks: Task[]; initialTags: (Tag & { usage: number })[]; - initialPreferences: UserPreferences; } export function WeeklyManagerPageClient({ initialSummary, initialTasks, - initialTags, - initialPreferences + initialTags }: WeeklyManagerPageClientProps) { return ( - - - - - + + + ); } diff --git a/src/app/weekly-manager/page.tsx b/src/app/weekly-manager/page.tsx index ef40891..c549987 100644 --- a/src/app/weekly-manager/page.tsx +++ b/src/app/weekly-manager/page.tsx @@ -2,7 +2,6 @@ import { Header } from '@/components/ui/Header'; import { ManagerSummaryService } from '@/services/manager-summary'; import { tasksService } from '@/services/tasks'; import { tagsService } from '@/services/tags'; -import { userPreferencesService } from '@/services/user-preferences'; import { WeeklyManagerPageClient } from './WeeklyManagerPageClient'; // Force dynamic rendering (no static generation) @@ -10,11 +9,10 @@ export const dynamic = 'force-dynamic'; export default async function WeeklyManagerPage() { // SSR - Récupération des données côté serveur - const [summary, initialTasks, initialTags, initialPreferences] = await Promise.all([ + const [summary, initialTasks, initialTags] = await Promise.all([ ManagerSummaryService.getManagerSummary(), tasksService.getTasks(), - tagsService.getTags(), - userPreferencesService.getAllPreferences() + tagsService.getTags() ]); return ( @@ -27,7 +25,6 @@ export default async function WeeklyManagerPage() { initialSummary={summary} initialTasks={initialTasks} initialTags={initialTags} - initialPreferences={initialPreferences} /> diff --git a/src/components/HomePageClient.tsx b/src/components/HomePageClient.tsx index 03a2c0f..5ee849d 100644 --- a/src/components/HomePageClient.tsx +++ b/src/components/HomePageClient.tsx @@ -2,8 +2,7 @@ import { Header } from '@/components/ui/Header'; import { TasksProvider, useTasksContext } from '@/contexts/TasksContext'; -import { UserPreferencesProvider } from '@/contexts/UserPreferencesContext'; -import { Task, Tag, UserPreferences, TaskStats } from '@/lib/types'; +import { Task, Tag, TaskStats } from '@/lib/types'; import { CreateTaskData } from '@/clients/tasks-client'; import { DashboardStats } from '@/components/dashboard/DashboardStats'; import { QuickActions } from '@/components/dashboard/QuickActions'; @@ -13,7 +12,6 @@ import { ProductivityAnalytics } from '@/components/dashboard/ProductivityAnalyt interface HomePageClientProps { initialTasks: Task[]; initialTags: (Tag & { usage: number })[]; - initialPreferences: UserPreferences; initialStats: TaskStats; } @@ -51,16 +49,14 @@ function HomePageContent() { ); } -export function HomePageClient({ initialTasks, initialTags, initialPreferences, initialStats }: HomePageClientProps) { +export function HomePageClient({ initialTasks, initialTags, initialStats }: HomePageClientProps) { return ( - - - - - + + + ); } diff --git a/src/components/settings/AdvancedSettingsPageClient.tsx b/src/components/settings/AdvancedSettingsPageClient.tsx index 525db4e..8694eaf 100644 --- a/src/components/settings/AdvancedSettingsPageClient.tsx +++ b/src/components/settings/AdvancedSettingsPageClient.tsx @@ -1,11 +1,9 @@ 'use client'; import { useState } from 'react'; -import { UserPreferences } from '@/lib/types'; import { Header } from '@/components/ui/Header'; import { Card, CardHeader, CardContent } from '@/components/ui/Card'; import { Button } from '@/components/ui/Button'; -import { UserPreferencesProvider } from '@/contexts/UserPreferencesContext'; import { backupClient, BackupListResponse } from '@/clients/backup-client'; import Link from 'next/link'; import { parseDate, getToday, formatDateForDisplay } from '@/lib/date-utils'; @@ -17,13 +15,11 @@ interface DatabaseStats { } interface AdvancedSettingsPageClientProps { - initialPreferences: UserPreferences; initialDbStats: DatabaseStats; initialBackupData: BackupListResponse; } export function AdvancedSettingsPageClient({ - initialPreferences, initialDbStats, initialBackupData }: AdvancedSettingsPageClientProps) { @@ -107,8 +103,7 @@ export function AdvancedSettingsPageClient({ }; return ( - -
+
-
); } diff --git a/src/components/settings/GeneralSettingsPageClient.tsx b/src/components/settings/GeneralSettingsPageClient.tsx index 875e382..289732b 100644 --- a/src/components/settings/GeneralSettingsPageClient.tsx +++ b/src/components/settings/GeneralSettingsPageClient.tsx @@ -1,23 +1,21 @@ 'use client'; import { useState, useMemo } from 'react'; -import { UserPreferences, Tag } from '@/lib/types'; +import { Tag } from '@/lib/types'; import { useTags } from '@/hooks/useTags'; import { Header } from '@/components/ui/Header'; import { Card, CardContent, CardHeader } from '@/components/ui/Card'; import { Button } from '@/components/ui/Button'; import { Input } from '@/components/ui/Input'; import { TagForm } from '@/components/forms/TagForm'; -import { UserPreferencesProvider } from '@/contexts/UserPreferencesContext'; import Link from 'next/link'; import { formatDateForDisplay } from '@/lib/date-utils'; interface GeneralSettingsPageClientProps { - initialPreferences: UserPreferences; initialTags: Tag[]; } -export function GeneralSettingsPageClient({ initialPreferences, initialTags }: GeneralSettingsPageClientProps) { +export function GeneralSettingsPageClient({ initialTags }: GeneralSettingsPageClientProps) { const { tags, refreshTags, @@ -82,8 +80,7 @@ export function GeneralSettingsPageClient({ initialPreferences, initialTags }: G } }; return ( - -
+
- - {/* Modals pour les tags */} - {isCreateModalOpen && ( - setIsCreateModalOpen(false)} - onSuccess={async () => { - setIsCreateModalOpen(false); - await refreshTags(); - }} - /> - )} - - {editingTag && ( - setEditingTag(null)} - onSuccess={async () => { - setEditingTag(null); - await refreshTags(); - }} - /> - )} -
+ {/* Modals pour les tags */} + {isCreateModalOpen && ( + setIsCreateModalOpen(false)} + onSuccess={async () => { + setIsCreateModalOpen(false); + await refreshTags(); + }} + /> + )} + + {editingTag && ( + setEditingTag(null)} + onSuccess={async () => { + setEditingTag(null); + await refreshTags(); + }} + /> + )} + ); } diff --git a/src/components/settings/IntegrationsSettingsPageClient.tsx b/src/components/settings/IntegrationsSettingsPageClient.tsx index 504fe61..17ec2d3 100644 --- a/src/components/settings/IntegrationsSettingsPageClient.tsx +++ b/src/components/settings/IntegrationsSettingsPageClient.tsx @@ -1,27 +1,23 @@ 'use client'; -import { UserPreferences, JiraConfig } from '@/lib/types'; +import { JiraConfig } from '@/lib/types'; import { Header } from '@/components/ui/Header'; import { Card, CardHeader, CardContent } from '@/components/ui/Card'; import { JiraConfigForm } from '@/components/settings/JiraConfigForm'; import { JiraSync } from '@/components/jira/JiraSync'; import { JiraLogs } from '@/components/jira/JiraLogs'; import { JiraSchedulerConfig } from '@/components/jira/JiraSchedulerConfig'; -import { UserPreferencesProvider } from '@/contexts/UserPreferencesContext'; import Link from 'next/link'; interface IntegrationsSettingsPageClientProps { - initialPreferences: UserPreferences; initialJiraConfig: JiraConfig; } export function IntegrationsSettingsPageClient({ - initialPreferences, initialJiraConfig }: IntegrationsSettingsPageClientProps) { return ( - -
+
-
); } diff --git a/src/components/settings/SettingsIndexPageClient.tsx b/src/components/settings/SettingsIndexPageClient.tsx index 7efdb8b..3dd32ef 100644 --- a/src/components/settings/SettingsIndexPageClient.tsx +++ b/src/components/settings/SettingsIndexPageClient.tsx @@ -1,9 +1,8 @@ 'use client'; -import { UserPreferences } from '@/lib/types'; import { Header } from '@/components/ui/Header'; import { Card, CardHeader, CardContent } from '@/components/ui/Card'; -import { UserPreferencesProvider } from '@/contexts/UserPreferencesContext'; +import { useUserPreferences } from '@/contexts/UserPreferencesContext'; import Link from 'next/link'; import { useState, useEffect, useTransition } from 'react'; import { backupClient } from '@/clients/backup-client'; @@ -12,11 +11,11 @@ import { getSystemInfo } from '@/actions/system-info'; import { SystemInfo } from '@/services/system-info'; interface SettingsIndexPageClientProps { - initialPreferences: UserPreferences; initialSystemInfo?: SystemInfo; } -export function SettingsIndexPageClient({ initialPreferences, initialSystemInfo }: SettingsIndexPageClientProps) { +export function SettingsIndexPageClient({ initialSystemInfo }: SettingsIndexPageClientProps) { + const { preferences } = useUserPreferences(); // États pour les actions const [isBackupLoading, setIsBackupLoading] = useState(false); const [isJiraTestLoading, setIsJiraTestLoading] = useState(false); @@ -140,8 +139,7 @@ export function SettingsIndexPageClient({ initialPreferences, initialSystemInfo ]; return ( - -
+
🎨

Thème actuel

-

{initialPreferences.viewPreferences.theme}

+

{preferences.viewPreferences.theme}

@@ -181,9 +179,9 @@ export function SettingsIndexPageClient({ initialPreferences, initialSystemInfo

Jira

- {initialPreferences.jiraConfig.enabled ? 'Configuré' : 'Non configuré'} + {preferences.jiraConfig.enabled ? 'Configuré' : 'Non configuré'}

- {initialPreferences.jiraConfig.enabled && ( + {preferences.jiraConfig.enabled && ( )}
@@ -198,7 +196,7 @@ export function SettingsIndexPageClient({ initialPreferences, initialSystemInfo 📏

Taille police

-

{initialPreferences.viewPreferences.fontSize}

+

{preferences.viewPreferences.fontSize}

@@ -325,7 +323,7 @@ export function SettingsIndexPageClient({ initialPreferences, initialSystemInfo