import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { api } from "../api/client"; import { ResourceConfig } from "../types/config"; import { ConfigContext } from "../providers/ConfigContext"; import * as React from "react"; export function useResource(config: ResourceConfig | undefined) { const queryClient = useQueryClient(); // Return empty/disabled hooks if config is missing const { name = '', endpoint = '', primaryKey = 'id' } = config || {}; // --- READ ALL --- const useList = (params?: any) => useQuery({ queryKey: [name, "list", params], queryFn: async () => { if (!endpoint) return { data: [], total: 0 }; console.log('params:', params); // @ts-ignore const res = await api.get(endpoint, { params }); const total = res.headers ? parseInt(res.headers['x-total-count'] || res.headers['X-Total-Count']) : undefined; return { data: res.data, total: isNaN(total as any) ? undefined : total }; }, enabled: !!endpoint, }); // --- READ ONE --- const useRead = (id: string | null) => useQuery({ queryKey: [name, "detail", id], queryFn: async () => { if (!id || !endpoint) return null; // @ts-ignore const res = await api.get(`${endpoint}/${id}`); return res.data; }, enabled: !!id && !!endpoint, }); // --- CREATE --- const useCreate = () => useMutation({ mutationFn: async (data: Partial) => { if (!endpoint) throw new Error("Endpoint not defined"); // @ts-ignore const res = await api.post(endpoint, data); return res.data; }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: [name, "list"] }); }, }); // --- UPDATE --- const useUpdate = () => useMutation({ mutationFn: async ({ id, data }: { id: string; data: Partial }) => { if (!endpoint) throw new Error("Endpoint not defined"); // @ts-ignore const res = await api.put(`${endpoint}/${id}`, data); return res.data; }, onSuccess: (updatedItem) => { // @ts-ignore const id = updatedItem[primaryKey]; queryClient.invalidateQueries({ queryKey: [name, "list"] }); queryClient.invalidateQueries({ queryKey: [name, "detail", id] }); }, }); // --- DELETE --- const useDelete = () => useMutation({ mutationFn: async (id: string) => { if (!endpoint) throw new Error("Endpoint not defined"); await api.delete(`${endpoint}/${id}`); return id; }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: [name, "list"] }); }, }); // --- HELPERS FOR useQueries --- const getListQueryOptions = (params?: any) => ({ queryKey: [name, "list", params], queryFn: async () => { if (!endpoint) return { data: [], total: 0 }; // @ts-ignore const res = await api.get(endpoint, { params }); const total = res.headers ? parseInt(res.headers['x-total-count'] || res.headers['X-Total-Count']) : undefined; return { data: res.data, total: isNaN(total as any) ? undefined : total }; }, enabled: !!endpoint, }); // --- READ ME --- const useMe = () => useQuery({ queryKey: [name, "me"], queryFn: async () => { if (!endpoint) return null; // @ts-ignore const res = await api.get(`${endpoint}/me`); return res.data; }, enabled: !!endpoint, }); // --- UPDATE ME --- const useUpdateMe = () => useMutation({ mutationFn: async (data: Partial) => { if (!endpoint) throw new Error("Endpoint not defined"); // @ts-ignore const res = await api.put(`${endpoint}/me`, data); return res.data; }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: [name, "me"] }); queryClient.invalidateQueries({ queryKey: [name, "list"] }); }, }); return { useList, useRead, useMe, useCreate, useUpdate, useUpdateMe, useDelete, getListQueryOptions, }; } export function useResourceByName(name: string) { const config = React.useContext(ConfigContext); const resourceConfig = config?.resources.find((r) => r.name === name); return useResource(resourceConfig); }