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.
This commit is contained in:
Julien Froidefond
2025-09-21 15:03:19 +02:00
parent 4ba6ba2c0b
commit c650c67627
17 changed files with 86 additions and 138 deletions

View File

@@ -4,8 +4,8 @@ import { useState } from 'react';
import { KanbanBoardContainer } from '@/components/kanban/BoardContainer'; import { KanbanBoardContainer } from '@/components/kanban/BoardContainer';
import { Header } from '@/components/ui/Header'; import { Header } from '@/components/ui/Header';
import { TasksProvider, useTasksContext } from '@/contexts/TasksContext'; import { TasksProvider, useTasksContext } from '@/contexts/TasksContext';
import { UserPreferencesProvider, useUserPreferences } from '@/contexts/UserPreferencesContext'; import { useUserPreferences } from '@/contexts/UserPreferencesContext';
import { Task, Tag, UserPreferences } from '@/lib/types'; import { Task, Tag } from '@/lib/types';
import { CreateTaskData } from '@/clients/tasks-client'; import { CreateTaskData } from '@/clients/tasks-client';
import { CreateTaskForm } from '@/components/forms/CreateTaskForm'; import { CreateTaskForm } from '@/components/forms/CreateTaskForm';
import { Button } from '@/components/ui/Button'; import { Button } from '@/components/ui/Button';
@@ -15,7 +15,6 @@ import { FontSizeToggle } from '@/components/ui/FontSizeToggle';
interface KanbanPageClientProps { interface KanbanPageClientProps {
initialTasks: Task[]; initialTasks: Task[];
initialTags: (Tag & { usage: number })[]; initialTags: (Tag & { usage: number })[];
initialPreferences: UserPreferences;
} }
function KanbanPageContent() { function KanbanPageContent() {
@@ -179,15 +178,13 @@ function KanbanPageContent() {
); );
} }
export function KanbanPageClient({ initialTasks, initialTags, initialPreferences }: KanbanPageClientProps) { export function KanbanPageClient({ initialTasks, initialTags }: KanbanPageClientProps) {
return ( return (
<UserPreferencesProvider initialPreferences={initialPreferences}> <TasksProvider
<TasksProvider initialTasks={initialTasks}
initialTasks={initialTasks} initialTags={initialTags}
initialTags={initialTags} >
> <KanbanPageContent />
<KanbanPageContent /> </TasksProvider>
</TasksProvider>
</UserPreferencesProvider>
); );
} }

View File

@@ -1,6 +1,5 @@
import { tasksService } from '@/services/tasks'; import { tasksService } from '@/services/tasks';
import { tagsService } from '@/services/tags'; import { tagsService } from '@/services/tags';
import { userPreferencesService } from '@/services/user-preferences';
import { KanbanPageClient } from './KanbanPageClient'; import { KanbanPageClient } from './KanbanPageClient';
// Force dynamic rendering (no static generation) // Force dynamic rendering (no static generation)
@@ -8,17 +7,15 @@ export const dynamic = 'force-dynamic';
export default async function KanbanPage() { export default async function KanbanPage() {
// SSR - Récupération des données côté serveur // 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(), tasksService.getTasks(),
tagsService.getTags(), tagsService.getTags()
userPreferencesService.getAllPreferences()
]); ]);
return ( return (
<KanbanPageClient <KanbanPageClient
initialTasks={initialTasks} initialTasks={initialTasks}
initialTags={initialTags} initialTags={initialTags}
initialPreferences={initialPreferences}
/> />
); );
} }

View File

