eletrotupi / tcc/ frontend/hooks/useInsights.queries.ts639638a33f393a399e9112ea8bd95a1d9e34d75c
1.8 KB | 60 lines Raw
1
import { format } from "date-fns";
2
import { useQuery } from "@tanstack/react-query";
3
import { apiClient, Insight, InsightType, InsightPeriod } from "@/lib/api";
4

5
// The device's local calendar day, used only to roll the cache over at midnight
6
// so the pair refetches; the server still resolves the actual day boundary
7
function localDay(): string {
8
  return format(new Date(), "yyyy-MM-dd");
9
}
10

11
export const insightKeys = {
12
  all: () => ["insights"] as const,
13
  lists: () => [...insightKeys.all(), "list"] as const,
14
  list: (filters?: InsightFilters) =>
15
    [...insightKeys.lists(), filters] as const,
16
  byType: (type: InsightType) =>
17
    [...insightKeys.all(), "type", type, localDay()] as const,
18
};
19

20
interface InsightFilters {
21
  type?: InsightType;
22
  period?: InsightPeriod;
23
  limit?: number;
24
}
25

26
const INSIGHT_STALE_TIMES: Record<InsightPeriod, number> = {
27
  DAILY: 1000 * 60 * 30, // 30 min, regenerates during the day
28
  WEEKLY: 1000 * 60 * 60 * 4, // 4h only changes on cron or mutations
29
  MONTHLY: 1000 * 60 * 60 * 24, // 24h
30
};
31

32
const INSIGHT_PERIOD: Record<InsightType, InsightPeriod> = {
33
  DAILY_ENERGY: "DAILY",
34
  MOOD_TREND: "WEEKLY",
35
  ENERGY_SLEEP_CORRELATION: "WEEKLY",
36
  TRIGGER_PATTERN: "WEEKLY",
37
  DAILY_SLEEP: "DAILY",
38
};
39

40
export const useInsight = <T extends InsightType>(type: T) => {
41
  const period = INSIGHT_PERIOD[type];
42
  const staleTime = INSIGHT_STALE_TIMES[period];
43

44
  return useQuery({
45
    queryKey: insightKeys.byType(type),
46
    queryFn: () =>
47
      apiClient
48
        .getInsights<T>({ type, limit: 1 })
49
        .then((res) => res.insights[0] ?? null),
50
    staleTime,
51
  });
52
};
53

54
export const useInsights = (filters?: InsightFilters) => {
55
  return useQuery({
56
    queryKey: insightKeys.list(filters),
57
    queryFn: () => apiClient.getInsights(filters).then((res) => res.insights),
58
    staleTime: 1000 * 60 * 15,
59
  });
60
};