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.
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import { DailyCheckbox, DailyCheckboxType } from '@/lib/types';
|
import { DailyCheckbox, DailyCheckboxType } from '@/lib/types';
|
||||||
import { Card } from '@/components/ui/Card';
|
import { Card } from '@/components/ui/Card';
|
||||||
|
import { Button } from '@/components/ui/Button';
|
||||||
import { DailyCheckboxItem } from './DailyCheckboxItem';
|
import { DailyCheckboxItem } from './DailyCheckboxItem';
|
||||||
import { DailyAddForm } from './DailyAddForm';
|
import { DailyAddForm } from './DailyAddForm';
|
||||||
|
|
||||||
@@ -13,6 +14,7 @@ interface DailySectionProps {
|
|||||||
onToggleCheckbox: (checkboxId: string) => Promise<void>;
|
onToggleCheckbox: (checkboxId: string) => Promise<void>;
|
||||||
onUpdateCheckbox: (checkboxId: string, text: string, type: DailyCheckboxType, taskId?: string) => Promise<void>;
|
onUpdateCheckbox: (checkboxId: string, text: string, type: DailyCheckboxType, taskId?: string) => Promise<void>;
|
||||||
onDeleteCheckbox: (checkboxId: string) => Promise<void>;
|
onDeleteCheckbox: (checkboxId: string) => Promise<void>;
|
||||||
|
onToggleAll?: () => Promise<void>;
|
||||||
saving: boolean;
|
saving: boolean;
|
||||||
refreshing?: boolean;
|
refreshing?: boolean;
|
||||||
}
|
}
|
||||||
@@ -25,6 +27,7 @@ export function DailySection({
|
|||||||
onToggleCheckbox,
|
onToggleCheckbox,
|
||||||
onUpdateCheckbox,
|
onUpdateCheckbox,
|
||||||
onDeleteCheckbox,
|
onDeleteCheckbox,
|
||||||
|
onToggleAll,
|
||||||
saving,
|
saving,
|
||||||
refreshing = false
|
refreshing = false
|
||||||
}: DailySectionProps) {
|
}: DailySectionProps) {
|
||||||
@@ -47,9 +50,24 @@ export function DailySection({
|
|||||||
<div className="w-4 h-4 border-2 border-[var(--primary)] border-t-transparent rounded-full animate-spin"></div>
|
<div className="w-4 h-4 border-2 border-[var(--primary)] border-t-transparent rounded-full animate-spin"></div>
|
||||||
)}
|
)}
|
||||||
</h2>
|
</h2>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
<span className="text-xs text-[var(--muted-foreground)] font-mono">
|
<span className="text-xs text-[var(--muted-foreground)] font-mono">
|
||||||
{checkboxes.filter(cb => cb.isChecked).length}/{checkboxes.length}
|
{checkboxes.filter(cb => cb.isChecked).length}/{checkboxes.length}
|
||||||
</span>
|
</span>
|
||||||
|
{onToggleAll && checkboxes.length > 0 && (
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
onClick={onToggleAll}
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
disabled={saving}
|
||||||
|
className="text-xs px-2 py-1 h-6"
|
||||||
|
title="Tout cocher/décocher"
|
||||||
|
>
|
||||||
|
✓
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ interface UseDailyActions {
|
|||||||
updateCheckbox: (checkboxId: string, data: UpdateDailyCheckboxData) => Promise<DailyCheckbox | null>;
|
updateCheckbox: (checkboxId: string, data: UpdateDailyCheckboxData) => Promise<DailyCheckbox | null>;
|
||||||
deleteCheckbox: (checkboxId: string) => Promise<void>;
|
deleteCheckbox: (checkboxId: string) => Promise<void>;
|
||||||
toggleCheckbox: (checkboxId: string) => Promise<void>;
|
toggleCheckbox: (checkboxId: string) => Promise<void>;
|
||||||
|
toggleAllToday: () => Promise<void>;
|
||||||
|
toggleAllYesterday: () => Promise<void>;
|
||||||
reorderCheckboxes: (data: ReorderCheckboxesData) => Promise<void>;
|
reorderCheckboxes: (data: ReorderCheckboxesData) => Promise<void>;
|
||||||
goToPreviousDay: () => Promise<void>;
|
goToPreviousDay: () => Promise<void>;
|
||||||
goToNextDay: () => Promise<void>;
|
goToNextDay: () => Promise<void>;
|
||||||
@@ -278,6 +280,72 @@ export function useDaily(initialDate?: Date, initialDailyView?: DailyView): UseD
|
|||||||
}
|
}
|
||||||
}, [dailyView]);
|
}, [dailyView]);
|
||||||
|
|
||||||
|
const toggleAllToday = useCallback(async (): Promise<void> => {
|
||||||
|
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<void> => {
|
||||||
|
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<void> => {
|
const reorderCheckboxes = useCallback(async (data: ReorderCheckboxesData): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
setSaving(true);
|
setSaving(true);
|
||||||
@@ -350,6 +418,8 @@ export function useDaily(initialDate?: Date, initialDailyView?: DailyView): UseD
|
|||||||
updateCheckbox,
|
updateCheckbox,
|
||||||
deleteCheckbox,
|
deleteCheckbox,
|
||||||
toggleCheckbox,
|
toggleCheckbox,
|
||||||
|
toggleAllToday,
|
||||||
|
toggleAllYesterday,
|
||||||
reorderCheckboxes,
|
reorderCheckboxes,
|
||||||
goToPreviousDay,
|
goToPreviousDay,
|
||||||
goToNextDay,
|
goToNextDay,
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ export function DailyPageClient({
|
|||||||
addTodayCheckbox,
|
addTodayCheckbox,
|
||||||
addYesterdayCheckbox,
|
addYesterdayCheckbox,
|
||||||
toggleCheckbox,
|
toggleCheckbox,
|
||||||
|
toggleAllToday,
|
||||||
|
toggleAllYesterday,
|
||||||
updateCheckbox,
|
updateCheckbox,
|
||||||
deleteCheckbox,
|
deleteCheckbox,
|
||||||
goToPreviousDay,
|
goToPreviousDay,
|
||||||
@@ -218,6 +220,7 @@ export function DailyPageClient({
|
|||||||
onToggleCheckbox={handleToggleCheckbox}
|
onToggleCheckbox={handleToggleCheckbox}
|
||||||
onUpdateCheckbox={handleUpdateCheckbox}
|
onUpdateCheckbox={handleUpdateCheckbox}
|
||||||
onDeleteCheckbox={handleDeleteCheckbox}
|
onDeleteCheckbox={handleDeleteCheckbox}
|
||||||
|
onToggleAll={toggleAllYesterday}
|
||||||
saving={saving}
|
saving={saving}
|
||||||
refreshing={refreshing}
|
refreshing={refreshing}
|
||||||
/>
|
/>
|
||||||
@@ -231,6 +234,7 @@ export function DailyPageClient({
|
|||||||
onToggleCheckbox={handleToggleCheckbox}
|
onToggleCheckbox={handleToggleCheckbox}
|
||||||
onUpdateCheckbox={handleUpdateCheckbox}
|
onUpdateCheckbox={handleUpdateCheckbox}
|
||||||
onDeleteCheckbox={handleDeleteCheckbox}
|
onDeleteCheckbox={handleDeleteCheckbox}
|
||||||
|
onToggleAll={toggleAllToday}
|
||||||
saving={saving}
|
saving={saving}
|
||||||
refreshing={refreshing}
|
refreshing={refreshing}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user