-
-
{`${masterType, " ", modalType}`}
+
+
+
{`${(masterType, " ", modalType)}`}
+
+ {modalComponents[modalType] || null}
- { modalComponents[modalType] || null}
-
);
};
diff --git a/src/components/master/paymentAdjustmentHead/ManagePaymentHead.jsx b/src/components/master/paymentAdjustmentHead/ManagePaymentHead.jsx
new file mode 100644
index 00000000..1afba4ab
--- /dev/null
+++ b/src/components/master/paymentAdjustmentHead/ManagePaymentHead.jsx
@@ -0,0 +1,107 @@
+import React, { useEffect } from "react";
+import { z } from "zod";
+import { useForm } from "react-hook-form";
+import { zodResolver } from "@hookform/resolvers/zod";
+import Label from "../../common/Label";
+import { useCreatePaymentAjustmentHead, useUpdatePaymentAjustmentHead } from "../../../hooks/masterHook/useMaster";
+
+export const simpleFormSchema = z.object({
+ name: z.string().min(1, "Name is required"),
+ description: z.string().min(1, "Description is required"),
+});
+
+const ManagePaymentHead = ({ data, onClose }) => {
+ const {
+ register,
+ handleSubmit,
+ reset,
+ formState: { errors },
+ } = useForm({
+ resolver: zodResolver(simpleFormSchema),
+ defaultValues: {
+ name: "",
+ description: "",
+ },
+ });
+
+ const {mutate:CreateAjustmentHead,isPending} = useCreatePaymentAjustmentHead(()=>{
+ handleClose?.()
+ });
+ const {mutate:UpdateAjustmentHead,isPending:isUpdating} = useUpdatePaymentAjustmentHead(()=>{
+ handleClose?.()
+ })
+ const onSubmit = (formData) => {
+ if(data){
+ let id = data?.id;
+ const payload = {
+ ...formData,
+ id:id,
+ }
+ UpdateAjustmentHead({id:id,payload:payload})
+ }else{
+ let payload={
+ ...formData
+ }
+ CreateAjustmentHead(payload)
+ }
+ };
+
+ useEffect(() => {
+ if (data) {
+ reset({
+ name: data.name,
+ description: data.description,
+ });
+ }
+ }, [data]);
+ const handleClose = () => {
+ reset();
+ onClose();
+ };
+ return (
+
+ );
+};
+
+export default ManagePaymentHead;
diff --git a/src/hooks/masterHook/useMaster.js b/src/hooks/masterHook/useMaster.js
index 3487b60b..c9c9216a 100644
--- a/src/hooks/masterHook/useMaster.js
+++ b/src/hooks/masterHook/useMaster.js
@@ -10,6 +10,14 @@ import {
} from "@tanstack/react-query";
import showToast from "../../services/toastService";
+export const usePaymentAjustmentHead = (isActive) => {
+ return useQuery({
+ queryKey: ["paymentType",isActive],
+ queryFn: async () => await MasterRespository.getPaymentAdjustmentHead(isActive),
+
+ });
+};
+
export const useServices = () => {
return useQuery({
queryKey: ["services"],
@@ -28,9 +36,8 @@ export const useActivitiesByGroups = (groupId) => {
return useQuery({
queryKey: ["activties", groupId],
queryFn: async () => await MasterRespository.getActivitesByGroup(groupId),
-
+
enabled: !!groupId,
-
});
};
export const useGlobalServices = () => {
@@ -296,6 +303,8 @@ const fetchMasterData = async (masterType) => {
return (await MasterRespository.getDocumentTypes()).data;
case "Document Category":
return (await MasterRespository.getDocumentCategories()).data;
+ case "Payment Adjustment Head":
+ return (await MasterRespository.getPaymentAdjustmentHead(true)).data;
case "Status":
return [
{
@@ -448,8 +457,6 @@ export const useUpdateApplicationRole = (onSuccessCallback) => {
});
};
-
-
//-----Create work Category-------------------------------
export const useCreateWorkCategory = (onSuccessCallback) => {
const queryClient = useQueryClient();
@@ -703,13 +710,11 @@ export const useCreateService = (onSuccessCallback) => {
return useMutation({
mutationFn: async (payload) => {
-
const resp = await MasterRespository.createService(payload);
-
+
return resp.data;
},
onSuccess: (data) => {
-
queryClient.invalidateQueries({ queryKey: ["masterData", "Services"] });
showToast(data?.message || "Service added successfully", "success");
@@ -717,8 +722,12 @@ export const useCreateService = (onSuccessCallback) => {
if (onSuccessCallback) onSuccessCallback(data?.data);
},
onError: (error) => {
-
- showToast( error?.response?.data?.message || error?.message || "Something went wrong", "error");
+ showToast(
+ error?.response?.data?.message ||
+ error?.message ||
+ "Something went wrong",
+ "error"
+ );
},
});
};
@@ -741,7 +750,12 @@ export const useUpdateService = (onSuccessCallback) => {
if (onSuccessCallback) onSuccessCallback(data);
},
onError: (error) => {
- showToast(error?.response?.data?.message || error?.message || "Something went wrong", "error");
+ showToast(
+ error?.response?.data?.message ||
+ error?.message ||
+ "Something went wrong",
+ "error"
+ );
},
});
};
@@ -759,15 +773,22 @@ export const useCreateActivityGroup = (onSuccessCallback) => {
queryKey: ["groups"],
});
- showToast( data?.message ||
- data?.response?.data?.message || "Activity Group created successfully.",
+ showToast(
+ data?.message ||
+ data?.response?.data?.message ||
+ "Activity Group created successfully.",
"success"
);
if (onSuccessCallback) onSuccessCallback(data);
},
onError: (error) => {
- showToast(error?.response?.data?.message || error?.message || "Something went wrong", "error");
+ showToast(
+ error?.response?.data?.message ||
+ error?.message ||
+ "Something went wrong",
+ "error"
+ );
},
});
};
@@ -775,8 +796,8 @@ export const useUpdateActivityGroup = (onSuccessCallback) => {
const queryClient = useQueryClient();
return useMutation({
- mutationFn: async ({id,payload}) => {
- const response = await MasterRespository.updateActivityGrop(id,payload);
+ mutationFn: async ({ id, payload }) => {
+ const response = await MasterRespository.updateActivityGrop(id, payload);
return response;
},
onSuccess: (data, variables) => {
@@ -786,7 +807,8 @@ export const useUpdateActivityGroup = (onSuccessCallback) => {
showToast(
data?.message ||
- data?.response?.data?.message|| "Activity Group Updated successfully.",
+ data?.response?.data?.message ||
+ "Activity Group Updated successfully.",
"success"
);
@@ -812,7 +834,12 @@ export const useCreateActivity = (onSuccessCallback) => {
if (onSuccessCallback) onSuccessCallback(data);
},
onError: (error) => {
- showToast(error?.response?.data?.message || error?.message || "Something went wrong", "error");
+ showToast(
+ error?.response?.data?.message ||
+ error?.message ||
+ "Something went wrong",
+ "error"
+ );
},
});
};
@@ -834,7 +861,12 @@ export const useUpdateActivity = (onSuccessCallback) => {
if (onSuccessCallback) onSuccessCallback(data);
},
onError: (error) => {
- showToast(error?.response?.data?.message || error?.message || "Something went wrong", "error");
+ showToast(
+ error?.response?.data?.message ||
+ error?.message ||
+ "Something went wrong",
+ "error"
+ );
},
});
};
@@ -968,7 +1000,52 @@ export const useUpdateDocumentType = (onSuccessCallback) => {
},
});
};
-// -Delete Master --------
+// ------------------------------x-x--------x-x------------------------------------
+
+// ==============================Payment Adjustment Head =============================
+export const useCreatePaymentAjustmentHead = (onSuccessCallback) => {
+ const queryClient = useQueryClient();
+
+ return useMutation({
+ mutationFn: async (payload) => {
+ const resp = await MasterRespository.createPaymentAjustmentHead(payload);
+ return resp.data;
+ },
+ onSuccess: (data) => {
+ queryClient.invalidateQueries({
+ queryKey: ["masterData", "Payment Adjustment Head"],
+ });
+ showToast("Payment Ajustment Head successfully", "success");
+ if (onSuccessCallback) onSuccessCallback(data);
+ },
+ onError: (error) => {
+ showToast(error.message || "Something went wrong", "error");
+ },
+ });
+};
+export const useUpdatePaymentAjustmentHead = (onSuccessCallback) => {
+ const queryClient = useQueryClient();
+
+ return useMutation({
+ mutationFn: async ({ id, payload }) => {
+ const resp = await MasterRespository.updatePaymentAjustmentHead(id, payload);
+ return resp.data;
+ },
+ onSuccess: (data) => {
+ queryClient.invalidateQueries({
+ queryKey: ["masterData", "Payment Adjustment Head"],
+ });
+ showToast("Payment Ajustment Head Updated successfully", "success");
+ if (onSuccessCallback) onSuccessCallback(data);
+ },
+ onError: (error) => {
+ showToast(error.message || "Something went wrong", "error");
+ },
+ });
+};
+// ====================x=x====================x=x==================================
+
+// --------Delete Master --------
export const useDeleteMasterItem = () => {
const queryClient = useQueryClient();
@@ -1001,14 +1078,12 @@ export const useDeleteMasterItem = () => {
});
};
-
-export const useDeleteServiceGroup =()=>{
- const queryClient = useQueryClient();
+export const useDeleteServiceGroup = () => {
+ const queryClient = useQueryClient();
return useMutation({
- mutationFn: async (id)=>await MasterRespository.deleteActivityGroup(id),
- onSuccess: ({_,variable}) => {
-
+ mutationFn: async (id) => await MasterRespository.deleteActivityGroup(id),
+ onSuccess: ({ _, variable }) => {
queryClient.invalidateQueries({ queryKey: ["groups"] });
showToast(`Group deleted successfully.`, "success");
@@ -1022,15 +1097,13 @@ export const useDeleteServiceGroup =()=>{
showToast(message, "error");
},
});
-}
-export const useDeleteActivity =()=>{
- const queryClient = useQueryClient();
+};
+export const useDeleteActivity = () => {
+ const queryClient = useQueryClient();
return useMutation({
- mutationFn: async (id)=>await MasterRespository.deleteActivity(id),
- onSuccess: ({_,variable}) => {
-
-
+ mutationFn: async (id) => await MasterRespository.deleteActivity(id),
+ onSuccess: ({ _, variable }) => {
queryClient.invalidateQueries({ queryKey: ["activties"] });
showToast(`Acivity deleted successfully.`, "success");
@@ -1044,4 +1117,4 @@ export const useDeleteActivity =()=>{
showToast(message, "error");
},
});
-}
+};
diff --git a/src/hooks/useAuth.jsx b/src/hooks/useAuth.jsx
index c9e763f9..ded67e13 100644
--- a/src/hooks/useAuth.jsx
+++ b/src/hooks/useAuth.jsx
@@ -32,6 +32,16 @@ export const useModal = (modalType) => {
return { isOpen, onOpen, onClose, onToggle };
};
+export const useSubscription = (frequency) => {
+ return useQuery({
+ queryKey: ["subscriptionPlans", frequency],
+ queryFn: async () => {
+ debugger
+ const resp = await AuthRepository.getSubscription(frequency);
+ return resp.data;
+ },
+ });
+};
// -------------------APIHook-------------------------------------
@@ -85,8 +95,8 @@ export const useAuthModal = () => {
export const useLogout = () => {
const queryClient = useQueryClient();
- const naviget = useNavigate()
- const dispatch = useDispatch()
+ const naviget = useNavigate();
+ const dispatch = useDispatch();
return useMutation({
mutationFn: async () => {
@@ -99,12 +109,12 @@ export const useLogout = () => {
},
onSuccess: (data) => {
- queryClient.clear()
+ queryClient.clear();
removeSession();
- dispatch(cacheProfileData(null))
+ dispatch(cacheProfileData(null));
// window.location.href = "/auth/login";
- naviget("/auth/login",{replace:true})
+ naviget("/auth/login", { replace: true });
if (onSuccessCallBack) onSuccessCallBack();
},
diff --git a/src/hooks/useCollections.jsx b/src/hooks/useCollections.jsx
new file mode 100644
index 00000000..c300462d
--- /dev/null
+++ b/src/hooks/useCollections.jsx
@@ -0,0 +1,152 @@
+import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
+import { CollectionRepository } from "../repositories/ColllectionRepository";
+import showToast from "../services/toastService";
+
+export const useCollections = (
+ pageSize,
+ pageNumber,
+ fromDate,
+ toDate,
+ isPending,
+ isActive,
+ projectId,
+ searchString
+) => {
+ return useQuery({
+ queryKey: [
+ "collections",
+ pageSize,
+ pageNumber,
+ fromDate,
+ toDate,
+ isPending,
+ isActive,
+ projectId,
+ searchString,
+ ],
+
+ queryFn: async () => {
+ const response = await CollectionRepository.getCollections(
+ pageSize,
+ pageNumber,
+ fromDate,
+ toDate,
+ isPending,
+ isActive,
+ projectId,
+ searchString
+ );
+ return response.data;
+ },
+
+ keepPreviousData: true,
+ staleTime: 1000 * 60 * 1,
+ });
+};
+
+
+export const useCollection =(collectionId)=>{
+ return useQuery({
+ queryKey:["collection",collectionId],
+ queryFn:async()=> {
+ const resp = await CollectionRepository.getCollection(collectionId);
+ return resp.data
+ },
+ enabled:!!collectionId
+ })
+}
+
+
+// =========================Mutation======================
+
+export const useCreateCollection = (onSuccessCallBack) => {
+ const clinent = useQueryClient();
+ return useMutation({
+ mutationFn: async (payload) =>
+ await CollectionRepository.createNewCollection(payload),
+ onSuccess: (_, variables) => {
+ showToast("New Collection created Successfully", "success");
+ clinent.invalidateQueries({ queryKey: ["collections"] });
+ if (onSuccessCallBack) onSuccessCallBack();
+ },
+ onError: (error) => {
+ showToast(
+ error.response.data.message || error.message || "Something Went wrong"
+ );
+ },
+ });
+};
+
+export const useMarkedPaymentReceived = (onSuccessCallBack) => {
+ const client = useQueryClient();
+ return useMutation({
+ mutationFn: async (payload) =>
+ await CollectionRepository.markPaymentReceived(payload),
+ onSuccess: async () => {
+ client.invalidateQueries({ queryKey: ["collections"] });
+ showToast("Payment Received marked Successfully", "success");
+ if (onSuccessCallBack) onSuccessCallBack();
+ },
+ onError: (error) => {
+ showToast(
+ error.response.data.message || error.message || "Something Went wrong"
+ );
+ },
+ });
+};
+
+export const useAddPayment = (onSuccessCallBack) => {
+ const client = useQueryClient();
+
+ return useMutation({
+ mutationFn: (payload) => CollectionRepository.makeReceivePayment(payload),
+ onSuccess: () => {
+ client.invalidateQueries({ queryKey: ["collections"] });
+ client.invalidateQueries({ queryKey: ["collection"] });
+ showToast("Payment Received marked Successfully", "success");
+ if (onSuccessCallBack) onSuccessCallBack();
+ },
+ onError: (error) => {
+ showToast(
+ error?.response?.data?.message || error.message || "Something Went wrong"
+ );
+ },
+ });
+};
+
+export const useAddComment = (onSuccessCallBack) => {
+ const client = useQueryClient();
+
+ return useMutation({
+ mutationFn: (payload) => CollectionRepository.addComment(payload),
+ onSuccess: () => {
+ client.invalidateQueries({ queryKey: ["collections"] });
+ client.invalidateQueries({ queryKey: ["collection"] });
+ showToast("Comment Successfully", "success");
+ if (onSuccessCallBack) onSuccessCallBack();
+ },
+ onError: (error) => {
+ showToast(
+ error?.response?.data?.message || error.message || "Something Went wrong"
+ );
+ },
+ });
+};
+
+export const useUpdateCollection =(onSuccessCallBack)=>{
+ const client = useQueryClient();
+ return useMutation({
+ mutationFn:async({collectionId,payload})=> await CollectionRepository.updateCollection(collectionId,payload),
+ onSuccess: () => {
+ client.invalidateQueries({ queryKey: ["collections"] });
+ client.invalidateQueries({ queryKey: ["collection"] });
+ showToast("Collection Updated Successfully", "success");
+ if (onSuccessCallBack) onSuccessCallBack();
+ },
+ onError: (error) => {
+ showToast(
+ error?.response?.data?.message || error.message || "Something Went wrong"
+ );
+ },
+ })
+}
\ No newline at end of file
diff --git a/src/hooks/useProjects.js b/src/hooks/useProjects.js
index d540a3ce..7175bb94 100644
--- a/src/hooks/useProjects.js
+++ b/src/hooks/useProjects.js
@@ -153,7 +153,7 @@ export const useProjectsAllocationByEmployee = (employeeId) => {
return { projectList, loading: isLoading, error, refetch };
};
-export const useProjectName = () => {
+export const useProjectName = (provideAll=false) => {
const {
data = [],
isLoading,
@@ -161,9 +161,9 @@ export const useProjectName = () => {
refetch,
isError,
} = useQuery({
- queryKey: ["basicProjectNameList"],
+ queryKey: ["basicProjectNameList",provideAll],
queryFn: async () => {
- const res = await ProjectRepository.projectNameList();
+ const res = await ProjectRepository.projectNameList(provideAll);
return res.data || res;
},
onError: (error) => {
diff --git a/src/pages/Home/LandingPage.jsx b/src/pages/Home/LandingPage.jsx
index 35b01202..d3288a9d 100644
--- a/src/pages/Home/LandingPage.jsx
+++ b/src/pages/Home/LandingPage.jsx
@@ -206,8 +206,8 @@ const LandingPage = () => {
navigation={false}
modules={[EffectFlip, Autoplay, Pagination, Navigation]}
className="mySwiper"
- onSlideChange={() => console.log("slide change")}
- onSwiper={(swiper) => console.log(swiper)}
+ onSlideChange={() => {}}
+ onSwiper={(swiper) => {}}
>
{
const [plans, setPlans] = useState([]);
const [frequency, setFrequency] = useState(1);
+ const { data, isLoading, isError, error } = useSubscription(frequency);
const [loading, setLoading] = useState(false);
- useEffect(() => {
- const fetchPlans = async () => {
- try {
- setLoading(true);
- const res = await axios.get(
- `http://localhost:5032/api/market/list/subscription-plan?frequency=${frequency}`,
- { headers: { "Content-Type": "application/json" } }
- );
- setPlans(res.data?.data || []);
- } catch (err) {
- console.error("Error fetching plans:", err);
- } finally {
- setLoading(false);
- }
- };
- fetchPlans();
- }, [frequency]);
+
const frequencyLabel = (freq) => {
switch (freq) {
- case 0: return "1 mo";
- case 1: return "3 mo";
- case 2: return "6 mo";
- case 3: return "1 yr";
- default: return "mo";
+ case 0:
+ return "1 mo";
+ case 1:
+ return "3 mo";
+ case 2:
+ return "6 mo";
+ case 3:
+ return "1 yr";
+ default:
+ return "mo";
}
};
@@ -41,38 +32,49 @@ const SubscriptionPlans = () => {
{/* Frequency Switcher */}
- {["Monthly", "Quarterly", "Half-Yearly", "Yearly"].map((label, idx) => (
-
- ))}
+ {["Monthly", "Quarterly", "Half-Yearly", "Yearly"].map(
+ (label, idx) => (
+
+ )
+ )}
{/* Cards */}
- {loading ? (
+ {isLoading ? (
// Show 3 skeletons
<>
>
- ) : plans.length === 0 ? (
+ ) : data.length === 0 ? (
No plans found
+ ) : isError ? (
+
+
{error.message}
+
{error.name}
+
) : (
- plans.map((plan) => (
+ data.map((plan) => (
{/* Header */}
-
{plan.planName}
+
+ {plan.planName}
+
{plan.description}
@@ -80,7 +82,9 @@ const SubscriptionPlans = () => {
{plan.currency?.symbol} {plan.price}
- / {frequencyLabel(frequency)}
+
+ / {frequencyLabel(frequency)}
+
@@ -133,7 +137,6 @@ const SubscriptionPlans = () => {
))
)}
-
);
};
diff --git a/src/pages/collections/CollectionPage.jsx b/src/pages/collections/CollectionPage.jsx
new file mode 100644
index 00000000..aac80d26
--- /dev/null
+++ b/src/pages/collections/CollectionPage.jsx
@@ -0,0 +1,223 @@
+import React, { createContext, useContext, useState } from "react";
+import moment from "moment";
+import Breadcrumb from "../../components/common/Breadcrumb";
+import CollectionList from "../../components/collections/CollectionList";
+import { useModal } from "../../hooks/useAuth";
+import { FormProvider, useForm } from "react-hook-form";
+import { zodResolver } from "@hookform/resolvers/zod";
+import { DateRangePicker1 } from "../../components/common/DateRangePicker";
+import { isPending } from "@reduxjs/toolkit";
+import ConfirmModal from "../../components/common/ConfirmModal";
+import showToast from "../../services/toastService";
+import { useMarkedPaymentReceived } from "../../hooks/useCollections";
+import GlobalModel from "../../components/common/GlobalModel";
+import AddPayment from "../../components/collections/AddPayment";
+import ViewCollection from "../../components/collections/ViewCollection";
+import ManageCollection from "../../components/collections/ManageCollection";
+import PreviewDocument from "../../components/Expenses/PreviewDocument";
+import { useHasUserPermission } from "../../hooks/useHasUserPermission";
+import {
+ ADDPAYMENT_COLLECTION,
+ ADMIN_COLLECTION,
+ CREATE_COLLECTION,
+ EDIT_COLLECTION,
+ VIEW_COLLECTION,
+} from "../../utils/constants";
+import AccessDenied from "../../components/common/AccessDenied";
+
+const CollectionContext = createContext();
+export const useCollectionContext = () => {
+ const context = useContext(CollectionContext);
+ if (!context) {
+ window.location = "/dashboard";
+ showToast("Out of Context Happend inside Collection Context", "warning");
+ }
+ return context;
+};
+const CollectionPage = () => {
+ const [viewCollection, setViewCollection] = useState(null);
+ const [makeCollection, setCollection] = useState({
+ isOpen: false,
+ invoiceId: null,
+ });
+ const [ViewDocument, setDocumentView] = useState({
+ IsOpen: false,
+ Image: null,
+ });
+ const [processedPayment, setProcessedPayment] = useState(null);
+ const [addPayment, setAddPayment] = useState({
+ isOpen: false,
+ invoiceId: null,
+ });
+ const [showPending, setShowPending] = useState(false);
+ const [searchText, setSearchText] = useState("");
+ const isAdmin = useHasUserPermission(ADMIN_COLLECTION);
+ const canViewCollection = useHasUserPermission(VIEW_COLLECTION);
+ const canCreate = useHasUserPermission(CREATE_COLLECTION);
+ const canEditCollection = useHasUserPermission(EDIT_COLLECTION);
+ const canAddPayment = useHasUserPermission(ADDPAYMENT_COLLECTION);
+ const methods = useForm({
+ defaultValues: {
+ fromDate: moment().subtract(180, "days").format("DD-MM-YYYY"),
+ toDate: moment().format("DD-MM-YYYY"),
+ },
+ });
+ const { watch } = methods;
+ const [fromDate, toDate] = watch(["fromDate", "toDate"]);
+
+ const handleToggleActive = (e) => setShowPending(e.target.checked);
+
+ const contextMassager = {
+ setProcessedPayment,
+ setCollection,
+ setAddPayment,
+ addPayment,
+ setViewCollection,
+ viewCollection,
+ setDocumentView,
+ };
+ const { mutate: MarkedReceived, isPending } = useMarkedPaymentReceived(() => {
+ setProcessedPayment(null);
+ });
+ const handleMarkedPayment = (payload) => {
+ MarkedReceived(payload);
+ };
+ if (isAdmin === undefined ||
+ canAddPayment === undefined ||
+ canEditCollection === undefined ||
+ canViewCollection === undefined ||
+ canCreate === undefined
+) {
+ return
Checking access...
;
+}
+
+if (!isAdmin && !canAddPayment && !canEditCollection && !canViewCollection && !canCreate) {
+ return
;
+}
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+ setShowPending(e.target.checked)}
+ />
+
+
+
+
+
+
+ {" "}
+ setSearchText(e.target.value)}
+ placeholder="search Collection"
+ className="form-control form-control-sm"
+ />
+
+ { (canCreate || isAdmin) && (
+
+)}
+
+
+
+
+
+
+
+ {makeCollection.isOpen && (
+
setCollection({ isOpen: false, invoiceId: null })}
+ >
+ setCollection({ isOpen: false, invoiceId: null })}
+ />
+
+ )}
+
+ {addPayment.isOpen && (
+
setAddPayment({ isOpen: false, invoiceId: null })}
+ >
+ setAddPayment({ isOpen: false, invoiceId: null })}
+ />
+
+ )}
+
+ {viewCollection && (
+
setViewCollection(null)}
+ >
+ setViewCollection(null)} />
+
+ )}
+
+ {ViewDocument.IsOpen && (
+
setDocumentView({ IsOpen: false, Image: null })}
+ >
+
+
+ )}
+
+
handleMarkedPayment(processedPayment?.invoiceId)}
+ onClose={() => setProcessedPayment(null)}
+ />
+
+
+ );
+};
+
+export default CollectionPage;
diff --git a/src/repositories/AuthRepository.jsx b/src/repositories/AuthRepository.jsx
index 700020fd..ba68946e 100644
--- a/src/repositories/AuthRepository.jsx
+++ b/src/repositories/AuthRepository.jsx
@@ -10,6 +10,7 @@ const AuthRepository = {
verifyOTP: (data) => api.postPublic("/api/auth/login-otp", data),
register: (data) => api.postPublic("/api/auth/register", data),
sendMail: (data) => api.postPublic("/api/auth/sendmail", data),
+ getSubscription:(frequency)=> api.getPublic(`/api/market/list/subscription-plan?frequency=${frequency}`),
// Protected routes (require auth token)
logout: (data) => api.post("/api/auth/logout", data),
@@ -17,7 +18,9 @@ const AuthRepository = {
changepassword: (data) => api.post("/api/auth/change-password", data),
appmenu: () => api.get('/api/appmenu/get/menu'),
selectTenant: (tenantId) => api.post(`/api/Auth/select-tenant/${tenantId}`),
- getTenantList: () => api.get("/api/Auth/get/user/tenants"),
+ getTenantList: () => api.get("/api/Auth/get/user/tenants"),
+
+ //
};
diff --git a/src/repositories/ColllectionRepository.jsx b/src/repositories/ColllectionRepository.jsx
new file mode 100644
index 00000000..8eb512da
--- /dev/null
+++ b/src/repositories/ColllectionRepository.jsx
@@ -0,0 +1,29 @@
+import { api } from "../utils/axiosClient";
+import { DirectoryRepository } from "./DirectoryRepository";
+
+export const CollectionRepository = {
+ createNewCollection: (data) =>
+ api.post(`/api/Collection/invoice/create`, data),
+ updateCollection:(id,data)=>{
+ api.put(`/api/Collection/invoice/edit/${id}`,data)
+ },
+ getCollections: (pageSize, pageNumber,fromDate,toDate, isPending,isActive,projectId, searchString) => {
+ let url = `/api/Collection/invoice/list?pageSize=${pageSize}&pageNumber=${pageNumber}&isPending=${isPending}&isActive=${isActive}&searchString=${searchString}`;
+
+ const params = [];
+ if (fromDate) params.push(`fromDate=${fromDate}`);
+ if (toDate) params.push(`toDate=${toDate}`);
+ if(projectId) params.push(`projectId=${projectId}`)
+
+ if (params.length > 0) {
+ url += `&${params.join("&")}`;
+ }
+ return api.get(url);
+ },
+
+ makeReceivePayment:(data)=> api.post(`/api/Collection/invoice/payment/received`,data),
+ markPaymentReceived:(invoiceId)=>api.put(`/api/Collection/invoice/marked/completed/${invoiceId}`),
+ getCollection:(id)=>api.get(`/api/Collection/invoice/details/${id}`),
+ addComment:(data)=>api.post(`/api/Collection/invoice/add/comment`,data)
+};
+
diff --git a/src/repositories/MastersRepository.jsx b/src/repositories/MastersRepository.jsx
index 3e9fac8f..d197c11c 100644
--- a/src/repositories/MastersRepository.jsx
+++ b/src/repositories/MastersRepository.jsx
@@ -58,6 +58,7 @@ export const MasterRespository = {
"Document Type": (id) => api.delete(`/api/Master/document-type/delete/${id}`),
"Document Category": (id) =>
api.delete(`/api/Master/document-category/delete/${id}`),
+ "Payment Adjustment Head":(id,isActive)=>api.delete(`/api/Master/payment-adjustment-head/delete/${id}`,(isActive=false)),
getWorkCategory: () => api.get(`/api/master/work-categories`),
createWorkCategory: (data) => api.post(`/api/master/work-category`, data),
@@ -124,10 +125,15 @@ export const MasterRespository = {
api.put(`/api/Master/activity-group/edit/${serviceId}`, data),
getActivitesByGroup: (activityGroupId) =>
api.get(`api/master/activities?activityGroupId=${activityGroupId}`),
- deleteActivityGroup:(id)=>api.delete(`/api/Master/activity-group/delete/${id}`),
+ deleteActivityGroup: (id) =>
+ api.delete(`/api/Master/activity-group/delete/${id}`),
-
- deleteActivity:(id)=>api.delete(`/api/Master/activity/delete/${id}`),
+ deleteActivity: (id) => api.delete(`/api/Master/activity/delete/${id}`),
getOrganizationType: () => api.get("/api/Master/organization-type/list"),
+
+ getPaymentAdjustmentHead: (isActive) =>
+ api.get(`/api/Master/payment-adjustment-head/list?isActive=${isActive}`),
+ createPaymentAjustmentHead:(data)=>api.post(`/api/Master/payment-adjustment-head`, data),
+ updatePaymentAjustmentHead:(id,data)=>api.put(`/api/Master/payment-adjustment-head/edit/${id}`, data)
};
diff --git a/src/repositories/ProjectRepository.jsx b/src/repositories/ProjectRepository.jsx
index 8f21acb4..06d33c58 100644
--- a/src/repositories/ProjectRepository.jsx
+++ b/src/repositories/ProjectRepository.jsx
@@ -40,7 +40,7 @@ const ProjectRepository = {
api.get(`/api/project/allocation-histery/${id}`),
updateProjectsByEmployee: (id, data) =>
api.post(`/api/project/assign-projects/${id}`, data),
- projectNameList: () => api.get("/api/project/list/basic"),
+ projectNameList: (provideAll) => api.get(`/api/project/list/basic?provideAll=${provideAll}`),
getProjectDetails: (id) => api.get(`/api/project/details/${id}`),
diff --git a/src/router/AppRoutes.jsx b/src/router/AppRoutes.jsx
index c0787e95..ac736d7b 100644
--- a/src/router/AppRoutes.jsx
+++ b/src/router/AppRoutes.jsx
@@ -53,6 +53,7 @@ import DailyProgrssReport from "../pages/DailyProgressReport/DailyProgrssReport"
import ProjectPage from "../pages/project/ProjectPage";
import { ComingSoonPage } from "../pages/Misc/ComingSoonPage";
import ImageGalleryPage from "../pages/Gallary/ImageGallaryPage";
+import CollectionPage from "../pages/collections/CollectionPage";
const router = createBrowserRouter(
[
{
@@ -95,6 +96,7 @@ const router = createBrowserRouter(
{ path: "/activities/reports", element:
},
{ path: "/gallary", element:
},
{ path: "/expenses", element:
},
+ { path: "/collection", element:
},
{ path: "/masters", element:
},
{ path: "/tenants", element:
},
{ path: "/tenants/new-tenant", element:
},
diff --git a/src/utils/appUtils.js b/src/utils/appUtils.js
index f9be1ebd..bfe9b692 100644
--- a/src/utils/appUtils.js
+++ b/src/utils/appUtils.js
@@ -113,7 +113,7 @@ export const formatFigure = (
type = "number",
currency = "INR",
locale = "en-US",
- notation = "compact",
+ notation = "standard", // standard or compact
compactDisplay = "short",
minimumFractionDigits = 0,
maximumFractionDigits = 2,
diff --git a/src/utils/axiosClient.jsx b/src/utils/axiosClient.jsx
index bf26500e..0f2f14a2 100644
--- a/src/utils/axiosClient.jsx
+++ b/src/utils/axiosClient.jsx
@@ -72,7 +72,9 @@ axiosClient.interceptors.response.use(
if (status === 401 && !isRefreshRequest) {
originalRequest._retry = true;
- const refreshToken = localStorage.getItem("refreshToken") || sessionStorage.getItem("refreshToken");
+ const refreshToken =
+ localStorage.getItem("refreshToken") ||
+ sessionStorage.getItem("refreshToken");
if (
!refreshToken ||
@@ -87,7 +89,9 @@ axiosClient.interceptors.response.use(
try {
// Refresh token call
const res = await axiosClient.post("/api/Auth/refresh-token", {
- token: localStorage.getItem("jwtToken") || sessionStorage.getItem("jwtToken"),
+ token:
+ localStorage.getItem("jwtToken") ||
+ sessionStorage.getItem("jwtToken"),
refreshToken,
});
@@ -144,6 +148,11 @@ export const api = {
headers: { ...customHeaders },
authRequired: false,
}),
+ getPublic: (url, data = {}, customHeaders = {}) =>
+ apiRequest("get", url, data, {
+ headers: { ...customHeaders },
+ authRequired: false,
+ }),
// Authenticated routes
get: (url, params = {}, customHeaders = {}) =>
diff --git a/src/utils/constants.jsx b/src/utils/constants.jsx
index 8d190f15..36a9ead4 100644
--- a/src/utils/constants.jsx
+++ b/src/utils/constants.jsx
@@ -3,7 +3,6 @@ export const DURATION_TIME = 10; // minutes
export const ITEMS_PER_PAGE = 20;
export const OTP_EXPIRY_SECONDS = 300; // OTP time
-
export const BASE_URL = process.env.VITE_BASE_URL;
// export const BASE_URL = "https://api.marcoaiot.com";
@@ -50,7 +49,7 @@ export const DIRECTORY_ADMIN = "4286a13b-bb40-4879-8c6d-18e9e393beda";
export const DIRECTORY_MANAGER = "62668630-13ce-4f52-a0f0-db38af2230c5";
export const DIRECTORY_USER = "0f919170-92d4-4337-abd3-49b66fc871bb";
-
+// ========================Finance=========================================================
// -----------------------Expense----------------------------------------
export const VIEW_SELF_EXPENSE = "385be49f-8fde-440e-bdbc-3dffeb8dd116";
@@ -66,6 +65,16 @@ export const PROCESS_EXPENSE = "ea5a1529-4ee8-4828-80ea-0e23c9d4dd11";
export const EXPENSE_MANAGE = "ea5a1529-4ee8-4828-80ea-0e23c9d4dd11";
+// --------------------------------Collection----------------------------
+
+export const ADMIN_COLLECTION = "dbf17591-09fe-4c93-9e1a-12db8f5cc5de";
+export const VIEW_COLLECTION = "c8d7eea5-4033-4aad-9ebe-76de49896830";
+export const CREATE_COLLECTION = "b93141fd-dbd3-4051-8f57-bf25d18e3555";
+export const EDIT_COLLECTION = "455187b4-fef1-41f9-b3d0-025d0b6302c3";
+export const ADDPAYMENT_COLLECTION = "061d9ccd-85b4-4cb0-be06-2f9f32cebb72";
+
+// ==========================================================================================
+
export const EXPENSE_REJECTEDBY = [
"d1ee5eec-24b6-4364-8673-a8f859c60729",
"965eda62-7907-4963-b4a1-657fb0b2724b",
@@ -146,4 +155,3 @@ export const PROJECT_STATUS = [
},
];
export const DEFAULT_EMPTY_STATUS_ID = "00000000-0000-0000-0000-000000000000";
-