diff --git a/src/_nav.js b/src/_nav.js
index 564411c..a0851ed 100644
--- a/src/_nav.js
+++ b/src/_nav.js
@@ -68,6 +68,13 @@ const _nav = [
},
],
},
+ {
+ component: CNavItem,
+ name: "ProductManual",
+ icon: ,
+ to: "/product-manual",
+ group: "Product Management",
+ },
{
component: CNavItem,
name: "Principal Distributor",
diff --git a/src/components/ProtectedRoute.js b/src/components/ProtectedRoute.js
index 421c151..63a755c 100644
--- a/src/components/ProtectedRoute.js
+++ b/src/components/ProtectedRoute.js
@@ -69,7 +69,11 @@ const ProtectedRoute = ({ element: Element }) => {
}
}
- checkToken()
+ checkToken();
+ const intervalId = setInterval(checkToken, 1 * 60 * 1000);
+
+ // Clear interval on component unmount
+ return () => clearInterval(intervalId);
}, [navigate])
return
diff --git a/src/routes.js b/src/routes.js
index 7d36ad9..0bd0f4f 100644
--- a/src/routes.js
+++ b/src/routes.js
@@ -33,7 +33,8 @@ import Products from "./views/Products/Products";
import AddProduct from "./views/Products/AddProduct";
import EditProduct from "./views/Products/EditProduct";
import ViewProduct from "./views/Products/ViewProduct";
-
+//product manual
+import ProductManual from "./views/ProductManual/ProductManual";
//Order Management
import NewOrders from "./views/orders/NewOrders.js";
import ProcessingOrders from "./views/orders/ProcessingOrders.js";
@@ -142,6 +143,9 @@ import AddMultipleProduct from "./views/Products/AddMultipleProducts";
import AddMultiplePd from "./views/PrincipalDistributors/AddMultiplePD";
import Inventory from "./views/Inventory/Inventory";
import SingleInventory from "./views/Inventory/SingleInventory";
+import ViewProductManual from "./views/ProductManual/SingleProductManual";
+import ViewSalesCoOrdinatorTM from "./views/TerritoryManager/ViewSalesCoOrdinatorTM";
+import ViewPrincipalDistributorTM from "./views/TerritoryManager/ViewPrincipalDistributorTM";
const routes = [
//dashboard
@@ -202,6 +206,18 @@ const routes = [
element: Brands,
navName: "Product Management",
},
+ {
+ path: "/product-manual",
+ name: "Product Manual",
+ element: ProductManual,
+ navName: "Product Management",
+ },
+ {
+ path: "/product-manual/view/:id",
+ name: "Product Manual",
+ element: ViewProductManual,
+ navName: "Product Management",
+ },
//SalesCoOrdinator
{
path: "/salescoordinator/edit/:id",
@@ -240,6 +256,18 @@ const routes = [
element: AddTerritoryManager,
navName: "TerritoryManagers",
},
+ {
+ path: "/view/salescoordinator/:id",
+ name: "View SalesCoOrdinator",
+ element: ViewSalesCoOrdinatorTM,
+ navName: "TerritoryManagers",
+ },
+ {
+ path: "/view/principaldistributor/:id",
+ name: "View Principal Distributor",
+ element: ViewPrincipalDistributorTM,
+ navName: "TerritoryManagers",
+ },
// Attendence
{
path: "/attendance/today",
diff --git a/src/views/ProductManual/ProductManual.js b/src/views/ProductManual/ProductManual.js
new file mode 100644
index 0000000..d4c226d
--- /dev/null
+++ b/src/views/ProductManual/ProductManual.js
@@ -0,0 +1,652 @@
+import React, { useState, useEffect, useCallback, useRef } from "react";
+import axios from "axios";
+import { Link } from "react-router-dom";
+import { isAutheticated } from "src/auth";
+import {
+ Button,
+ Box,
+ IconButton,
+ Modal,
+ TextField,
+ Typography,
+} from "@mui/material";
+import CloseIcon from "@mui/icons-material/Close";
+import { ClipLoader } from "react-spinners";
+import swal from "sweetalert";
+import { useNavigate } from "react-router-dom";
+import debounce from "lodash/debounce";
+
+const style = {
+ position: "absolute",
+ top: "50%",
+ left: "50%",
+ transform: "translate(-50%, -50%)",
+ width: 500,
+ bgcolor: "background.paper",
+ borderRadius: "0.5rem",
+ boxShadow: 24,
+};
+
+const ProductManual = () => {
+ const token = isAutheticated();
+ const navigate = useNavigate();
+ const [loading, setLoading] = useState(true);
+ const [updating, setUpdating] = useState(true);
+ const [saveLoding, setSaveLoading] = useState(true);
+ const [edit, setEdit] = useState(false);
+ const [title, setTitle] = useState("");
+ const [pdfFile, setPdfFile] = useState(null);
+ const [itemPerPage, setItemPerPage] = useState(10);
+ const [currentPage, setCurrentPage] = useState(1);
+ const [open, setOpen] = useState(false);
+ const [currentManual, setCurrentManual] = useState(null);
+ const [productManuals, setProductManuals] = useState([]);
+ const [fileError, setFileError] = useState("");
+ const [totalData, setTotalData] = useState(0);
+ const [success, setSuccess] = useState(true);
+ const titleRef = useRef();
+ // const handleOpen = (manual = null) => {
+ // setOpen(true);
+ // setCurrentManual(manual);
+ // if (manual) {
+ // setTitle(manual.title);
+ // setPdfFile(null);
+ // setEdit(true);
+ // } else {
+ // setTitle("");
+ // setPdfFile(null);
+ // setEdit(false);
+ // }
+ // };
+ const handleOpen = () => setOpen(true);
+ const handleClose = () => {
+ setOpen(false);
+ setEdit(false);
+ setTitle("");
+ setPdfFile(null);
+ setFileError("");
+ };
+ const handleEditClick = (manual) => {
+ setOpen(true);
+ setCurrentManual(manual);
+ setTitle(manual.title);
+ setPdfFile(null);
+ setEdit(true);
+ };
+ const getProductManuals = async () => {
+ try {
+ setLoading(true);
+ const response = await axios.get(`/api/productmanual`, {
+ headers: { Authorization: `Bearer ${token}` },
+ params: {
+ page: currentPage,
+ show: itemPerPage,
+ title: titleRef.current?.value || "",
+ },
+ });
+ if (response.status === 200) {
+ const { productManuals, total } = response.data;
+ setProductManuals(productManuals);
+ setTotalData(total);
+ setLoading(false);
+ }
+ } catch (error) {
+ console.error("Failed to fetch product manuals:", error);
+ setLoading(false);
+ }
+ };
+
+ useEffect(() => {
+ getProductManuals();
+ }, [itemPerPage, currentPage, success]);
+
+ const validateFile = (file) => {
+ return file && file.type === "application/pdf";
+ };
+
+ const handleSave = async () => {
+ if (!title || !pdfFile || !validateFile(pdfFile)) {
+ setFileError("Please upload a valid PDF file!");
+ return;
+ }
+ setFileError("");
+
+ setSaveLoading(false);
+ const formData = new FormData();
+ formData.append("title", title);
+ formData.append("pdfFile", pdfFile);
+
+ try {
+ await axios.post("/api/productmanual/create", formData, {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ "Content-Type": "multipart/form-data",
+ },
+ });
+ handleClose();
+ swal("Success", "New product manual added successfully!", "success");
+ getProductManuals();
+ } catch (error) {
+ swal("Error", "Failed to add product manual", "error");
+ } finally {
+ setSaveLoading(true);
+ }
+ };
+
+ const handleUpdate = async () => {
+ if (!title) {
+ setFileError("Please upload a valid PDF file!");
+ return;
+ }
+ setFileError("");
+
+ setUpdating(false);
+ const formData = new FormData();
+ formData.append("title", title);
+ formData.append("pdfFile", pdfFile);
+
+ try {
+ await axios.put(
+ `/api/productmanual/update/${currentManual._id}`,
+ formData,
+ {
+ headers: { Authorization: `Bearer ${token}` },
+ }
+ );
+ handleClose();
+ setSuccess((prev) => !prev);
+ swal(
+ "Success",
+ "The product manual was updated successfully!",
+ "success"
+ );
+ getProductManuals();
+ } catch (err) {
+ swal("Error", "Failed to update product manual", "error");
+ } finally {
+ setUpdating(true);
+ }
+ };
+
+ const handleDelete = async (_id) => {
+ swal({
+ title: "Are you sure?",
+ icon: "warning",
+ buttons: {
+ Yes: { text: "Yes", value: true },
+ Cancel: { text: "Cancel", value: "cancel" },
+ },
+ }).then(async (value) => {
+ if (value === true) {
+ try {
+ await axios.delete(`/api/productmanual/delete/${_id}`, {
+ headers: { Authorization: `Bearer ${token}` },
+ });
+ setSuccess((prev) => !prev);
+ swal(
+ "Success",
+ "The product manual was deleted successfully!",
+ "success"
+ );
+ getProductManuals();
+ } catch (err) {
+ swal("Error", "Failed to delete product manual", "error");
+ }
+ }
+ });
+ };
+
+ const debouncedSearch = useCallback(
+ debounce(() => {
+ setCurrentPage(1);
+ getProductManuals();
+ }, 500),
+ []
+ );
+
+ const handleSearchChange = (e) => {
+ debouncedSearch();
+ };
+
+ return (
+
+
+
+
+
+
+
+ Product Manual
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Modal for Add/Edit Product Manual */}
+
+
+
+
+ {edit
+ ? "Edit Product Manual"
+ : "Add New Product Manual"}
+
+
+
+
+
+
+ setTitle(e.target.value)}
+ />
+ setPdfFile(e.target.files[0])}
+ />
+
+
+
+ {!edit && (
+
+ )}
+ {edit && (
+
+ )}
+
+
+
+
+
+
+
+
+ Title |
+ File Name |
+ Updated Date |
+ Actions |
+
+
+
+
+ {loading ? (
+
+
+ Loading...
+ |
+
+ ) : productManuals?.length > 0 ? (
+ productManuals?.map((manual, i) => {
+ return (
+
+ {manual.title} |
+
+ {manual.product_manual.filename}
+ |
+
+ {new Date(manual.updatedAt).toLocaleString(
+ "en-IN",
+ {
+ weekday: "short",
+ month: "short",
+ day: "numeric",
+ year: "numeric",
+ hour: "numeric",
+ minute: "numeric",
+ hour12: true,
+ }
+ )}
+ |
+
+
+
+
+
+
+
+
+
+
+ |
+
+ );
+ })
+ ) : (
+ !loading &&
+ productManuals?.length === 0 && (
+
+
+ No Product manual Available...
+ |
+
+ )
+ )}
+
+
+
+
+
+
+
+ Showing {currentPage * itemPerPage - itemPerPage + 1} to{" "}
+ {Math.min(currentPage * itemPerPage, totalData)} of{" "}
+ {totalData} entries
+
+
+
+
+
+
+ -
+ setCurrentPage((prev) => prev - 1)}
+ disabled={loading}
+ >
+ Previous
+
+
+
+ {!(currentPage - 1 < 1) && (
+ -
+
+ setCurrentPage((prev) => prev - 1)
+ }
+ disabled={loading}
+ >
+ {currentPage - 1}
+
+
+ )}
+
+ -
+
+ {currentPage}
+
+
+
+ {!(
+ (currentPage + 1) * itemPerPage - itemPerPage >
+ totalData - 1
+ ) && (
+ -
+ {
+ setCurrentPage((prev) => prev + 1);
+ }}
+ disabled={loading}
+ >
+ {currentPage + 1}
+
+
+ )}
+
+ -
+ totalData - 1
+ )
+ ? "paginate_button page-item next"
+ : "paginate_button page-item next disabled"
+ }
+ >
+ setCurrentPage((prev) => prev + 1)}
+ disabled={loading}
+ >
+ Next
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default ProductManual;
diff --git a/src/views/ProductManual/SingleProductManual.js b/src/views/ProductManual/SingleProductManual.js
new file mode 100644
index 0000000..0f0787e
--- /dev/null
+++ b/src/views/ProductManual/SingleProductManual.js
@@ -0,0 +1,107 @@
+import React, { useEffect, useState } from "react";
+import Button from "@material-ui/core/Button";
+import { Link, useParams } from "react-router-dom";
+import swal from "sweetalert";
+import axios from "axios";
+import { isAutheticated } from "src/auth";
+
+const ViewProductManual = () => {
+ const [title, setTitle] = useState("");
+ const [image, setImage] = useState("");
+ const token = isAutheticated();
+ const { id } = useParams();
+
+ const getproductmanual = async () => {
+ try {
+ const res = await axios.get(`/api/productmanual/${id}`, {
+ headers: { Authorization: `Bearer ${token}` },
+ });
+ // console.log(res);
+ setTitle(res?.data?.productManual?.title);
+ setImage(res?.data?.productManual?.product_manual);
+ } catch (err) {
+ console.error(err);
+ swal({
+ title: "Error",
+ text: "Unable to fetch the blog",
+ icon: "error",
+ button: "Retry",
+ dangerMode: true,
+ });
+ }
+ };
+
+ useEffect(() => {
+ getproductmanual();
+ }, []);
+
+ return (
+
+
+
+
+
+ View Product Manual
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {title}
+
+
+ {image && (
+ image.url.endsWith('.pdf') ? (
+
+ ) : (
+

+ )
+ )}
+
+
+
+
+
+
+ );
+};
+
+export default ViewProductManual;
diff --git a/src/views/TerritoryManager/TerritoryManager.js b/src/views/TerritoryManager/TerritoryManager.js
index b666d95..38ce033 100644
--- a/src/views/TerritoryManager/TerritoryManager.js
+++ b/src/views/TerritoryManager/TerritoryManager.js
@@ -274,6 +274,34 @@ const TerritoryManager = () => {
})}
+
+
+
+
+
+
diff --git a/src/views/TerritoryManager/ViewPrincipalDistributorTM.js b/src/views/TerritoryManager/ViewPrincipalDistributorTM.js
new file mode 100644
index 0000000..06efb5e
--- /dev/null
+++ b/src/views/TerritoryManager/ViewPrincipalDistributorTM.js
@@ -0,0 +1,548 @@
+import React, { useState, useEffect, useRef, useCallback } from "react";
+import { Link, useParams } from "react-router-dom";
+import axios from "axios";
+import Button from "@material-ui/core/Button";
+import { useNavigate } from "react-router-dom";
+import { isAutheticated } from "src/auth";
+import swal from "sweetalert";
+import debounce from "lodash.debounce";
+import Dialog from "@material-ui/core/Dialog";
+import DialogActions from "@material-ui/core/DialogActions";
+import DialogContent from "@material-ui/core/DialogContent";
+import DialogTitle from "@material-ui/core/DialogTitle";
+import TextField from "@material-ui/core/TextField";
+
+const ViewPrincipalDistributorTM = () => {
+ const token = isAutheticated();
+ const { id } = useParams();
+ const navigate = useNavigate();
+ const [loading, setLoading] = useState(false);
+ const [success, setSuccess] = useState(true);
+ const [principaldistributorData, setprincipaldistributorData] = useState([]);
+ const [data, setData] = useState({});
+ const nameRef = useRef();
+ const mobileRef = useRef();
+ const pdnameRef = useRef();
+ const pdmobileRef = useRef();
+
+ const [currentPage, setCurrentPage] = useState(1);
+ const [itemPerPage, setItemPerPage] = useState(10);
+ const [modalcurrentPage, setmodalCurrentPage] = useState(1);
+ const modalitemPerPage = 10;
+ const [totalData, setTotalData] = useState(0);
+ const [openModal, setOpenModal] = useState(false);
+ const [modalPrincipalDistributors, setmodalPrincipalDistributors] = useState(
+ []
+ );
+ const [modalTotalData, setModalTotalData] = useState(0);
+
+ // Fetch territory manager data
+ useEffect(() => {
+ axios
+ .get(`/api/territorymanager/getOne/${id}`, {
+ headers: { Authorization: `Bearer ${token}` },
+ })
+ .then((response) => setData(response.data.data))
+ .catch((error) => console.error("Error fetching TM data:", error));
+ }, [id, token]);
+
+ // Fetch Principal Distributors data
+ const getTMsprincipaldistributorData = async () => {
+ setLoading(true);
+ axios
+ .get(`/api/v1/getbyTmId/${id}`, {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ },
+ params: {
+ page: currentPage,
+ show: itemPerPage,
+ name: nameRef.current?.value,
+ mobileNumber: mobileRef.current?.value,
+ },
+ })
+ .then((res) => {
+ setprincipaldistributorData(res.data?.principaldistributor);
+ setTotalData(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(() => {
+ getTMsprincipaldistributorData();
+ }, [success, itemPerPage, currentPage]);
+
+ // Debounced search for Principal Distributors
+ const debouncedSearch = useCallback(
+ debounce(() => {
+ setCurrentPage(1);
+ getTMsprincipaldistributorData();
+ }, 500),
+ [currentPage, itemPerPage]
+ );
+
+ const handleSearchChange = useCallback(() => {
+ debouncedSearch();
+ }, [debouncedSearch]);
+ // Fetch Principal Distributors data for modal
+ 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 (openModal) {
+ getprincipaldistributorData();
+ }
+ }, [openModal, modalcurrentPage]);
+
+ // Debounced search for Principal Distributors in modal
+ const debouncedmodalSearch = useCallback(
+ debounce(() => {
+ setmodalCurrentPage(1);
+ getprincipaldistributorData();
+ }, 500),
+ [modalcurrentPage]
+ );
+
+ const handlemodalSearchChange = useCallback(() => {
+ debouncedmodalSearch();
+ }, [debouncedmodalSearch]);
+
+ const handleOpenModal = () => {
+ setOpenModal(true);
+ };
+
+ const handleCloseModal = () => {
+ setOpenModal(false);
+ };
+ const handlePreviousPage = () => {
+ if (modalcurrentPage > 1) {
+ setmodalCurrentPage(modalcurrentPage - 1);
+ }
+ };
+
+ const handleNextPage = () => {
+ if (modalPrincipalDistributors.length === modalitemPerPage) {
+ setmodalCurrentPage(modalcurrentPage + 1);
+ }
+ };
+
+ const handleDelete = (id) => {
+ swal({
+ title: "Are you sure?",
+ icon: "warning",
+ buttons: {
+ Yes: { text: "Yes", value: true },
+ Cancel: { text: "Cancel", value: "cancel" },
+ },
+ }).then((value) => {
+ if (value === true) {
+ axios
+ .patch(`/api/v1/unmap/${id}`, {}, { // Changed to PATCH and sent an empty body
+ headers: {
+ "Access-Control-Allow-Origin": "*",
+ Authorization: `Bearer ${token}`,
+ },
+ })
+ .then((res) => {
+ swal({
+ title: "Deleted",
+ text: "Principal Distributor Unmapped successfully!",
+ icon: "success",
+ button: "ok",
+ });
+ setSuccess((prev) => !prev);
+ })
+ .catch((err) => {
+ let msg = err?.response?.data?.message
+ ? err?.response?.data?.message
+ : "Something went wrong!";
+ swal({
+ title: "Warning",
+ text: msg,
+ icon: "error",
+ button: "Retry",
+ dangerMode: true,
+ });
+ });
+ }
+ });
+ };
+ const handleAddPrincipalDistributor = async (pdid) => {
+ try {
+ await axios.put(
+ `/api/v1/mappedtm/${pdid}`,
+ { mappedby: id },
+ {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ },
+ }
+ );
+ swal({
+ title: "Success",
+ text: "Principal Distributor added successfully!",
+ icon: "success",
+ button: "Ok",
+ });
+ setSuccess((prev) => !prev);
+ handleCloseModal(); // Close modal after adding
+ } catch (err) {
+ const msg = err?.response?.data?.message || "Something went wrong!";
+ swal({
+ title: "Error",
+ text: msg,
+ icon: "error",
+ button: "Retry",
+ dangerMode: true,
+ });
+ }
+ };
+
+ return (
+
+
+
+
+
+
+ {/* Left Side with Information in Separate Columns */}
+
+
+ Unique ID: {data?.uniqueId}
+
+
+ Name: {data?.name}
+
+
+ Mobile Number: {data?.mobileNumber}
+
+
+ Mail: {data?.email}
+
+
+
+ {/* Right Side with the Button */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Unique Id |
+ SBU |
+ Name |
+ Mobile No. |
+ Email |
+ Action |
+
+
+
+
+ {loading ? (
+
+
+ Loading...
+ |
+
+ ) : principaldistributorData?.length > 0 ? (
+ principaldistributorData?.map((PD, i) => {
+ return (
+
+ {PD?.uniqueId} |
+ {PD?.SBU} |
+ {PD?.name} |
+ {PD?.phone} |
+
+ {PD?.email ? (
+ PD?.email
+ ) : (
+
+ No Email Added!
+
+ )}
+ |
+
+
+ |
+
+ );
+ })
+ ) : (
+
+
+ No Principal Distributor found!
+ |
+
+ )}
+
+
+
+
+
+ Showing {principaldistributorData?.length} of {totalData}{" "}
+ entries
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default ViewPrincipalDistributorTM;
diff --git a/src/views/TerritoryManager/ViewSalesCoOrdinatorTM.js b/src/views/TerritoryManager/ViewSalesCoOrdinatorTM.js
new file mode 100644
index 0000000..1f8e752
--- /dev/null
+++ b/src/views/TerritoryManager/ViewSalesCoOrdinatorTM.js
@@ -0,0 +1,546 @@
+import React, { useState, useEffect, useRef, useCallback } from "react";
+import { Link, useParams } from "react-router-dom";
+import axios from "axios";
+import Button from "@material-ui/core/Button";
+import { useNavigate } from "react-router-dom";
+import { isAutheticated } from "src/auth";
+import swal from "sweetalert";
+import debounce from "lodash.debounce";
+import Dialog from "@material-ui/core/Dialog";
+import DialogActions from "@material-ui/core/DialogActions";
+import DialogContent from "@material-ui/core/DialogContent";
+import DialogTitle from "@material-ui/core/DialogTitle";
+import TextField from "@material-ui/core/TextField";
+
+const ViewSalesCoOrdinatorTM = () => {
+ const token = isAutheticated();
+ const { id } = useParams();
+ const navigate = useNavigate();
+ const [loading, setLoading] = useState(false);
+ const [success, setSuccess] = useState(true);
+ const [salescoordinatorsData, setSalesCoOrdinatorsData] = useState([]);
+ const [data, setData] = useState({});
+ const nameRef = useRef();
+ const mobileRef = useRef();
+ const scnameRef = useRef();
+ const scmobileRef = useRef();
+
+ const [currentPage, setCurrentPage] = useState(1);
+ const [itemPerPage, setItemPerPage] = useState(10);
+ const [modalcurrentPage, setmodalCurrentPage] = useState(1);
+ const modalitemPerPage = 10;
+ const [totalData, setTotalData] = useState(0);
+ const [openModal, setOpenModal] = useState(false);
+ const [modalSalesCoordinators, setModalSalesCoordinators] = useState([]);
+ const [modalTotalData, setModalTotalData] = useState(0);
+
+ // Fetch territory manager data
+ useEffect(() => {
+ axios
+ .get(`/api/territorymanager/getOne/${id}`, {
+ headers: { Authorization: `Bearer ${token}` },
+ })
+ .then((response) => setData(response.data.data))
+ .catch((error) => console.error("Error fetching TM data:", error));
+ }, [id, token]);
+
+ // Fetch Sales Coordinators data
+ const getTMsSalesCoOrdinatorsData = async () => {
+ setLoading(true);
+ axios
+ .get(`/api/salescoordinator/getbyTmId/${id}`, {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ },
+ params: {
+ page: currentPage,
+ show: itemPerPage,
+ name: nameRef.current?.value,
+ mobileNumber: mobileRef.current?.value,
+ },
+ })
+ .then((res) => {
+ setSalesCoOrdinatorsData(res.data?.salesCoOrinators);
+ setTotalData(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(() => {
+ getTMsSalesCoOrdinatorsData();
+ }, [success, itemPerPage, currentPage]);
+
+ // Debounced search for Sales Coordinators
+ const debouncedSearch = useCallback(
+ debounce(() => {
+ setCurrentPage(1);
+ getTMsSalesCoOrdinatorsData();
+ }, 500),
+ [currentPage, itemPerPage]
+ );
+
+ const handleSearchChange = useCallback(() => {
+ debouncedSearch();
+ }, [debouncedSearch]);
+ // Fetch Sales Coordinators data for modal
+ 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 (openModal) {
+ getSalesCoOrdinatorsData();
+ }
+ }, [openModal, modalcurrentPage]);
+
+ // Debounced search for Sales Coordinators in modal
+ const debouncedmodalSearch = useCallback(
+ debounce(() => {
+ setmodalCurrentPage(1);
+ getSalesCoOrdinatorsData();
+ }, 500),
+ [modalcurrentPage]
+ );
+
+ const handlemodalSearchChange = useCallback(() => {
+ debouncedmodalSearch();
+ }, [debouncedmodalSearch]);
+
+ const handleOpenModal = () => {
+ setOpenModal(true);
+ };
+
+ const handleCloseModal = () => {
+ setOpenModal(false);
+ };
+ const handlePreviousPage = () => {
+ if (modalcurrentPage > 1) {
+ setmodalCurrentPage(modalcurrentPage - 1);
+ }
+ };
+
+ const handleNextPage = () => {
+ if (modalPrincipalDistributors.length === modalitemPerPage) {
+ setmodalCurrentPage(modalcurrentPage + 1);
+ }
+ };
+ const handleDelete = (id) => {
+ swal({
+ title: "Are you sure?",
+ icon: "error",
+ buttons: {
+ Yes: { text: "Yes", value: true },
+ Cancel: { text: "Cancel", value: "cancel" },
+ },
+ }).then((value) => {
+ if (value === true) {
+ axios
+ .delete(`/api/salescoordinator/unmap/${id}`, {
+ headers: {
+ "Access-Control-Allow-Origin": "*",
+ Authorization: `Bearer ${token}`,
+ },
+ })
+ .then((res) => {
+ swal({
+ title: "Deleted",
+ text: "SalesCoOrdinator Unmapped successfully!",
+ icon: "success",
+ button: "ok",
+ });
+ setSuccess((prev) => !prev);
+ })
+ .catch((err) => {
+ let msg = err?.response?.data?.message
+ ? err?.response?.data?.message
+ : "Something went wrong!";
+ swal({
+ title: "Warning",
+ text: msg,
+ icon: "error",
+ button: "Retry",
+ dangerMode: true,
+ });
+ });
+ }
+ });
+ };
+ const handleAddSalesCoordinator = async (scid) => {
+ try {
+ await axios.put(
+ `/api/salescoordinator/mappedtm/${scid}`,
+ { mappedby: id },
+ {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ },
+ }
+ );
+ swal({
+ title: "Success",
+ text: "Sales Coordinator added successfully!",
+ icon: "success",
+ button: "Ok",
+ });
+ setSuccess((prev) => !prev);
+ handleCloseModal(); // Close modal after adding
+ } catch (err) {
+ const msg = err?.response?.data?.message || "Something went wrong!";
+ swal({
+ title: "Error",
+ text: msg,
+ icon: "error",
+ button: "Retry",
+ dangerMode: true,
+ });
+ }
+ };
+
+ return (
+
+
+
+
+
+
+ {/* Left Side with Information in Separate Columns */}
+
+
+ Unique ID: {data?.uniqueId}
+
+
+ Name: {data?.name}
+
+
+ Mobile Number: {data?.mobileNumber}
+
+
+ Mail: {data?.email}
+
+
+
+ {/* Right Side with the Button */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Unique Id |
+ Name |
+ Mobile No. |
+ Email |
+ Action |
+
+
+
+
+ {loading ? (
+
+
+ Loading...
+ |
+
+ ) : salescoordinatorsData?.length > 0 ? (
+ salescoordinatorsData?.map((salescoordinator, i) => {
+ return (
+
+
+ {salescoordinator?.uniqueId}
+ |
+
+ {salescoordinator?.name}
+ |
+
+ {salescoordinator?.mobileNumber}
+ |
+
+ {salescoordinator?.email ? (
+ salescoordinator?.email
+ ) : (
+
+ No Email Added!
+
+ )}
+ |
+
+ {/*
+
+ */}
+
+
+ |
+
+ );
+ })
+ ) : (
+
+
+ No Sales Coordinator found!
+ |
+
+ )}
+
+
+
+
+
+ Showing {salescoordinatorsData?.length} of {totalData}{" "}
+ entries
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default ViewSalesCoOrdinatorTM;
|