/ client / src / utils / querySettings.ts
querySettings.ts
 1  import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
 2  import { getAPIURL } from "./url";
 3  
 4  interface SettingResponseValue {
 5    value: string;
 6    is_set: boolean;
 7    type: string;
 8  }
 9  
10  interface SettingsResponse {
11    [key: string]: SettingResponseValue;
12  }
13  
14  export function useGetSettings() {
15    return useQuery<SettingsResponse>({
16      queryKey: ["settings"],
17      queryFn: async () => {
18        const response = await fetch(`${getAPIURL()}/setting/`);
19        return response.json();
20      },
21    });
22  }
23  
24  export function useGetSetting(key: string) {
25    return useQuery<SettingResponseValue>({
26      queryKey: ["settings", key],
27      queryFn: async () => {
28        const response = await fetch(`${getAPIURL()}/setting/${key}`);
29        return response.json();
30      },
31    });
32  }
33  
34  export function useSetSetting<T>(key: string) {
35    const queryClient = useQueryClient();
36  
37    return useMutation<SettingResponseValue, unknown, T, SettingResponseValue | undefined>({
38      mutationFn: async (value) => {
39        const response = await fetch(`${getAPIURL()}/setting/${key}`, {
40          method: "POST",
41          headers: {
42            "Content-Type": "application/json",
43          },
44          body: JSON.stringify(JSON.stringify(value)),
45        });
46  
47        // Throw error if response is not ok
48        if (!response.ok) {
49          throw new Error((await response.json()).message);
50        }
51  
52        return response.json();
53      },
54      onMutate: async (value) => {
55        await queryClient.cancelQueries({
56          queryKey: ["settings", key],
57        });
58        const previousValue = queryClient.getQueryData<SettingResponseValue>(["settings", key]);
59        queryClient.setQueryData<SettingResponseValue>(["settings", key], (old) =>
60          old ? { ...old, value: JSON.stringify(value) } : undefined,
61        );
62        return previousValue;
63      },
64      onError: (_error, _value, context) => {
65        queryClient.setQueryData<SettingResponseValue>(["settings", key], context);
66      },
67      onSuccess: () => {
68        // Invalidate and refetch
69        queryClient.invalidateQueries({
70          queryKey: ["settings", key],
71        });
72      },
73    });
74  }