diff --git a/src/routes.js b/src/routes.js index becc2c8..2105a1b 100644 --- a/src/routes.js +++ b/src/routes.js @@ -151,6 +151,7 @@ import AddRetailDistributor from "./views/RetailDistributors/addRetailDistributo import ViewPrincipalDistributorSC from "./views/SalesCoOrdinators/ViewPrincipalDistributorSC"; import ViewRetailDistributorSC from "./views/SalesCoOrdinators/ViewRetailDistributorSC"; import ViewRetailDistributorPD from "./views/PrincipalDistributors/ViewRetailDistributorPD"; +import MapRD from "./views/RetailDistributors/MapRD"; const routes = [ //dashboard @@ -360,6 +361,12 @@ const routes = [ element: AddRetailDistributor, navName: "RetailDistributor", }, + { + path: "/retaildistributor/mapping/:id", + name: "Mapping Retail Distributor with PD SC TM", + element: MapRD, + navName: "RetailDistributor", + }, //----------------------- End Product Management Routes------------------------------------------------ //Departure diff --git a/src/views/Leaves/TodayLeaves.js b/src/views/Leaves/TodayLeaves.js index d87ae6c..49ee52a 100644 --- a/src/views/Leaves/TodayLeaves.js +++ b/src/views/Leaves/TodayLeaves.js @@ -27,7 +27,7 @@ const TodayLeave = () => { show: itemPerPage, }, }); - console.log(res.data); + // console.log(res.data); setSalesCoOrdinatorsData(res.data?.leave); setTotalData(res.data?.total_data); } catch (err) { diff --git a/src/views/RetailDistributors/MapRD.js b/src/views/RetailDistributors/MapRD.js new file mode 100644 index 0000000..97736e4 --- /dev/null +++ b/src/views/RetailDistributors/MapRD.js @@ -0,0 +1,897 @@ +import React, { useState, useEffect, useRef, useCallback } from "react"; +import axios from "axios"; +import { + Box, + Typography, + Grid, + Paper, + Dialog, + DialogContent, + DialogTitle, +} from "@mui/material"; +import { useParams, useNavigate } from "react-router-dom"; +import { isAutheticated } from "../../auth"; +import Button from "@material-ui/core/Button"; +import swal from "sweetalert"; +import debounce from "lodash.debounce"; +import TextField from "@mui/material/TextField"; +import DialogActions from "@mui/material/DialogActions"; + +const MapRD = () => { + const { id } = useParams(); + const token = isAutheticated(); + const navigate = useNavigate(); + + const [loading, setLoading] = useState(false); + const [success, setSuccess] = useState(true); + const [data, setData] = useState(null); + + const pdnameRef = useRef(); + const pdmobileRef = useRef(); + const scnameRef = useRef(); + const scmobileRef = useRef(); + const tmnameRef = useRef(); + const tmmobileRef = useRef(); + + const [modalcurrentPage, setmodalCurrentPage] = useState(1); + const modalitemPerPage = 10; + const [openPDModal, setOpenPDModal] = useState(false); + const [openSCModal, setOpenSCModal] = useState(false); + const [openTMModal, setOpenTMModal] = useState(false); + + // For opening each modal + const handleOpenPDModal = () => setOpenPDModal(true); + const handleOpenSCModal = () => setOpenSCModal(true); + const handleOpenTMModal = () => setOpenTMModal(true); + + // For closing each modal + const handleClosePDModal = () => setOpenPDModal(false); + const handleCloseSCModal = () => setOpenSCModal(false); + const handleCloseTMModal = () => setOpenTMModal(false); + + const [modalTotalData, setModalTotalData] = useState(0); + const [modalSalesCoordinators, setModalSalesCoordinators] = useState([]); + const [modalPrincipalDistributors, setmodalPrincipalDistributors] = useState( + [] + ); + const [modalterritorymanagers, setmodalterritorymanagers] = useState([]); + + useEffect(() => { + const fetchData = async () => { + try { + // Commented out the API call and using dummy data + const response = await axios.get(`/api/getRD/${id}`, { + headers: { + "Access-Control-Allow-Origin": "*", + Authorization: `Bearer ${token}`, + "Content-Type": "multipart/form-data", + }, + }); + setData(response.data); + // console.log('Retailer Details: ', response.data); + } catch (error) { + console.error("Error fetching data: ", error); + } + }; + + fetchData(); + }, [id, token, success]); + + // SC + const getSalesCoOrdinatorsData = async () => { + setLoading(true); + try { + const res = await axios.get(`/api/salescoordinator/getAll`, { + headers: { + Authorization: `Bearer ${token}`, + }, + params: { + page: modalcurrentPage, + show: modalitemPerPage, + name: scnameRef.current?.value, + mobileNumber: scmobileRef.current?.value, + }, + }); + setModalSalesCoordinators(res.data?.salesCoOrinators); + setModalTotalData(res.data?.total_data); + } catch (err) { + const msg = err?.response?.data?.message || "Something went wrong!"; + swal({ + title: "Error", + text: msg, + icon: "error", + button: "Retry", + dangerMode: true, + }); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + if (openSCModal) { + getSalesCoOrdinatorsData(); + } + }, [openSCModal, modalcurrentPage]); + + // Debounced search for Sales Coordinators in modal + const debouncedmodalSearchforSC = useCallback( + debounce(() => { + setmodalCurrentPage(1); + getSalesCoOrdinatorsData(); + }, 500), + [modalcurrentPage] + ); + + const handlemodalSearchChangeinSC = useCallback(() => { + debouncedmodalSearchforSC(); + }, [debouncedmodalSearchforSC]); + + // PD + const getprincipaldistributorData = async () => { + setLoading(true); + try { + const res = await axios.get(`/api/v1/admin/users`, { + headers: { + Authorization: `Bearer ${token}`, + }, + params: { + page: modalcurrentPage, + show: modalitemPerPage, + name: pdnameRef.current?.value, + mobileNumber: pdmobileRef.current?.value, + }, + }); + setmodalPrincipalDistributors(res.data?.users); + setModalTotalData(res.data?.totalUsers); + } catch (err) { + const msg = err?.response?.data?.message || "Something went wrong!"; + swal({ + title: "Error", + text: msg, + icon: "error", + button: "Retry", + dangerMode: true, + }); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + if (openPDModal) { + getprincipaldistributorData(); + } + }, [openPDModal, modalcurrentPage]); + + // Debounced search for Principal Distributors in modal + const debouncedmodalSearchforPD = useCallback( + debounce(() => { + setmodalCurrentPage(1); + getprincipaldistributorData(); + }, 500), + [modalcurrentPage] + ); + + const handlemodalSearchChangeinPD = useCallback(() => { + debouncedmodalSearchforPD(); + }, [debouncedmodalSearchforPD]); + + // TM + const getTerritorymanagersData = async () => { + setLoading(true); + try { + const res = await axios.get(`/api/territorymanager/getAll`, { + headers: { + Authorization: `Bearer ${token}`, + }, + params: { + page: modalcurrentPage, + show: modalitemPerPage, + name: tmnameRef.current?.value, + mobileNumber: tmmobileRef.current?.value, + }, + }); + setmodalterritorymanagers(res.data?.territoryManager); + setModalTotalData(res.data?.total_data); + } catch (err) { + const msg = err?.response?.data?.message || "Something went wrong!"; + swal({ + title: "Error", + text: msg, + icon: "error", + button: "Retry", + dangerMode: true, + }); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + if (openTMModal) { + getTerritorymanagersData(); + } + }, [openTMModal, modalcurrentPage]); + + // Debounced search for Territory manager in modal + const debouncedmodalSearchforTM = useCallback( + debounce(() => { + setmodalCurrentPage(1); + getTerritorymanagersData(); + }, 500), + [modalcurrentPage] + ); + + const handlemodalSearchChangeinTM = useCallback(() => { + debouncedmodalSearchforTM(); + }, [debouncedmodalSearchforTM]); + + const handlePreviousPage = () => { + if (modalcurrentPage > 1) { + setmodalCurrentPage(modalcurrentPage - 1); + } + }; + const handleDelete = (designation) => { + swal({ + title: "Are you sure?", + icon: "warning", + buttons: { + Yes: { text: "Yes", value: true }, + Cancel: { text: "Cancel", value: "cancel" }, + }, + }).then((value) => { + if (value === true) { + // Create the data object based on designation + let data = {}; + if (designation === "TM") { + data.mappedTM = true; + } else if (designation === "SC") { + data.mappedSC = true; + } else { + data.principal_distributor = true; + } + + // Make the PATCH request with the constructed data object + axios + .patch( + `/api/unmap/${id}`, + data, // Send the constructed data object + { + headers: { + "Access-Control-Allow-Origin": "*", + Authorization: `Bearer ${token}`, + }, + } + ) + .then((res) => { + swal({ + title: "Deleted", + text: "Retail Distributor Unmapped successfully!", + icon: "success", + button: "Ok", + }); + setSuccess((prev) => !prev); + }) + .catch((err) => { + let msg = err?.response?.data?.message || "Something went wrong!"; + swal({ + title: "Warning", + text: msg, + icon: "error", + button: "Retry", + dangerMode: true, + }); + }); + } + }); + }; + + const handleUpdateMapping = async (rdid, designation) => { + try { + // Create the data object based on designation + let data = {}; + if (designation === "TM") { + data.mappedTM = rdid; + } else if (designation === "SC") { + data.mappedSC = rdid; + } else { + data.principal_distributor = rdid; + } + + // Make the API request + await axios.put( + `/api/mapped/${id}`, + data, // Send the constructed data object + { + headers: { + Authorization: `Bearer ${token}`, + }, + } + ); + + // Success alert + swal({ + title: "Success", + text: "Mapped successfully!", + icon: "success", + button: "Ok", + }); + + // Trigger success state change and close modals + setSuccess((prev) => !prev); + handleClosePDModal(); + handleCloseSCModal(); + handleCloseTMModal(); + } catch (err) { + // Handle error and show error message + const msg = err?.response?.data?.message || "Something went wrong!"; + swal({ + title: "Error", + text: msg, + icon: "error", + button: "Retry", + dangerMode: true, + }); + } + }; + + if (!data) { + return Loading...; + } + + return ( + + + Retailer Details + + + + + + Retailer Details + + + + + Trade Name: {data.kyc.trade_name} + + + Name: {data.name} + + + Address: {data.kyc.address} + + + Town/City: {data.kyc.city} + + + District: {data.kyc.district} + + + State: {data.kyc.state} + + + Pincode: {data.kyc.pincode} + + + Mobile Number: {data.mobile_number} + + + + + Mapped Territory Manager:{" "} + {data?.mappedTM?.name || "Not Mapped"} + + + Mapped Principal Distributor:{" "} + {data?.principal_distributer?.name || "Not Mapped"} + + + Mapped Sales Coordinator:{" "} + {data?.mappedSC?.name || "Not Mapped"} + + + + + + {/* Territory Managers */} + + + + Territory Manager Details + + + + + + + + + + Name: {data.mappedTM?.name || "Not Mapped"} + + + Mobile Number:{" "} + {data.mappedTM?.mobileNumber || "Not Mapped"} + + + Email: {data.mappedTM?.email || "Not Mapped"} + + + + + + {/* Sales Coordinators */} + + + + Sales Coordinator Details + + + + + + + + + + Name: {data.mappedSC?.name || "Not Mapped"} + + + Mobile Number:{" "} + {data.mappedSC?.mobileNumber || "Not Mapped"} + + + Email: {data.mappedSC?.email || "Not Mapped"} + + + + + + {/* Principal Distributor */} + + + + Principal Distributor Details + + + + + + + + + + Name:{" "} + {data.principal_distributer?.name || "Not Mapped"} + + + Mobile Number:{" "} + {data.principal_distributer?.phone || "Not Mapped"} + + + Email:{" "} + {data.principal_distributer?.email || "Not Mapped"} + + + + + {/* Principal Distributor */} + + Search and Add Principal Distributor + +
+ + +
+
+ + + + + + + + + + + + + + + {modalPrincipalDistributors.length > 0 ? ( + modalPrincipalDistributors.map((PD) => ( + + + + + + + + + + + )) + ) : ( + + + + )} + +
IdSBUNameMobileEmailSCTMAction
{PD.uniqueId}{PD.SBU}{PD.name}{PD.phone}{PD.email}{PD.mappedbySC?.name || "N/A"}{PD.mappedby?.name || "N/A"} + +
+ No Principal Distributor found! +
+
+
+
+ Showing {modalPrincipalDistributors?.length} of {modalTotalData}{" "} + entries +
+
+ + +
+
+
+ + + +
+ {/* Sales Coordinator */} + + Search and Add Sales Coordinator + +
+ + +
+ +
+ + + + + + + + + + + + {modalSalesCoordinators.map((coordinator) => ( + + + + + + + + ))} + +
IdNameMobileTMAction
{coordinator.uniqueId}{coordinator.name}{coordinator.mobileNumber}{coordinator.mappedby?.name || "N/A"} + +
+
+
+
+ Showing {modalSalesCoordinators?.length} of {modalTotalData}{" "} + entries +
+
+ + +
+
+
+ + + +
+ {/* Territory Manager */} + + Search and Add Territory Manager + +
+ + +
+
+ + + + + + + + + + + + {modalterritorymanagers.length > 0 ? ( + modalterritorymanagers.map((TM) => ( + + + + + + + + )) + ) : ( + + + + )} + +
IdNameMobileEmailAction
{TM.uniqueId}{TM.name}{TM.mobileNumber}{TM.email} + +
+ No Territory Manager found! +
+
+
+
+ Showing {modalterritorymanagers?.length} of {modalTotalData}{" "} + entries +
+
+ + +
+
+
+ + + +
+
+ ); +}; + +export default MapRD; diff --git a/src/views/RetailDistributors/RetailDistributor.js b/src/views/RetailDistributors/RetailDistributor.js index 102ff54..580937e 100644 --- a/src/views/RetailDistributors/RetailDistributor.js +++ b/src/views/RetailDistributors/RetailDistributor.js @@ -157,6 +157,7 @@ const [totalPages, setTotalPages] = useState(1); Principal Distributor Territory Manager Sales Coordinator + Mapping Action @@ -200,6 +201,22 @@ const [totalPages, setTotalPages] = useState(1); {retailDistributor?.mappedSCDetails?.name || "N/A"} + + + + + { const fetchData = async () => { try { // Commented out the API call and using dummy data - const response = await axios.get(`api/getRD/${id}`, { + const response = await axios.get(`/api/getRD/${id}`, { headers: { 'Access-Control-Allow-Origin': '*', Authorization: `Bearer ${token}`, @@ -154,7 +154,7 @@ const SingleRetailDistributor = () => { {retailerDetails.kyc.fertilizer_license_img ? ( handleOpenPopup(retailerDetails.kyc.fertilizer_license_img.url)} />