84 lines
3.0 KiB
JavaScript
84 lines
3.0 KiB
JavaScript
import { useQuery, useQueryClient, keepPreviousData } from '@tanstack/react-query';
|
|
import { useCallback } from 'react';
|
|
import { api } from '@/api';
|
|
|
|
// Custom hook for fetching tracker data
|
|
export function useTracker(year, month) {
|
|
return useQuery({
|
|
queryKey: ['tracker', year, month],
|
|
queryFn: () => api.tracker(year, month),
|
|
staleTime: 1000 * 60 * 5, // 5 minutes
|
|
cacheTime: 1000 * 60 * 30, // 30 minutes
|
|
});
|
|
}
|
|
|
|
// Custom hook for fetching all bills
|
|
export function useBills() {
|
|
return useQuery({
|
|
queryKey: ['bills'],
|
|
queryFn: () => api.allBills(),
|
|
staleTime: 1000 * 60 * 5, // 5 minutes
|
|
cacheTime: 1000 * 60 * 30, // 30 minutes
|
|
});
|
|
}
|
|
|
|
// Custom hook for fetching categories
|
|
export function useCategories() {
|
|
return useQuery({
|
|
queryKey: ['categories'],
|
|
queryFn: () => api.categories(),
|
|
staleTime: 1000 * 60 * 60, // 1 hour
|
|
cacheTime: 1000 * 60 * 60 * 2, // 2 hours
|
|
});
|
|
}
|
|
|
|
// Lightweight overdue count for sidebar badge — polls every 5 minutes
|
|
export function useOverdueCount() {
|
|
return useQuery({
|
|
queryKey: ['overdue-count'],
|
|
queryFn: () => api.overdueCount(),
|
|
staleTime: 1000 * 60 * 2, // 2 minutes
|
|
refetchInterval: 1000 * 60 * 5, // poll every 5 minutes
|
|
refetchIntervalInBackground: false, // only when tab is active
|
|
});
|
|
}
|
|
// Drift / price-change report — refreshed on demand, not auto-polled
|
|
export function useDriftReport() {
|
|
return useQuery({
|
|
queryKey: ['drift-report'],
|
|
queryFn: () => api.driftReport(),
|
|
staleTime: 1000 * 60 * 10,
|
|
refetchOnWindowFocus: false,
|
|
});
|
|
}
|
|
|
|
// A single invalidation for every query a bill mutation can affect. Previously a
|
|
// row action only refetch()'d the one tracker query passed down as `refresh`, so
|
|
// the sidebar overdue badge (['overdue-count'], 2-min staleTime), the drift
|
|
// report and the bills list stayed stale after paying/skipping/editing a bill —
|
|
// e.g. clearing your last overdue bill still showed "3" on the badge for minutes.
|
|
// Hand this to rows / BillModal.onSave / payment + sync handlers so the whole
|
|
// shell updates live. Returns a stable callback safe to use as an effect dep.
|
|
export function useInvalidateTrackerData() {
|
|
const queryClient = useQueryClient();
|
|
return useCallback(() => {
|
|
for (const key of [['tracker'], ['overdue-count'], ['drift-report'], ['bills']]) {
|
|
queryClient.invalidateQueries({ queryKey: key });
|
|
}
|
|
}, [queryClient]);
|
|
}
|
|
|
|
// ── Page data (migrated off manual useEffect + load()) ───────────────────────
|
|
// The queryKey encodes the params, so React Query handles caching, request
|
|
// dedup, cancellation, and out-of-order responses — no manual sequence guards.
|
|
// keepPreviousData keeps the last result visible while a new month/filter loads.
|
|
|
|
export function useAnalyticsSummary(params) {
|
|
return useQuery({
|
|
queryKey: ['analytics-summary', params],
|
|
queryFn: () => api.analyticsSummary(params),
|
|
staleTime: 1000 * 60 * 2,
|
|
placeholderData: keepPreviousData,
|
|
});
|
|
}
|