sales data and maprd
This commit is contained in:
parent
957cfd5fd9
commit
4ad5003607
@ -132,6 +132,13 @@ const _nav = [
|
|||||||
to: "/inventory",
|
to: "/inventory",
|
||||||
group: "Inventory",
|
group: "Inventory",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
component: CNavItem,
|
||||||
|
name: "Sales Data",
|
||||||
|
icon: <CIcon icon={cilAddressBook} customClassName="nav-icon" />,
|
||||||
|
to: "/sales",
|
||||||
|
group: "Sales",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
component: CNavGroup,
|
component: CNavGroup,
|
||||||
name: "Orders",
|
name: "Orders",
|
||||||
|
@ -162,6 +162,9 @@ import AddMultiplesc from "./views/SalesCoOrdinators/AddMultipleSC";
|
|||||||
import Announcements from "./views/Announcment/announcement";
|
import Announcements from "./views/Announcment/announcement";
|
||||||
import CreateAnnouncement from "./views/Announcment/createAnnouncement";
|
import CreateAnnouncement from "./views/Announcment/createAnnouncement";
|
||||||
import TodayTask from "./views/Tasks/TodayTasks";
|
import TodayTask from "./views/Tasks/TodayTasks";
|
||||||
|
import Sales from "./views/Sales/Sales";
|
||||||
|
import SingleSales from "./views/Sales/SingleSale";
|
||||||
|
import MobileApp from "./views/configuration/MobileApp";
|
||||||
const routes = [
|
const routes = [
|
||||||
//dashboard
|
//dashboard
|
||||||
|
|
||||||
@ -483,6 +486,19 @@ const routes = [
|
|||||||
element: SingleInventory,
|
element: SingleInventory,
|
||||||
navName: "Inventory",
|
navName: "Inventory",
|
||||||
},
|
},
|
||||||
|
//Sales
|
||||||
|
{
|
||||||
|
path: "/sales",
|
||||||
|
name: "Sales",
|
||||||
|
element: Sales,
|
||||||
|
navName: "Sales",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/sales/view/:id",
|
||||||
|
name: "Sales",
|
||||||
|
element: SingleSales,
|
||||||
|
navName: "Sales",
|
||||||
|
},
|
||||||
//------------------ End customers Route-------------------------
|
//------------------ End customers Route-------------------------
|
||||||
|
|
||||||
// {
|
// {
|
||||||
@ -775,6 +791,7 @@ const routes = [
|
|||||||
navName: "Configuration",
|
navName: "Configuration",
|
||||||
},
|
},
|
||||||
{ path: "/logo", name: "Logo", element: Logo, navName: "Configuration" },
|
{ path: "/logo", name: "Logo", element: Logo, navName: "Configuration" },
|
||||||
|
{ path: "/mobile-app", name: "MobileApp", element: MobileApp, navName: "Configuration" },
|
||||||
//----------------- End Configuration Routes-----------------------------------
|
//----------------- End Configuration Routes-----------------------------------
|
||||||
|
|
||||||
//-----------------Affiliate & Coupons Routes-----------------------------------
|
//-----------------Affiliate & Coupons Routes-----------------------------------
|
||||||
|
@ -442,7 +442,7 @@ const Categories = () => {
|
|||||||
<tbody>
|
<tbody>
|
||||||
{!loading && category.length === 0 && (
|
{!loading && category.length === 0 && (
|
||||||
<tr className="text-center">
|
<tr className="text-center">
|
||||||
<td colSpan="">
|
<td colSpan="2">
|
||||||
<h5>No Data Available</h5>
|
<h5>No Data Available</h5>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -1,65 +1,27 @@
|
|||||||
import React, { useState, useEffect, useRef, useCallback } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import {
|
import { Box, Typography, Grid, Paper } from "@mui/material";
|
||||||
Box,
|
|
||||||
Typography,
|
|
||||||
Grid,
|
|
||||||
Paper,
|
|
||||||
Dialog,
|
|
||||||
DialogContent,
|
|
||||||
DialogTitle,
|
|
||||||
} from "@mui/material";
|
|
||||||
import { useParams, useNavigate } from "react-router-dom";
|
import { useParams, useNavigate } from "react-router-dom";
|
||||||
import { isAutheticated } from "../../auth";
|
import { isAutheticated } from "../../auth";
|
||||||
import Button from "@material-ui/core/Button";
|
import Button from "@material-ui/core/Button";
|
||||||
import swal from "sweetalert";
|
import swal from "sweetalert";
|
||||||
import debounce from "lodash.debounce";
|
import PDmodal from "./ModalPD.js";
|
||||||
import TextField from "@mui/material/TextField";
|
import SCmodal from "./ModalSC.js";
|
||||||
import DialogActions from "@mui/material/DialogActions";
|
import TMmodal from "./ModalTM.js";
|
||||||
|
|
||||||
const MapRD = () => {
|
const MapRD = () => {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const token = isAutheticated();
|
const token = isAutheticated();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
const [success, setSuccess] = useState(true);
|
const [success, setSuccess] = useState(true);
|
||||||
const [data, setData] = useState(null);
|
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 [openPDModal, setOpenPDModal] = useState(false);
|
||||||
const [openSCModal, setOpenSCModal] = useState(false);
|
const [openSCModal, setOpenSCModal] = useState(false);
|
||||||
const [openTMModal, setOpenTMModal] = 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(() => {
|
useEffect(() => {
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
try {
|
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: {
|
headers: {
|
||||||
"Access-Control-Allow-Origin": "*",
|
"Access-Control-Allow-Origin": "*",
|
||||||
@ -67,8 +29,7 @@ const MapRD = () => {
|
|||||||
"Content-Type": "multipart/form-data",
|
"Content-Type": "multipart/form-data",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
setData(response.data);
|
setData(response?.data);
|
||||||
// console.log('Retailer Details: ', response.data);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching data: ", error);
|
console.error("Error fetching data: ", error);
|
||||||
}
|
}
|
||||||
@ -77,161 +38,6 @@ const MapRD = () => {
|
|||||||
fetchData();
|
fetchData();
|
||||||
}, [id, token, success]);
|
}, [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) => {
|
const handleDelete = (designation) => {
|
||||||
swal({
|
swal({
|
||||||
title: "Are you sure?",
|
title: "Are you sure?",
|
||||||
@ -242,7 +48,6 @@ const MapRD = () => {
|
|||||||
},
|
},
|
||||||
}).then((value) => {
|
}).then((value) => {
|
||||||
if (value === true) {
|
if (value === true) {
|
||||||
// Create the data object based on designation
|
|
||||||
let data = {};
|
let data = {};
|
||||||
if (designation === "TM") {
|
if (designation === "TM") {
|
||||||
data.mappedTM = true;
|
data.mappedTM = true;
|
||||||
@ -252,18 +57,13 @@ const MapRD = () => {
|
|||||||
data.principal_distributor = true;
|
data.principal_distributor = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make the PATCH request with the constructed data object
|
|
||||||
axios
|
axios
|
||||||
.patch(
|
.patch(`/api/unmap/${id}`, data, {
|
||||||
`/api/unmap/${id}`,
|
|
||||||
data, // Send the constructed data object
|
|
||||||
{
|
|
||||||
headers: {
|
headers: {
|
||||||
"Access-Control-Allow-Origin": "*",
|
"Access-Control-Allow-Origin": "*",
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
)
|
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
swal({
|
swal({
|
||||||
title: "Deleted",
|
title: "Deleted",
|
||||||
@ -287,59 +87,19 @@ const MapRD = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUpdateMapping = async (rdid, designation) => {
|
const handleOpenPDModal = () => setOpenPDModal(true);
|
||||||
try {
|
const handleClosePDModal = () => setOpenPDModal(false);
|
||||||
// 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
|
const handleOpenSCModal = () => setOpenSCModal(true);
|
||||||
await axios.put(
|
const handleCloseSCModal = () => setOpenSCModal(false);
|
||||||
`/api/mapped/${id}`,
|
|
||||||
data, // Send the constructed data object
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Success alert
|
const handleOpenTMModal = () => setOpenTMModal(true);
|
||||||
swal({
|
const handleCloseTMModal = () => setOpenTMModal(false);
|
||||||
title: "Success",
|
|
||||||
text: "Mapped successfully!",
|
|
||||||
icon: "success",
|
|
||||||
button: "Ok",
|
|
||||||
});
|
|
||||||
|
|
||||||
// Trigger success state change and close modals
|
const refreshData = () => {
|
||||||
setSuccess((prev) => !prev);
|
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 <Typography>Loading...</Typography>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ p: 3 }}>
|
<Box sx={{ p: 3 }}>
|
||||||
<Box
|
<Box
|
||||||
@ -374,28 +134,28 @@ const MapRD = () => {
|
|||||||
<Grid container spacing={2}>
|
<Grid container spacing={2}>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Typography>
|
<Typography>
|
||||||
<strong>Trade Name:</strong> {data.kyc.trade_name}
|
<strong>Trade Name:</strong> {data?.kyc.trade_name}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography>
|
<Typography>
|
||||||
<strong>Name:</strong> {data.name}
|
<strong>Name:</strong> {data?.name}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography>
|
<Typography>
|
||||||
<strong>Address:</strong> {data.kyc.address}
|
<strong>Address:</strong> {data?.kyc.address}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography>
|
<Typography>
|
||||||
<strong>Town/City:</strong> {data.kyc.city}
|
<strong>Town/City:</strong> {data?.kyc.city}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography>
|
<Typography>
|
||||||
<strong>District:</strong> {data.kyc.district}
|
<strong>District:</strong> {data?.kyc.district}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography>
|
<Typography>
|
||||||
<strong>State:</strong> {data.kyc.state}
|
<strong>State:</strong> {data?.kyc.state}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography>
|
<Typography>
|
||||||
<strong>Pincode:</strong> {data.kyc.pincode}
|
<strong>Pincode:</strong> {data?.kyc.pincode}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography>
|
<Typography>
|
||||||
<strong>Mobile Number:</strong> {data.mobile_number}
|
<strong>Mobile Number:</strong> {data?.mobile_number}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
@ -414,7 +174,6 @@ const MapRD = () => {
|
|||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
|
||||||
{/* Territory Managers */}
|
{/* Territory Managers */}
|
||||||
<Paper sx={{ p: 2, mb: 3 }}>
|
<Paper sx={{ p: 2, mb: 3 }}>
|
||||||
<Box
|
<Box
|
||||||
@ -451,19 +210,18 @@ const MapRD = () => {
|
|||||||
<Grid container spacing={2}>
|
<Grid container spacing={2}>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Typography>
|
<Typography>
|
||||||
<strong>Name:</strong> {data.mappedTM?.name || "Not Mapped"}
|
<strong>Name:</strong> {data?.mappedTM?.name || "Not Mapped"}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography>
|
<Typography>
|
||||||
<strong>Mobile Number:</strong>{" "}
|
<strong>Mobile Number:</strong>{" "}
|
||||||
{data.mappedTM?.mobileNumber || "Not Mapped"}
|
{data?.mappedTM?.mobileNumber || "Not Mapped"}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography>
|
<Typography>
|
||||||
<strong>Email:</strong> {data.mappedTM?.email || "Not Mapped"}
|
<strong>Email:</strong> {data?.mappedTM?.email || "Not Mapped"}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
|
||||||
{/* Sales Coordinators */}
|
{/* Sales Coordinators */}
|
||||||
<Paper sx={{ p: 2, mb: 3 }}>
|
<Paper sx={{ p: 2, mb: 3 }}>
|
||||||
<Box
|
<Box
|
||||||
@ -500,19 +258,18 @@ const MapRD = () => {
|
|||||||
<Grid container spacing={2}>
|
<Grid container spacing={2}>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Typography>
|
<Typography>
|
||||||
<strong>Name:</strong> {data.mappedSC?.name || "Not Mapped"}
|
<strong>Name:</strong> {data?.mappedSC?.name || "Not Mapped"}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography>
|
<Typography>
|
||||||
<strong>Mobile Number:</strong>{" "}
|
<strong>Mobile Number:</strong>{" "}
|
||||||
{data.mappedSC?.mobileNumber || "Not Mapped"}
|
{data?.mappedSC?.mobileNumber || "Not Mapped"}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography>
|
<Typography>
|
||||||
<strong>Email:</strong> {data.mappedSC?.email || "Not Mapped"}
|
<strong>Email:</strong> {data?.mappedSC?.email || "Not Mapped"}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
|
||||||
{/* Principal Distributor */}
|
{/* Principal Distributor */}
|
||||||
<Paper sx={{ p: 2, mb: 3 }}>
|
<Paper sx={{ p: 2, mb: 3 }}>
|
||||||
<Box
|
<Box
|
||||||
@ -529,8 +286,8 @@ const MapRD = () => {
|
|||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
size="small" // Set button size to small
|
size="small"
|
||||||
style={{ backgroundColor: "blue", marginRight: "8px" }} // marginRight for gap
|
style={{ backgroundColor: "blue", marginRight: "8px" }}
|
||||||
onClick={handleOpenPDModal}
|
onClick={handleOpenPDModal}
|
||||||
>
|
>
|
||||||
Map PD
|
Map PD
|
||||||
@ -538,7 +295,7 @@ const MapRD = () => {
|
|||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="secondary"
|
color="secondary"
|
||||||
size="small" // Set button size to small
|
size="small"
|
||||||
style={{ backgroundColor: "red" }}
|
style={{ backgroundColor: "red" }}
|
||||||
onClick={() => handleDelete("PD")}
|
onClick={() => handleDelete("PD")}
|
||||||
>
|
>
|
||||||
@ -550,346 +307,38 @@ const MapRD = () => {
|
|||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Typography>
|
<Typography>
|
||||||
<strong>Name:</strong>{" "}
|
<strong>Name:</strong>{" "}
|
||||||
{data.principal_distributer?.name || "Not Mapped"}
|
{data?.principal_distributer?.name || "Not Mapped"}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography>
|
<Typography>
|
||||||
<strong>Mobile Number:</strong>{" "}
|
<strong>Mobile Number:</strong>{" "}
|
||||||
{data.principal_distributer?.phone || "Not Mapped"}
|
{data?.principal_distributer?.phone || "Not Mapped"}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography>
|
<Typography>
|
||||||
<strong>Email:</strong>{" "}
|
<strong>Email:</strong>{" "}
|
||||||
{data.principal_distributer?.email || "Not Mapped"}
|
{data?.principal_distributer?.email || "Not Mapped"}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Paper>
|
</Paper>
|
||||||
{/* Principal Distributor */}
|
|
||||||
<Dialog
|
|
||||||
open={openPDModal}
|
|
||||||
onClose={handleClosePDModal}
|
|
||||||
maxWidth="md"
|
|
||||||
fullWidth
|
|
||||||
>
|
|
||||||
<DialogTitle>Search and Add Principal Distributor</DialogTitle>
|
|
||||||
<DialogContent>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
gap: "16px",
|
|
||||||
marginBottom: "2rem",
|
|
||||||
marginTop: "-1rem",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<TextField
|
|
||||||
label="Principal Distributor Name"
|
|
||||||
placeholder="Principal Distributor name"
|
|
||||||
inputRef={pdnameRef}
|
|
||||||
onChange={handlemodalSearchChangeinPD}
|
|
||||||
disabled={loading}
|
|
||||||
style={{ flex: 1, marginRight: "16px" }}
|
|
||||||
/>
|
|
||||||
<TextField
|
|
||||||
style={{ flex: 1 }}
|
|
||||||
label="Mobile Number"
|
|
||||||
placeholder="Mobile Number"
|
|
||||||
inputRef={pdmobileRef}
|
|
||||||
onChange={handlemodalSearchChangeinPD}
|
|
||||||
disabled={loading}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="table-responsive table-shoot mt-3">
|
|
||||||
<table className="table table-centered table-nowrap">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Id</th>
|
|
||||||
<th>SBU</th>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Mobile</th>
|
|
||||||
<th>Email</th>
|
|
||||||
<th>SC</th>
|
|
||||||
<th>TM</th>
|
|
||||||
<th>Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{modalPrincipalDistributors.length > 0 ? (
|
|
||||||
modalPrincipalDistributors.map((PD) => (
|
|
||||||
<tr key={PD._id}>
|
|
||||||
<td>{PD.uniqueId}</td>
|
|
||||||
<td>{PD.SBU}</td>
|
|
||||||
<td>{PD.name}</td>
|
|
||||||
<td>{PD.phone}</td>
|
|
||||||
<td>{PD.email}</td>
|
|
||||||
<td>{PD.mappedbySC?.name || "N/A"}</td>
|
|
||||||
<td>{PD.mappedby?.name || "N/A"}</td>
|
|
||||||
<td>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
onClick={() => handleUpdateMapping(PD._id, "PD")}
|
|
||||||
>
|
|
||||||
Add
|
|
||||||
</Button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
))
|
|
||||||
) : (
|
|
||||||
<tr>
|
|
||||||
<td colSpan="6" className="text-center">
|
|
||||||
No Principal Distributor found!
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div className="d-flex justify-content-between">
|
|
||||||
<div>
|
|
||||||
Showing {modalPrincipalDistributors?.length} of {modalTotalData}{" "}
|
|
||||||
entries
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
onClick={handlePreviousPage}
|
|
||||||
disabled={modalcurrentPage === 1 || loading}
|
|
||||||
className="btn btn-primary"
|
|
||||||
>
|
|
||||||
Previous
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={
|
|
||||||
modalPrincipalDistributors.length === modalitemPerPage
|
|
||||||
? setmodalCurrentPage(modalcurrentPage + 1)
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
disabled={
|
|
||||||
modalPrincipalDistributors?.length < modalitemPerPage ||
|
|
||||||
loading
|
|
||||||
}
|
|
||||||
className="btn btn-primary ml-2"
|
|
||||||
>
|
|
||||||
Next
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</DialogContent>
|
|
||||||
<DialogActions>
|
|
||||||
<Button onClick={handleClosePDModal} color="secondary">
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
</DialogActions>
|
|
||||||
</Dialog>
|
|
||||||
{/* Sales Coordinator */}
|
|
||||||
<Dialog
|
|
||||||
open={openSCModal}
|
|
||||||
onClose={handleCloseSCModal}
|
|
||||||
maxWidth="md"
|
|
||||||
fullWidth
|
|
||||||
>
|
|
||||||
<DialogTitle>Search and Add Sales Coordinator</DialogTitle>
|
|
||||||
<DialogContent>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
gap: "16px",
|
|
||||||
marginBottom: "2rem",
|
|
||||||
marginTop: "-1rem",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<TextField
|
|
||||||
label="Sales Coordinator Name"
|
|
||||||
placeholder="Sales Coordinator name"
|
|
||||||
inputRef={scnameRef}
|
|
||||||
onChange={handlemodalSearchChangeinSC}
|
|
||||||
disabled={loading}
|
|
||||||
style={{ flex: 1, marginRight: "16px" }}
|
|
||||||
/>
|
|
||||||
<TextField
|
|
||||||
style={{ flex: 1 }}
|
|
||||||
label="Mobile Number"
|
|
||||||
placeholder="Mobile Number"
|
|
||||||
inputRef={scmobileRef}
|
|
||||||
onChange={handlemodalSearchChangeinSC}
|
|
||||||
disabled={loading}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="table-responsive table-shoot mt-3">
|
<PDmodal
|
||||||
<table className="table table-centered table-nowrap">
|
rdid={id}
|
||||||
<thead>
|
openPDModal={openPDModal}
|
||||||
<tr>
|
handleClosePDModal={handleClosePDModal}
|
||||||
<th>Id</th>
|
refreshData={refreshData}
|
||||||
<th>Name</th>
|
|
||||||
<th>Mobile</th>
|
|
||||||
<th>TM</th>
|
|
||||||
<th>Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{modalSalesCoordinators.map((coordinator) => (
|
|
||||||
<tr key={coordinator._id}>
|
|
||||||
<td>{coordinator.uniqueId}</td>
|
|
||||||
<td>{coordinator.name}</td>
|
|
||||||
<td>{coordinator.mobileNumber}</td>
|
|
||||||
<td>{coordinator.mappedby?.name || "N/A"}</td>
|
|
||||||
<td>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
onClick={() => handleUpdateMapping(coordinator._id, "SC")}
|
|
||||||
>
|
|
||||||
Add
|
|
||||||
</Button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div className="d-flex justify-content-between">
|
|
||||||
<div>
|
|
||||||
Showing {modalSalesCoordinators?.length} of {modalTotalData}{" "}
|
|
||||||
entries
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
onClick={handlePreviousPage}
|
|
||||||
disabled={modalcurrentPage === 1 || loading}
|
|
||||||
className="btn btn-primary"
|
|
||||||
>
|
|
||||||
Previous
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={
|
|
||||||
modalSalesCoordinators.length === modalitemPerPage
|
|
||||||
? setmodalCurrentPage(modalcurrentPage + 1)
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
disabled={
|
|
||||||
modalSalesCoordinators?.length < modalitemPerPage || loading
|
|
||||||
}
|
|
||||||
className="btn btn-primary ml-2"
|
|
||||||
>
|
|
||||||
Next
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</DialogContent>
|
|
||||||
<DialogActions>
|
|
||||||
<Button onClick={handleCloseSCModal} color="secondary">
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
</DialogActions>
|
|
||||||
</Dialog>
|
|
||||||
{/* Territory Manager */}
|
|
||||||
<Dialog
|
|
||||||
open={openTMModal}
|
|
||||||
onClose={handleCloseTMModal}
|
|
||||||
maxWidth="md"
|
|
||||||
fullWidth
|
|
||||||
>
|
|
||||||
<DialogTitle>Search and Add Territory Manager</DialogTitle>
|
|
||||||
<DialogContent>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
gap: "16px",
|
|
||||||
marginBottom: "2rem",
|
|
||||||
marginTop: "-1rem",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<TextField
|
|
||||||
label="Territory Manager Name"
|
|
||||||
placeholder="Territory Manager name"
|
|
||||||
inputRef={tmnameRef}
|
|
||||||
onChange={handlemodalSearchChangeinTM}
|
|
||||||
disabled={loading}
|
|
||||||
style={{ flex: 1, marginRight: "16px" }}
|
|
||||||
/>
|
/>
|
||||||
<TextField
|
<SCmodal
|
||||||
style={{ flex: 1 }}
|
rdid={id}
|
||||||
label="Mobile Number"
|
openSCModal={openSCModal}
|
||||||
placeholder="Mobile Number"
|
handleCloseSCModal={handleCloseSCModal}
|
||||||
inputRef={tmmobileRef}
|
refreshData={refreshData}
|
||||||
onChange={handlemodalSearchChangeinTM}
|
/>
|
||||||
disabled={loading}
|
<TMmodal
|
||||||
|
rdid={id}
|
||||||
|
openTMModal={openTMModal}
|
||||||
|
handleCloseTMModal={handleCloseTMModal}
|
||||||
|
refreshData={refreshData}
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
<div className="table-responsive table-shoot mt-3">
|
|
||||||
<table className="table table-centered table-nowrap">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Id</th>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Mobile</th>
|
|
||||||
<th>Email</th>
|
|
||||||
<th>Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{modalterritorymanagers.length > 0 ? (
|
|
||||||
modalterritorymanagers.map((TM) => (
|
|
||||||
<tr key={TM._id}>
|
|
||||||
<td>{TM.uniqueId}</td>
|
|
||||||
<td>{TM.name}</td>
|
|
||||||
<td>{TM.mobileNumber}</td>
|
|
||||||
<td>{TM.email}</td>
|
|
||||||
<td>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
onClick={() => handleUpdateMapping(TM._id, "TM")}
|
|
||||||
>
|
|
||||||
Add
|
|
||||||
</Button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
))
|
|
||||||
) : (
|
|
||||||
<tr>
|
|
||||||
<td colSpan="6" className="text-center">
|
|
||||||
No Territory Manager found!
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div className="d-flex justify-content-between">
|
|
||||||
<div>
|
|
||||||
Showing {modalterritorymanagers?.length} of {modalTotalData}{" "}
|
|
||||||
entries
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
onClick={handlePreviousPage}
|
|
||||||
disabled={modalcurrentPage === 1 || loading}
|
|
||||||
className="btn btn-primary"
|
|
||||||
>
|
|
||||||
Previous
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={
|
|
||||||
modalterritorymanagers.length === modalitemPerPage
|
|
||||||
? setmodalCurrentPage(modalcurrentPage + 1)
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
disabled={
|
|
||||||
modalterritorymanagers?.length < modalitemPerPage || loading
|
|
||||||
}
|
|
||||||
className="btn btn-primary ml-2"
|
|
||||||
>
|
|
||||||
Next
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</DialogContent>
|
|
||||||
<DialogActions>
|
|
||||||
<Button onClick={handleCloseTMModal} color="secondary">
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
</DialogActions>
|
|
||||||
</Dialog>
|
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
224
src/views/RetailDistributors/ModalPD.js
Normal file
224
src/views/RetailDistributors/ModalPD.js
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
import React, { useState, useEffect, useRef, useCallback } from "react";
|
||||||
|
import axios from "axios";
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Typography,
|
||||||
|
Grid,
|
||||||
|
Paper,
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogTitle,
|
||||||
|
Button,
|
||||||
|
TextField,
|
||||||
|
DialogActions,
|
||||||
|
} from "@mui/material";
|
||||||
|
import { isAutheticated } from "../../auth";
|
||||||
|
import swal from "sweetalert";
|
||||||
|
import debounce from "lodash.debounce";
|
||||||
|
|
||||||
|
const PDmodal = ({ openPDModal, handleClosePDModal, refreshData, rdid }) => {
|
||||||
|
const token = isAutheticated();
|
||||||
|
const [modalPrincipalDistributors, setmodalPrincipalDistributors] = useState(
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
const [modalTotalData, setModalTotalData] = useState(0);
|
||||||
|
const [modalcurrentPage, setmodalCurrentPage] = useState(1);
|
||||||
|
const [modalitemPerPage, setmodalItemPerPage] = useState(10);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const pdnameRef = useRef();
|
||||||
|
const pdmobileRef = useRef();
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePDMap = (id) => {
|
||||||
|
const data = {
|
||||||
|
principal_distributor: id,
|
||||||
|
};
|
||||||
|
axios
|
||||||
|
.put(`/api/mapped/${rdid}`, data, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
swal({
|
||||||
|
title: "Success",
|
||||||
|
text: "Principal Distributor mapped successfully!",
|
||||||
|
icon: "success",
|
||||||
|
button: "Ok",
|
||||||
|
});
|
||||||
|
refreshData(); // Call the refresh function
|
||||||
|
handleClosePDModal();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
const msg = err?.response?.data?.message || "Something went wrong!";
|
||||||
|
swal({
|
||||||
|
title: "Error",
|
||||||
|
text: msg,
|
||||||
|
icon: "error",
|
||||||
|
button: "Retry",
|
||||||
|
dangerMode: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getprincipaldistributorData();
|
||||||
|
}, [modalcurrentPage]);
|
||||||
|
|
||||||
|
const handleInputChange = useCallback(
|
||||||
|
debounce(() => {
|
||||||
|
getprincipaldistributorData();
|
||||||
|
}, 1000),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
const handleNextPage = () => {
|
||||||
|
setmodalCurrentPage((prev) => prev + 1);
|
||||||
|
};
|
||||||
|
const handlePreviousPage = () => {
|
||||||
|
setmodalCurrentPage((prev) => prev - 1);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
open={openPDModal}
|
||||||
|
onClose={handleClosePDModal}
|
||||||
|
fullWidth
|
||||||
|
maxWidth="lg"
|
||||||
|
>
|
||||||
|
<DialogTitle>Map Principal Distributor</DialogTitle>
|
||||||
|
<DialogTitle>Search and Add Principal Distributor</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
gap: "16px",
|
||||||
|
marginBottom: "2rem",
|
||||||
|
marginTop: "-1rem",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TextField
|
||||||
|
label="Principal Distributor Name"
|
||||||
|
placeholder="Principal Distributor name"
|
||||||
|
inputRef={pdnameRef}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
disabled={loading}
|
||||||
|
style={{ flex: 1, marginRight: "16px" }}
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
style={{ flex: 1 }}
|
||||||
|
label="Mobile Number"
|
||||||
|
placeholder="Mobile Number"
|
||||||
|
inputRef={pdmobileRef}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
disabled={loading}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="table-responsive table-shoot mt-3">
|
||||||
|
<table className="table table-centered table-nowrap">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Id</th>
|
||||||
|
<th>SBU</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Mobile</th>
|
||||||
|
<th>Email</th>
|
||||||
|
<th>SC</th>
|
||||||
|
<th>TM</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{modalPrincipalDistributors.length > 0 ? (
|
||||||
|
modalPrincipalDistributors.map((PD) => (
|
||||||
|
<tr key={PD._id}>
|
||||||
|
<td>{PD.uniqueId}</td>
|
||||||
|
<td>{PD.SBU}</td>
|
||||||
|
<td>{PD.name}</td>
|
||||||
|
<td>{PD.phone}</td>
|
||||||
|
<td>{PD.email}</td>
|
||||||
|
<td>{PD.mappedbySC?.name || "N/A"}</td>
|
||||||
|
<td>{PD.mappedby?.name || "N/A"}</td>
|
||||||
|
<td>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
onClick={() => handlePDMap(PD._id)}
|
||||||
|
>
|
||||||
|
Add
|
||||||
|
</Button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<tr>
|
||||||
|
<td colSpan="8" className="text-center">
|
||||||
|
No Principal Distributor found!
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div className="d-flex justify-content-between">
|
||||||
|
<div>
|
||||||
|
Showing {modalPrincipalDistributors.length} of {modalTotalData}{" "}
|
||||||
|
entries
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
onClick={handlePreviousPage}
|
||||||
|
disabled={modalcurrentPage === 1 || loading}
|
||||||
|
className="btn btn-primary"
|
||||||
|
>
|
||||||
|
Previous
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={handleNextPage}
|
||||||
|
disabled={
|
||||||
|
modalPrincipalDistributors.length < modalitemPerPage || loading
|
||||||
|
}
|
||||||
|
className="btn btn-primary ml-2"
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={handleClosePDModal} color="secondary">
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PDmodal;
|
206
src/views/RetailDistributors/ModalSC.js
Normal file
206
src/views/RetailDistributors/ModalSC.js
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
import React, { useState, useEffect, useRef, useCallback } from "react";
|
||||||
|
import axios from "axios";
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogTitle,
|
||||||
|
Button,
|
||||||
|
TextField,
|
||||||
|
DialogActions,
|
||||||
|
} from "@mui/material";
|
||||||
|
import { isAutheticated } from "../../auth";
|
||||||
|
import swal from "sweetalert";
|
||||||
|
import debounce from "lodash.debounce";
|
||||||
|
|
||||||
|
const SCmodal = ({ openSCModal, handleCloseSCModal, refreshData, rdid }) => {
|
||||||
|
const token = isAutheticated();
|
||||||
|
const [modalSalesCoordinators, setmodalSalesCoordinators] = useState(
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
const [modalTotalData, setModalTotalData] = useState(0);
|
||||||
|
const [modalcurrentPage, setmodalCurrentPage] = useState(1);
|
||||||
|
const [modalitemPerPage, setmodalItemPerPage] = useState(10);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const scnameRef = useRef();
|
||||||
|
const scmobileRef = useRef();
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSCMap = (id) => {
|
||||||
|
const data = {
|
||||||
|
mappedSC: id,
|
||||||
|
};
|
||||||
|
axios
|
||||||
|
.put(`/api/mapped/${rdid}`, data, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
swal({
|
||||||
|
title: "Success",
|
||||||
|
text: "Principal Distributor mapped successfully!",
|
||||||
|
icon: "success",
|
||||||
|
button: "Ok",
|
||||||
|
});
|
||||||
|
refreshData(); // Call the refresh function
|
||||||
|
handleCloseSCModal();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
const msg = err?.response?.data?.message || "Something went wrong!";
|
||||||
|
swal({
|
||||||
|
title: "Error",
|
||||||
|
text: msg,
|
||||||
|
icon: "error",
|
||||||
|
button: "Retry",
|
||||||
|
dangerMode: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getSalesCoOrdinatorsData();
|
||||||
|
}, [modalcurrentPage]);
|
||||||
|
|
||||||
|
const handleInputChange = useCallback(
|
||||||
|
debounce(() => {
|
||||||
|
getSalesCoOrdinatorsData();
|
||||||
|
}, 1000),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
const handleNextPage = () => {
|
||||||
|
setmodalCurrentPage((prev) => prev + 1);
|
||||||
|
};
|
||||||
|
const handlePreviousPage = () => {
|
||||||
|
setmodalCurrentPage((prev) => prev - 1);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
open={openSCModal}
|
||||||
|
onClose={handleCloseSCModal}
|
||||||
|
fullWidth
|
||||||
|
maxWidth="lg"
|
||||||
|
>
|
||||||
|
<DialogTitle>Search and Add Sales Coordinator</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
gap: "16px",
|
||||||
|
marginBottom: "2rem",
|
||||||
|
marginTop: "-1rem",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TextField
|
||||||
|
label="Sales Coordinator Name"
|
||||||
|
placeholder="Sales Coordinator name"
|
||||||
|
inputRef={scnameRef}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
disabled={loading}
|
||||||
|
style={{ flex: 1, marginRight: "16px" }}
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
style={{ flex: 1 }}
|
||||||
|
label="Mobile Number"
|
||||||
|
placeholder="Mobile Number"
|
||||||
|
inputRef={scmobileRef}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
disabled={loading}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="table-responsive table-shoot mt-3">
|
||||||
|
<table className="table table-centered table-nowrap">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Id</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Mobile</th>
|
||||||
|
<th>TM</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{modalSalesCoordinators.map((coordinator) => (
|
||||||
|
<tr key={coordinator._id}>
|
||||||
|
<td>{coordinator.uniqueId}</td>
|
||||||
|
<td>{coordinator.name}</td>
|
||||||
|
<td>{coordinator.mobileNumber}</td>
|
||||||
|
<td>{coordinator.mappedby?.name || "N/A"}</td>
|
||||||
|
<td>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
onClick={() => handleSCMap(coordinator._id)}
|
||||||
|
>
|
||||||
|
Add
|
||||||
|
</Button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div className="d-flex justify-content-between">
|
||||||
|
<div>
|
||||||
|
Showing {modalSalesCoordinators?.length} of {modalTotalData}{" "}
|
||||||
|
entries
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
onClick={handlePreviousPage}
|
||||||
|
disabled={modalcurrentPage === 1 || loading}
|
||||||
|
className="btn btn-primary"
|
||||||
|
>
|
||||||
|
Previous
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={handleNextPage}
|
||||||
|
disabled={
|
||||||
|
modalSalesCoordinators?.length < modalitemPerPage || loading
|
||||||
|
}
|
||||||
|
className="btn btn-primary ml-2"
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={handleCloseSCModal} color="secondary">
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SCmodal;
|
213
src/views/RetailDistributors/ModalTM.js
Normal file
213
src/views/RetailDistributors/ModalTM.js
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
import React, { useState, useEffect, useRef, useCallback } from "react";
|
||||||
|
import axios from "axios";
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogTitle,
|
||||||
|
Button,
|
||||||
|
TextField,
|
||||||
|
DialogActions,
|
||||||
|
} from "@mui/material";
|
||||||
|
import { isAutheticated } from "../../auth";
|
||||||
|
import swal from "sweetalert";
|
||||||
|
import debounce from "lodash.debounce";
|
||||||
|
|
||||||
|
const TMmodal = ({ openTMModal, handleCloseTMModal, refreshData, rdid }) => {
|
||||||
|
const token = isAutheticated();
|
||||||
|
const [modalTerritoryManagers, setmodalTerritoryManagers] = useState(
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
const [modalTotalData, setModalTotalData] = useState(0);
|
||||||
|
const [modalcurrentPage, setmodalCurrentPage] = useState(1);
|
||||||
|
const [modalitemPerPage, setmodalItemPerPage] = useState(10);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const tmnameRef = useRef();
|
||||||
|
const tmmobileRef = useRef();
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleTMMap = (id) => {
|
||||||
|
const data = {
|
||||||
|
mappedTM: id,
|
||||||
|
};
|
||||||
|
axios
|
||||||
|
.put(`/api/mapped/${rdid}`, data, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
swal({
|
||||||
|
title: "Success",
|
||||||
|
text: "Principal Distributor mapped successfully!",
|
||||||
|
icon: "success",
|
||||||
|
button: "Ok",
|
||||||
|
});
|
||||||
|
refreshData(); // Call the refresh function
|
||||||
|
handleCloseTMModal();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
const msg = err?.response?.data?.message || "Something went wrong!";
|
||||||
|
swal({
|
||||||
|
title: "Error",
|
||||||
|
text: msg,
|
||||||
|
icon: "error",
|
||||||
|
button: "Retry",
|
||||||
|
dangerMode: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getTerritorymanagersData();
|
||||||
|
}, [modalcurrentPage]);
|
||||||
|
|
||||||
|
const handleInputChange = useCallback(
|
||||||
|
debounce(() => {
|
||||||
|
getTerritorymanagersData();
|
||||||
|
}, 1000),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
const handleNextPage = () => {
|
||||||
|
setmodalCurrentPage((prev) => prev + 1);
|
||||||
|
};
|
||||||
|
const handlePreviousPage = () => {
|
||||||
|
setmodalCurrentPage((prev) => prev - 1);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
open={openTMModal}
|
||||||
|
onClose={handleCloseTMModal}
|
||||||
|
fullWidth
|
||||||
|
maxWidth="lg"
|
||||||
|
>
|
||||||
|
<DialogTitle>Search and Add Territory Manager</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
gap: "16px",
|
||||||
|
marginBottom: "2rem",
|
||||||
|
marginTop: "-1rem",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TextField
|
||||||
|
label="Territory Manager Name"
|
||||||
|
placeholder="Territory Manager name"
|
||||||
|
inputRef={tmnameRef}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
disabled={loading}
|
||||||
|
style={{ flex: 1, marginRight: "16px" }}
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
style={{ flex: 1 }}
|
||||||
|
label="Mobile Number"
|
||||||
|
placeholder="Mobile Number"
|
||||||
|
inputRef={tmmobileRef}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
disabled={loading}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="table-responsive table-shoot mt-3">
|
||||||
|
<table className="table table-centered table-nowrap">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Id</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Mobile</th>
|
||||||
|
<th>Email</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{modalTerritoryManagers.length > 0 ? (
|
||||||
|
modalTerritoryManagers.map((TM) => (
|
||||||
|
<tr key={TM._id}>
|
||||||
|
<td>{TM.uniqueId}</td>
|
||||||
|
<td>{TM.name}</td>
|
||||||
|
<td>{TM.mobileNumber}</td>
|
||||||
|
<td>{TM.email}</td>
|
||||||
|
<td>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
onClick={() => handleTMMap(TM._id)}
|
||||||
|
>
|
||||||
|
Add
|
||||||
|
</Button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<tr>
|
||||||
|
<td colSpan="6" className="text-center">
|
||||||
|
No Territory Manager found!
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div className="d-flex justify-content-between">
|
||||||
|
<div>
|
||||||
|
Showing {modalTerritoryManagers?.length} of {modalTotalData}{" "}
|
||||||
|
entries
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
onClick={handlePreviousPage}
|
||||||
|
disabled={modalcurrentPage === 1 || loading}
|
||||||
|
className="btn btn-primary"
|
||||||
|
>
|
||||||
|
Previous
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={handleNextPage}
|
||||||
|
disabled={
|
||||||
|
modalTerritoryManagers?.length < modalitemPerPage || loading
|
||||||
|
}
|
||||||
|
className="btn btn-primary ml-2"
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={handleCloseTMModal} color="secondary">
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TMmodal;
|
481
src/views/Sales/Sales.js
Normal file
481
src/views/Sales/Sales.js
Normal file
@ -0,0 +1,481 @@
|
|||||||
|
import React, { useState, useEffect, useRef, useCallback } from "react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import axios from "axios";
|
||||||
|
import { isAutheticated } from "src/auth";
|
||||||
|
import swal from "sweetalert";
|
||||||
|
import debounce from "lodash.debounce";
|
||||||
|
|
||||||
|
const Sales = () => {
|
||||||
|
const token = isAutheticated();
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [SalesData, setSalesData] = useState([]);
|
||||||
|
|
||||||
|
const nameRef = useRef();
|
||||||
|
const startDateRef = useRef();
|
||||||
|
const endDateRef = useRef();
|
||||||
|
|
||||||
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
|
const [itemPerPage, setItemPerPage] = useState(10);
|
||||||
|
const [totalData, setTotalData] = useState(0);
|
||||||
|
|
||||||
|
const getSalesData = async () => {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
const response = await axios.get(`/api/sales/all`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
page: currentPage,
|
||||||
|
show: itemPerPage,
|
||||||
|
startDate: startDateRef.current?.value || "",
|
||||||
|
endDate: endDateRef.current?.value || "",
|
||||||
|
name: nameRef.current?.value || "",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// console.log("response", response.data);
|
||||||
|
const transformedData =
|
||||||
|
response.data?.Sales?.map((entry) => ({
|
||||||
|
id: entry._id,
|
||||||
|
uniqueId: entry.uniqueId,
|
||||||
|
tradeName: entry.tradeName || "N/A",
|
||||||
|
designation: entry.addedFor === "PrincipalDistributor" ? "PD" : "RD",
|
||||||
|
products: entry.products.map((product) => ({
|
||||||
|
SKU: product.SKU,
|
||||||
|
ProductName: product.ProductName,
|
||||||
|
SalesAmount: product.SalesAmount,
|
||||||
|
QuantitySold: product.QuantitySold,
|
||||||
|
})),
|
||||||
|
createdAt: entry.createdAt,
|
||||||
|
updatedAt: entry.updatedAt,
|
||||||
|
})) || [];
|
||||||
|
|
||||||
|
setSalesData(transformedData);
|
||||||
|
setTotalData(response.data?.total_data || 0);
|
||||||
|
} catch (err) {
|
||||||
|
const msg = err?.response?.data?.msg || "Something went wrong!";
|
||||||
|
swal({
|
||||||
|
title: "Error",
|
||||||
|
text: msg,
|
||||||
|
icon: "error",
|
||||||
|
button: "Retry",
|
||||||
|
dangerMode: true,
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const debouncedSearch = useCallback(
|
||||||
|
debounce(() => {
|
||||||
|
setCurrentPage(1);
|
||||||
|
getSalesData();
|
||||||
|
}, 500),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleSearchChange = () => {
|
||||||
|
debouncedSearch();
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getSalesData();
|
||||||
|
}, [itemPerPage, currentPage]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="main-content">
|
||||||
|
<div className="page-content">
|
||||||
|
<div className="container-fluid">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-12">
|
||||||
|
<div
|
||||||
|
className="
|
||||||
|
page-title-box
|
||||||
|
d-flex
|
||||||
|
align-items-center
|
||||||
|
justify-content-between
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div style={{ fontSize: "22px" }} className="fw-bold">
|
||||||
|
Sales List
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="card">
|
||||||
|
<div className="card-body">
|
||||||
|
<div className="row ml-0 mr-0 mb-10">
|
||||||
|
<div className="col-lg-1">
|
||||||
|
<div className="dataTables_length">
|
||||||
|
<label className="w-100">
|
||||||
|
Show
|
||||||
|
<select
|
||||||
|
onChange={(e) => {
|
||||||
|
setItemPerPage(e.target.value);
|
||||||
|
setCurrentPage(1);
|
||||||
|
}}
|
||||||
|
className="form-control"
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
<option value="10">10</option>
|
||||||
|
<option value="25">25</option>
|
||||||
|
<option value="50">50</option>
|
||||||
|
<option value="100">100</option>
|
||||||
|
</select>
|
||||||
|
entries
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-lg-3">
|
||||||
|
<label>Trade Name:</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Trade name"
|
||||||
|
className="form-control"
|
||||||
|
ref={nameRef}
|
||||||
|
onChange={handleSearchChange}
|
||||||
|
disabled={loading}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-lg-3">
|
||||||
|
<label>Start Date:</label>
|
||||||
|
<input
|
||||||
|
type="date"
|
||||||
|
className="form-control"
|
||||||
|
ref={startDateRef}
|
||||||
|
onChange={handleSearchChange}
|
||||||
|
disabled={loading}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-lg-3">
|
||||||
|
<label>End Date:</label>
|
||||||
|
<input
|
||||||
|
type="date"
|
||||||
|
className="form-control"
|
||||||
|
ref={endDateRef}
|
||||||
|
onChange={handleSearchChange}
|
||||||
|
disabled={loading}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="table-responsive table-shoot mt-3">
|
||||||
|
<table
|
||||||
|
className="table table-centered table-nowrap"
|
||||||
|
style={{
|
||||||
|
border: "1px solid",
|
||||||
|
borderCollapse: "collapse",
|
||||||
|
}} // Ensure borders collapse for clean lines
|
||||||
|
>
|
||||||
|
<thead
|
||||||
|
className="thead-light"
|
||||||
|
style={{ background: "#ecdddd" }}
|
||||||
|
>
|
||||||
|
<tr>
|
||||||
|
<th
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
ID
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
Date
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
Time
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
Trade Name
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
PD/RD
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
Product SKU
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
Product Name
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
QuantitySold
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
SalesAmount
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
Actions
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
{loading ? (
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
className="text-center"
|
||||||
|
colSpan="10"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
Loading...
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
) : SalesData.length > 0 ? (
|
||||||
|
SalesData.map((entry, i) =>
|
||||||
|
entry.products.map((product, j) => (
|
||||||
|
<tr key={`${i}-${j}`}>
|
||||||
|
{/* Only show ID, Date, Time, Trade Name, PD/RD, and Actions on the first row of each entry */}
|
||||||
|
{j === 0 && (
|
||||||
|
<>
|
||||||
|
<td
|
||||||
|
className="text-start"
|
||||||
|
rowSpan={entry.products.length}
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
{entry.uniqueId}
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="text-start"
|
||||||
|
rowSpan={entry.products.length}
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
{new Date(entry.createdAt).toLocaleString(
|
||||||
|
"en-IN",
|
||||||
|
{
|
||||||
|
month: "short",
|
||||||
|
day: "numeric",
|
||||||
|
year: "numeric",
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="text-start"
|
||||||
|
rowSpan={entry.products.length}
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
{new Date(entry.createdAt).toLocaleString(
|
||||||
|
"en-IN",
|
||||||
|
{
|
||||||
|
hour: "numeric",
|
||||||
|
minute: "numeric",
|
||||||
|
hour12: true,
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="text-start"
|
||||||
|
rowSpan={entry.products.length}
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
{entry.tradeName}
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="text-start"
|
||||||
|
rowSpan={entry.products.length}
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
{entry.designation}
|
||||||
|
</td>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{/* Product details */}
|
||||||
|
<td
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
{product.SKU}
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
{product.ProductName}
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
{product.QuantitySold}
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
{product.SalesAmount}
|
||||||
|
</td>
|
||||||
|
{/* Actions: only show on the first row of each entry */}
|
||||||
|
{j === 0 && (
|
||||||
|
<td
|
||||||
|
className="text-start"
|
||||||
|
rowSpan={entry.products.length}
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
<Link
|
||||||
|
to={`/sales/view/${entry.id}`}
|
||||||
|
state={{ product }}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
style={{
|
||||||
|
color: "white",
|
||||||
|
marginRight: "1rem",
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
className="btn btn-primary btn-sm waves-effect waves-light btn-table mx-1 mt-1"
|
||||||
|
>
|
||||||
|
View
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
</td>
|
||||||
|
)}
|
||||||
|
</tr>
|
||||||
|
))
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<tr className="text-center">
|
||||||
|
<td colSpan="10" style={{ border: "1px solid" }}>
|
||||||
|
<h5>No Data Available...</h5>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div className="row mt-20">
|
||||||
|
<div className="col-sm-12 col-md-6 mb-20">
|
||||||
|
<div
|
||||||
|
className="dataTables_info"
|
||||||
|
id="datatable_info"
|
||||||
|
role="status"
|
||||||
|
aria-live="polite"
|
||||||
|
>
|
||||||
|
Showing {currentPage * itemPerPage - itemPerPage + 1} to{" "}
|
||||||
|
{Math.min(currentPage * itemPerPage, totalData)} of{" "}
|
||||||
|
{totalData} entries
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-sm-12 col-md-6">
|
||||||
|
<div className="d-flex">
|
||||||
|
<ul className="pagination ms-auto">
|
||||||
|
<li
|
||||||
|
className={
|
||||||
|
currentPage === 1
|
||||||
|
? "paginate_button page-item previous disabled"
|
||||||
|
: "paginate_button page-item previous"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
onClick={() => setCurrentPage((prev) => prev - 1)}
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
Previous
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{!(currentPage - 1 < 1) && (
|
||||||
|
<li className="paginate_button page-item">
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
onClick={(e) =>
|
||||||
|
setCurrentPage((prev) => prev - 1)
|
||||||
|
}
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
{currentPage - 1}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<li className="paginate_button page-item active">
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
>
|
||||||
|
{currentPage}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{!(
|
||||||
|
(currentPage + 1) * itemPerPage - itemPerPage >
|
||||||
|
totalData - 1
|
||||||
|
) && (
|
||||||
|
<li className="paginate_button page-item ">
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
onClick={() => {
|
||||||
|
setCurrentPage((prev) => prev + 1);
|
||||||
|
}}
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
{currentPage + 1}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<li
|
||||||
|
className={
|
||||||
|
!(
|
||||||
|
(currentPage + 1) * itemPerPage - itemPerPage >
|
||||||
|
totalData - 1
|
||||||
|
)
|
||||||
|
? "paginate_button page-item next"
|
||||||
|
: "paginate_button page-item next disabled"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
onClick={() => setCurrentPage((prev) => prev + 1)}
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Sales;
|
178
src/views/Sales/SingleSale.js
Normal file
178
src/views/Sales/SingleSale.js
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import axios from "axios";
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Typography,
|
||||||
|
Grid,
|
||||||
|
Paper,
|
||||||
|
IconButton,
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableContainer,
|
||||||
|
TableHead,
|
||||||
|
TableRow,
|
||||||
|
Paper as MuiPaper,
|
||||||
|
} from "@mui/material";
|
||||||
|
import { useParams, useNavigate } from "react-router-dom";
|
||||||
|
import { isAutheticated } from "../../auth";
|
||||||
|
import CancelIcon from "@mui/icons-material/Cancel"; // Add this import
|
||||||
|
|
||||||
|
const SingleSales = () => {
|
||||||
|
const { id } = useParams();
|
||||||
|
const [SalesDetails, setSalesDetails] = useState(null);
|
||||||
|
const token = isAutheticated();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await axios.get(`/api/sales/${id}`, {
|
||||||
|
headers: {
|
||||||
|
"Access-Control-Allow-Origin": "*",
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
setSalesDetails(response.data);
|
||||||
|
// console.log("Inventory Details: ", response.data);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching data: ", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchData();
|
||||||
|
}, [id]);
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
navigate("/inventory");
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!SalesDetails) {
|
||||||
|
return <Typography>Loading...</Typography>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ p: 3 }}>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
alignItems: "center",
|
||||||
|
mb: 3,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography variant="h4">Sales Details</Typography>
|
||||||
|
<IconButton sx={{ color: "red" }} onClick={handleCancel}>
|
||||||
|
<CancelIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Paper sx={{ p: 2, mb: 3 }}>
|
||||||
|
<Typography variant="h5" gutterBottom>
|
||||||
|
Sales Data
|
||||||
|
</Typography>
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography>
|
||||||
|
<strong>Timestamp:</strong>{" "}
|
||||||
|
{new Date(SalesDetails.createdAt).toLocaleString("en-IN", {
|
||||||
|
weekday: "short",
|
||||||
|
month: "short",
|
||||||
|
day: "numeric",
|
||||||
|
year: "numeric",
|
||||||
|
hour: "numeric",
|
||||||
|
minute: "numeric",
|
||||||
|
hour12: true,
|
||||||
|
})}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Paper>
|
||||||
|
|
||||||
|
<Paper sx={{ p: 2, mb: 3 }}>
|
||||||
|
<Typography variant="h6" gutterBottom>
|
||||||
|
Product Details
|
||||||
|
</Typography>
|
||||||
|
<TableContainer component={MuiPaper}>
|
||||||
|
<Table>
|
||||||
|
<TableHead >
|
||||||
|
<TableRow>
|
||||||
|
<TableCell><strong>Product Name</strong></TableCell>
|
||||||
|
<TableCell><strong>SKU</strong></TableCell>
|
||||||
|
<TableCell><strong>QuantitySold</strong></TableCell>
|
||||||
|
<TableCell><strong>SalesAmount</strong></TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
{SalesDetails.products.map((product, index) => (
|
||||||
|
<TableRow key={index}>
|
||||||
|
<TableCell>{product.ProductName}</TableCell>
|
||||||
|
<TableCell>{product.SKU}</TableCell>
|
||||||
|
<TableCell>{product.QuantitySold}</TableCell>
|
||||||
|
<TableCell>{product.SalesAmount}</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
</Paper>
|
||||||
|
|
||||||
|
<Paper sx={{ p: 2, mb: 3 }}>
|
||||||
|
<Typography variant="h6" gutterBottom>
|
||||||
|
Data Added For
|
||||||
|
</Typography>
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Typography>
|
||||||
|
<strong>PD or RD:</strong>{" "}
|
||||||
|
{SalesDetails.addedFor}
|
||||||
|
</Typography>
|
||||||
|
<Typography>
|
||||||
|
<strong>Name:</strong> {SalesDetails.addedForData.name}
|
||||||
|
</Typography>
|
||||||
|
<Typography>
|
||||||
|
<strong>Mobile Number:</strong>{" "}
|
||||||
|
{SalesDetails.addedForData.phone || SalesDetails.addedForData.mobile_number}
|
||||||
|
</Typography>
|
||||||
|
<Typography>
|
||||||
|
<strong>Email:</strong> {SalesDetails.addedForData.email||'N/A'}
|
||||||
|
</Typography>
|
||||||
|
<Typography>
|
||||||
|
<strong>Trade Name:</strong>{" "}
|
||||||
|
{SalesDetails.addedForData.shippingAddress?.tradeName||SalesDetails.addedForData.kyc.trade_name}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Paper>
|
||||||
|
|
||||||
|
<Paper sx={{ p: 2, mb: 3 }}>
|
||||||
|
<Typography variant="h6" gutterBottom>
|
||||||
|
Data Entered By
|
||||||
|
</Typography>
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Typography>
|
||||||
|
<strong>Designation:</strong> {SalesDetails.userType}
|
||||||
|
</Typography>
|
||||||
|
<Typography>
|
||||||
|
<strong>Name:</strong> {SalesDetails.user?.name}
|
||||||
|
</Typography>
|
||||||
|
<Typography>
|
||||||
|
<strong>ID:</strong> {SalesDetails.user?.uniqueId}
|
||||||
|
</Typography>
|
||||||
|
<Typography>
|
||||||
|
<strong>Email:</strong> {SalesDetails.user?.email}
|
||||||
|
</Typography>
|
||||||
|
<Typography>
|
||||||
|
<strong>Mobile Number:</strong>{" "}
|
||||||
|
{SalesDetails.user?.mobileNumber}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Paper>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SingleSales;
|
249
src/views/configuration/MobileApp.js
Normal file
249
src/views/configuration/MobileApp.js
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import swal from "sweetalert";
|
||||||
|
import ClipLoader from "react-spinners/ClipLoader";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import axios from "axios";
|
||||||
|
import { isAutheticated } from "src/auth";
|
||||||
|
|
||||||
|
function MobileApp() {
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [PDApp, setPDApp] = useState("");
|
||||||
|
const [RDApp, setRDApp] = useState("");
|
||||||
|
const [SCApp, setSCApp] = useState("");
|
||||||
|
const [TMApp, setTMApp] = useState("");
|
||||||
|
const [display, setDisplay] = useState(true);
|
||||||
|
const token = isAutheticated();
|
||||||
|
|
||||||
|
// urlcreated images
|
||||||
|
|
||||||
|
const [PDAppUrl, setPDAppUrl] = useState("");
|
||||||
|
const [RDAppUrl, setRDAppUrl] = useState("");
|
||||||
|
const [SCAppUrl, setSCAppUrl] = useState("");
|
||||||
|
const [TMAppUrl, setTMAppUrl] = useState("");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
async function getConfiguration() {
|
||||||
|
const configDetails = await axios.get(`/api/config`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// console.log(configDetails.data.result[0]?.logo[0]);
|
||||||
|
const data = configDetails.data.result[0]?.logo[0];
|
||||||
|
setPDApp(data?.PDApp);
|
||||||
|
setRDApp(data?.RDApp);
|
||||||
|
setSCApp(data?.SCApp);
|
||||||
|
setTMApp(data?.TMApp);
|
||||||
|
}
|
||||||
|
getConfiguration();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
async function handelSubmit() {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
const formdata = new FormData();
|
||||||
|
formdata.append("PDApp", PDApp);
|
||||||
|
formdata.append("RDApp", RDApp);
|
||||||
|
formdata.append("SCApp", SCApp);
|
||||||
|
formdata.append("TMApp", TMApp);
|
||||||
|
|
||||||
|
await axios
|
||||||
|
.post(`/api/config/logo`, formdata, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
"Content-Type": "multipart/formdata",
|
||||||
|
"Access-Control-Allow-Origin": "*",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
setLoading(false);
|
||||||
|
swal("Success!", res.data.message, res.data.status);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="main-content">
|
||||||
|
<div className="page-content">
|
||||||
|
<div className="container-fluid">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="card">
|
||||||
|
<div className="card-body">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12 col-lg-6 col-xl-6">
|
||||||
|
<h1 className="text-left head-small">Mobile App</h1>
|
||||||
|
|
||||||
|
<form>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="form-group">
|
||||||
|
<>
|
||||||
|
<label
|
||||||
|
htmlFor="basicpill-phoneno-input"
|
||||||
|
className="label-100 mt-3"
|
||||||
|
style={{ fontWeight: "bold" }}
|
||||||
|
>
|
||||||
|
Header Logo for user Website(250 x 100
|
||||||
|
pixels) <br />
|
||||||
|
</label>
|
||||||
|
<div>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
name="Logo htmlFor Website Header(148 x 48 px)"
|
||||||
|
onChange={(e) => {
|
||||||
|
setPDApp(e.target.files[0]);
|
||||||
|
if (
|
||||||
|
e.target.files &&
|
||||||
|
e.target.files[0]
|
||||||
|
) {
|
||||||
|
setPDAppUrl({
|
||||||
|
image: URL.createObjectURL(
|
||||||
|
e.target.files[0]
|
||||||
|
),
|
||||||
|
});
|
||||||
|
console.log(setPDAppUrl);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
className="form-control input-field mb-3 col-md-6 d-inline-block"
|
||||||
|
id="basicpill-phoneno-input"
|
||||||
|
/>
|
||||||
|
{display ? (
|
||||||
|
<img
|
||||||
|
className="ms-1"
|
||||||
|
style={{ width: "100px" }}
|
||||||
|
src={
|
||||||
|
PDAppUrl.image
|
||||||
|
? PDAppUrl.image
|
||||||
|
: PDApp
|
||||||
|
}
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<label
|
||||||
|
htmlFor="basicpill-phoneno-input"
|
||||||
|
className="label-100 mt-3"
|
||||||
|
style={{ fontWeight: "bold" }}
|
||||||
|
>
|
||||||
|
{/* Logo htmlFor Website Footer(148 x 48 px) */}
|
||||||
|
Footer logo for user Website(250 x 100
|
||||||
|
pixels) <br />
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
name="Logo htmlFor Website Footer(148 x 48 px)"
|
||||||
|
onChange={(e) => {
|
||||||
|
setRDApp(e.target.files[0]);
|
||||||
|
|
||||||
|
if (e.target.files && e.target.files[0]) {
|
||||||
|
setRDAppUrl({
|
||||||
|
image: URL.createObjectURL(
|
||||||
|
e.target.files[0]
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
className="form-control input-field mt-1 col-md-6 d-inline-block"
|
||||||
|
id="basicpill-phoneno-input"
|
||||||
|
/>{" "}
|
||||||
|
{display ? (
|
||||||
|
<img
|
||||||
|
style={{ width: "100px" }}
|
||||||
|
src={
|
||||||
|
RDAppUrl.image
|
||||||
|
? RDAppUrl.image
|
||||||
|
: RDApp
|
||||||
|
}
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
<label
|
||||||
|
htmlFor="basicpill-phoneno-input"
|
||||||
|
className="label-100 mt-2 row ms-1"
|
||||||
|
style={{ fontWeight: "bold" }}
|
||||||
|
>
|
||||||
|
{/* Logo htmlFor Admin Header(148 x 48 px) */}
|
||||||
|
Logo for admin website(250 x 100 pixels){" "}
|
||||||
|
<br />
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
name="Logo htmlFor Admin Header(148 x 48 px)"
|
||||||
|
onChange={(e) => {
|
||||||
|
setSCApp(e.target.files[0]);
|
||||||
|
|
||||||
|
if (e.target.files && e.target.files[0]) {
|
||||||
|
setSCAppUrl({
|
||||||
|
image: URL.createObjectURL(
|
||||||
|
e.target.files[0]
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
className="form-control input-field col-md-6 d-inline-block"
|
||||||
|
id="basicpill-phoneno-input"
|
||||||
|
/>{" "}
|
||||||
|
{display ? (
|
||||||
|
<img
|
||||||
|
style={{ width: "100px" }}
|
||||||
|
src={
|
||||||
|
SCAppUrl.image
|
||||||
|
? SCAppUrl.image
|
||||||
|
: SCApp
|
||||||
|
}
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="form-group text-left">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
disabled={
|
||||||
|
SCApp === "" ||
|
||||||
|
RDApp === "" ||
|
||||||
|
PDApp === ""
|
||||||
|
}
|
||||||
|
onClick={handelSubmit}
|
||||||
|
className="btn btn-success btn-login waves-effect waves-light mr-3 pt-2 pb-2 pr-4 pl-4"
|
||||||
|
>
|
||||||
|
<ClipLoader loading={loading} size={18} />
|
||||||
|
{!loading && "Save"}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* <!-- end table-responsive --> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* <!-- container-fluid --> */}
|
||||||
|
</div>
|
||||||
|
{/* <!-- End Page-content --> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MobileApp;
|
Loading…
Reference in New Issue
Block a user