From 9f650d157e38bf1f4b7fd45d3a0a7a659b564c7e Mon Sep 17 00:00:00 2001 From: Sibunnayak Date: Mon, 30 Sep 2024 16:42:25 +0530 Subject: [PATCH] rd totalorder and order view ui created --- .../singlePrincipalDistributorAllDetails.js | 130 +++-- .../RetailDistributors/RetailDistributor.js | 6 +- .../SingleRetailDistributor.js | 463 +++++++++++++++--- 3 files changed, 468 insertions(+), 131 deletions(-) diff --git a/src/views/PrincipalDistributors/singlePrincipalDistributorAllDetails.js b/src/views/PrincipalDistributors/singlePrincipalDistributorAllDetails.js index 8f23162..2dcd7f2 100644 --- a/src/views/PrincipalDistributors/singlePrincipalDistributorAllDetails.js +++ b/src/views/PrincipalDistributors/singlePrincipalDistributorAllDetails.js @@ -38,7 +38,7 @@ const SinglePrincipalDistributorAllDetails = () => { const [orders, setOrders] = useState([]); const [totalOrders, setTotalOrders] = useState(0); const [page, setPage] = useState(0); - const [rowsPerPage, setRowsPerPage] = useState(10); + const [rowsPerPage, setRowsPerPage] = useState(5); const [loading, setLoading] = useState(true); const [searchField, setSearchField] = useState("Order ID"); const [searchText, setSearchText] = useState(""); @@ -56,8 +56,15 @@ const SinglePrincipalDistributorAllDetails = () => { ).current; const handleSearchFieldChange = (event) => { - setSearchField(event.target.value); + const newSearchField = event.target.value; + setSearchField(newSearchField); setSearchText(""); + + if (newSearchField === "Order ID") { + searchStatusRef.current = ""; + } else { + searchOrderIdRef.current = ""; + } }; const handleSearchChange = (event) => { @@ -67,9 +74,10 @@ const SinglePrincipalDistributorAllDetails = () => { } else { searchStatusRef.current = event.target.value; } - // Call the debounced function to fetch orders + // Reset page to 0 and fetch orders with the new search term + setPage(0); fetchOrdersDebounced( - page + 1, + 1, rowsPerPage, searchOrderIdRef.current, searchStatusRef.current @@ -86,19 +94,21 @@ const SinglePrincipalDistributorAllDetails = () => { // Function to fetch order details const fetchOrderDetails = async (id) => { try { - const response = await axios.get(`/api/get-single-placed-order-pd/${id}`, { - headers: { - Authorization: `Bearer ${token}`, - }, - }); + const response = await axios.get( + `/api/get-single-placed-order-pd/${id}`, + { + headers: { + Authorization: `Bearer ${token}`, + }, + } + ); setSingleOrder(response.data?.singleOrder); - setOpenTMModal(true); + setOpenTMModal(true); } catch (error) { - console.error('Error fetching order details:', error); - + console.error("Error fetching order details:", error); } }; - + // Fetch Shipping address of the individual user const getUserAddress = useCallback(async () => { try { @@ -163,63 +173,49 @@ const SinglePrincipalDistributorAllDetails = () => { }, [_id, token]); // Fetch Orders with Pagination, Order ID, and Status search - const fetchOrders = useCallback(async () => { - setLoading(true); - try { - const response = await axios.get(`/api/single-pd-order/${_id}`, { - headers: { - Authorization: `Bearer ${token}`, - }, - params: { - page: page + 1, - limit: rowsPerPage, - orderId: searchOrderIdRef.current, - status: searchStatusRef.current, - }, - }); - setOrders(response.data.orders || []); - setTotalOrders(response.data.totalOrders || 0); - } catch (error) { - swal({ - title: "Warning", - text: error.message, - icon: "error", - button: "Close", - dangerMode: true, - }); - } finally { - setLoading(false); - } - }, [_id, token, page, rowsPerPage]); + const fetchOrders = useCallback( + async (page = 1, limit = rowsPerPage, orderId = "", status = "") => { + setLoading(true); + try { + const response = await axios.get(`/api/single-pd-order/${_id}`, { + headers: { Authorization: `Bearer ${token}` }, + params: { page, limit, orderId, status }, + }); + setOrders(response.data.orders || []); + setTotalOrders(response.data.totalOrders || 0); + } catch (error) { + swal({ + title: "Warning", + text: error.message, + icon: "error", + button: "Close", + dangerMode: true, + }); + } finally { + setLoading(false); + } + }, + [_id, token, rowsPerPage] + ); useEffect(() => { getOrdersCount(); getUserAddress(); getUserDetails(); - fetchOrders(); - }, [_id, getOrdersCount, getUserAddress, getUserDetails, fetchOrders]); + }, [_id, getOrdersCount, getUserAddress, getUserDetails]); + useEffect(() => { + fetchOrders(page + 1, rowsPerPage, searchOrderIdRef.current, searchStatusRef.current); + }, [page, rowsPerPage]); const handleChangePage = (event, newPage) => { setPage(newPage); - // Fetch orders whenever page changes - fetchOrdersDebounced( - newPage + 1, - rowsPerPage, - searchOrderIdRef.current, - searchStatusRef.current - ); }; + // Handle rows per page change const handleChangeRowsPerPage = (event) => { - setRowsPerPage(parseInt(event.target.value)); + const newRowsPerPage = parseInt(event.target.value, 10); + setRowsPerPage(newRowsPerPage); setPage(0); - // Fetch orders with the new rows per page setting - fetchOrdersDebounced( - 1, - parseInt(event.target.value), - searchOrderIdRef.current, - searchStatusRef.current - ); }; return (
@@ -463,7 +459,7 @@ const SinglePrincipalDistributorAllDetails = () => { {/* Pagination */} { {singleorder?.invoices?.length > 0 && ( <> - Order Items {singleorder?.status=="pending"?"to be Processed":"Cancelled"} + Order Items{" "} + {singleorder?.status == "pending" + ? "to be Processed" + : "Cancelled"} @@ -575,15 +574,4 @@ const SinglePrincipalDistributorAllDetails = () => {
); }; -// Helper function to format time as AM/PM -const formatAMPM = (date) => { - var hours = new Date(date).getHours(); - var minutes = new Date(date).getMinutes(); - var ampm = hours >= 12 ? "PM" : "AM"; - hours = hours % 12; - hours = hours ? hours : 12; - minutes = minutes < 10 ? "0" + minutes : minutes; - var strTime = hours + ":" + minutes + " " + ampm; - return strTime; -}; export default SinglePrincipalDistributorAllDetails; diff --git a/src/views/RetailDistributors/RetailDistributor.js b/src/views/RetailDistributors/RetailDistributor.js index 439faef..6897e6d 100644 --- a/src/views/RetailDistributors/RetailDistributor.js +++ b/src/views/RetailDistributors/RetailDistributor.js @@ -24,7 +24,7 @@ const [totalPages, setTotalPages] = useState(1); const getRetailDistributorsData = async () => { setLoading(true); try { - const res = await axios.get(`/api/getAllRD`, { + const res = await axios.get(`/api/getAllRDandorder`, { headers: { Authorization: `Bearer ${token}`, }, @@ -158,6 +158,7 @@ const [totalPages, setTotalPages] = useState(1); Territory Manager Sales Coordinator Mapping + Orders Action @@ -217,6 +218,9 @@ const [totalPages, setTotalPages] = useState(1); + + {retailDistributor?.totalOrders} + { const { id } = useParams(); const [retailerDetails, setRetailerDetails] = useState(null); const [openPopup, setOpenPopup] = useState(false); - const [selectedImage, setSelectedImage] = useState(''); + const [selectedImage, setSelectedImage] = useState(""); + const [orders, setOrders] = useState([]); + const [totalOrders, setTotalOrders] = useState(0); + const [page, setPage] = useState(0); + const [rowsPerPage, setRowsPerPage] = useState(5); + const [loading, setLoading] = useState(true); + const [searchField, setSearchField] = useState("Order ID"); + const [searchText, setSearchText] = useState(""); const token = isAutheticated(); const navigate = useNavigate(); + const searchOrderIdRef = useRef(""); + const searchStatusRef = useRef(""); + // Debounced function to fetch orders + const fetchOrdersDebounced = useRef( + debounce((page, limit, orderId, status) => { + fetchOrders(page, limit, orderId, status); + }, 500) + ).current; + + const handleSearchFieldChange = (event) => { + const newSearchField = event.target.value; + setSearchField(newSearchField); + + setSearchText(""); + + if (newSearchField === "Order ID") { + searchStatusRef.current = ""; + } else { + searchOrderIdRef.current = ""; + } + }; + + +// When search text is typed +const handleSearchChange = (event) => { + setSearchText(event.target.value); + if (searchField === "Order ID") { + searchOrderIdRef.current = event.target.value; + } else { + searchStatusRef.current = event.target.value; + } + + // Reset page to 0 and fetch orders with the new search term + setPage(0); + fetchOrdersDebounced(1, rowsPerPage, searchOrderIdRef.current, searchStatusRef.current); +}; + const [openOrderModal, setopenOrderModal] = useState(false); + const [singleorder, setSingleOrder] = useState(null); + + const handleCloseTMModal = () => { + setopenOrderModal(false); + setSingleOrder(null); // Clear the order details when closing the modal + }; + // Function to fetch order details + const fetchOrderDetails = async (id) => { + try { + const response = await axios.get( + `/api/get-single-placed-order-rd/${id}`, + { + headers: { + Authorization: `Bearer ${token}`, + }, + } + ); + setSingleOrder(response.data?.singleOrder); + setopenOrderModal(true); + } catch (error) { + console.error("Error fetching order details:", error); + } + }; + const getUserDetails = useCallback(async () => { + try { + // Commented out the API call and using dummy data + const response = await axios.get(`/api/getRD/${id}`, { + headers: { + "Access-Control-Allow-Origin": "*", + Authorization: `Bearer ${token}`, + "Content-Type": "multipart/form-data", + }, + }); + setRetailerDetails(response.data); + // console.log('Retailer Details: ', response.data); + } catch (error) { + console.error("Error fetching data: ", error); + } + }, [id, token]); + // Fetch Orders with Pagination, Order ID, and Status search + const fetchOrders = useCallback( + async (page = 1, limit = rowsPerPage, orderId = "", status = "") => { + setLoading(true); + try { + const response = await axios.get(`/api/single-rd-order/${id}`, { + headers: { Authorization: `Bearer ${token}` }, + params: { page, limit, orderId, status }, + }); + setOrders(response.data.orders || []); + setTotalOrders(response.data.totalOrders || 0); + } catch (error) { + swal({ + title: "Warning", + text: error.message, + icon: "error", + button: "Close", + dangerMode: true, + }); + } finally { + setLoading(false); + } + }, + [id, token, rowsPerPage] + ); useEffect(() => { - const fetchData = async () => { - try { - // Commented out the API call and using dummy data - const response = await axios.get(`/api/getRD/${id}`, { - headers: { - 'Access-Control-Allow-Origin': '*', - Authorization: `Bearer ${token}`, - 'Content-Type': 'multipart/form-data', - }, - }); - setRetailerDetails(response.data); - // console.log('Retailer Details: ', response.data); - } catch (error) { - console.error('Error fetching data: ', error); - } - }; + fetchOrders(page + 1, rowsPerPage, searchOrderIdRef.current, searchStatusRef.current); + }, [page, rowsPerPage]); - fetchData(); - }, [id]); +// Fetch retailer details on mount +useEffect(() => { + getUserDetails(); +}, [id, getUserDetails]); const handleOpenPopup = (imageUrl) => { setSelectedImage(imageUrl); @@ -42,25 +165,40 @@ const SingleRetailDistributor = () => { const handleClosePopup = () => { setOpenPopup(false); - setSelectedImage(''); + setSelectedImage(""); }; const handleCancel = () => { - navigate('/retail-distributor'); + navigate("/retail-distributor"); }; if (!retailerDetails) { return Loading...; } +// Handle page change +const handleChangePage = (event, newPage) => { + setPage(newPage); +}; + +// Handle rows per page change +const handleChangeRowsPerPage = (event) => { + const newRowsPerPage = parseInt(event.target.value, 10); + setRowsPerPage(newRowsPerPage); + setPage(0); +}; return ( - + Retailer Details - + Cancel @@ -98,7 +236,8 @@ const SingleRetailDistributor = () => { Mobile Number: {retailerDetails.mobile_number} - Mapped Principal Distributor: {retailerDetails?.principal_distributer?.name || 'Not Mapped'} + Mapped Principal Distributor:{" "} + {retailerDetails?.principal_distributer?.name || "Not Mapped"} @@ -116,17 +255,20 @@ const SingleRetailDistributor = () => { handleOpenPopup(retailerDetails.kyc.pan_img.url)} /> - Aadhar Number: {retailerDetails.kyc.aadhar_number} + Aadhar Number:{" "} + {retailerDetails.kyc.aadhar_number} handleOpenPopup(retailerDetails.kyc.aadhar_img.url)} + sx={{ width: 100, height: 100, mb: 2, cursor: "pointer" }} + onClick={() => + handleOpenPopup(retailerDetails.kyc.aadhar_img.url) + } /> GST Number: {retailerDetails.kyc.gst_number} @@ -134,7 +276,7 @@ const SingleRetailDistributor = () => { handleOpenPopup(retailerDetails.kyc.gst_img.url)} /> @@ -145,8 +287,10 @@ const SingleRetailDistributor = () => { handleOpenPopup(retailerDetails.kyc.pesticide_license_img.url)} + sx={{ width: 100, height: 100, mb: 2, cursor: "pointer" }} + onClick={() => + handleOpenPopup(retailerDetails.kyc.pesticide_license_img.url) + } /> Fertilizer License (optional): @@ -155,8 +299,12 @@ const SingleRetailDistributor = () => { handleOpenPopup(retailerDetails.kyc.fertilizer_license_img.url)} + sx={{ width: 100, height: 100, mb: 2, cursor: "pointer" }} + onClick={() => + handleOpenPopup( + retailerDetails.kyc.fertilizer_license_img.url + ) + } /> ) : ( Img not available @@ -167,8 +315,10 @@ const SingleRetailDistributor = () => { handleOpenPopup(retailerDetails.kyc.selfie_entrance_img.url)} + sx={{ width: 100, height: 100, mb: 2, cursor: "pointer" }} + onClick={() => + handleOpenPopup(retailerDetails.kyc.selfie_entrance_img.url) + } /> @@ -181,22 +331,217 @@ const SingleRetailDistributor = () => { - Designation: {retailerDetails?.userType|| 'Not Available'} + Designation:{" "} + {retailerDetails?.userType || "Not Available"} - Name: {retailerDetails?.addedBy?.name || 'Not Available'} + Name:{" "} + {retailerDetails?.addedBy?.name || "Not Available"} - ID: {retailerDetails?.addedBy?.uniqueId || 'Not Available'} + ID:{" "} + {retailerDetails?.addedBy?.uniqueId || "Not Available"} + + {/*
*/} + + Orders + + + + + Search By + + + + + + + + + Order ID + Order Date + Items + Order Value + Status + Action + + + + {loading ? ( + + + Loading... + + + ) : orders.length === 0 ? ( + + + No Orders Found + + + ) : ( + orders.map((order) => ( + + {order.uniqueId} + + {new Date(order.createdAt).toLocaleString()} + + {order.orderItem.length} + ₹ {order.grandTotal} + {order.status} + + + + + )) + )} + +
+
+ {/* Pagination */} + + + Order Details + Order Id : {singleorder?.uniqueId} + + {singleorder?.invoices?.length > 0 && ( + <> + + Invoices + + + + )} + + Order Summary + - + + + + + + + Product + Price (₹) + Quantity + Subtotal (₹) + GST (%) + GST Amount (₹) + + Total with GST (₹) + + + + + {singleorder?.orderItem.map((item, index) => { + const subtotal = item.price * item.quantity; + const gstAmount = + ((item.GST * item.price) / 100) * item.quantity; + const totalWithGST = subtotal + gstAmount; + + return ( + + + {item.productId.name} + + {item.productId.name} + + + ₹{item.price} + + {item.quantity} + + ₹{subtotal} + {item.GST}% + ₹{gstAmount} + + ₹{totalWithGST} + + + ); + })} + +
+
+
+
+ {singleorder?.invoices?.length > 0 && ( + <> + + Order Items{" "} + {singleorder?.status == "pending" + ? "to be Processed" + : "Cancelled"} + + + + )} +
+ + + +
+
+ {/*
*/} +
+ @@ -204,22 +549,22 @@ const SingleRetailDistributor = () => { Large Preview