eletrotupi / tcc/ commit / 0979621

frontend: fetch a single sleep entry record

Pedro Lucas Porcellis porcellis@eletrotupi.com 1 month ago 097962129b7a820be8edd48f6ebd3213a58486f9
Parents: 384a4a6
2 file(s) changed
  • frontend/hooks/useSleepRecord.queries.ts +40 -0
  • frontend/lib/api/client.ts +8 -0
frontend/hooks/useSleepRecord.queries.ts
1 1
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
2 2

3 3
import { apiClient, SleepRecord, SleepRecordPayload } from "@/lib/api";
4 4

5 5
export const sleepRecordKeys = {
▸ 15 unchanged lines
21 21
    queryKey: sleepRecordKeys.list(filters),
22 22
    queryFn: () => apiClient.getSleepRecords(filters),
23 23
  });
24 24
};
25 25

26 +
// Single entry detail
27 +
export const useSleepRecord = (id: string) => {
28 +
  return useQuery({
29 +
    queryKey: sleepRecordKeys.detail(id),
30 +
    queryFn: () => apiClient.getSleepRecord(id),
31 +
    enabled: !!id,
32 +
  });
33 +
};
34 +

26 35
export const useCreateSleepRecord = () => {
27 36
  const queryClient = useQueryClient();
28 37

29 38
  return useMutation({
30 39
    mutationFn: (payload: SleepRecordPayload) =>
▸ 30 unchanged lines
61 70
    onSuccess: () => {
62 71
      queryClient.invalidateQueries({ queryKey: sleepRecordKeys.lists() });
63 72
    },
64 73
  });
65 74
};
75 +

76 +
// Delete a sleep record with optimistic removal
77 +
export const useDeleteSleepRecord = () => {
78 +
  const queryClient = useQueryClient();
79 +

80 +
  return useMutation({
81 +
    mutationFn: (id: string) => apiClient.deleteSleepRecord(id),
82 +

83 +
    onMutate: async (id) => {
84 +
      await queryClient.cancelQueries({ queryKey: sleepRecordKeys.lists() });
85 +
      const previous = queryClient.getQueryData(sleepRecordKeys.list());
86 +

87 +
      queryClient.setQueryData(
88 +
        sleepRecordKeys.list(),
89 +
        (old: SleepRecord[] = []) => old.filter((e) => e.id !== Number(id)),
90 +
      );
91 +

92 +
      return { previous };
93 +
    },
94 +

95 +
    onError: (_err, _id, context) => {
96 +
      if (context?.previous) {
97 +
        queryClient.setQueryData(sleepRecordKeys.list(), context.previous);
98 +
      }
99 +
    },
100 +

101 +
    onSuccess: () => {
102 +
      queryClient.invalidateQueries({ queryKey: sleepRecordKeys.lists() });
103 +
    },
104 +
  });
105 +
};
frontend/lib/api/client.ts
1 1
import * as SecureStore from "expo-secure-store";
2 2
import {
3 3
  User,
4 4
  AuthResponse,
5 5
  VerifyTokenResponse,
▸ 234 unchanged lines
240 240

241 241
    const qs = query.toString();
242 242
    return this.request(`/sleep_records${qs ? `?${qs}` : ""}`);
243 243
  }
244 244

245 +
  async getSleepRecord(id: string): Promise<SleepRecord> {
246 +
    return this.request(`/sleep_records/${id}`);
247 +
  }
248 +

249 +
  async deleteSleepRecord(id: string): Promise<void> {
250 +
    return this.request(`/sleep_records/${id}`, { method: "DELETE" });
251 +
  }
252 +

245 253
  // Trigger
246 254
  async createTrigger(trigger: CreateTriggerPayload): Promise<TriggerResponse> {
247 255
    return await this.request(`/triggers`, {
248 256
      method: "POST",
249 257
      body: JSON.stringify({ trigger }),
▸ 39 unchanged lines
289 297
    return this.request(`/insights${qs ? `?${qs}` : ""}`);
290 298
  }
291 299
}
292 300

293 301
export const apiClient = new ApiClient();