From 11200f85ac5328077e1b3a4e0bf1ce0f574a5409 Mon Sep 17 00:00:00 2001 From: Julien Froidefond Date: Tue, 16 Sep 2025 08:09:13 +0200 Subject: [PATCH] feat: add toggle all functionality for daily checkboxes - Implemented `toggleAllToday` and `toggleAllYesterday` methods in `useDaily` for batch checkbox state management. - Updated `DailySection` to include a button for toggling all checkboxes, enhancing user interaction. - Integrated new toggle functions in `DailyPageClient` to support the updated checkbox handling. --- components/daily/DailySection.tsx | 24 +++++++++-- hooks/useDaily.ts | 70 +++++++++++++++++++++++++++++++ src/app/daily/DailyPageClient.tsx | 4 ++ 3 files changed, 95 insertions(+), 3 deletions(-) diff --git a/components/daily/DailySection.tsx b/components/daily/DailySection.tsx index dcda622..0b9b161 100644 --- a/components/daily/DailySection.tsx +++ b/components/daily/DailySection.tsx @@ -2,6 +2,7 @@ import { DailyCheckbox, DailyCheckboxType } from '@/lib/types'; import { Card } from '@/components/ui/Card'; +import { Button } from '@/components/ui/Button'; import { DailyCheckboxItem } from './DailyCheckboxItem'; import { DailyAddForm } from './DailyAddForm'; @@ -13,6 +14,7 @@ interface DailySectionProps { onToggleCheckbox: (checkboxId: string) => Promise; onUpdateCheckbox: (checkboxId: string, text: string, type: DailyCheckboxType, taskId?: string) => Promise; onDeleteCheckbox: (checkboxId: string) => Promise; + onToggleAll?: () => Promise; saving: boolean; refreshing?: boolean; } @@ -25,6 +27,7 @@ export function DailySection({ onToggleCheckbox, onUpdateCheckbox, onDeleteCheckbox, + onToggleAll, saving, refreshing = false }: DailySectionProps) { @@ -47,9 +50,24 @@ export function DailySection({
)} - - {checkboxes.filter(cb => cb.isChecked).length}/{checkboxes.length} - +
+ + {checkboxes.filter(cb => cb.isChecked).length}/{checkboxes.length} + + {onToggleAll && checkboxes.length > 0 && ( + + )} +
diff --git a/hooks/useDaily.ts b/hooks/useDaily.ts index 9e46dff..7ccc3c8 100644 --- a/hooks/useDaily.ts +++ b/hooks/useDaily.ts @@ -20,6 +20,8 @@ interface UseDailyActions { updateCheckbox: (checkboxId: string, data: UpdateDailyCheckboxData) => Promise; deleteCheckbox: (checkboxId: string) => Promise; toggleCheckbox: (checkboxId: string) => Promise; + toggleAllToday: () => Promise; + toggleAllYesterday: () => Promise; reorderCheckboxes: (data: ReorderCheckboxesData) => Promise; goToPreviousDay: () => Promise; goToNextDay: () => Promise; @@ -278,6 +280,72 @@ export function useDaily(initialDate?: Date, initialDailyView?: DailyView): UseD } }, [dailyView]); + const toggleAllToday = useCallback(async (): Promise => { + if (!dailyView) return; + + const todayCheckboxes = dailyView.today; + if (todayCheckboxes.length === 0) return; + + // Déterminer si on coche tout ou on décoche tout + const allChecked = todayCheckboxes.every(cb => cb.isChecked); + const newCheckedState = !allChecked; + + const previousDailyView = dailyView; + + // Mise à jour optimiste IMMÉDIATE + setDailyView(prev => prev ? { + ...prev, + today: prev.today.map(cb => ({ ...cb, isChecked: newCheckedState })) + } : null); + + try { + // Appeler l'API pour chaque checkbox en parallèle + await Promise.all( + todayCheckboxes.map(checkbox => + dailyClient.updateCheckbox(checkbox.id, { isChecked: newCheckedState }) + ) + ); + } catch (err) { + // Rollback en cas d'erreur + setDailyView(previousDailyView); + setError(err instanceof Error ? err.message : 'Erreur lors de la mise à jour des checkboxes'); + console.error('Erreur toggleAllToday:', err); + } + }, [dailyView]); + + const toggleAllYesterday = useCallback(async (): Promise => { + if (!dailyView) return; + + const yesterdayCheckboxes = dailyView.yesterday; + if (yesterdayCheckboxes.length === 0) return; + + // Déterminer si on coche tout ou on décoche tout + const allChecked = yesterdayCheckboxes.every(cb => cb.isChecked); + const newCheckedState = !allChecked; + + const previousDailyView = dailyView; + + // Mise à jour optimiste IMMÉDIATE + setDailyView(prev => prev ? { + ...prev, + yesterday: prev.yesterday.map(cb => ({ ...cb, isChecked: newCheckedState })) + } : null); + + try { + // Appeler l'API pour chaque checkbox en parallèle + await Promise.all( + yesterdayCheckboxes.map(checkbox => + dailyClient.updateCheckbox(checkbox.id, { isChecked: newCheckedState }) + ) + ); + } catch (err) { + // Rollback en cas d'erreur + setDailyView(previousDailyView); + setError(err instanceof Error ? err.message : 'Erreur lors de la mise à jour des checkboxes'); + console.error('Erreur toggleAllYesterday:', err); + } + }, [dailyView]); + const reorderCheckboxes = useCallback(async (data: ReorderCheckboxesData): Promise => { try { setSaving(true); @@ -350,6 +418,8 @@ export function useDaily(initialDate?: Date, initialDailyView?: DailyView): UseD updateCheckbox, deleteCheckbox, toggleCheckbox, + toggleAllToday, + toggleAllYesterday, reorderCheckboxes, goToPreviousDay, goToNextDay, diff --git a/src/app/daily/DailyPageClient.tsx b/src/app/daily/DailyPageClient.tsx index bf79f9a..a581f9d 100644 --- a/src/app/daily/DailyPageClient.tsx +++ b/src/app/daily/DailyPageClient.tsx @@ -32,6 +32,8 @@ export function DailyPageClient({ addTodayCheckbox, addYesterdayCheckbox, toggleCheckbox, + toggleAllToday, + toggleAllYesterday, updateCheckbox, deleteCheckbox, goToPreviousDay, @@ -218,6 +220,7 @@ export function DailyPageClient({ onToggleCheckbox={handleToggleCheckbox} onUpdateCheckbox={handleUpdateCheckbox} onDeleteCheckbox={handleDeleteCheckbox} + onToggleAll={toggleAllYesterday} saving={saving} refreshing={refreshing} /> @@ -231,6 +234,7 @@ export function DailyPageClient({ onToggleCheckbox={handleToggleCheckbox} onUpdateCheckbox={handleUpdateCheckbox} onDeleteCheckbox={handleDeleteCheckbox} + onToggleAll={toggleAllToday} saving={saving} refreshing={refreshing} />