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:
@@ -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>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -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} />;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
{/* Modals pour les tags */}
|
||||||
|
{isCreateModalOpen && (
|
||||||
|
<TagForm
|
||||||
|
isOpen={isCreateModalOpen}
|
||||||
|
onClose={() => setIsCreateModalOpen(false)}
|
||||||
|
onSuccess={async () => {
|
||||||
|
setIsCreateModalOpen(false);
|
||||||
|
await refreshTags();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{editingTag && (
|
||||||
|
<TagForm
|
||||||
|
isOpen={!!editingTag}
|
||||||
|
tag={editingTag}
|
||||||
|
onClose={() => setEditingTag(null)}
|
||||||
|
onSuccess={async () => {
|
||||||
|
setEditingTag(null);
|
||||||
|
await refreshTags();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Modals pour les tags */}
|
|
||||||
{isCreateModalOpen && (
|
|
||||||
<TagForm
|
|
||||||
isOpen={isCreateModalOpen}
|
|
||||||
onClose={() => setIsCreateModalOpen(false)}
|
|
||||||
onSuccess={async () => {
|
|
||||||
setIsCreateModalOpen(false);
|
|
||||||
await refreshTags();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{editingTag && (
|
|
||||||
<TagForm
|
|
||||||
isOpen={!!editingTag}
|
|
||||||
tag={editingTag}
|
|
||||||
onClose={() => setEditingTag(null)}
|
|
||||||
onSuccess={async () => {
|
|
||||||
setEditingTag(null);
|
|
||||||
await refreshTags();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</UserPreferencesProvider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<{
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user