From 44df8c89b822a1c3ac7a34dd6d0a69ec0c103bfd Mon Sep 17 00:00:00 2001 From: Julien Froidefond Date: Mon, 15 Sep 2025 21:31:34 +0200 Subject: [PATCH] feat: add user preferences for filter and objective visibility in HomePageClient - Implemented state management for filter and objective visibility using `useState`. - Integrated `userPreferencesService` to load and save user preferences on component mount and toggle actions. - Updated `KanbanBoardContainer` to conditionally render filters and objectives based on user preferences. - Enhanced UI with buttons for toggling visibility, improving user experience and customization. --- components/HomePageClient.tsx | 72 ++++++++++++++++++++++- components/kanban/BoardContainer.tsx | 29 ++++++--- components/ui/Header.tsx | 61 ++++--------------- components/ui/SimpleHeader.tsx | 78 ++++++++++++++++++++++++ services/user-preferences.ts | 4 +- src/app/daily/DailyPageClient.tsx | 88 +++++++++++++--------------- src/app/tags/TagsPageClient.tsx | 34 ++++------- 7 files changed, 235 insertions(+), 131 deletions(-) create mode 100644 components/ui/SimpleHeader.tsx diff --git a/components/HomePageClient.tsx b/components/HomePageClient.tsx index dfbbf9a..eee7ba8 100644 --- a/components/HomePageClient.tsx +++ b/components/HomePageClient.tsx @@ -1,9 +1,11 @@ 'use client'; +import { useState, useEffect } from 'react'; import { KanbanBoardContainer } from '@/components/kanban/BoardContainer'; import { Header } from '@/components/ui/Header'; import { TasksProvider, useTasksContext } from '@/contexts/TasksContext'; import { Task, Tag, TaskStats } from '@/lib/types'; +import { userPreferencesService } from '@/services/user-preferences'; interface HomePageClientProps { initialTasks: Task[]; @@ -13,6 +15,28 @@ interface HomePageClientProps { function HomePageContent() { const { stats, syncing } = useTasksContext(); + const [showFilters, setShowFilters] = useState(true); + const [showObjectives, setShowObjectives] = useState(true); + + // Charger les préférences depuis le service + useEffect(() => { + const viewPreferences = userPreferencesService.getViewPreferences(); + setShowFilters(viewPreferences.showFilters); + setShowObjectives(viewPreferences.showObjectives); + }, []); + + // Sauvegarder les préférences via le service + const handleToggleFilters = () => { + const newValue = !showFilters; + setShowFilters(newValue); + userPreferencesService.updateViewPreferences({ showFilters: newValue }); + }; + + const handleToggleObjectives = () => { + const newValue = !showObjectives; + setShowObjectives(newValue); + userPreferencesService.updateViewPreferences({ showObjectives: newValue }); + }; return (
@@ -23,8 +47,52 @@ function HomePageContent() { syncing={syncing} /> -
- + {/* Barre de contrôles de visibilité */} +
+
+
+
+ + + +
+ +
+ Affichage des composants +
+
+
+
+ +
+
); diff --git a/components/kanban/BoardContainer.tsx b/components/kanban/BoardContainer.tsx index 3012af3..0c049ec 100644 --- a/components/kanban/BoardContainer.tsx +++ b/components/kanban/BoardContainer.tsx @@ -13,7 +13,15 @@ import { UpdateTaskData } from '@/clients/tasks-client'; import { useColumnVisibility } from '@/hooks/useColumnVisibility'; import { getAllStatuses } from '@/lib/status-config'; -export function KanbanBoardContainer() { +interface KanbanBoardContainerProps { + showFilters?: boolean; + showObjectives?: boolean; +} + +export function KanbanBoardContainer({ + showFilters = true, + showObjectives = true +}: KanbanBoardContainerProps = {}) { const { filteredTasks, pinnedTasks, @@ -61,15 +69,18 @@ export function KanbanBoardContainer() { return ( <> - + {/* Barre de filtres - conditionnelle */} + {showFilters && ( + + )} - {/* Section Objectifs Principaux */} - {pinnedTasks.length > 0 && ( + {/* Section Objectifs Principaux - conditionnelle */} + {showObjectives && pinnedTasks.length > 0 && ( - {/* Stats tech dashboard */} + {/* Stats essentielles */}
- {stats.completed > 0 && ( - - )} - {stats.inProgress > 0 && ( - - )} - {stats.backlog > 0 && ( - - )} - {stats.todo > 0 && ( - - )} - {stats.freeze > 0 && ( - - )} - {stats.cancelled > 0 && ( - - )} - {stats.archived > 0 && ( - - )} + + +
+
+ {/* Titre tech avec glow */} +
+
+
+
+

+ {title} +

+

+ {subtitle} {syncing && '• Synchronisation...'} +

+
+
+ + {/* Navigation */} + +
+
+
+ + ); +} diff --git a/services/user-preferences.ts b/services/user-preferences.ts index 2173187..996ff30 100644 --- a/services/user-preferences.ts +++ b/services/user-preferences.ts @@ -14,6 +14,7 @@ export interface ViewPreferences { swimlanesByTags: boolean; swimlanesMode?: 'tags' | 'priority'; showObjectives: boolean; + showFilters: boolean; } export interface ColumnVisibility { @@ -37,7 +38,8 @@ const DEFAULT_PREFERENCES: UserPreferences = { viewPreferences: { compactView: false, swimlanesByTags: false, - showObjectives: true + showObjectives: true, + showFilters: true }, columnVisibility: { hiddenStatuses: [] diff --git a/src/app/daily/DailyPageClient.tsx b/src/app/daily/DailyPageClient.tsx index 98bfe25..b639b0b 100644 --- a/src/app/daily/DailyPageClient.tsx +++ b/src/app/daily/DailyPageClient.tsx @@ -10,6 +10,7 @@ import { Card } from '@/components/ui/Card'; import Link from 'next/link'; import { DailyCalendar } from '@/components/daily/DailyCalendar'; import { dailyClient } from '@/clients/daily-client'; +import { SimpleHeader } from '@/components/ui/SimpleHeader'; interface DailySectionProps { title: string; @@ -367,58 +368,51 @@ export function DailyPageClient({ return (
- {/* Header */} -
-
-
-
- - ← Kanban - -

- 📝 Daily -

-
+ {/* Header uniforme */} + -
- - -
-
- {formatCurrentDate()} -
- {!isToday() && ( - - )} + {/* Navigation Daily spécifique */} +
+
+
+ + +
+
+ {formatCurrentDate()}
- - + {!isToday() && ( + + )}
+ +
-
+
{/* Contenu principal */}
diff --git a/src/app/tags/TagsPageClient.tsx b/src/app/tags/TagsPageClient.tsx index b4608b4..45380a2 100644 --- a/src/app/tags/TagsPageClient.tsx +++ b/src/app/tags/TagsPageClient.tsx @@ -8,7 +8,7 @@ import { CreateTagData } from '@/clients/tags-client'; import { Button } from '@/components/ui/Button'; import { Input } from '@/components/ui/Input'; import { TagForm } from '@/components/forms/TagForm'; -import Link from 'next/link'; +import { SimpleHeader } from '@/components/ui/SimpleHeader'; interface TagsPageClientProps { initialTags: Tag[]; @@ -82,31 +82,21 @@ export function TagsPageClient({ initialTags }: TagsPageClientProps) { return (
- {/* Header simplifié */} -
+ {/* Header uniforme */} + + + {/* Header spécifique aux tags */} +
- {/* Bouton retour */} - - - - - - -
-

+

Tags ({filteredAndSortedTags.length}) -

+