import { useQuery, useQueryClient, useMutation } from "@tanstack/react-query"; import axios from "axios"; export const useEntities = ( key: string, url: string ) => { const entities = useQuery( [key], async ({ signal }): Promise => { const { data } = await axios.get(url, { signal }); return data; } ); return { entities, }; }; export const useEntity = ( key: string, url: string, id: string | undefined | null ) => { const queryClient = useQueryClient(); const invalidateActive = () => queryClient.invalidateQueries({ queryKey: [key, "query"], type: "active", }); const entity = useQuery( [key, id], async ({ signal }): Promise => { const { data } = await axios.get(url + "/" + id, { signal }); return data; }, { enabled: !!id } ); const add = useMutation( async (entity: T): Promise => { const { data } = await axios.post(url, entity); return data; }, { onSuccess: (addedEntity) => { queryClient.setQueryData([key, addedEntity.id], addedEntity); queryClient.setQueryData([key], (cachedEntities: T[] | undefined) => cachedEntities ? [...cachedEntities, addedEntity] : undefined ); invalidateActive(); }, } ); const update = useMutation( async (entity: T): Promise => { const { data } = await axios.put(url + "/" + id, entity); return data; }, { onSuccess: (updatedEntity, variable) => { queryClient.setQueryData([key, id], updatedEntity); queryClient.setQueryData( [key], (cachedEntities: T[] | undefined) => cachedEntities?.map((cachedEntity) => cachedEntity.id === variable.id ? updatedEntity : cachedEntity ) ); invalidateActive(); }, } ); const remove = useMutation( async (id: string): Promise => { const { data } = await axios.delete(url + "/" + id); return data; }, { onSuccess: (deletedId) => { queryClient.setQueryData([key, id], null); queryClient.setQueryData( [key], (cachedEntities: T[] | undefined) => cachedEntities?.filter( (cachedEntity) => cachedEntity.id !== deletedId ) ); invalidateActive(); }, } ); return { entity, add, update, remove, }; };