diff --git a/src/_nav.js b/src/_nav.js
index 0d3c9ca..2e52e46 100644
--- a/src/_nav.js
+++ b/src/_nav.js
@@ -248,13 +248,13 @@ const _nav = [
group: "",
items: [
- // {
- // component: CNavItem,
- // name: "Testimonials",
- // icon: ,
- // to: "/testimonials",
- // group: "Website Related",
- // },
+ {
+ component: CNavItem,
+ name: "Transporter",
+ icon: ,
+ to: "/transporter",
+ group: "Transporter",
+ },
// {
// component: CNavItem,
diff --git a/src/routes.js b/src/routes.js
index fedd951..0c43088 100644
--- a/src/routes.js
+++ b/src/routes.js
@@ -169,6 +169,7 @@ import DistributorOpeningInventory from "./views/PrincipalDistributors/OpeningIn
import UploadOpeningInventory from "./views/PrincipalDistributors/UploadOpeningInventory";
import OpeningInventoryReports from "./views/Reports/OpeningInventoryReports";
import StockReports from "./views/Reports/StockReports ";
+import Transporter from "./views/Transporter/Transporter";
const routes = [
//dashboard
@@ -930,6 +931,14 @@ const routes = [
element: EditEmployee,
navName: "Employees & Access",
},
+
+ // Transporter
+ {
+ path: "transporter",
+ name: "Transporter",
+ element: Transporter,
+ navName: "Employees & Access",
+ },
];
export default routes;
diff --git a/src/views/Transporter/Transporter.js b/src/views/Transporter/Transporter.js
new file mode 100644
index 0000000..a52622b
--- /dev/null
+++ b/src/views/Transporter/Transporter.js
@@ -0,0 +1,537 @@
+import React, { useState, useEffect, useRef, useCallback } from "react";
+import axios from "axios";
+import { isAutheticated } from "src/auth";
+import {
+ Button,
+ Box,
+ IconButton,
+ Modal,
+ Pagination,
+ TextField,
+ Typography,
+} from "@mui/material";
+import CloseIcon from "@mui/icons-material/Close";
+import { ClipLoader } from "react-spinners";
+import swal from "sweetalert";
+import { toast } from "react-hot-toast";
+import debounce from "lodash.debounce";
+const style = {
+ position: "absolute",
+ top: "50%",
+ left: "50%",
+ transform: "translate(-50%, -50%)",
+ width: 400,
+ bgcolor: "background.paper",
+ borderRadius: "0.5rem",
+ boxShadow: 24,
+ width: "500px",
+};
+
+const Transporter = () => {
+ const token = isAutheticated();
+ const nameRef = useRef();
+ const [loading, setLoading] = useState(true);
+ const [updating, setUpdating] = useState(true);
+ const [saveLoding, setSaveLoading] = useState(true);
+ const [edit, setEdit] = useState(false);
+ const [transporterName, settransporterName] = useState("");
+ const [categoryId, setCategoryId] = useState("");
+ const [transporter, setTransporter] = useState([]);
+ const [itemPerPage, setItemPerPage] = useState(10);
+ const [page, setPage] = useState(1);
+ const [open, setOpen] = useState(false);
+ const [oldertransporterName, setOlderCategoruName] = useState("");
+
+ const handleOpen = () => setOpen(true);
+ const handleClose = () => {
+ setOpen(false);
+ // setUpdating(false);
+ setEdit(false);
+
+ settransporterName("");
+ setCategoryId("");
+ };
+
+ const getCategories = async () => {
+ try {
+ setLoading(true);
+ const response = await axios.get("/api/transporter/get", {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ }, // Include pagination and search
+ });
+
+ if (response.status === 200) {
+ setTransporter(response?.data?.transporters);
+ }
+ } catch (error) {
+ console.error("Failed to fetch brands:", error);
+ } finally {
+ setLoading(false); // Set loading to false after fetching
+ }
+ };
+
+ useEffect(() => {
+ getCategories();
+ }, []);
+
+ const handleEditClick = (_id, transporterName) => {
+ setOpen(true);
+ settransporterName(transporterName);
+ setCategoryId(_id);
+ setOlderCategoruName(transporterName);
+ setEdit(true);
+ // setUpdating(false);
+ };
+
+ const handleUpdate = async () => {
+ const filteredArrayNames = transporter
+ .filter(
+ (item) =>
+ item.transporterName.toLowerCase() !==
+ oldertransporterName.toLowerCase()
+ )
+ .map((item) => item.transporterName.toLowerCase());
+ // console.log(filteredArrayNames, "filter");
+ if (filteredArrayNames.includes(transporterName.toLowerCase())) {
+ swal({
+ title: "Warning",
+ text: "Transporter name already exists ",
+ icon: "error",
+ button: "Retry",
+ dangerMode: true,
+ });
+ }
+ if (!transporterName) {
+ swal({
+ title: "Warning",
+ text: "Please fill all the required fields!",
+ icon: "error",
+ button: "Retry",
+ dangerMode: true,
+ });
+ return;
+ }
+ setUpdating(false);
+ const formData = new FormData();
+ formData.append("transporterName", transporterName);
+ try {
+ await axios.patch(`/api/transporter/edit/${categoryId}`, formData, {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ },
+ });
+ handleClose();
+ toast.success("Transporter updated successfully");
+ getCategories();
+ } catch (err) {
+ swal({
+ title: "",
+ text: "Something went wrong!",
+ icon: "error",
+ button: "Retry",
+ dangerMode: true,
+ });
+ } finally {
+ setUpdating(true);
+ }
+ };
+
+ const handleDelete = (_id) => {
+ swal({
+ title: "Are you sure?",
+ icon: "error",
+ buttons: {
+ Yes: { text: "Yes", value: true },
+ Cancel: { text: "Cancel", value: "cancel" },
+ },
+ }).then(async (value) => {
+ if (value === true) {
+ try {
+ await axios.delete(`/api/transporter/delete/${_id}`, {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ },
+ });
+ toast.success("Transporter deleted successfully");
+ getCategories();
+ } catch (err) {
+ swal({
+ title: "",
+ text: "Something went wrong!",
+ icon: "error",
+ button: "Retry",
+ dangerMode: true,
+ });
+ }
+ }
+ });
+ };
+
+ const handleSaveCategory = async () => {
+ if (
+ transporter.some(
+ (item) =>
+ item.transporterName.toLowerCase() === transporterName.toLowerCase()
+ )
+ ) {
+ swal({
+ title: "Warning",
+ text: "Category already exists ",
+ icon: "error",
+ button: "Retry",
+ dangerMode: true,
+ });
+ return;
+ }
+ if (!transporterName) {
+ swal({
+ title: "Warning",
+ text: "Please fill all the required fields!",
+ icon: "error",
+ button: "Retry",
+ dangerMode: true,
+ });
+ return;
+ }
+ setSaveLoading(false);
+ setLoading(true);
+ const formData = new FormData();
+ formData.append("transporterName", transporterName);
+ try {
+ await axios.post("/api/transporter/add", formData, {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ "Content-Type": "multipart/formdata",
+ },
+ });
+ handleClose();
+ toast.success("Transpoter added successfully");
+ getCategories();
+ } catch (err) {
+ swal({
+ title: "",
+ text: "Something went wrong!",
+ icon: "error",
+ button: "Retry",
+ dangerMode: true,
+ });
+ } finally {
+ setSaveLoading(true);
+ }
+ };
+ const getPageCount = () => {
+ return Math.max(1, Math.ceil(transporter.length / itemPerPage));
+ };
+ const debouncedSearch = useCallback(
+ debounce(() => {
+ setPage(1);
+ getCategories();
+ }, 500),
+ []
+ );
+
+ const handleSearchChange = () => {
+ debouncedSearch();
+ };
+ return (
+
+
+
+
+
+
+
+ Transporter
+
+
+
+
+
+
+
+
+ Transporter name
+
+ handleClose()}>
+
+
+
+
+
+ settransporterName(
+ e.target.value.charAt(0).toUpperCase() +
+ e.target.value.slice(1)
+ )
+ }
+ />
+ {transporterName ? (
+ <>
+
+ {25 - transporterName.length} characters left
+
+ >
+ ) : (
+ <>>
+ )}
+
+
+ {!edit && (
+
+ )}
+ {edit && (
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/*
+
+
+
*/}
+
+
+
+
+
+
+ Transporter Name |
+
+ Action |
+
+
+
+ {!loading && transporter.length === 0 && (
+
+
+ No Data Available
+ |
+
+ )}
+ {loading ? (
+
+
+ Loading...
+ |
+
+ ) : (
+ transporter &&
+ transporter
+ .slice(
+ (`${page}` - 1) * itemPerPage,
+ `${page}` * itemPerPage
+ )
+ .map((item, i) => (
+
+
+ {item.transporterName}
+ |
+
+
+
+ |
+
+ ))
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default Transporter;
diff --git a/src/views/orders/ViewOrders.js b/src/views/orders/ViewOrders.js
index 5caec2d..bde6f35 100644
--- a/src/views/orders/ViewOrders.js
+++ b/src/views/orders/ViewOrders.js
@@ -17,7 +17,10 @@ import {
DialogContentText,
DialogTitle,
TextField,
- Divider, InputLabel, Select, MenuItem
+ Divider,
+ InputLabel,
+ Select,
+ MenuItem,
} from "@mui/material";
import onvoicesData from "../../assets/incoicedata.json";
import { useNavigate, useParams } from "react-router-dom";
@@ -340,8 +343,8 @@ const ViewOrders = () => {
{
}}
/>
- {item?.name}
+ {item.productId.name}
- ₹{item.price.toFixed(2)}
- {item.quantity}
- ₹{subtotal.toFixed(2)}
+ ₹{item.price}
+
+ {item.quantity}
+
+ ₹{subtotal}
{item.GST}%
- ₹{gstAmount.toFixed(2)}
- ₹{totalWithGST.toFixed(2)}
+ ₹{gstAmount}
+ ₹{totalWithGST}
);
})}
@@ -370,7 +375,8 @@ const ViewOrders = () => {
<>
{" "}
- Order Items {order?.status=="pending"?"to be Processed":"Cancelled"}
+ Order Items{" "}
+ {order?.status == "pending" ? "to be Processed" : "Cancelled"}
>
@@ -394,10 +400,10 @@ const ViewOrders = () => {
Total Items: {order?.orderItem.length}
- Total Subtotal: ₹{order?.subtotal.toFixed(2)}
- Total GST: ₹{order?.gstTotal.toFixed(2)}
+ Total Subtotal: ₹{order?.subtotal}
+ Total GST: ₹{order?.gstTotal}
- Grand Total: ₹{order?.grandTotal.toFixed(2)}
+ Grand Total: ₹{order?.grandTotal}
diff --git a/src/views/orders/viewInoices.js b/src/views/orders/viewInoices.js
index 9a3a92d..97ad16b 100644
--- a/src/views/orders/viewInoices.js
+++ b/src/views/orders/viewInoices.js
@@ -19,6 +19,9 @@ import {
TextField,
Divider,
Chip,
+ InputLabel,
+ Select,
+ MenuItem,
} from "@mui/material";
import onvoicesData from "../../assets/incoicedata.json";
import { useNavigate, useParams } from "react-router-dom";
@@ -58,7 +61,7 @@ const ViewInvoices = () => {
Authorization: `Bearer ${token}`,
},
});
- // console.log(response);
+ console.log(response);
setInvoice(response.data);
setStatus(response.data.courierStatus);
@@ -139,6 +142,31 @@ const ViewInvoices = () => {
setOpenDispatchDialog(false);
setOpenDeliveredDialog(false); // Close delivered dialog
};
+ const [transporterName, setTransporterName] = useState("");
+ const [transporter, setTransporter] = useState([]);
+ // Get order ID from URL params
+ const getCategories = async () => {
+ try {
+ setLoading(true);
+ const response = await axios.get("/api/transporter/get", {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ }, // Include pagination and search
+ });
+
+ if (response.status === 200) {
+ setTransporter(response?.data?.transporters);
+ }
+ } catch (error) {
+ console.error("Failed to fetch brands:", error);
+ } finally {
+ setLoading(false); // Set loading to false after fetching
+ }
+ };
+
+ useEffect(() => {
+ getCategories();
+ }, []);
if (loading) {
return Loading...;
@@ -188,27 +216,27 @@ const ViewInvoices = () => {
-
- {invoice.invoiceId}
+
+ {invoice?.invoiceId}
- {invoice.items.map((item) => (
+ {invoice?.items?.map((item) => (
- {item.name} ({item.SKU}) x{" "}
- {item.processquantity}
+ {item?.name} ({item?.SKU}) x{" "}
+ {item?.processquantity}
))}
- ₹{invoice.subtotal.toFixed(2)}
- ₹{invoice.gstTotal.toFixed(2)}
- ₹{invoice.invoiceAmount.toFixed(2)}
+ ₹{invoice?.subtotal.toFixed(2)}
+ ₹{invoice?.gstTotal.toFixed(2)}
+ ₹{invoice?.invoiceAmount.toFixed(2)}
{
Total Items: {invoice?.items.length}
Total Subtotal: ₹{invoice?.subtotal}
- Total GST: ₹{invoice?.gstTotal}
+
+ Total GST: ₹{invoice?.gstTotal.toFixed(2)}
+
Grand Total: ₹{invoice?.invoiceAmount}
@@ -431,28 +461,35 @@ const ViewInvoices = () => {