+
-
{`${modaldata?.modalType} `}
+ {modaldata?.modalType}
+ />
-
- {modaldata.modalType === "Application Role" && (
-
- )}
- {modaldata.modalType === "Edit-Application Role" && (
-
- )}
- {modaldata.modalType === "Job Role" && (
-
- )}
- {modaldata.modalType === "Edit-Job Role" && (
-
- )}
- {modaldata.modalType === "Activity" && (
-
- )}
- {modaldata.modalType === "Edit-Activity" && (
-
- )}
- {modaldata.modalType === "Work Category" && (
-
- )}
- {modaldata.modalType === "Edit-Work Category" && (
-
- )}
- {modaldata.modalType === "Contact Category" && (
-
- )}
- {modaldata.modalType === "Edit-Contact Category" && (
-
- )}
- {modaldata.modalType === "Contact Tag" && (
-
- )}
- {modaldata.modalType === "Edit-Contact Tag" && (
-
- )}
+ {renderModalContent()}
diff --git a/src/data/masters.js b/src/data/masters.js
index e94de7a3..54942c87 100644
--- a/src/data/masters.js
+++ b/src/data/masters.js
@@ -1,153 +1,157 @@
// it important ------
-export const mastersList = [ {id: 1, name: "Application Role"}, {id: 2, name: "Job Role"}, {id: 3, name: "Activity"},{id: 4, name:"Work Category"},{id:5,name:"Contact Category"},{id:6,name:"Contact Tag"}]
+export const mastersList = [
+ { id: 1, name: "Application Role" },
+ { id: 2, name: "Job Role" },
+ { id: 3, name: "Activity" },
+ { id: 4, name: "Work Category" },
+ { id: 5, name: "Contact Category" },
+ { id: 6, name: "Contact Tag" },
+ { id: 7, name: "Expense Type" },
+ { id: 8, name: "Payment Mode" },
+ { id: 9, name: "Expense Status" },
+];
// -------------------
-export const dailyTask = [
- {
- id:1,
- project:{
- projectName:"Project Name1",
- building:"buildName1",
- floor:"floorName1",
- workArea:"workarea1"
- },
- target:80,
- employees:[
- {
- id:1,
- name:"Vishal Patil",
- role:"helper"
- },
- {
- id:202,
- name:"Vishal Patil",
- role:"helper"
- },
- {
- id:101,
- name:"Kushal Patil",
- role:"Engineer"
- }
- ]
-
- },
- {
- id:2,
- project:{
- projectName:"Project Name1",
- building:"buildName1",
- floor:"floorName1",
- workArea:"workarea1"
- },
- target:90,
- employees:[
- {
- id:1,
- name:"Vishal Patil",
- role:"welder"
- },
- {
- id:202,
- name:"Vishal Patil",
- role:"welder"
- },
- {
- id:101,
- name:"Kushal Patil",
- role:"Site Engineer"
- }
- ]
-
- }
-]
-
-
-
-export const jobRoles =[
- {
- id:1,
- name:"Project Manager"
- },
- {
- id:2,
- name:"Software Developer"
- },
- {
- id:3,
- name:"Estimation Engineer"
- },
- {
- id:4,
- name:"Designer"
- },
- {
- id:5,
- name:"Site Engineer"
- }
-]
-
-export const employee =[
- {
- id:1,
- FirtsName:"Pramod",
- LastName:"Mahajan",
- JobRoleId:2,
- },
- {
- id:2,
- FirtsName:"Akahsy",
- LastName:"Patil",
- JobRoleId:1,
- },
- {
- id:3,
- FirtsName:"janvi",
- LastName:"Potdar",
- JobRoleId:3,
- },
- {
- id:4,
- FirtsName:"Aboli",
- LastName:"Patil",
- JobRoleId:2,
- },
- {
- id:5,
- FirtsName:"Shubham",
- LastName:"Tamboli",
- JobRoleId:1,
- },
- {
- id:6,
- FirtsName:"Alwin",
- LastName:"Joy",
- JobRoleId:4,
- },
- {
- id:7,
- FirtsName:"John",
- LastName:"kwel",
- JobRoleId:4,
- },
- {
- id:8,
- FirtsName:"Gita",
- LastName:"shaha",
- JobRoleId:1,
- },{
- id:9,
- FirtsName:"Pratik",
- LastName:"Joshi",
- JobRoleId:5,
- },
- {
- id:10,
- FirtsName:"Nikil",
- LastName:"Patil",
- JobRoleId:5,
- }
-]
+// export const dailyTask = [
+// {
+// id:1,
+// project:{
+// projectName:"Project Name1",
+// building:"buildName1",
+// floor:"floorName1",
+// workArea:"workarea1"
+// },
+// target:80,
+// employees:[
+// {
+// id:1,
+// name:"Vishal Patil",
+// role:"helper"
+// },
+// {
+// id:202,
+// name:"Vishal Patil",
+// role:"helper"
+// },
+// {
+// id:101,
+// name:"Kushal Patil",
+// role:"Engineer"
+// }
+// ]
+// },
+// {
+// id:2,
+// project:{
+// projectName:"Project Name1",
+// building:"buildName1",
+// floor:"floorName1",
+// workArea:"workarea1"
+// },
+// target:90,
+// employees:[
+// {
+// id:1,
+// name:"Vishal Patil",
+// role:"welder"
+// },
+// {
+// id:202,
+// name:"Vishal Patil",
+// role:"welder"
+// },
+// {
+// id:101,
+// name:"Kushal Patil",
+// role:"Site Engineer"
+// }
+// ]
+// }
+// ]
+// export const jobRoles =[
+// {
+// id:1,
+// name:"Project Manager"
+// },
+// {
+// id:2,
+// name:"Software Developer"
+// },
+// {
+// id:3,
+// name:"Estimation Engineer"
+// },
+// {
+// id:4,
+// name:"Designer"
+// },
+// {
+// id:5,
+// name:"Site Engineer"
+// }
+// ]
+// export const employee =[
+// {
+// id:1,
+// FirtsName:"Pramod",
+// LastName:"Mahajan",
+// JobRoleId:2,
+// },
+// {
+// id:2,
+// FirtsName:"Akahsy",
+// LastName:"Patil",
+// JobRoleId:1,
+// },
+// {
+// id:3,
+// FirtsName:"janvi",
+// LastName:"Potdar",
+// JobRoleId:3,
+// },
+// {
+// id:4,
+// FirtsName:"Aboli",
+// LastName:"Patil",
+// JobRoleId:2,
+// },
+// {
+// id:5,
+// FirtsName:"Shubham",
+// LastName:"Tamboli",
+// JobRoleId:1,
+// },
+// {
+// id:6,
+// FirtsName:"Alwin",
+// LastName:"Joy",
+// JobRoleId:4,
+// },
+// {
+// id:7,
+// FirtsName:"John",
+// LastName:"kwel",
+// JobRoleId:4,
+// },
+// {
+// id:8,
+// FirtsName:"Gita",
+// LastName:"shaha",
+// JobRoleId:1,
+// },{
+// id:9,
+// FirtsName:"Pratik",
+// LastName:"Joshi",
+// JobRoleId:5,
+// },
+// {
+// id:10,
+// FirtsName:"Nikil",
+// LastName:"Patil",
+// JobRoleId:5,
+// }
+// ]
diff --git a/src/data/menuData.json b/src/data/menuData.json
index bbd37e2c..d4b2104d 100644
--- a/src/data/menuData.json
+++ b/src/data/menuData.json
@@ -66,6 +66,12 @@
"available": true,
"link": "/gallary"
},
+ {
+ "text": "Expense",
+ "icon": "bx bx-receipt",
+ "available": true,
+ "link": "/expenses"
+ },
{
"text": "Administration",
"icon": "bx bx-box",
diff --git a/src/hooks/masterHook/useMaster.js b/src/hooks/masterHook/useMaster.js
index 20caff62..15dc3305 100644
--- a/src/hooks/masterHook/useMaster.js
+++ b/src/hooks/masterHook/useMaster.js
@@ -12,213 +12,6 @@ import showToast from "../../services/toastService";
-// const useMaster = () => {
-
-// const selectedMaster = useSelector((store)=>store.localVariables.selectedMaster);
-// const [data, setData] = useState([]);
-// const [loading, setLoading] = useState(true);
-// const [error, setError] = useState("");
-// useEffect(() => {
-// const fetchData = async () => {
-// if (!selectedMaster) return;
-// setLoading(true);
-// try {
-// const cachedData = getCachedData(selectedMaster);
-// if (cachedData) {
-
-// setData(cachedData);
-
-// } else {
-// let response;
-// switch (selectedMaster) {
-// case "Application Role":
-// response = await MasterRespository.getRoles();
-// response = response.data;
-// break;
-// case "Job Role":
-// response = await MasterRespository.getJobRole();
-// response = response.data
-// break;
-// case "Activity":
-// response = await MasterRespository.getActivites();
-// response = response.data
-// break;
-// case "Work Category":
-// response = await MasterRespository.getWorkCategory();
-// response = response.data
-// break;
-// case "Contact Category":
-// response = await MasterRespository.getContactCategory();
-// response = response.data
-// break;
-// case "Contact Tag":
-// response = await MasterRespository.getContactTag();
-// response = response.data
-// break;
-// case "Status":
-// response = [{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"}];
-// break;
-// default:
-// response = [];
-// }
-
-// if (response) {
-// setData(response);
-// cacheData(selectedMaster, response);
-// }
-// }
-// } catch (err) {
-// setError("Failed to fetch data.");
-// } finally {
-// setLoading(false);
-// }
-// };
-
-// if ( selectedMaster )
-// {
-
-// fetchData();
-// }
-
-// }, [selectedMaster]);
-
-
-
-// return { data, loading, error }
-// };
-
-
-
-
-// export const useActivitiesMaster = () =>
-// {
-// const [ activities, setActivites ] = useState( [] )
-// const [ loading, setloading ] = useState( false );
-// const [ error, setError ] = useState()
-// const fetchActivities =async () => {
-// setloading(true);
-// try {
-// const response = await MasterRespository.getActivites();
-// setActivites(response.data);
-// cacheData( "ActivityMaster", response.data );
-// setloading(false);
-// } catch (err) {
-// setError(err);
-// setloading(false);
-// }
-// }
-// useEffect( () =>
-// {
-// const cacheddata = getCachedData( "ActivityMaster" );
-// if ( !cacheddata )
-// {
-// fetchActivities()
-// } else
-// {
-// setActivites(cacheddata);
-// }
-// }, [] )
-
-// return {activities,loading,error}
-// }
-
-// export const useWorkCategoriesMaster = () =>
-// {
-// const [ categories, setCategories ] = useState( [] )
-// const [ categoryLoading, setloading ] = useState( false );
-// const [ categoryError, setError ] = useState( "" )
-
-// const fetchCategories =async () => {
-// const cacheddata = getCachedData("Work Category");
-
-// if (!cacheddata) {
-// setloading(true);
-// try {
-// const response = await MasterRespository.getWorkCategory();
-// setCategories(response.data);
-// cacheData("Work Category", response.data);
-// } catch (err) {
-// setError(err);
-// console.log(err);
-// } finally {
-// setloading(false);
-// }
-// } else {
-// setCategories(cacheddata);
-// }
-// }
-// useEffect( () =>
-// {
-// fetchCategories()
-// }, [] )
-
-// return {categories,categoryLoading,categoryError}
-// }
-
-// export const useContactCategory = () =>
-// {
-// const [ contactCategory, setContactCategory ] = useState( [] )
-// const [ loading, setLoading ] = useState( false )
-// const [ Error, setError ] = useState()
-
-// const fetchConatctCategory = async() =>
-// {
-// const cache_Category = getCachedData( "Contact Category" );
-// if ( !cache_Category )
-// {
-// try
-// {
-// let resp = await MasterRespository.getContactCategory();
-// setContactCategory( resp.data );
-// cacheData("Contact Category",resp.data)
-// } catch ( error )
-// {
-// setError(error)
-// }
-// } else
-// {
-// setContactCategory(cache_Category)
-// }
-// }
-
-// useEffect( () =>
-// {
-// fetchConatctCategory()
-// }, [] )
-// return { contactCategory,loading,Error}
-// }
-// export const useContactTags = () => {
-// const [contactTags, setContactTags] = useState([]);
-// const [loading, setLoading] = useState(false);
-// const [error, setError] = useState(null);
-
-// useEffect(() => {
-// const fetchContactTag = async () => {
-// const cache_Tags = getCachedData("Contact Tag");
-
-// if (!cache_Tags) {
-// setLoading(true);
-// try {
-// const resp = await MasterRespository.getContactTag();
-// setContactTags(resp.data);
-// cacheData("Contact Tag", resp.data);
-// } catch (err) {
-// setError(err);
-// } finally {
-// setLoading(false);
-// }
-// } else {
-// setContactTags(cache_Tags);
-// }
-// };
-
-// fetchContactTag();
-// }, []);
-
-// return { contactTags, loading, error };
-// };
-
-// Separate matser-------------
export const useActivitiesMaster = () =>
{
@@ -300,6 +93,76 @@ export const useContactTags = () => {
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 };
+}
// ===Application Masters Query=================================================
const fetchMasterData = async (masterType) => {
@@ -316,6 +179,12 @@ const fetchMasterData = async (masterType) => {
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 "Status":
return [
{
@@ -666,6 +535,140 @@ export const useUpdateContactTag = (onSuccessCallback) =>
});
}
+// ----------------------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");
+ }
+ })
+}
+// -------------------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");
+ }
+ })
+}
// -Delete Master --------
export const useDeleteMasterItem = () => {
const queryClient = useQueryClient();
diff --git a/src/hooks/useEmployees.js b/src/hooks/useEmployees.js
index 30e41256..b911d2dc 100644
--- a/src/hooks/useEmployees.js
+++ b/src/hooks/useEmployees.js
@@ -3,27 +3,22 @@ import { cacheData, getCachedData } from "../slices/apiDataManager";
import { RolesRepository } from "../repositories/MastersRepository";
import EmployeeRepository from "../repositories/EmployeeRepository";
import ProjectRepository from "../repositories/ProjectRepository";
-import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
+import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import showToast from "../services/toastService";
-import {useSelector} from "react-redux";
-import {store} from "../store/store";
-import {queryClient} from "../layouts/AuthLayout";
-
-
-
+import { useSelector } from "react-redux";
+import { store } from "../store/store";
+import { queryClient } from "../layouts/AuthLayout";
// Query ---------------------------------------------------------------------------
-
-export const useAllEmployees = ( showInactive ) =>
-{
+export const useAllEmployees = (showInactive) => {
const {
data = [],
isLoading,
error,
refetch, // optional if you want recall functionality
} = useQuery({
- queryKey: ['allEmployee', showInactive],
+ queryKey: ["allEmployee", showInactive],
queryFn: async () => {
const res = await EmployeeRepository.getAllEmployeeList(showInactive);
return res.data;
@@ -34,14 +29,12 @@ export const useAllEmployees = ( showInactive ) =>
employeesList: data,
loading: isLoading,
error,
- recallEmployeeData: refetch,
+ recallEmployeeData: refetch,
};
};
// ManageBucket.jsx
-export const useEmployees = ( selectedProject ) =>
-{
-
+export const useEmployees = (selectedProject) => {
const {
data = [],
isLoading,
@@ -50,7 +43,9 @@ export const useEmployees = ( selectedProject ) =>
} = useQuery({
queryKey: ["employeeListByProject", selectedProject],
queryFn: async () => {
- const res = await EmployeeRepository.getEmployeeListByproject(selectedProject);
+ const res = await EmployeeRepository.getEmployeeListByproject(
+ selectedProject
+ );
return res.data || res;
},
enabled: !!selectedProject,
@@ -72,12 +67,12 @@ export const useEmployeeRoles = (employeeId) => {
isLoading: loading,
error,
} = useQuery({
- queryKey: ['employeeRoles', employeeId],
+ queryKey: ["employeeRoles", employeeId],
queryFn: async () => {
const res = await RolesRepository.getEmployeeRoles(employeeId);
return res.data;
},
- enabled: !!employeeId,
+ enabled: !!employeeId,
});
return {
@@ -95,12 +90,12 @@ export const useEmployeesByProject = (projectId) => {
error,
refetch: recallProjectEmplloyee,
} = useQuery({
- queryKey: ['projectEmployees', projectId],
+ queryKey: ["projectEmployees", projectId],
queryFn: async () => {
const res = await ProjectRepository.getEmployeesByProject(projectId);
return res.data;
},
- enabled: !!projectId,
+ enabled: !!projectId,
});
return {
@@ -112,16 +107,17 @@ export const useEmployeesByProject = (projectId) => {
};
// EmployeeList.jsx
-export const useEmployeesAllOrByProjectId = (showAllEmployees ,projectId,
- showInactive) => {
-
-
- const queryKey = showAllEmployees
- ? ['allEmployees', showInactive]
- : ['projectEmployees', projectId, showInactive];
+export const useEmployeesAllOrByProjectId = (
+ showAllEmployees,
+ projectId,
+ showInactive
+) => {
+ const queryKey = showAllEmployees
+ ? ["allEmployees", showInactive]
+ : ["projectEmployees", projectId, showInactive];
const queryFn = async () => {
- if (showAllEmployees) {
+ if (showAllEmployees) {
const res = await EmployeeRepository.getAllEmployeeList(showInactive);
return res.data;
} else {
@@ -139,7 +135,8 @@ export const useEmployeesAllOrByProjectId = (showAllEmployees ,projectId,
} = useQuery({
queryKey,
queryFn,
- enabled:typeof showInactive === "boolean" && (showAllEmployees || !!projectId),
+ enabled:
+ typeof showInactive === "boolean" && (showAllEmployees || !!projectId),
});
return {
@@ -151,69 +148,98 @@ export const useEmployeesAllOrByProjectId = (showAllEmployees ,projectId,
};
// ManageEmployee.jsx
-export const useEmployeeProfile = ( employeeId ) =>
-{
+export const useEmployeeProfile = (employeeId) => {
const isEnabled = !!employeeId;
const {
data = null,
isLoading: loading,
error,
- refetch
+ refetch,
} = useQuery({
- queryKey: ['employeeProfile', employeeId],
+ queryKey: ["employeeProfile", employeeId],
queryFn: async () => {
if (!employeeId) return null;
const res = await EmployeeRepository.getEmployeeProfile(employeeId);
return res.data;
},
- enabled: isEnabled,
+ enabled: isEnabled,
});
return {
employee: data,
loading,
error,
- refetch
+ refetch,
};
};
+export const useEmployeesName = (projectId, search) => {
+ return useQuery({
+ queryKey: ["employees", projectId, search],
+ queryFn: async() => await EmployeeRepository.getEmployeeName(projectId, search),
+
+ staleTime: 5 * 60 * 1000, // Optional: cache for 5 minutes
+ });
+};
+
+export const useEmployeesNameByProject = (projectId) => {
+ return useQuery({
+ queryKey: ["Projectemployees", projectId],
+ queryFn: async () => {
+ const response = await EmployeeRepository.getEmployeeName(projectId);
+ return response?.data || []; // handle undefined/null response
+ },
+ enabled: !!projectId, // only fetch if projectId is truthy
+ staleTime: 5 * 60 * 1000, // cache for 5 minutes
+ });
+};
+
// Mutation------------------------------------------------------------------
-
-
-export const useUpdateEmployee = () =>
-{
- const selectedProject = useSelector((store)=>store.localVariables.projectId)
- const queryClient = useQueryClient();
+export const useUpdateEmployee = () => {
+ const selectedProject = useSelector(
+ (store) => store.localVariables.projectId
+ );
+ const queryClient = useQueryClient();
return useMutation({
- mutationFn: (employeeData) => EmployeeRepository.manageEmployee(employeeData),
+ mutationFn: (employeeData) =>
+ EmployeeRepository.manageEmployee(employeeData),
onSuccess: (_, variables) => {
const id = variables.id || variables.employeeId;
const isAllEmployee = variables.IsAllEmployee;
-
+
// Cache invalidation
- queryClient.invalidateQueries( {queryKey:[ 'allEmployees'] });
+ queryClient.invalidateQueries({ queryKey: ["allEmployees"] });
// queryClient.invalidateQueries(['employeeProfile', id]);
- queryClient.invalidateQueries( {queryKey: [ 'projectEmployees' ]} );
- queryClient.removeQueries( {queryKey: [ "empListByProjectAllocated" ]} );
-
+ queryClient.invalidateQueries({ queryKey: ["projectEmployees"] });
+ queryClient.removeQueries({ queryKey: ["empListByProjectAllocated"] });
+
// queryClient.invalidateQueries( {queryKey:[ 'employeeListByProject']} );
- showToast( `Employee ${ id ? 'updated' : 'created' } successfully`, 'success' );
+ showToast(
+ `Employee ${id ? "updated" : "created"} successfully`,
+ "success"
+ );
},
onError: (error) => {
- const msg = error?.response?.data?.message || error.message || 'Something went wrong';
- showToast(msg, 'error');
+ const msg =
+ error?.response?.data?.message ||
+ error.message ||
+ "Something went wrong";
+ showToast(msg, "error");
},
});
};
-
-
-export const useSuspendEmployee = ({ setIsDeleteModalOpen, setemployeeLodaing }) => {
+export const useSuspendEmployee = ({
+ setIsDeleteModalOpen,
+ setemployeeLodaing,
+}) => {
const queryClient = useQueryClient();
- const selectedProject = useSelector((store)=>store.localVariables.projectId)
+ const selectedProject = useSelector(
+ (store) => store.localVariables.projectId
+ );
return useMutation({
mutationFn: (id) => {
setemployeeLodaing(true);
@@ -221,12 +247,12 @@ export const useSuspendEmployee = ({ setIsDeleteModalOpen, setemployeeLodaing })
},
onSuccess: () => {
-
-
// queryClient.invalidateQueries( ['allEmployee',false]);
- queryClient.invalidateQueries( {queryKey: [ 'projectEmployees' ]} );
- queryClient.invalidateQueries( {queryKey:[ 'employeeListByProject' ,selectedProject]} );
- showToast("Employee deleted successfully.", "success");
+ queryClient.invalidateQueries({ queryKey: ["projectEmployees"] });
+ queryClient.invalidateQueries({
+ queryKey: ["employeeListByProject", selectedProject],
+ });
+ showToast("Employee deleted successfully.", "success");
setIsDeleteModalOpen(false);
},
@@ -247,8 +273,11 @@ export const useSuspendEmployee = ({ setIsDeleteModalOpen, setemployeeLodaing })
// Manage Role
-
-export const useUpdateEmployeeRoles = ({ onClose, resetForm, onSuccessCallback } = {}) => {
+export const useUpdateEmployeeRoles = ({
+ onClose,
+ resetForm,
+ onSuccessCallback,
+} = {}) => {
const queryClient = useQueryClient();
const mutation = useMutation({
mutationFn: (updates) => RolesRepository.createEmployeeRoles(updates),
@@ -259,12 +288,14 @@ export const useUpdateEmployeeRoles = ({ onClose, resetForm, onSuccessCallback }
onClose?.();
onSuccessCallback?.();
- queryClient.invalidateQueries( {queryKey: [ "employeeRoles" ]} );
- queryClient.invalidateQueries( {queryKey: [ "profile" ]} );
+ queryClient.invalidateQueries({ queryKey: ["employeeRoles"] });
+ queryClient.invalidateQueries({ queryKey: ["profile"] });
},
onError: (err) => {
const message =
- err?.response?.data?.message || err?.message || "Error occurred while updating roles";
+ err?.response?.data?.message ||
+ err?.message ||
+ "Error occurred while updating roles";
showToast(message, "error");
},
});
diff --git a/src/hooks/useExpense.js b/src/hooks/useExpense.js
new file mode 100644
index 00000000..cdb36605
--- /dev/null
+++ b/src/hooks/useExpense.js
@@ -0,0 +1,263 @@
+import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
+import ExpenseRepository from "../repositories/ExpsenseRepository";
+import showToast from "../services/toastService";
+import { queryClient } from "../layouts/AuthLayout";
+import { useSelector } from "react-redux";
+import moment from "moment";
+
+// -------------------Query------------------------------------------------------
+
+const cleanFilter = (filter) => {
+ const cleaned = { ...filter };
+
+ ["projectIds", "statusIds", "createdByIds", "paidById"].forEach((key) => {
+ if (Array.isArray(cleaned[key]) && cleaned[key].length === 0) {
+ delete cleaned[key];
+ }
+ });
+
+ // moment.utc() to get consistent UTC ISO strings
+ if (!cleaned.startDate) {
+ cleaned.startDate = moment.utc().subtract(7, "days").startOf("day").toISOString();
+ }
+
+ if (!cleaned.endDate) {
+ cleaned.endDate = moment.utc().startOf("day").toISOString();
+ }
+
+ return cleaned;
+};
+
+
+export const useExpenseList = (
+ pageSize,
+ pageNumber,
+ filter,
+ searchString = ""
+) => {
+ return useQuery({
+ queryKey: ["Expenses", pageNumber, pageSize, filter, searchString],
+ queryFn: async () => {
+ const cleanedFilter = cleanFilter(filter);
+ const response = await ExpenseRepository.GetExpenseList(
+ pageSize,
+ pageNumber,
+ cleanedFilter,
+ searchString
+ );
+ return response.data;
+ },
+ keepPreviousData: true,
+ });
+};
+
+export const useExpense = (ExpenseId) => {
+ return useQuery({
+ queryKey: ["Expense", ExpenseId],
+ queryFn: async () =>
+ await ExpenseRepository.GetExpenseDetails(ExpenseId).then(
+ (res) => res.data
+ ),
+ enabled: !!ExpenseId,
+ });
+};
+
+export const useExpenseFilter = () => {
+ return useQuery({
+ queryKey: ["ExpenseFilter"],
+ queryFn: async () =>
+ await ExpenseRepository.GetExpenseFilter().then((res) => res.data),
+ });
+};
+
+// ---------------------------Mutation---------------------------------------------
+
+export const useCreateExpnse = (onSuccessCallBack) => {
+ const queryClient = useQueryClient();
+ return useMutation({
+ mutationFn: async (payload) => {
+ await ExpenseRepository.CreateExpense(payload);
+ },
+ onSuccess: (_, variables) => {
+ queryClient.invalidateQueries({ queryKey: ["Expenses"] });
+ showToast("Expense Created Successfully", "success");
+ if (onSuccessCallBack) onSuccessCallBack();
+ },
+ onError: (error) => {
+ showToast(
+ error.message || "Something went wrong please try again !",
+ "error"
+ );
+ },
+ });
+};
+
+export const useUpdateExpense = (onSuccessCallBack) => {
+ const queryClient = useQueryClient();
+ return useMutation({
+ mutationFn: async ({ id, payload }) => {
+ const response = await ExpenseRepository.UpdateExpense(id, payload);
+ return response.data;
+ },
+ onSuccess: (updatedExpense, variables) => {
+ // queryClient.setQueriesData(
+ // {queryKey:['expenses'],exact:true},
+ // (oldData) => {
+ // if (!oldData || !oldData.data) return oldData;
+
+ // const updatedList = oldData.data.map((expense) => {
+ // if (expense.id !== variables.id) return expense;
+
+ // return {
+ // ...expense,
+ // project:
+ // expense.project.id !== updatedExpense.project.id
+ // ? updatedExpense.project
+ // : expense.project,
+ // expensesType:
+ // expense.expensesType.id !== updatedExpense.expensesType.id
+ // ? updatedExpense.expensesType
+ // : expense.expensesType,
+ // paymentMode:
+ // expense.paymentMode.id !== updatedExpense.paymentMode.id
+ // ? updatedExpense.paymentMode
+ // : expense.paymentMode,
+ // paidBy:
+ // expense.paidBy.id !== updatedExpense.paidBy.id
+ // ? updatedExpense.paidBy
+ // : expense.paidBy,
+ // createdBy:
+ // expense.createdBy.id !== updatedExpense.createdBy.id
+ // ? updatedExpense.createdBy
+ // : expense.createdBy,
+ // createdAt: updatedExpense.createdAt,
+ // status: updatedExpense.status,
+ // nextStatus: updatedExpense.nextStatus,
+ // preApproved: updatedExpense.preApproved,
+ // transactionDate: updatedExpense.transactionDate,
+ // amount: updatedExpense.amount,
+ // };
+ // });
+
+ // return {
+ // ...oldData,
+ // data: updatedList,
+ // };
+ // }
+ // );
+ queryClient.removeQueries({ queryKey: ["Expense", variables.id] });
+ queryClient.invalidateQueries({ queryKey: ["Expenses"] });
+ showToast("Expense updated Successfully", "success");
+
+ if (onSuccessCallBack) onSuccessCallBack();
+ },
+ onError: (error) => {
+ showToast("Something went wrong.Please try again later.", "error");
+ },
+ });
+};
+
+export const useActionOnExpense = (onSuccessCallBack) => {
+ const queryClient = useQueryClient();
+
+ return useMutation({
+ mutationFn: async (payload) => {
+ const response = await ExpenseRepository.ActionOnExpense(payload);
+ return response.data;
+ },
+ onSuccess: (updatedExpense, variables) => {
+ showToast("Request processed successfully.", "success");
+
+ queryClient.setQueriesData(
+ {
+ queryKey: ["Expenses"],
+ exact: false,
+ },
+ (oldData) => {
+ if (!oldData) return oldData;
+ return {
+ ...oldData,
+ data: oldData.data.map((item) =>
+ item.id === updatedExpense.id
+ ? {
+ ...item,
+ nextStatus: updatedExpense.nextStatus,
+ status: updatedExpense.status,
+ }
+ : item
+ ),
+ };
+ }
+ );
+ // queryClient.setQueriesData(
+ // { queryKey: ["Expense", updatedExpense.id] },
+ // (oldData) => {
+ // return {
+ // ...oldData,
+ // nextStatus: updatedExpense.nextStatus,
+ // status: updatedExpense.status,
+ // };
+ // }
+ // );
+ queryClient.invalidateQueries({queryKey:["Expense",updatedExpense.id]})
+
+ if (onSuccessCallBack) onSuccessCallBack();
+ },
+ onError: (error) => {
+ showToast(
+ error.response.data.message ||
+ "Something went wrong.Please try again later.",
+ "error"
+ );
+ },
+ });
+};
+
+export const useDeleteExpense = () => {
+ const queryClient = useQueryClient();
+
+ return useMutation({
+ mutationFn: async ({ id }) => {
+ const response = await ExpenseRepository.DeleteExpense(id);
+ return response.data;
+ },
+ onSuccess: (data, variables) => {
+ queryClient.setQueryData(["Expenses"], (oldData) => {
+ if (!oldData || !oldData.data)
+ return queryClient.invalidateQueries({ queryKey: ["Expenses"] });
+
+ const updatedList = oldData.data.filter(
+ (expense) => expense.id !== variables.id
+ );
+
+ return {
+ ...oldData,
+ data: updatedList,
+ };
+ });
+
+ showToast(data.message || "Expense deleted successfully", "success");
+ },
+ onError: (error) => {
+ showToast(
+ error.message ||
+ error.response.message ||
+ "Something went wrong.Please try again later.",
+ "error"
+ );
+ },
+ });
+};
+
+export const useHasAnyPermission = (permissionIdsInput) => {
+ const permissions = useSelector((state) => state?.profile?.permissions || []);
+
+ const permissionIds = Array.isArray(permissionIdsInput)
+ ? permissionIdsInput
+ : [];
+
+ // No permission needed
+ if (permissionIds.length === 0) return true;
+
+ return permissionIds.some((id) => permissions.includes(id));
+};
diff --git a/src/hooks/usePositionTracker.js b/src/hooks/usePositionTracker.js
index f5d122d0..43ed4e9d 100644
--- a/src/hooks/usePositionTracker.js
+++ b/src/hooks/usePositionTracker.js
@@ -1,4 +1,5 @@
import { useState, useEffect } from 'react';
+import showToast from '../services/toastService';
export const usePositionTracker = () => {
const [coords, setCoords] = useState({ latitude: 0, longitude: 0 });
@@ -9,7 +10,7 @@ export const usePositionTracker = () => {
setCoords(coords);
},
(error) => {
- alert(error.message);
+ showToast("Please Allow Location","warn");
},
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 }
);
diff --git a/src/hooks/useProjects.js b/src/hooks/useProjects.js
index daf705fa..68fe5793 100644
--- a/src/hooks/useProjects.js
+++ b/src/hooks/useProjects.js
@@ -313,6 +313,7 @@ export const useProjectName = () => {
isLoading,
error,
refetch,
+ isError
} = useQuery({
queryKey: ["basicProjectNameList"],
queryFn: async () => {
@@ -323,7 +324,7 @@ export const useProjectName = () => {
showToast(error.message || "Error while Fetching project Name", "error");
},
});
- return { projectNames: data, loading: isLoading, Error: error, refetch };
+ return { projectNames: data, loading: isLoading, Error: error, refetch,isError };
};
export const useProjectInfra = (projectId) => {
diff --git a/src/layouts/HomeLayout.jsx b/src/layouts/HomeLayout.jsx
index 34639ee0..0de9e4b9 100644
--- a/src/layouts/HomeLayout.jsx
+++ b/src/layouts/HomeLayout.jsx
@@ -7,6 +7,8 @@ import Footer from "../components/Layout/Footer";
import FloatingMenu from "../components/common/FloatingMenu";
import { FabProvider } from "../Context/FabContext";
import { useSelector } from "react-redux";
+import OffcanvasTrigger from "../components/common/OffcanvasTrigger";
+import GlobalOffcanvas from "../components/common/GlobalOffcanvas ";
const HomeLayout = () => {
const loggedUser = useSelector((store) => store.globalVariables.loginUser);
@@ -34,9 +36,11 @@ const HomeLayout = () => {