Retail distributor

This commit is contained in:
Sibunnayak 2024-08-05 19:05:28 +05:30
parent 059ddd0fa1
commit 99a358a567
4 changed files with 217 additions and 165 deletions

View File

@ -89,13 +89,13 @@ const _nav = [
to: "/territorymanagers", to: "/territorymanagers",
group: "TerritoryManager", group: "TerritoryManager",
}, },
// { {
// component: CNavItem, component: CNavItem,
// name: "retail Distributor", name: "retail Distributor",
// icon: <CIcon icon={cilCompress} customClassName="nav-icon" />, icon: <CIcon icon={cilCompress} customClassName="nav-icon" />,
// to: "/retail-distributor", to: "/retail-distributor",
// group: "RetailDistributor", group: "RetailDistributor",
// }, },
{ {
component: CNavItem, component: CNavItem,
name: "Attendance", name: "Attendance",

View File

@ -304,7 +304,7 @@ const routes = [
navName: "RetailDistributor", navName: "RetailDistributor",
}, },
{ {
path: "/single/retail-distributor", path: "/retaildistributor/view/:id",
name: "Single Retail Distributor", name: "Single Retail Distributor",
element: SingleRetailDistributor, element: SingleRetailDistributor,
navName: "RetailDistributor", navName: "RetailDistributor",

View File

@ -1,44 +1,36 @@
import React, { useState, useEffect, useRef, useCallback } from "react"; import React, { useState, useEffect, useCallback } from "react";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import axios from "axios"; import axios from "axios";
import Button from "@material-ui/core/Button"; import Button from "@material-ui/core/Button";
import { useNavigate } from "react-router-dom";
import { isAutheticated } from "src/auth"; import { isAutheticated } from "src/auth";
import swal from "sweetalert"; import swal from "sweetalert";
import debounce from 'lodash.debounce'; import debounce from "lodash.debounce";
const RetailDistributor = () => { const RetailDistributor = () => {
const token = isAutheticated(); const token = isAutheticated();
const navigate = useNavigate();
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [success, setSuccess] = useState(true); const [allRetailDistributorsData, setAllRetailDistributorsData] = useState(
const [retailDistributorsData, setRetailDistributorsData] = useState([]); []
);
const nameRef = useRef(); const [filteredRetailDistributorsData, setFilteredRetailDistributorsData] =
const mobileRef = useRef(); useState([]);
const VerifyRetailDistributorRef = useRef(); const [searchTerm, setSearchTerm] = useState("");
const [searchPrincipalDistributor, setSearchPrincipalDistributor] =
useState("");
const [currentPage, setCurrentPage] = useState(1); const [currentPage, setCurrentPage] = useState(1);
const [itemPerPage, setItemPerPage] = useState(10); const [itemPerPage, setItemPerPage] = useState(10);
const [totalData, setTotalData] = useState(0);
const getRetailDistributorsData = async () => { const getRetailDistributorsData = async () => {
setLoading(true); setLoading(true);
try { try {
const res = await axios.get(`/api/retaildistributor/getAll/`, { const res = await axios.get(`/api/kyc/getAllapproved/`, {
headers: { headers: {
Authorization: `Bearer ${token}`, Authorization: `Bearer ${token}`,
}, },
params: {
page: currentPage,
show: itemPerPage,
name: nameRef.current.value,
mobileNumber: mobileRef.current.value,
isVerified: VerifyRetailDistributorRef.current.value,
},
}); });
setRetailDistributorsData(res.data?.retailDistributors); setAllRetailDistributorsData(res.data || []);
setTotalData(res.data?.total_data); setFilteredRetailDistributorsData(res.data || []); // Initialize filtered data
} catch (err) { } catch (err) {
const msg = err?.response?.data?.message || "Something went wrong!"; const msg = err?.response?.data?.message || "Something went wrong!";
swal({ swal({
@ -55,18 +47,64 @@ const RetailDistributor = () => {
useEffect(() => { useEffect(() => {
getRetailDistributorsData(); getRetailDistributorsData();
}, [success, itemPerPage, currentPage]); }, []);
const debouncedSearch = useCallback(debounce(() => { useEffect(() => {
setCurrentPage(1); filterData();
getRetailDistributorsData(); }, [searchTerm, searchPrincipalDistributor, allRetailDistributorsData]);
}, 500), []);
const handleSearchChange = () => { const filterData = () => {
let filteredData = allRetailDistributorsData;
if (searchTerm) {
filteredData = filteredData.filter((item) =>
item.trade_name.toLowerCase().includes(searchTerm.toLowerCase())
);
}
if (searchPrincipalDistributor) {
filteredData = filteredData.filter((item) =>
item.principal_distributer?.name
?.toLowerCase()
.includes(searchPrincipalDistributor.toLowerCase())
);
}
setFilteredRetailDistributorsData(filteredData);
setCurrentPage(1); // Reset to first page when filtering
};
const debouncedSearch = useCallback(
debounce(() => {
filterData();
}, 500),
[searchTerm, searchPrincipalDistributor]
);
const handleSearchChange = (e) => {
const { name, value } = e.target;
if (name === "searchTerm") {
setSearchTerm(value);
} else if (name === "searchPrincipalDistributor") {
setSearchPrincipalDistributor(value);
}
debouncedSearch(); debouncedSearch();
}; };
const totalPages = Math.ceil(totalData / itemPerPage); const totalPages = Math.ceil(
filteredRetailDistributorsData.length / itemPerPage
);
const paginatedData = filteredRetailDistributorsData.slice(
(currentPage - 1) * itemPerPage,
currentPage * itemPerPage
);
const handleResetSearch = () => {
setSearchTerm("");
setSearchPrincipalDistributor("");
setFilteredRetailDistributorsData(allRetailDistributorsData); // Reset filtered data
setCurrentPage(1); // Reset to first page
};
return ( return (
<div className="main-content"> <div className="main-content">
@ -93,8 +131,8 @@ const RetailDistributor = () => {
Show Show
<select <select
onChange={(e) => { onChange={(e) => {
setItemPerPage(e.target.value); setItemPerPage(Number(e.target.value));
setCurrentPage(1); setCurrentPage(1); // Reset to first page when changing items per page
}} }}
className="form-control" className="form-control"
disabled={loading} disabled={loading}
@ -109,39 +147,37 @@ const RetailDistributor = () => {
</div> </div>
</div> </div>
<div className="col-lg-3"> <div className="col-lg-3">
<label>Retail Distributor Name:</label> <label>Trade Name:</label>
<input <input
type="text" type="text"
placeholder="Retail Distributor name" name="searchTerm"
placeholder="Trade name"
className="form-control" className="form-control"
ref={nameRef}
onChange={handleSearchChange} onChange={handleSearchChange}
disabled={loading} disabled={loading}
value={searchTerm}
/> />
</div> </div>
<div className="col-lg-3"> <div className="col-lg-3">
<label>Mobile Number:</label> <label>Principal Distributor Name:</label>
<input <input
type="text" type="text"
placeholder="Mobile Number" name="searchPrincipalDistributor"
placeholder="Principal Distributor name"
className="form-control" className="form-control"
ref={mobileRef}
onChange={handleSearchChange} onChange={handleSearchChange}
disabled={loading} disabled={loading}
value={searchPrincipalDistributor}
/> />
</div> </div>
<div className="col-lg-3"> <div className="col-lg-3">
<label>Verify Retail Distributor:</label> <Button
<select variant="outlined"
className="form-control" color="primary"
ref={VerifyRetailDistributorRef} onClick={handleResetSearch}
onChange={handleSearchChange}
disabled={loading}
> >
<option value="">----Select----</option> Reset Search
<option value="true">YES</option> </Button>
<option value="false">NO</option>
</select>
</div> </div>
</div> </div>
@ -155,9 +191,9 @@ const RetailDistributor = () => {
<th>ID</th> <th>ID</th>
<th className="text-start">Trade Name</th> <th className="text-start">Trade Name</th>
<th className="text-start">Created On</th> <th className="text-start">Created On</th>
<th className="text-start">PrincipleDistributor</th> <th className="text-start">Principal Distributor</th>
<th className="text-start">TerritoryManager</th> <th className="text-start">Territory Manager</th>
<th className="text-start">SalesCoOrdinator</th> <th className="text-start">Sales Coordinator</th>
<th className="text-start">Action</th> <th className="text-start">Action</th>
</tr> </tr>
</thead> </thead>
@ -165,61 +201,62 @@ const RetailDistributor = () => {
<tbody> <tbody>
{loading ? ( {loading ? (
<tr> <tr>
<td className="text-center" colSpan="5"> <td className="text-center" colSpan="7">
Loading... Loading...
</td> </td>
</tr> </tr>
) : retailDistributorsData?.length > 0 ? ( ) : paginatedData.length > 0 ? (
retailDistributorsData?.map((retailDistributor, i) => { paginatedData.map((retailDistributor) => (
return ( <tr key={retailDistributor._id}>
<tr key={i}> <td className="text-start">
<td className="text-start"> {retailDistributor._id}
{retailDistributor?.id} </td>
</td> <td className="text-start">
<td className="text-start"> {retailDistributor.trade_name}
{retailDistributor?.tradeName} </td>
</td> <td className="text-start">
<td className="text-start"> {new Date(
{new Date( retailDistributor.updatedAt
retailDistributor.createdAt ).toLocaleString("en-IN", {
).toLocaleString("en-IN", { weekday: "short",
weekday: "short", month: "short",
month: "short", day: "numeric",
day: "numeric", year: "numeric",
year: "numeric", hour: "numeric",
hour: "numeric", minute: "numeric",
minute: "numeric", hour12: true,
hour12: true, })}
})} </td>
</td> <td className="text-start">
<td className="text-start"> {retailDistributor.principal_distributer
<div> ?.name || "N/A"}
<div>Principal Distributor: {retailDistributor.principalDistributor || 'N/A'}</div> </td>
<div>Territory Manager: {retailDistributor.territoryManager || 'N/A'}</div> <td className="text-start">
<div>Sales Coordinator: {retailDistributor.salesCoordinator || 'N/A'}</div> {retailDistributor.userType ===
</div> "TerritoryManager"
</td> ? retailDistributor.addedBy?.name || "N/A"
<td className="text-start"> : "N/A"}
<Link </td>
to={`/retaildistributor/view/${retailDistributor._id}`} <td className="text-start">
> {retailDistributor.userType ===
<button "SalesCoOrdinator"
style={{ ? retailDistributor.addedBy?.name || "N/A"
color: "white", : "N/A"}
}} </td>
type="button" <td className="text-start">
className="btn btn-info btn-sm waves-effect waves-light btn-table ml-2" <Link
> to={`/retaildistributor/view/${retailDistributor._id}`}
View >
</button> <Button variant="contained" color="primary">
</Link> View
</td> </Button>
</tr> </Link>
); </td>
}) </tr>
))
) : ( ) : (
<tr> <tr>
<td className="text-center" colSpan="5"> <td className="text-center" colSpan="7">
No Retail Distributor found! No Retail Distributor found!
</td> </td>
</tr> </tr>
@ -236,49 +273,64 @@ const RetailDistributor = () => {
aria-live="polite" aria-live="polite"
> >
Showing {currentPage * itemPerPage - itemPerPage + 1} to{" "} Showing {currentPage * itemPerPage - itemPerPage + 1} to{" "}
{Math.min(currentPage * itemPerPage, totalData)} of{" "} {Math.min(
{totalData} entries currentPage * itemPerPage,
filteredRetailDistributorsData.length
)}{" "}
of {filteredRetailDistributorsData.length} entries
</div> </div>
</div> </div>
<div className="col-sm-12 col-md-6"> <div className="col-sm-12 col-md-6">
<div className="d-flex"> <div className="dataTables_paginate paging_simple_numbers">
<ul className="pagination ms-auto"> <ul className="pagination">
<li <li
className={ className={`paginate_button page-item previous ${
currentPage === 1 currentPage === 1 ? "disabled" : ""
? "paginate_button page-item previous disabled" }`}
: "paginate_button page-item previous"
}
> >
<span <a
className="page-link" className="page-link"
onClick={() => onClick={() =>
setCurrentPage((prev) => setCurrentPage((prev) => Math.max(prev - 1, 1))
prev > 1 ? prev - 1 : prev
)
} }
aria-controls="datatable"
> >
Previous Previous
</span> </a>
</li> </li>
{Array.from({ length: totalPages }, (_, index) => (
<li
key={index}
className={`paginate_button page-item ${
currentPage === index + 1 ? "active" : ""
}`}
>
<a
className="page-link"
onClick={() => setCurrentPage(index + 1)}
aria-controls="datatable"
>
{index + 1}
</a>
</li>
))}
<li <li
className={ className={`paginate_button page-item next ${
currentPage === totalPages currentPage === totalPages ? "disabled" : ""
? "paginate_button page-item next disabled" }`}
: "paginate_button page-item next"
}
> >
<span <a
className="page-link" className="page-link"
onClick={() => onClick={() =>
setCurrentPage((prev) => setCurrentPage((prev) =>
prev < totalPages ? prev + 1 : prev Math.min(prev + 1, totalPages)
) )
} }
aria-controls="datatable"
> >
Next Next
</span> </a>
</li> </li>
</ul> </ul>
</div> </div>

View File

@ -18,43 +18,43 @@ const SingleRetailDistributor = () => {
const fetchData = async () => { const fetchData = async () => {
try { try {
// Commented out the API call and using dummy data // Commented out the API call and using dummy data
// const response = await axios.get(`/api/kyc/get-single-kyc/${id}`, { const response = await axios.get(`api/kyc/get-single-kyc/${id}`, {
// headers: { headers: {
// 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Origin': '*',
// Authorization: `Bearer ${token}`, Authorization: `Bearer ${token}`,
// 'Content-Type': 'multipart/form-data', 'Content-Type': 'multipart/form-data',
// }, },
// }); });
// setRetailerDetails(response.data); setRetailerDetails(response.data);
// Dummy data // // Dummy data
const dummyData = { // const dummyData = {
_id: '66a8bb8392d90216331b1f73', // _id: '66a8bb8392d90216331b1f73',
name: 'roshan garg', // name: 'roshan garg',
trade_name: 'abc', // trade_name: 'abc',
address: 'abc btm', // address: 'abc btm',
state: 'KA', // state: 'KA',
city: 'Bengaluru', // city: 'Bengaluru',
district: 'benga', // district: 'benga',
pincode: '124515', // pincode: '124515',
mobile_number: '8516913819', // mobile_number: '8516913819',
principal_distributer: { name: 'Distributor Name' }, // principal_distributer: { name: 'Distributor Name' },
pan_number: '123456454', // pan_number: '123456454',
pan_img: { url: 'https://res.cloudinary.com/dslvetard/image/upload/v1722334072/KYC/pan/u3a08xjvrpovfzruedeq.png' }, // pan_img: { url: 'https://res.cloudinary.com/dslvetard/image/upload/v1722334072/KYC/pan/u3a08xjvrpovfzruedeq.png' },
aadhar_number: '123123123123', // aadhar_number: '123123123123',
aadhar_img: { url: 'https://res.cloudinary.com/dslvetard/image/upload/v1722334074/KYC/aadhar/ep64tuufileifysol4dx.png' }, // aadhar_img: { url: 'https://res.cloudinary.com/dslvetard/image/upload/v1722334074/KYC/aadhar/ep64tuufileifysol4dx.png' },
gst_number: '121212', // gst_number: '121212',
gst_img: { url: 'https://res.cloudinary.com/dslvetard/image/upload/v1722334076/KYC/gst/jqy8uqa6ejntwhc7mq86.png' }, // gst_img: { url: 'https://res.cloudinary.com/dslvetard/image/upload/v1722334076/KYC/gst/jqy8uqa6ejntwhc7mq86.png' },
pesticide_license_img: { url: 'https://res.cloudinary.com/dslvetard/image/upload/v1722334077/KYC/pesticide_license/iyznci3iibp50pug8e8p.png' }, // pesticide_license_img: { url: 'https://res.cloudinary.com/dslvetard/image/upload/v1722334077/KYC/pesticide_license/iyznci3iibp50pug8e8p.png' },
fertilizer_license_img: { url: 'https://res.cloudinary.com/dslvetard/image/upload/v1722334080/KYC/fertilizer_license/jnj1r8rzwsbkclarbbch.png' }, // fertilizer_license_img: { url: 'https://res.cloudinary.com/dslvetard/image/upload/v1722334080/KYC/fertilizer_license/jnj1r8rzwsbkclarbbch.png' },
selfie_entrance_img: { url: 'https://res.cloudinary.com/dslvetard/image/upload/v1722334082/KYC/selfie_entrance/weri7zhyioi7lqwv3dvg.png' }, // selfie_entrance_img: { url: 'https://res.cloudinary.com/dslvetard/image/upload/v1722334082/KYC/selfie_entrance/weri7zhyioi7lqwv3dvg.png' },
status: 'new', // status: 'new',
addedBy: { name: 'Added By', uniqueId: 'E123' }, // addedBy: { name: 'Added By', uniqueId: 'E123' },
notes: [], // notes: [],
createdAt: '2024-01-01T00:00:00Z', // createdAt: '2024-01-01T00:00:00Z',
updatedAt: '2024-01-01T00:00:00Z', // updatedAt: '2024-01-01T00:00:00Z',
}; // };
setRetailerDetails(dummyData); // setRetailerDetails(dummyData);
} catch (error) { } catch (error) {
console.error('Error fetching data: ', error); console.error('Error fetching data: ', error);
} }