feat: add initial pending tasks support in DailyPage

- Updated `DailyPageClient` to accept and pass `initialPendingTasks` to the `PendingTasksSection`.
- Modified `page.tsx` to fetch pending tasks from the service and handle graceful fallbacks.
- Adjusted `PendingTasksSection` to initialize state with `initialPendingTasks` and prevent unnecessary loading when initial data is present.
This commit is contained in:
Julien Froidefond
2025-09-25 21:36:13 +02:00
parent 0f22ae7019
commit a870f7f3dc
3 changed files with 26 additions and 9 deletions

View File

@@ -3,7 +3,7 @@
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import React from 'react'; import React from 'react';
import { useDaily } from '@/hooks/useDaily'; import { useDaily } from '@/hooks/useDaily';
import { DailyView, DailyCheckboxType } from '@/lib/types'; import { DailyView, DailyCheckboxType, DailyCheckbox } from '@/lib/types';
import { DeadlineMetrics } from '@/services/analytics/deadline-analytics'; import { DeadlineMetrics } from '@/services/analytics/deadline-analytics';
import { Button } from '@/components/ui/Button'; import { Button } from '@/components/ui/Button';
import { Card } from '@/components/ui/Card'; import { Card } from '@/components/ui/Card';
@@ -20,13 +20,15 @@ interface DailyPageClientProps {
initialDailyDates?: string[]; initialDailyDates?: string[];
initialDate?: Date; initialDate?: Date;
initialDeadlineMetrics?: DeadlineMetrics | null; initialDeadlineMetrics?: DeadlineMetrics | null;
initialPendingTasks?: DailyCheckbox[];
} }
export function DailyPageClient({ export function DailyPageClient({
initialDailyView, initialDailyView,
initialDailyDates = [], initialDailyDates = [],
initialDate, initialDate,
initialDeadlineMetrics initialDeadlineMetrics,
initialPendingTasks = []
}: DailyPageClientProps = {}) { }: DailyPageClientProps = {}) {
const { const {
dailyView, dailyView,
@@ -306,6 +308,7 @@ export function DailyPageClient({
onDeleteCheckbox={handleDeleteCheckbox} onDeleteCheckbox={handleDeleteCheckbox}
onRefreshDaily={refreshDailySilent} onRefreshDaily={refreshDailySilent}
refreshTrigger={refreshTrigger} refreshTrigger={refreshTrigger}
initialPendingTasks={initialPendingTasks}
/> />
{/* Footer avec stats - dans le flux normal */} {/* Footer avec stats - dans le flux normal */}

View File

@@ -17,10 +17,15 @@ export default async function DailyPage() {
const today = getToday(); const today = getToday();
try { try {
const [dailyView, dailyDates, deadlineMetrics] = await Promise.all([ const [dailyView, dailyDates, deadlineMetrics, pendingTasks] = await Promise.all([
dailyService.getDailyView(today), dailyService.getDailyView(today),
dailyService.getDailyDates(), dailyService.getDailyDates(),
DeadlineAnalyticsService.getDeadlineMetrics().catch(() => null) // Graceful fallback DeadlineAnalyticsService.getDeadlineMetrics().catch(() => null), // Graceful fallback
dailyService.getPendingCheckboxes({
maxDays: 7,
excludeToday: true,
limit: 50
}).catch(() => []) // Graceful fallback
]); ]);
return ( return (
@@ -29,6 +34,7 @@ export default async function DailyPage() {
initialDailyDates={dailyDates} initialDailyDates={dailyDates}
initialDate={today} initialDate={today}
initialDeadlineMetrics={deadlineMetrics} initialDeadlineMetrics={deadlineMetrics}
initialPendingTasks={pendingTasks}
/> />
); );
} catch (error) { } catch (error) {

View File

@@ -13,16 +13,18 @@ interface PendingTasksSectionProps {
onDeleteCheckbox: (checkboxId: string) => Promise<void>; onDeleteCheckbox: (checkboxId: string) => Promise<void>;
onRefreshDaily?: () => Promise<void>; // Pour rafraîchir la vue daily principale onRefreshDaily?: () => Promise<void>; // Pour rafraîchir la vue daily principale
refreshTrigger?: number; // Pour forcer le refresh depuis le parent refreshTrigger?: number; // Pour forcer le refresh depuis le parent
initialPendingTasks?: DailyCheckbox[]; // Données SSR
} }
export function PendingTasksSection({ export function PendingTasksSection({
onToggleCheckbox, onToggleCheckbox,
onDeleteCheckbox, onDeleteCheckbox,
onRefreshDaily, onRefreshDaily,
refreshTrigger refreshTrigger,
initialPendingTasks = []
}: PendingTasksSectionProps) { }: PendingTasksSectionProps) {
const [isCollapsed, setIsCollapsed] = useState(true); const [isCollapsed, setIsCollapsed] = useState(false); // Open by default
const [pendingTasks, setPendingTasks] = useState<DailyCheckbox[]>([]); const [pendingTasks, setPendingTasks] = useState<DailyCheckbox[]>(initialPendingTasks);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [isPending, startTransition] = useTransition(); const [isPending, startTransition] = useTransition();
const [filters, setFilters] = useState({ const [filters, setFilters] = useState({
@@ -52,9 +54,15 @@ export function PendingTasksSection({
// Charger au montage et quand les filtres changent // Charger au montage et quand les filtres changent
useEffect(() => { useEffect(() => {
if (!isCollapsed) { if (!isCollapsed) {
// Si on a des données initiales et qu'on utilise les filtres par défaut, ne pas recharger
const hasInitialData = initialPendingTasks.length > 0;
const usingDefaultFilters = filters.maxDays === 7 && filters.type === 'all' && filters.limit === 50;
if (!hasInitialData || !usingDefaultFilters) {
loadPendingTasks(); loadPendingTasks();
} }
}, [isCollapsed, filters, refreshTrigger, loadPendingTasks]); }
}, [isCollapsed, filters, refreshTrigger, loadPendingTasks, initialPendingTasks.length]);
// Gérer l'archivage d'une tâche // Gérer l'archivage d'une tâche
const handleArchiveTask = async (checkboxId: string) => { const handleArchiveTask = async (checkboxId: string) => {