frontend: add sleep record hooks/queries

Pedro Lucas Porcellis porcellis@eletrotupi.com 24 days ago c00102e4121175ec5a0ad91435073a5e8f33e3c1
Parents: 5e76bad
2 file(s) changed
  • frontend/hooks/index.ts +5 -0
  • frontend/hooks/useSleepRecord.queries.ts +65 -0
frontend/hooks/index.ts
@@ -16,3 +16,8 @@ useMoodEntry,
16 16 useCreateMoodEntry,
17 17 useDeleteMoodEntry
18 18 } from '@/hooks/useMoodEntries.queries';
19 +
20 + export {
21 + useSleepRecords,
22 + useCreateSleepRecord
23 + } from '@/hooks/useSleepRecord.queries';
frontend/hooks/useSleepRecord.queries.ts
@@ -0,0 +1,65 @@
1 + import {
2 + useQuery,
3 + useMutation,
4 + useQueryClient
5 + } from '@tanstack/react-query';
6 +
7 + import { apiClient, SleepRecord, SleepRecordPayload } from '@/lib/api';
8 +
9 + export const sleepRecordKeys = {
10 + all: () => ['sleep-records'] as const,
11 + lists: () => [...sleepRecordKeys.all(), 'list'] as const,
12 + list: (filters?: SleepRecordFilters) => [...sleepRecordKeys.lists(), filters] as const,
13 + detail: (id: string) => [...sleepRecordKeys.all(), 'detail', id] as const,
14 + };
15 +
16 + interface SleepRecordFilters {
17 + from?: string; // ISO date
18 + to?: string; // ISO date
19 + limit?: number;
20 + }
21 +
22 + export const useSleepRecords = (filters?: SleepRecordFilters) => {
23 + return useQuery({
24 + queryKey: sleepRecordKeys.list(filters),
25 + queryFn: () => apiClient.getSleepRecords(filters),
26 + });
27 + };
28 +
29 + export const useCreateSleepRecord = () => {
30 + const queryClient = useQueryClient();
31 +
32 + return useMutation({
33 + mutationFn: (payload: SleepRecordPayload) =>
34 + apiClient.createSleepRecord(payload),
35 +
36 + onMutate: async (payload) => {
37 + await queryClient.cancelQueries({ queryKey: sleepRecordKeys.lists() });
38 +
39 + const previous = queryClient.getQueryData(sleepRecordKeys.list());
40 +
41 + // TODO: might as well create a shared attrs that we're keeping it
42 + queryClient.setQueryData(sleepRecordKeys, (old: SleepRecord[] = []) => [
43 + {
44 + ...payload,
45 + id: `temp-${Date.now()}`,
46 + createdAt: new Date().toISOString(),
47 + _optimistic: true,
48 + },
49 + ...old,
50 + ]);
51 +
52 + return { previous };
53 + },
54 +
55 + onError: (_err, _payload, context) => {
56 + if (context?.previous) {
57 + queryClient.setQueryData(sleepRecordKeys.list(), context.previous);
58 + }
59 + },
60 +
61 + onSuccess: () => {
62 + queryClient.invalidateQueries({ queryKey: sleepRecordKeys.lists() });
63 + },
64 + });
65 + }