import {useState,useEffect, useCallback} from "react" import { MasterRespository } from "../../repositories/MastersRepository"; import { cacheData,getCachedData } from "../../slices/apiDataManager"; import { useSelector } from "react-redux"; import {useMutation, useQueries, useQuery, useQueryClient} from "@tanstack/react-query"; import showToast from "../../services/toastService"; export const useServices = ()=>{ return useQuery({ queryKey:["services"], queryFn:async()=> await MasterRespository.getMasterServices() }) } export const useGlobalServices = ()=>{ return useQuery({ queryKey:["globalServices"], queryFn:async()=> await MasterRespository.getGlobalServices() }) } export const useMasterMenu = ()=>{ return useQuery({ queryKey:["MasterMenu"], queryFn:async()=> { const resp = await MasterRespository.getMasterMenus(); return resp.data } }) } export const useActivitiesMaster = () => { const { data:activities=[],isLoading:loading,error} = useQuery( { queryKey: [ "ActivityMaster" ], queryFn: async() => { const response = await MasterRespository.getActivites(); return response.data }, onError: (error) => { showToast(error?.response?.data?.message || error.message || "Failed to fetch ActivityMasters", "error"); }, } ) return {activities,loading,error} } export const useWorkCategoriesMaster = () => { const { data: categories = [], isLoading: categoryLoading, error: categoryError, } = useQuery({ queryKey: ["Work Category"], queryFn: async () => { const response = await MasterRespository.getWorkCategory(); return response.data; }, onError: (error) => { showToast( error?.response?.data?.message || error.message || "Failed to fetch work categories", "error" ); }, }); return { categories, categoryLoading, categoryError }; }; export const useContactCategory = () => { const {data:contactCategory=[],isLoading:loading,error:Error } = useQuery( { queryKey: [ "Contact Category" ], queryFn: async () => { let resp = await MasterRespository.getContactCategory(); return resp.data }, onError: (error) => { showToast(error?.response?.data?.message || error.message || "Failed to fetch Contact categories", "error"); }, } ) return { contactCategory,loading,Error} } export const useContactTags = () => { const { data: contactTags = [], isLoading: loading, error, } = useQuery({ queryKey: ["Contact Tag"], queryFn: async () => { const res = await MasterRespository.getContactTag(); return res.data; }, onError: (error) => { showToast( error?.response?.data?.message || error.message || "Failed to fetch Contact Tag", "error" ); }, }); return { contactTags, loading, error }; }; export const useExpenseType =()=>{ const { data: ExpenseTypes = [], isLoading: loading, error, } = useQuery({ queryKey: ["Expense Type"], queryFn: async () => { const res = await MasterRespository.getExpenseType() return res.data; }, onError: (error) => { showToast( error?.response?.data?.message || error.message || "Failed to fetch Expense Type", "error" ); }, }); return { ExpenseTypes, loading, error }; } export const usePaymentMode =()=>{ const { data: PaymentModes = [], isLoading: loading, error, } = useQuery({ queryKey: ["Payment Mode"], queryFn: async () => { const res = await MasterRespository.getPaymentMode() return res.data; }, onError: (error) => { showToast( error?.response?.data?.message || error.message || "Failed to fetch Payment Mode", "error" ); }, }); return { PaymentModes, loading, error }; } export const useExpenseStatus =()=>{ const { data: ExpenseStatus = [], isLoading: loading, error, } = useQuery({ queryKey: ["Expense Status"], queryFn: async () => { const res = await MasterRespository.getExpenseStatus() return res.data; }, onError: (error) => { showToast( error?.response?.data?.message || error.message || "Failed to fetch Expense Status", "error" ); }, }); return { ExpenseStatus, loading, error }; } export const useDocumentTypes =(category)=>{ const { data: DocumentTypes = [], error, isError, isLoading } = useQuery({ queryKey: ["Document Type",category], queryFn: async () => { const res = await MasterRespository.getDocumentTypes(category) return res.data; }, enabled:!!category, onError: (error) => { showToast( error?.response?.data?.message || error.message || "Failed to fetch Expense Status", "error" ); }, }); return { DocumentTypes, isError, isLoading, error }; } export const useDocumentCategories =(EntityType)=>{ const { data: DocumentCategories = [], error, isError, isLoading } = useQuery({ queryKey: ["Document Category",EntityType], queryFn: async () => { const res = await MasterRespository.getDocumentCategories(EntityType) return res.data; }, enabled:!!EntityType, onError: (error) => { showToast( error?.response?.data?.message || error.message || "Failed to fetch Expense Status", "error" ); }, }); return { DocumentCategories, isError, isLoading, error }; } export const useOrganizationType =()=>{ return useQuery({ queryKey:["orgType"], queryFn:async()=>await MasterRespository.getOrganizationType() }) } // ===Application Masters Query================================================= const fetchMasterData = async (masterType) => { switch (masterType) { case "Application Role": return (await MasterRespository.getRoles()).data; case "Job Role": return (await MasterRespository.getJobRole()).data; case "Activity": return (await MasterRespository.getActivites()).data; case "Services": return (await MasterRespository.getService()).data; case "Work Category": return (await MasterRespository.getWorkCategory()).data; case "Contact Category": return (await MasterRespository.getContactCategory()).data; case "Contact Tag": return (await MasterRespository.getContactTag()).data; case "Expense Type": return (await MasterRespository.getExpenseType()).data; case "Payment Mode": return (await MasterRespository.getPaymentMode()).data; case "Expense Status": return (await MasterRespository.getExpenseStatus()).data; case "Document Type": return (await MasterRespository.getDocumentTypes()).data; case "Document Category": return (await MasterRespository.getDocumentCategories()).data; case "Status": return [ { description: null, featurePermission: null, id: "02dd4761-363c-49ed-8851-3d2489a3e98d", status: "status 1", }, { description: null, featurePermission: null, id: "03dy9761-363c-49ed-8851-3d2489a3e98d", status: "status 2", }, { description: null, featurePermission: null, id: "03dy7761-263c-49ed-8851-3d2489a3e98d", status: "Status 3", }, ]; default: return []; } }; const useMaster = () => { const selectedMaster = useSelector((store) => store.localVariables.selectedMaster); const queryFn = useCallback(() => fetchMasterData(selectedMaster), [selectedMaster]); const { data = [], isLoading, error, } = useQuery({ queryKey: ["masterData", selectedMaster], queryFn, enabled: !!selectedMaster, staleTime: 1000 * 60 * 10, refetchOnWindowFocus: false, onError: (error) => { showToast(error?.response?.data?.message || error.message || `Failed to fetch ${selectedMaster} Maseter`, "error"); }, }); return { data, loading: isLoading, error }; }; export default useMaster; // ================================Mutation==================================== // Job Role----------------------------------- export const useUpdateJobRole = (onSuccessCallback, onErrorCallback) => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async ({ id, payload }) => { const response = await MasterRespository.updateJobRole(id, payload); return response.data; }, onSuccess: (data, variables) => { showToast("JobRole updated successfully.", "success"); queryClient.invalidateQueries({ queryKey: ["masterData", "Job Role"], }); if (onSuccessCallback) onSuccessCallback(data); }, onError: (error) => { showToast(error.message || "Something went wrong", "error"); if (onErrorCallback) onErrorCallback(error); }, }); }; export const useCreateJobRole = (onSuccessCallback) => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async (payload) => { const response = await MasterRespository.createJobRole(payload); return response.data; }, onSuccess: (data) => { showToast("JobRole added successfully.", "success"); queryClient.invalidateQueries({queryKey:["masterData", "Job Role"]}); if (onSuccessCallback) onSuccessCallback(data); }, onError: (error) => { showToast(error.message || "Something went wrong", "error"); }, }); }; // Application Role------------------------------------------- export const useCreateApplicationRole = (onSuccessCallback) => { const queryClient = useQueryClient(); return useMutation( { mutationFn: async ( payload ) => { const resp = await MasterRespository.createRole( payload ); return resp.data; }, onSuccess: ( data ) => { queryClient.invalidateQueries( {queryKey:[ "masterData", "Application Role" ]} ) showToast( "Application Role added successfully", "success" ); if(onSuccessCallback) onSuccessCallback(data) }, onError: ( error ) => { showToast(error.message || "Something went wrong", "error"); } }) } export const useUpdateApplicationRole = (onSuccessCallback) => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async ( {id, payload} ) => { const response = await MasterRespository.updateRoles(id,payload); return response.data; }, onSuccess: (data, variables) => { queryClient.invalidateQueries({ queryKey: ["masterData", "Application Role"], }); showToast("Application Role updated successfully.", "success"); if (onSuccessCallback) onSuccessCallback(data); }, onError: (error) => { showToast(error.message || "Something went wrong", "error"); }, }); } // Activity------------------------------ export const useCreateActivity = (onSuccessCallback) => { const queryClient = useQueryClient(); return useMutation( { mutationFn: async ( payload ) => { const resp = await MasterRespository.createActivity(payload); return resp.data; }, onSuccess: ( data ) => { queryClient.invalidateQueries( {queryKey:[ "masterData", "Activity" ]} ) showToast( "Activity added successfully", "success" ); if(onSuccessCallback) onSuccessCallback(data) }, onError: ( error ) => { showToast(error.message || "Something went wrong", "error"); } }) } export const useUpdateActivity = (onSuccessCallback) => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async ( {id, payload} ) => { const response = await MasterRespository.updateActivity(id,payload); return response.data; }, onSuccess: (data, variables) => { queryClient.invalidateQueries({ queryKey: ["masterData", "Activity"], }); showToast("Activity updated successfully.", "success"); if (onSuccessCallback) onSuccessCallback(data); }, onError: (error) => { showToast(error.message || "Something went wrong", "error"); }, }); } //-----Create work Category------------------------------- export const useCreateWorkCategory = (onSuccessCallback) => { const queryClient = useQueryClient(); return useMutation( { mutationFn: async ( payload ) => { const resp = await MasterRespository.createWorkCategory(payload); return resp.data; }, onSuccess: ( data ) => { queryClient.invalidateQueries({queryKey: [ "masterData", "Work Category" ]} ) showToast( "Work Category added successfully", "success" ); if(onSuccessCallback) onSuccessCallback(data) }, onError: ( error ) => { showToast(error.message || "Something went wrong", "error"); } }) } export const useUpdateWorkCategory = (onSuccessCallback) => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async ( {id, payload} ) => { const response = await MasterRespository.updateWorkCategory(id,payload); return response.data; }, onSuccess: (data, variables) => { queryClient.invalidateQueries({ queryKey: ["masterData", "Work Category"], }); showToast("Work Category updated successfully.", "success"); if (onSuccessCallback) onSuccessCallback(data); }, onError: (error) => { showToast(error.message || "Something went wrong", "error"); }, }); } //-- Contact Category--------------------------- export const useCreateContactCategory = (onSuccessCallback) => { const queryClient = useQueryClient(); return useMutation( { mutationFn: async ( payload ) => { const resp = await MasterRespository.createContactCategory(payload); return resp.data; }, onSuccess: ( data ) => { queryClient.invalidateQueries( {queryKey:[ "masterData", "Contact Category" ]} ) showToast( "Contact Category added successfully", "success" ); if(onSuccessCallback) onSuccessCallback(data) }, onError: ( error ) => { showToast(error.message || "Something went wrong", "error"); } }) } export const useUpdateContactCategory = (onSuccessCallback) => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async ( {id, payload} ) => { const response = await MasterRespository.updateContactCategory(id,payload); return response.data; }, onSuccess: (data, variables) => { queryClient.invalidateQueries({ queryKey: ["masterData", "Contact Category"], }); showToast("Contact Category updated successfully.", "success"); if (onSuccessCallback) onSuccessCallback(data); }, onError: (error) => { showToast(error.message || "Something went wrong", "error"); }, }); } // ---------Contact Tag------------------- export const useCreateContactTag = (onSuccessCallback) => { const queryClient = useQueryClient(); return useMutation( { mutationFn: async ( payload ) => { const resp = await MasterRespository.createContactTag(payload); return resp.data; }, onSuccess: ( data ) => { queryClient.invalidateQueries( {queryKey:[ "masterData", "Contact Tag" ]} ) showToast( "Contact Tag added successfully", "success" ); if(onSuccessCallback) onSuccessCallback(data) }, onError: ( error ) => { showToast(error.message || "Something went wrong", "error"); } }) } export const useUpdateContactTag = (onSuccessCallback) => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async ( {id, payload} ) => { debugger const response = await MasterRespository.updateContactTag(id,payload); return response.data; }, onSuccess: (data, variables) => { queryClient.invalidateQueries({ queryKey: ["masterData", "Contact Tag"], }); showToast("Contact Tag updated successfully.", "success"); if (onSuccessCallback) onSuccessCallback(data); }, onError: (error) => { showToast(error.message || "Something went wrong", "error"); }, }); } // ----------------------Expense Type------------------ export const useCreateExpenseType = (onSuccessCallback)=>{ const queryClient = useQueryClient(); return useMutation( { mutationFn: async ( payload ) => { const resp = await MasterRespository.createExpenseType(payload); return resp.data; }, onSuccess: ( data ) => { queryClient.invalidateQueries( {queryKey:[ "masterData", "Expense Type" ]} ) showToast( "Expense Type added successfully", "success" ); if(onSuccessCallback) onSuccessCallback(data) }, onError: ( error ) => { showToast(error.message || "Something went wrong", "error"); } }) } export const useUpdateExpenseType = (onSuccessCallback) => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async ( {id, payload} ) => { const response = await MasterRespository.updateExpenseType(id,payload); return response.data; }, onSuccess: (data, variables) => { queryClient.invalidateQueries({ queryKey: ["masterData", "Expense Type"], }); showToast("Expense Type updated successfully.", "success"); if (onSuccessCallback) onSuccessCallback(data); }, onError: (error) => { showToast(error.message || "Something went wrong", "error"); }, }); } // -----------------Payment Mode ------------- export const useCreatePaymentMode = (onSuccessCallback)=>{ const queryClient = useQueryClient(); return useMutation( { mutationFn: async ( payload ) => { const resp = await MasterRespository.createPaymentMode(payload); return resp.data; }, onSuccess: ( data ) => { queryClient.invalidateQueries( {queryKey:[ "masterData", "Payment Mode" ]} ) showToast( "Payment Mode added successfully", "success" ); if(onSuccessCallback) onSuccessCallback(data) }, onError: ( error ) => { showToast(error.message || "Something went wrong", "error"); } }) } export const useUpdatePaymentMode = (onSuccessCallback)=>{ const queryClient = useQueryClient(); return useMutation( { mutationFn: async ( {id,payload} ) => { const resp = await MasterRespository.updatePaymentMode(id,payload); return resp.data; }, onSuccess: ( data ) => { queryClient.invalidateQueries( {queryKey:[ "masterData", "Payment Mode" ]} ) showToast( "Payment Mode Updated successfully", "success" ); if(onSuccessCallback) onSuccessCallback(data) }, onError: ( error ) => { showToast(error.message || "Something went wrong", "error"); } }) } // Services------------------------------- // export const useCreateService = (onSuccessCallback) => { // const queryClient = useQueryClient(); // return useMutation({ // mutationFn: async (payload) => { // const resp = await MasterRespository.createService(payload); // return resp.data; // full API response // }, // onSuccess: (data) => { // // Invalidate & refetch service list // queryClient.invalidateQueries({ queryKey: ["masterData", "Services"] }); // showToast(data?.message || "Service added successfully", "success"); // if (onSuccessCallback) onSuccessCallback(data?.data); // pass back new service object // }, // onError: (error) => { // showToast(error.message || "Something went wrong", "error"); // }, // }); // }; export const useCreateService = (onSuccessCallback) => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async (payload) => { debugger; const resp = await MasterRespository.createService(payload); debugger; return resp.data; }, onSuccess: (data) => { debugger; queryClient.invalidateQueries({ queryKey: ["masterData", "Services"] }); showToast(data?.message || "Service added successfully", "success"); if (onSuccessCallback) onSuccessCallback(data?.data); }, onError: (error) => { debugger; showToast(error.message || "Something went wrong", "error"); }, }); }; export const useUpdateService = (onSuccessCallback) => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async ({ id, payload }) => { const response = await MasterRespository.updateService(id, payload); return response; // full response since it already has { success, message, data } }, onSuccess: (data, variables) => { queryClient.invalidateQueries({ queryKey: ["masterData", "Services"], }); showToast(data.message || "Service updated successfully.", "success"); if (onSuccessCallback) onSuccessCallback(data); }, onError: (error) => { showToast(error?.message || "Something went wrong", "error"); }, }); }; // -------------------Expense Status---------------------------------- export const useCreateExpenseStatus =(onSuccessCallback)=>{ const queryClient = useQueryClient(); return useMutation( { mutationFn: async ( payload ) => { const resp = await MasterRespository.createExpenseStatus(payload); return resp.data; }, onSuccess: ( data ) => { queryClient.invalidateQueries( {queryKey:[ "masterData", "Expense Status" ]} ) showToast( "Expense Status added successfully", "success" ); if(onSuccessCallback) onSuccessCallback(data) }, onError: ( error ) => { showToast(error.message || "Something went wrong", "error"); } }) } export const useUpdateExpenseStatus = (onSuccessCallback)=>{ const queryClient = useQueryClient(); return useMutation( { mutationFn: async ( {id,payload} ) => { const resp = await MasterRespository.updateExepnseStatus(id,payload); return resp.data; }, onSuccess: ( data ) => { queryClient.invalidateQueries( {queryKey:[ "masterData", "Expense Status" ]} ) showToast( "Expense Status Updated successfully", "success" ); if(onSuccessCallback) onSuccessCallback(data) }, onError: ( error ) => { showToast(error.message || "Something went wrong", "error"); } }) } // --------------------Document-Category-------------------------------- export const useCreateDocumentCatgory =(onSuccessCallback)=>{ const queryClient = useQueryClient(); return useMutation( { mutationFn: async ( payload ) => { const resp = await MasterRespository.createDocumenyCategory(payload); return resp.data; }, onSuccess: ( data ) => { queryClient.invalidateQueries( {queryKey:[ "masterData", "Document Category" ]} ) queryClient.invalidateQueries( {queryKey:[ "Document Category" ]} ) showToast( "Document Category added successfully", "success" ); if(onSuccessCallback) onSuccessCallback(data) }, onError: ( error ) => { showToast(error.message || "Something went wrong", "error"); } }) } export const useUpdateDocumentCategory =(onSuccessCallback)=>{ const queryClient = useQueryClient(); return useMutation( { mutationFn: async ( {id,payload} ) => { const resp = await MasterRespository.updateDocumentCategory(id,payload); return resp.data; }, onSuccess: ( data ) => { queryClient.invalidateQueries( {queryKey:[ "masterData", "Document Category" ]} ) queryClient.invalidateQueries( {queryKey:[ "Document Category" ]} ) showToast( "Document Category Updated successfully", "success" ); if(onSuccessCallback) onSuccessCallback(data) }, onError: ( error ) => { showToast(error.message || "Something went wrong", "error"); } }) } // ------------------------------Document-Type----------------------------------- export const useCreateDocumentType =(onSuccessCallback)=>{ const queryClient = useQueryClient(); return useMutation( { mutationFn: async ( payload ) => { const resp = await MasterRespository.createDocumentType(payload); return resp.data; }, onSuccess: ( data ) => { queryClient.invalidateQueries( {queryKey:[ "masterData", "Document Type" ]} ) showToast( "Document Type added successfully", "success" ); if(onSuccessCallback) onSuccessCallback(data) }, onError: ( error ) => { showToast(error.message || "Something went wrong", "error"); } }) } export const useUpdateDocumentType =(onSuccessCallback)=>{ const queryClient = useQueryClient(); return useMutation( { mutationFn: async ( {id,payload} ) => { const resp = await MasterRespository.updateDocumentType(id,payload); return resp.data; }, onSuccess: ( data ) => { queryClient.invalidateQueries( {queryKey:[ "masterData", "Document Type" ]} ) showToast( "Document Type Updated successfully", "success" ); if(onSuccessCallback) onSuccessCallback(data) }, onError: ( error ) => { showToast(error.message || "Something went wrong", "error"); } }) } // -Delete Master -------- export const useDeleteMasterItem = () => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async ( {masterType, item} ) => { const deleteFn = MasterRespository[masterType]; if (!deleteFn) { throw new Error(`No delete strategy defined for master type: ${masterType}`); } await deleteFn(item.id); return { masterType }; }, onSuccess: ({ masterType }) => { queryClient.invalidateQueries({ queryKey: ["masterData", masterType] }); showToast(`${masterType} deleted successfully.`, "success"); }, onError: (error) => { const message = error?.response?.data?.message || error?.message || "Error occurred during deletion"; showToast(message, "error"); }, }); };