feat: enhance useDaily hook and DailyPageClient for improved data handling

- Added `refreshDailySilent` method to `useDaily` for silent data refresh without loading state.
- Updated `useDaily` to accept an optional `initialDailyView` parameter, improving initial state management.
- Modified `DailyPageClient` to utilize `refreshDailySilent` for smoother user experience during checkbox updates.
- Implemented server-side data fetching in `DailyPage` for better initial load performance.
- Enhanced UI to indicate refreshing state in `DailySectionComponent`.
This commit is contained in:
Julien Froidefond
2025-09-15 21:23:03 +02:00
parent 936e0306fc
commit cb2e8e9c9f
3 changed files with 111 additions and 27 deletions

View File

@@ -7,12 +7,14 @@ import { DailyView, DailyCheckbox, UpdateDailyCheckboxData } from '@/lib/types';
interface UseDailyState {
dailyView: DailyView | null;
loading: boolean;
refreshing: boolean; // Pour les refresh silencieux
error: string | null;
saving: boolean; // Pour indiquer les opérations en cours
}
interface UseDailyActions {
refreshDaily: () => Promise<void>;
refreshDailySilent: () => Promise<void>;
addTodayCheckbox: (text: string, taskId?: string) => Promise<DailyCheckbox | null>;
addYesterdayCheckbox: (text: string, taskId?: string) => Promise<DailyCheckbox | null>;
updateCheckbox: (checkboxId: string, data: UpdateDailyCheckboxData) => Promise<DailyCheckbox | null>;
@@ -28,10 +30,11 @@ interface UseDailyActions {
/**
* Hook pour la gestion d'une vue daily spécifique
*/
export function useDaily(initialDate?: Date): UseDailyState & UseDailyActions & { currentDate: Date } {
export function useDaily(initialDate?: Date, initialDailyView?: DailyView): UseDailyState & UseDailyActions & { currentDate: Date } {
const [currentDate, setCurrentDate] = useState<Date>(initialDate || new Date());
const [dailyView, setDailyView] = useState<DailyView | null>(null);
const [loading, setLoading] = useState(true);
const [dailyView, setDailyView] = useState<DailyView | null>(initialDailyView || null);
const [loading, setLoading] = useState(!initialDailyView); // Pas de loading si on a des données SSR
const [refreshing, setRefreshing] = useState(false); // Pour les refresh silencieux
const [error, setError] = useState<string | null>(null);
const [saving, setSaving] = useState(false);
@@ -50,6 +53,20 @@ export function useDaily(initialDate?: Date): UseDailyState & UseDailyActions &
}
}, [currentDate]);
const refreshDailySilent = useCallback(async () => {
try {
setRefreshing(true);
// Refresh silencieux sans setLoading(true) pour éviter le clignotement
const view = await dailyClient.getDailyView(currentDate);
setDailyView(view);
} catch (err) {
console.error('Erreur refreshDailySilent:', err);
// On n'affiche pas l'erreur pour ne pas perturber l'UX
} finally {
setRefreshing(false);
}
}, [currentDate]);
const addTodayCheckbox = useCallback(async (text: string, taskId?: string): Promise<DailyCheckbox | null> => {
if (!dailyView) return null;
@@ -200,21 +217,36 @@ export function useDaily(initialDate?: Date): UseDailyState & UseDailyActions &
setCurrentDate(date);
}, []);
// État pour savoir si c'est le premier chargement
const [isInitialLoad, setIsInitialLoad] = useState(!initialDailyView);
// Charger le daily quand la date change
useEffect(() => {
refreshDaily();
}, [refreshDaily]);
if (isInitialLoad) {
// Premier chargement : utiliser refreshDaily normal seulement si pas de données SSR
if (!initialDailyView) {
refreshDaily().finally(() => setIsInitialLoad(false));
} else {
setIsInitialLoad(false);
}
} else {
// Changements suivants : utiliser refreshDailySilent
refreshDailySilent();
}
}, [refreshDaily, refreshDailySilent, isInitialLoad, initialDailyView]);
return {
// State
dailyView,
loading,
refreshing,
error,
saving,
currentDate,
// Actions
refreshDaily,
refreshDailySilent,
addTodayCheckbox,
addYesterdayCheckbox,
updateCheckbox,