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 }