@@ -3,6 +3,7 @@ import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css"; import "./globals.css";
import { ThemeProvider } from "@/contexts/ThemeContext"; import { ThemeProvider } from "@/contexts/ThemeContext";
import { JiraConfigProvider } from "@/contexts/JiraConfigContext"; import { JiraConfigProvider } from "@/contexts/JiraConfigContext";
import { UserPreferencesProvider } from "@/contexts/UserPreferencesContext";
import { userPreferencesService } from "@/services/user-preferences"; import { userPreferencesService } from "@/services/user-preferences";
const geistSans = Geist({ const geistSans = Geist({
@@ -25,20 +26,19 @@ export default async function RootLayout({
}: Readonly<{ }: Readonly<{
children: React.ReactNode; children: React.ReactNode;
}>) { }>) {
// Récupérer les données côté serveur pour le SSR // Récupérer toutes les préférences côté serveur pour le SSR
const [initialTheme, jiraConfig] = await Promise.all([ const initialPreferences = await userPreferencesService.getAllPreferences();
userPreferencesService.getTheme(),
userPreferencesService.getJiraConfig()
]);
return ( return (
<html lang="en" className={initialTheme}> <html lang="en" className={initialPreferences.viewPreferences.theme}>
<body <body
className={`${geistSans.variable} ${geistMono.variable} antialiased`} className={`${geistSans.variable} ${geistMono.variable} antialiased`}
> >
<ThemeProvider initialTheme={initialTheme}> <ThemeProvider initialTheme={initialPreferences.viewPreferences.theme}>
<JiraConfigProvider config={jiraConfig}> <JiraConfigProvider config={initialPreferences.jiraConfig}>
{children} <UserPreferencesProvider initialPreferences={initialPreferences}>
{children}
</UserPreferencesProvider>
</JiraConfigProvider> </JiraConfigProvider>
</ThemeProvider> </ThemeProvider>
</body> </body>

View File

@@ -1,6 +1,5 @@
import { tasksService } from '@/services/tasks'; import { tasksService } from '@/services/tasks';
import { tagsService } from '@/services/tags'; import { tagsService } from '@/services/tags';
import { userPreferencesService } from '@/services/user-preferences';
import { HomePageClient } from '@/components/HomePageClient'; import { HomePageClient } from '@/components/HomePageClient';
// Force dynamic rendering (no static generation) // Force dynamic rendering (no static generation)
@@ -8,10 +7,9 @@ export const dynamic = 'force-dynamic';
export default async function HomePage() { export default async function HomePage() {
// SSR - Récupération des données côté serveur // 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(), tasksService.getTasks(),
tagsService.getTags(), tagsService.getTags(),
userPreferencesService.getAllPreferences(),
tasksService.getTaskStats() tasksService.getTaskStats()
]); ]);
@@ -19,7 +17,6 @@ export default async function HomePage() {
<HomePageClient <HomePageClient
initialTasks={initialTasks} initialTasks={initialTasks}
initialTags={initialTags} initialTags={initialTags}
initialPreferences={initialPreferences}
initialStats={initialStats} initialStats={initialStats}
/> />
); );

View File

@@ -1,4 +1,3 @@
import { userPreferencesService } from '@/services/user-preferences';
import { tasksService } from '@/services/tasks'; import { tasksService } from '@/services/tasks';
import { tagsService } from '@/services/tags'; import { tagsService } from '@/services/tags';
import { backupService } from '@/services/backup'; import { backupService } from '@/services/backup';
@@ -10,8 +9,7 @@ export const dynamic = 'force-dynamic';
export default async function AdvancedSettingsPage() { export default async function AdvancedSettingsPage() {
// Fetch all data server-side // Fetch all data server-side
const [preferences, taskStats, tags] = await Promise.all([ const [taskStats, tags] = await Promise.all([
userPreferencesService.getAllPreferences(),
tasksService.getTaskStats(), tasksService.getTaskStats(),
tagsService.getTags() tagsService.getTags()
]); ]);
@@ -38,7 +36,6 @@ export default async function AdvancedSettingsPage() {
return ( return (
<AdvancedSettingsPageClient <AdvancedSettingsPageClient
initialPreferences={preferences}
initialDbStats={dbStats} initialDbStats={dbStats}
initialBackupData={backupData} initialBackupData={backupData}
/> />

View File

@@ -1,4 +1,3 @@
import { userPreferencesService } from '@/services/user-preferences';
import { tagsService } from '@/services/tags'; import { tagsService } from '@/services/tags';
import { GeneralSettingsPageClient } from '@/components/settings/GeneralSettingsPageClient'; import { GeneralSettingsPageClient } from '@/components/settings/GeneralSettingsPageClient';
@@ -7,10 +6,7 @@ export const dynamic = 'force-dynamic';
export default async function GeneralSettingsPage() { export default async function GeneralSettingsPage() {
// Fetch data server-side // Fetch data server-side
const [preferences, tags] = await Promise.all([ const tags = await tagsService.getTags();
userPreferencesService.getAllPreferences(),
tagsService.getTags()
]);
return <GeneralSettingsPageClient initialPreferences={preferences} initialTags={tags} />; return <GeneralSettingsPageClient initialTags={tags} />;
} }

View File

@@ -6,12 +6,11 @@ export const dynamic = 'force-dynamic';
export default async function IntegrationsSettingsPage() { export default async function IntegrationsSettingsPage() {
// Fetch data server-side // Fetch data server-side
const preferences = await userPreferencesService.getAllPreferences(); // Preferences are now available via context
const jiraConfig = await userPreferencesService.getJiraConfig(); const jiraConfig = await userPreferencesService.getJiraConfig();
return ( return (
<IntegrationsSettingsPageClient <IntegrationsSettingsPageClient
initialPreferences={preferences}
initialJiraConfig={jiraConfig} initialJiraConfig={jiraConfig}
/> />
); );

View File

@@ -1,4 +1,3 @@
import { userPreferencesService } from '@/services/user-preferences';
import { SystemInfoService } from '@/services/system-info'; import { SystemInfoService } from '@/services/system-info';
import { SettingsIndexPageClient } from '@/components/settings/SettingsIndexPageClient'; import { SettingsIndexPageClient } from '@/components/settings/SettingsIndexPageClient';
@@ -7,14 +6,10 @@ export const dynamic = 'force-dynamic';
export default async function SettingsPage() { export default async function SettingsPage() {
// Fetch data in parallel for better performance // Fetch data in parallel for better performance
const [preferences, systemInfo] = await Promise.all([ const systemInfo = await SystemInfoService.getSystemInfo();
userPreferencesService.getAllPreferences(),
SystemInfoService.getSystemInfo()
]);
return ( return (
<SettingsIndexPageClient <SettingsIndexPageClient
initialPreferences={preferences}
initialSystemInfo={systemInfo} initialSystemInfo={systemInfo}
/> />
); );

View File

@@ -1,32 +1,27 @@
'use client'; 'use client';
import { TasksProvider } from '@/contexts/TasksContext'; import { TasksProvider } from '@/contexts/TasksContext';
import { UserPreferencesProvider } from '@/contexts/UserPreferencesContext';
import ManagerWeeklySummary from '@/components/dashboard/ManagerWeeklySummary'; import ManagerWeeklySummary from '@/components/dashboard/ManagerWeeklySummary';
import { ManagerSummary } from '@/services/manager-summary'; import { ManagerSummary } from '@/services/manager-summary';
import { Task, Tag, UserPreferences } from '@/lib/types'; import { Task, Tag } from '@/lib/types';
interface WeeklyManagerPageClientProps { interface WeeklyManagerPageClientProps {
initialSummary: ManagerSummary; initialSummary: ManagerSummary;
initialTasks: Task[]; initialTasks: Task[];
initialTags: (Tag & { usage: number })[]; initialTags: (Tag & { usage: number })[];
initialPreferences: UserPreferences;
} }
export function WeeklyManagerPageClient({ export function WeeklyManagerPageClient({
initialSummary, initialSummary,
initialTasks, initialTasks,
initialTags, initialTags
initialPreferences
}: WeeklyManagerPageClientProps) { }: WeeklyManagerPageClientProps) {
return ( return (
<UserPreferencesProvider initialPreferences={initialPreferences}> <TasksProvider
<TasksProvider initialTasks={initialTasks}
initialTasks={initialTasks} initialTags={initialTags}
initialTags={initialTags} >
> <ManagerWeeklySummary initialSummary={initialSummary} />
<ManagerWeeklySummary initialSummary={initialSummary} /> </TasksProvider>
</TasksProvider>
</UserPreferencesProvider>
); );
} }

View File

@@ -2,7 +2,6 @@ import { Header } from '@/components/ui/Header';
import { ManagerSummaryService } from '@/services/manager-summary'; import { ManagerSummaryService } from '@/services/manager-summary';
import { tasksService } from '@/services/tasks'; import { tasksService } from '@/services/tasks';
import { tagsService } from '@/services/tags'; import { tagsService } from '@/services/tags';
import { userPreferencesService } from '@/services/user-preferences';
import { WeeklyManagerPageClient } from './WeeklyManagerPageClient'; import { WeeklyManagerPageClient } from './WeeklyManagerPageClient';
// Force dynamic rendering (no static generation) // Force dynamic rendering (no static generation)
@@ -10,11 +9,10 @@ export const dynamic = 'force-dynamic';
export default async function WeeklyManagerPage() { export default async function WeeklyManagerPage() {
// SSR - Récupération des données côté serveur // 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(), ManagerSummaryService.getManagerSummary(),
tasksService.getTasks(), tasksService.getTasks(),
tagsService.getTags(), tagsService.getTags()
userPreferencesService.getAllPreferences()
]); ]);
return ( return (
@@ -27,7 +25,6 @@ export default async function WeeklyManagerPage() {
initialSummary={summary} initialSummary={summary}
initialTasks={initialTasks} initialTasks={initialTasks}
initialTags={initialTags} initialTags={initialTags}
initialPreferences={initialPreferences}
/> />
</div> </div>
</div> </div>

View File

@@ -2,8 +2,7 @@
import { Header } from '@/components/ui/Header'; import { Header } from '@/components/ui/Header';
import { TasksProvider, useTasksContext } from '@/contexts/TasksContext'; import { TasksProvider, useTasksContext } from '@/contexts/TasksContext';
import { UserPreferencesProvider } from '@/contexts/UserPreferencesContext'; import { Task, Tag, TaskStats } from '@/lib/types';
import { Task, Tag, UserPreferences, TaskStats } from '@/lib/types';
import { CreateTaskData } from '@/clients/tasks-client'; import { CreateTaskData } from '@/clients/tasks-client';
import { DashboardStats } from '@/components/dashboard/DashboardStats'; import { DashboardStats } from '@/components/dashboard/DashboardStats';
import { QuickActions } from '@/components/dashboard/QuickActions'; import { QuickActions } from '@/components/dashboard/QuickActions';
@@ -13,7 +12,6 @@ import { ProductivityAnalytics } from '@/components/dashboard/ProductivityAnalyt
interface HomePageClientProps { interface HomePageClientProps {
initialTasks: Task[]; initialTasks: Task[];
initialTags: (Tag & { usage: number })[]; initialTags: (Tag & { usage: number })[];
initialPreferences: UserPreferences;
initialStats: TaskStats; initialStats: TaskStats;
} }
@@ -51,16 +49,14 @@ function HomePageContent() {
); );
} }
export function HomePageClient({ initialTasks, initialTags, initialPreferences, initialStats }: HomePageClientProps) { export function HomePageClient({ initialTasks, initialTags, initialStats }: HomePageClientProps) {
return ( return (
<UserPreferencesProvider initialPreferences={initialPreferences}> <TasksProvider
<TasksProvider initialTasks={initialTasks}
initialTasks={initialTasks} initialTags={initialTags}
initialTags={initialTags} initialStats={initialStats}
initialStats={initialStats} >
> <HomePageContent />
<HomePageContent /> </TasksProvider>
</TasksProvider>
</UserPreferencesProvider>
); );
} }

View File

@@ -1,11 +1,9 @@
'use client'; 'use client';
import { useState } from 'react'; import { useState } from 'react';
import { UserPreferences } from '@/lib/types';
import { Header } from '@/components/ui/Header'; import { Header } from '@/components/ui/Header';
import { Card, CardHeader, CardContent } from '@/components/ui/Card'; import { Card, CardHeader, CardContent } from '@/components/ui/Card';
import { Button } from '@/components/ui/Button'; import { Button } from '@/components/ui/Button';
import { UserPreferencesProvider } from '@/contexts/UserPreferencesContext';
import { backupClient, BackupListResponse } from '@/clients/backup-client'; import { backupClient, BackupListResponse } from '@/clients/backup-client';
import Link from 'next/link'; import Link from 'next/link';
import { parseDate, getToday, formatDateForDisplay } from '@/lib/date-utils'; import { parseDate, getToday, formatDateForDisplay } from '@/lib/date-utils';
@@ -17,13 +15,11 @@ interface DatabaseStats {
} }
interface AdvancedSettingsPageClientProps { interface AdvancedSettingsPageClientProps {
initialPreferences: UserPreferences;
initialDbStats: DatabaseStats; initialDbStats: DatabaseStats;
initialBackupData: BackupListResponse; initialBackupData: BackupListResponse;
} }
export function AdvancedSettingsPageClient({ export function AdvancedSettingsPageClient({
initialPreferences,
initialDbStats, initialDbStats,
initialBackupData initialBackupData
}: AdvancedSettingsPageClientProps) { }: AdvancedSettingsPageClientProps) {
@@ -107,8 +103,7 @@ export function AdvancedSettingsPageClient({
}; };
return ( return (
<UserPreferencesProvider initialPreferences={initialPreferences}> <div className="min-h-screen bg-[var(--background)]">
<div className="min-h-screen bg-[var(--background)]">
<Header <Header
title="TowerControl" title="TowerControl"
subtitle="Paramètres avancés" subtitle="Paramètres avancés"
@@ -251,6 +246,5 @@ export function AdvancedSettingsPageClient({
</div> </div>
</div> </div>
</div> </div>
</UserPreferencesProvider>
); );
} }

View File

@@ -1,23 +1,21 @@
'use client'; 'use client';
import { useState, useMemo } from 'react'; import { useState, useMemo } from 'react';
import { UserPreferences, Tag } from '@/lib/types'; import { Tag } from '@/lib/types';
import { useTags } from '@/hooks/useTags'; import { useTags } from '@/hooks/useTags';
import { Header } from '@/components/ui/Header'; import { Header } from '@/components/ui/Header';
import { Card, CardContent, CardHeader } from '@/components/ui/Card'; import { Card, CardContent, CardHeader } from '@/components/ui/Card';
import { Button } from '@/components/ui/Button'; import { Button } from '@/components/ui/Button';
import { Input } from '@/components/ui/Input'; import { Input } from '@/components/ui/Input';
import { TagForm } from '@/components/forms/TagForm'; import { TagForm } from '@/components/forms/TagForm';
import { UserPreferencesProvider } from '@/contexts/UserPreferencesContext';
import Link from 'next/link'; import Link from 'next/link';
import { formatDateForDisplay } from '@/lib/date-utils'; import { formatDateForDisplay } from '@/lib/date-utils';
interface GeneralSettingsPageClientProps { interface GeneralSettingsPageClientProps {
initialPreferences: UserPreferences;
initialTags: Tag[]; initialTags: Tag[];
} }
export function GeneralSettingsPageClient({ initialPreferences, initialTags }: GeneralSettingsPageClientProps) { export function GeneralSettingsPageClient({ initialTags }: GeneralSettingsPageClientProps) {
const { const {
tags, tags,
refreshTags, refreshTags,
@@ -82,8 +80,7 @@ export function GeneralSettingsPageClient({ initialPreferences, initialTags }: G
} }
}; };
return ( return (
<UserPreferencesProvider initialPreferences={initialPreferences}> <div className="min-h-screen bg-[var(--background)]">
<div className="min-h-screen bg-[var(--background)]">
<Header <Header
title="TowerControl" title="TowerControl"
subtitle="Paramètres généraux" subtitle="Paramètres généraux"
@@ -332,31 +329,30 @@ export function GeneralSettingsPageClient({ initialPreferences, initialTags }: G
</div> </div>
</div> </div>
</div> </div>
</div>
{/* Modals pour les tags */} {/* Modals pour les tags */}
{isCreateModalOpen && ( {isCreateModalOpen && (
<TagForm <TagForm
isOpen={isCreateModalOpen} isOpen={isCreateModalOpen}
onClose={() => setIsCreateModalOpen(false)} onClose={() => setIsCreateModalOpen(false)}
onSuccess={async () => { onSuccess={async () => {
setIsCreateModalOpen(false); setIsCreateModalOpen(false);
await refreshTags(); await refreshTags();
}} }}
/> />
)} )}
{editingTag && ( {editingTag && (
<TagForm <TagForm
isOpen={!!editingTag} isOpen={!!editingTag}
tag={editingTag} tag={editingTag}
onClose={() => setEditingTag(null)} onClose={() => setEditingTag(null)}
onSuccess={async () => { onSuccess={async () => {
setEditingTag(null); setEditingTag(null);
await refreshTags(); await refreshTags();
}} }}
/> />
)} )}
</UserPreferencesProvider> </div>
); );
} }

View File

@@ -1,27 +1,23 @@
'use client'; 'use client';
import { UserPreferences, JiraConfig } from '@/lib/types'; import { JiraConfig } from '@/lib/types';
import { Header } from '@/components/ui/Header'; import { Header } from '@/components/ui/Header';
import { Card, CardHeader, CardContent } from '@/components/ui/Card'; import { Card, CardHeader, CardContent } from '@/components/ui/Card';
import { JiraConfigForm } from '@/components/settings/JiraConfigForm'; import { JiraConfigForm } from '@/components/settings/JiraConfigForm';
import { JiraSync } from '@/components/jira/JiraSync'; import { JiraSync } from '@/components/jira/JiraSync';
import { JiraLogs } from '@/components/jira/JiraLogs'; import { JiraLogs } from '@/components/jira/JiraLogs';
import { JiraSchedulerConfig } from '@/components/jira/JiraSchedulerConfig'; import { JiraSchedulerConfig } from '@/components/jira/JiraSchedulerConfig';
import { UserPreferencesProvider } from '@/contexts/UserPreferencesContext';
import Link from 'next/link'; import Link from 'next/link';
interface IntegrationsSettingsPageClientProps { interface IntegrationsSettingsPageClientProps {
initialPreferences: UserPreferences;
initialJiraConfig: JiraConfig; initialJiraConfig: JiraConfig;
} }
export function IntegrationsSettingsPageClient({ export function IntegrationsSettingsPageClient({
initialPreferences,
initialJiraConfig initialJiraConfig
}: IntegrationsSettingsPageClientProps) { }: IntegrationsSettingsPageClientProps) {
return ( return (
<UserPreferencesProvider initialPreferences={initialPreferences}> <div className="min-h-screen bg-[var(--background)]">
<div className="min-h-screen bg-[var(--background)]">
<Header <Header
title="TowerControl" title="TowerControl"
subtitle="Intégrations externes" subtitle="Intégrations externes"
@@ -169,6 +165,5 @@ export function IntegrationsSettingsPageClient({
</div> </div>
</div> </div>
</div> </div>
</UserPreferencesProvider>
); );
} }

View File

@@ -1,9 +1,8 @@
'use client'; 'use client';
import { UserPreferences } from '@/lib/types';
import { Header } from '@/components/ui/Header'; import { Header } from '@/components/ui/Header';
import { Card, CardHeader, CardContent } from '@/components/ui/Card'; import { Card, CardHeader, CardContent } from '@/components/ui/Card';
import { UserPreferencesProvider } from '@/contexts/UserPreferencesContext'; import { useUserPreferences } from '@/contexts/UserPreferencesContext';
import Link from 'next/link'; import Link from 'next/link';
import { useState, useEffect, useTransition } from 'react'; import { useState, useEffect, useTransition } from 'react';
import { backupClient } from '@/clients/backup-client'; import { backupClient } from '@/clients/backup-client';
@@ -12,11 +11,11 @@ import { getSystemInfo } from '@/actions/system-info';
import { SystemInfo } from '@/services/system-info'; import { SystemInfo } from '@/services/system-info';
interface SettingsIndexPageClientProps { interface SettingsIndexPageClientProps {
initialPreferences: UserPreferences;
initialSystemInfo?: SystemInfo; initialSystemInfo?: SystemInfo;
} }
export function SettingsIndexPageClient({ initialPreferences, initialSystemInfo }: SettingsIndexPageClientProps) { export function SettingsIndexPageClient({ initialSystemInfo }: SettingsIndexPageClientProps) {
const { preferences } = useUserPreferences();
// États pour les actions // États pour les actions
const [isBackupLoading, setIsBackupLoading] = useState(false); const [isBackupLoading, setIsBackupLoading] = useState(false);
const [isJiraTestLoading, setIsJiraTestLoading] = useState(false); const [isJiraTestLoading, setIsJiraTestLoading] = useState(false);
@@ -140,8 +139,7 @@ export function SettingsIndexPageClient({ initialPreferences, initialSystemInfo
]; ];
return ( return (
<UserPreferencesProvider initialPreferences={initialPreferences}> <div className="min-h-screen bg-[var(--background)]">
<div className="min-h-screen bg-[var(--background)]">
<Header <Header
title="TowerControl" title="TowerControl"
subtitle="Configuration & Paramètres" subtitle="Configuration & Paramètres"
@@ -167,7 +165,7 @@ export function SettingsIndexPageClient({ initialPreferences, initialSystemInfo
<span className="text-2xl">🎨</span> <span className="text-2xl">🎨</span>
<div> <div>
<p className="text-sm text-[var(--muted-foreground)]">Thème actuel</p> <p className="text-sm text-[var(--muted-foreground)]">Thème actuel</p>
<p className="font-medium capitalize">{initialPreferences.viewPreferences.theme}</p> <p className="font-medium capitalize">{preferences.viewPreferences.theme}</p>
</div> </div>
</div> </div>
</CardContent> </CardContent>
@@ -181,9 +179,9 @@ export function SettingsIndexPageClient({ initialPreferences, initialSystemInfo
<p className="text-sm text-[var(--muted-foreground)]">Jira</p> <p className="text-sm text-[var(--muted-foreground)]">Jira</p>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<p className="font-medium"> <p className="font-medium">
{initialPreferences.jiraConfig.enabled ? 'Configuré' : 'Non configuré'} {preferences.jiraConfig.enabled ? 'Configuré' : 'Non configuré'}
</p> </p>
{initialPreferences.jiraConfig.enabled && ( {preferences.jiraConfig.enabled && (
<span className="w-2 h-2 bg-green-500 rounded-full" title="Jira configuré"></span> <span className="w-2 h-2 bg-green-500 rounded-full" title="Jira configuré"></span>
)} )}
</div> </div>
@@ -198,7 +196,7 @@ export function SettingsIndexPageClient({ initialPreferences, initialSystemInfo
<span className="text-2xl">📏</span> <span className="text-2xl">📏</span>
<div> <div>
<p className="text-sm text-[var(--muted-foreground)]">Taille police</p> <p className="text-sm text-[var(--muted-foreground)]">Taille police</p>
<p className="font-medium capitalize">{initialPreferences.viewPreferences.fontSize}</p> <p className="font-medium capitalize">{preferences.viewPreferences.fontSize}</p>
</div> </div>
</div> </div>
</CardContent> </CardContent>
@@ -325,7 +323,7 @@ export function SettingsIndexPageClient({ initialPreferences, initialSystemInfo
</div> </div>
<button <button
onClick={handleTestJira} onClick={handleTestJira}
disabled={!initialPreferences.jiraConfig.enabled || isJiraTestLoading} disabled={!preferences.jiraConfig.enabled || isJiraTestLoading}
className="px-3 py-1.5 bg-[var(--card)] text-[var(--foreground)] border border-[var(--border)] rounded text-sm disabled:opacity-50 disabled:cursor-not-allowed" className="px-3 py-1.5 bg-[var(--card)] text-[var(--foreground)] border border-[var(--border)] rounded text-sm disabled:opacity-50 disabled:cursor-not-allowed"
> >
{isJiraTestLoading ? 'Test...' : 'Tester'} {isJiraTestLoading ? 'Test...' : 'Tester'}
@@ -404,6 +402,5 @@ export function SettingsIndexPageClient({ initialPreferences, initialSystemInfo
</div> </div>
</div> </div>
</div> </div>
</UserPreferencesProvider>
); );
} }

View File

@@ -1,6 +1,6 @@
import { Task, TaskStatus, TaskPriority, TaskSource } from '@/lib/types'; import { Task, TaskStatus, TaskPriority, TaskSource } from '@/lib/types';
import { prisma } from './database'; import { prisma } from './database';
import { getToday, parseDate, subtractDays, addDays } from '@/lib/date-utils'; import { getToday, parseDate, subtractDays } from '@/lib/date-utils';
export interface ProductivityMetrics { export interface ProductivityMetrics {
completionTrend: Array<{ completionTrend: Array<{

View File

@@ -5,7 +5,7 @@
import { JiraService } from './jira'; import { JiraService } from './jira';
import { jiraAnalyticsCache } from './jira-analytics-cache'; import { jiraAnalyticsCache } from './jira-analytics-cache';
import { getToday, parseDate, addDays, subtractDays } from '@/lib/date-utils'; import { getToday, parseDate, subtractDays } from '@/lib/date-utils';
import { import {
JiraAnalytics, JiraAnalytics,
JiraTask, JiraTask,