Merge branch 'master' of https://github.com/cheminova2024/cheminova-admin
This commit is contained in:
commit
9654247d77
12
src/_nav.js
12
src/_nav.js
@ -54,16 +54,16 @@ const _nav = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: CNavItem,
|
component: CNavItem,
|
||||||
name: "Products",
|
name: "Brands",
|
||||||
icon: <CIcon icon={cilClipboard} customClassName="nav-icon" />,
|
icon: <CIcon icon={cilCat} customClassName="nav-icon" />,
|
||||||
to: "/products",
|
to: "/brands",
|
||||||
group: "Product Management",
|
group: "Product Management",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: CNavItem,
|
component: CNavItem,
|
||||||
name: "GST",
|
name: "Products",
|
||||||
icon: <CIcon icon={cilTablet} customClassName="nav-icon" />,
|
icon: <CIcon icon={cilClipboard} customClassName="nav-icon" />,
|
||||||
to: "/tax",
|
to: "/products",
|
||||||
group: "Product Management",
|
group: "Product Management",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -42,10 +42,6 @@ import DeliveredOrders from "./views/orders/DeliveredOrders.js";
|
|||||||
import CancelledOrders from "./views/orders/CancelledOrders.js";
|
import CancelledOrders from "./views/orders/CancelledOrders.js";
|
||||||
import ReturnedOrders from "./views/orders/ReturnedOrders.js";
|
import ReturnedOrders from "./views/orders/ReturnedOrders.js";
|
||||||
import AddOrder from "./views/orders/AddOrder";
|
import AddOrder from "./views/orders/AddOrder";
|
||||||
//Taxes
|
|
||||||
import Tax from "./views/configuration/tax/Tax";
|
|
||||||
import Addtax from "./views/configuration/tax/Addtax";
|
|
||||||
import Edittax from "./views/configuration/tax/Edittax";
|
|
||||||
import EditOrder from "./views/orders/EditOrder";
|
import EditOrder from "./views/orders/EditOrder";
|
||||||
import ViewOrders from "./views/orders/ViewOrders";
|
import ViewOrders from "./views/orders/ViewOrders";
|
||||||
import Departures from "./views/Departures/Departures";
|
import Departures from "./views/Departures/Departures";
|
||||||
@ -81,6 +77,7 @@ import AddNewAppointment from "./views/Appointments/AddNewAppointment";
|
|||||||
import Campaign from "./views/Campaigns/Campaign.js";
|
import Campaign from "./views/Campaigns/Campaign.js";
|
||||||
import AddCampaign from "./views/Campaigns/AddCampaign.js";
|
import AddCampaign from "./views/Campaigns/AddCampaign.js";
|
||||||
import Categories from "./views/Categories/categories";
|
import Categories from "./views/Categories/categories";
|
||||||
|
import Brands from "./views/Brands/Brands";
|
||||||
import Content from "./views/Content/content";
|
import Content from "./views/Content/content";
|
||||||
|
|
||||||
import EditPrivacyPolicy from "./views/Content/editPrivacyPolicy";
|
import EditPrivacyPolicy from "./views/Content/editPrivacyPolicy";
|
||||||
@ -199,6 +196,12 @@ const routes = [
|
|||||||
element: Categories,
|
element: Categories,
|
||||||
navName: "Product Management",
|
navName: "Product Management",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/brands",
|
||||||
|
name: "Brands",
|
||||||
|
element: Brands,
|
||||||
|
navName: "Product Management",
|
||||||
|
},
|
||||||
//SalesCoOrdinator
|
//SalesCoOrdinator
|
||||||
{
|
{
|
||||||
path: "/salescoordinator/edit/:id",
|
path: "/salescoordinator/edit/:id",
|
||||||
@ -287,25 +290,6 @@ const routes = [
|
|||||||
element: SingleUserleave,
|
element: SingleUserleave,
|
||||||
navName: "Leaves",
|
navName: "Leaves",
|
||||||
},
|
},
|
||||||
//Gst tax
|
|
||||||
{
|
|
||||||
path: "/tax",
|
|
||||||
name: "Tax Rates",
|
|
||||||
element: Tax,
|
|
||||||
navName: "Product Management",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/tax/add",
|
|
||||||
name: "Add Tax",
|
|
||||||
element: Addtax,
|
|
||||||
navName: "Product Management",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/tax/edit/:id",
|
|
||||||
name: "Edit Tax",
|
|
||||||
element: Edittax,
|
|
||||||
navName: "Product Management",
|
|
||||||
},
|
|
||||||
// RetailDistributor
|
// RetailDistributor
|
||||||
{
|
{
|
||||||
path: "/retail-distributor",
|
path: "/retail-distributor",
|
||||||
|
460
src/views/Brands/Brands.js
Normal file
460
src/views/Brands/Brands.js
Normal file
@ -0,0 +1,460 @@
|
|||||||
|
import React, { useState, useEffect } 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";
|
||||||
|
|
||||||
|
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 Brands = () => {
|
||||||
|
const token = isAutheticated();
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [updating, setUpdating] = useState(true);
|
||||||
|
const [saveLoding, setSaveLoading] = useState(true);
|
||||||
|
const [edit, setEdit] = useState(false);
|
||||||
|
const [brandName, setbrandName] = useState("");
|
||||||
|
const [brandId, setbrandId] = useState("");
|
||||||
|
const [brand, setbrand] = useState([]);
|
||||||
|
const [itemPerPage, setItemPerPage] = useState(10);
|
||||||
|
const [page, setPage] = useState(1);
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const [olderbrandName, setOlderBrandName] = useState("");
|
||||||
|
|
||||||
|
|
||||||
|
const handleOpen = () => setOpen(true);
|
||||||
|
const handleClose = () => {
|
||||||
|
setOpen(false);
|
||||||
|
setEdit(false);
|
||||||
|
setbrandName("");
|
||||||
|
setbrandId("");
|
||||||
|
};
|
||||||
|
|
||||||
|
const getBrands = async () => {
|
||||||
|
try {
|
||||||
|
const response = await axios.get("/api/brand/getBrands");
|
||||||
|
if (response.status === 200) {
|
||||||
|
setbrand(response.data.brands);
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to fetch brands:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getBrands();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleEditClick = (_id, brandName) => {
|
||||||
|
setOpen(true);
|
||||||
|
setbrandName(brandName);
|
||||||
|
setbrandId(_id);
|
||||||
|
setOlderBrandName(brandName);
|
||||||
|
setEdit(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleUpdate = async () => {
|
||||||
|
const filteredBrandNames = brand
|
||||||
|
.filter((brand) => brand.brandName.toLowerCase() !== olderbrandName.toLowerCase())
|
||||||
|
.map((brand) => brand.brandName.toLowerCase());
|
||||||
|
|
||||||
|
if (filteredBrandNames.includes(brandName.toLowerCase())) {
|
||||||
|
swal("Warning", "Brand already exists", "error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!brandName) {
|
||||||
|
swal("Warning", "Please fill all the required fields!", "error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setUpdating(false);
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("brandName", brandName);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await axios.patch(`/api/brand/update/${brandId}`, formData, {
|
||||||
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
|
});
|
||||||
|
handleClose();
|
||||||
|
swal("Success", "The brand was updated successfully!", "success");
|
||||||
|
getBrands();
|
||||||
|
} catch (err) {
|
||||||
|
swal("Error", "Failed to update brand", "error");
|
||||||
|
} finally {
|
||||||
|
setUpdating(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDelete = (_id) => {
|
||||||
|
swal({
|
||||||
|
title: "Are you sure?",
|
||||||
|
icon: "warning",
|
||||||
|
buttons: {
|
||||||
|
Yes: { text: "Yes", value: true },
|
||||||
|
Cancel: { text: "Cancel", value: "cancel" },
|
||||||
|
},
|
||||||
|
}).then(async (value) => {
|
||||||
|
if (value === true) {
|
||||||
|
try {
|
||||||
|
await axios.delete(`/api/brand/delete/${_id}`, {
|
||||||
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
|
});
|
||||||
|
swal("Success", "The brand was deleted successfully!", "success");
|
||||||
|
getBrands();
|
||||||
|
} catch (err) {
|
||||||
|
swal("Error", "Failed to delete brand", "error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSavebrand = async () => {
|
||||||
|
if (brand.some((brand) => brand.brandName.toLowerCase() === brandName.toLowerCase())) {
|
||||||
|
swal("Warning", "Brand already exists.", "error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!brandName) {
|
||||||
|
swal("Warning", "Please fill all the required fields!", "error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setSaveLoading(false);
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("brandName", brandName);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await axios.post("/api/brand/add", formData, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
"Content-Type": "multipart/formdata",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
handleClose();
|
||||||
|
swal("Success", "New brand added successfully!", "success");
|
||||||
|
getBrands();
|
||||||
|
} catch (error) {
|
||||||
|
swal("Error", "Failed to add brand", "error");
|
||||||
|
} finally {
|
||||||
|
setSaveLoading(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getPageCount = () => Math.max(1, Math.ceil(brand.length / itemPerPage));
|
||||||
|
|
||||||
|
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">
|
||||||
|
Brands
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="page-title-right">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
style={{
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginBottom: "1rem",
|
||||||
|
textTransform: "capitalize",
|
||||||
|
}}
|
||||||
|
onClick={handleOpen}
|
||||||
|
// onClick={() => {
|
||||||
|
// navigate("/testimonial/new", { replace: true });
|
||||||
|
// }}
|
||||||
|
>
|
||||||
|
Add New brand
|
||||||
|
</Button>
|
||||||
|
<Modal
|
||||||
|
open={open}
|
||||||
|
onClose={handleClose}
|
||||||
|
aria-labelledby="modal-modal-title"
|
||||||
|
aria-describedby="modal-modal-description"
|
||||||
|
>
|
||||||
|
<Box sx={style}>
|
||||||
|
<Box p={2} display={"flex"}>
|
||||||
|
<Typography
|
||||||
|
id="modal-modal-title"
|
||||||
|
variant="body"
|
||||||
|
component="h2"
|
||||||
|
flex={1}
|
||||||
|
>
|
||||||
|
Brand Name
|
||||||
|
</Typography>
|
||||||
|
<IconButton onClick={() => handleClose()}>
|
||||||
|
<CloseIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Box>
|
||||||
|
<hr />
|
||||||
|
<TextField
|
||||||
|
placeholder="brand name"
|
||||||
|
value={brandName}
|
||||||
|
fullWidth
|
||||||
|
inputProps={{
|
||||||
|
maxLength: 25,
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
padding: "1rem",
|
||||||
|
}}
|
||||||
|
onChange={(e) =>
|
||||||
|
setbrandName(
|
||||||
|
e.target.value.charAt(0).toUpperCase() +
|
||||||
|
e.target.value.slice(1)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
{brandName ? (
|
||||||
|
<>
|
||||||
|
<small className="charLeft mt-2 ml-3 fst-italic">
|
||||||
|
{25 - brandName.length} characters left
|
||||||
|
</small>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Box
|
||||||
|
p={2}
|
||||||
|
display={"flex"}
|
||||||
|
justifyContent={"right"}
|
||||||
|
// width={"500px"}
|
||||||
|
>
|
||||||
|
{!edit && (
|
||||||
|
<button
|
||||||
|
style={{
|
||||||
|
color: "white",
|
||||||
|
marginRight: "1rem",
|
||||||
|
}}
|
||||||
|
onClick={() => handleSavebrand()}
|
||||||
|
type="button"
|
||||||
|
className="
|
||||||
|
btn btn-primary btn-sm
|
||||||
|
waves-effect waves-light
|
||||||
|
btn-table
|
||||||
|
mx-1
|
||||||
|
mt-1
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<ClipLoader loading={!saveLoding} size={18} />
|
||||||
|
{saveLoding && "Save"}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
{edit && (
|
||||||
|
<button
|
||||||
|
style={{
|
||||||
|
color: "white",
|
||||||
|
marginRight: "1rem",
|
||||||
|
}}
|
||||||
|
onClick={() => handleUpdate()}
|
||||||
|
type="button"
|
||||||
|
className="
|
||||||
|
btn btn-primary btn-sm
|
||||||
|
waves-effect waves-light
|
||||||
|
btn-table
|
||||||
|
mx-1
|
||||||
|
mt-1
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<ClipLoader loading={!updating} size={18} />
|
||||||
|
{updating && "update"}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
<button
|
||||||
|
style={{
|
||||||
|
color: "black",
|
||||||
|
marginRight: "1rem",
|
||||||
|
background: "grey",
|
||||||
|
}}
|
||||||
|
onClick={() => setOpen(false)}
|
||||||
|
type="button"
|
||||||
|
className="
|
||||||
|
btn btn-sm
|
||||||
|
waves-effect waves-light
|
||||||
|
btn-table
|
||||||
|
mx-1
|
||||||
|
mt-1
|
||||||
|
"
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Modal>
|
||||||
|
</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-sm-12 col-md-12">
|
||||||
|
<div className="dataTables_length">
|
||||||
|
<label className="w-100">
|
||||||
|
Show
|
||||||
|
<select
|
||||||
|
style={{ width: "10%" }}
|
||||||
|
onChange={(e) => setItemPerPage(e.target.value)}
|
||||||
|
className="
|
||||||
|
select-w
|
||||||
|
custom-select custom-select-sm
|
||||||
|
form-control form-control-sm
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<div className="table-responsive table-shoot mt-3">
|
||||||
|
<table
|
||||||
|
className="table table-centered table-nowrap"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
<thead
|
||||||
|
className="thead-info"
|
||||||
|
style={{ background: "rgb(140, 213, 213)" }}
|
||||||
|
>
|
||||||
|
<tr>
|
||||||
|
|
||||||
|
<th> Brand Name</th>
|
||||||
|
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{!loading && brand.length === 0 && (
|
||||||
|
<tr className="text-center">
|
||||||
|
<td colSpan="6">
|
||||||
|
<h5>No Data Available</h5>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
{loading ? (
|
||||||
|
<tr>
|
||||||
|
<td className="text-center" colSpan="6">
|
||||||
|
Loading...
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
) : (
|
||||||
|
brand &&
|
||||||
|
brand
|
||||||
|
.slice(
|
||||||
|
(`${page}` - 1) * itemPerPage,
|
||||||
|
`${page}` * itemPerPage
|
||||||
|
)
|
||||||
|
.map((item, i) => (
|
||||||
|
<tr key={i}>
|
||||||
|
<td>
|
||||||
|
<h5>{item.brandName} </h5>
|
||||||
|
</td>
|
||||||
|
<td className="text-start">
|
||||||
|
<button
|
||||||
|
style={{
|
||||||
|
color: "white",
|
||||||
|
marginRight: "1rem",
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
className="
|
||||||
|
btn btn-primary btn-sm
|
||||||
|
waves-effect waves-light
|
||||||
|
btn-table
|
||||||
|
mx-1
|
||||||
|
mt-1
|
||||||
|
"
|
||||||
|
onClick={() =>
|
||||||
|
handleEditClick(
|
||||||
|
item._id,
|
||||||
|
item.brandName,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Edit
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
style={{
|
||||||
|
color: "white",
|
||||||
|
marginRight: "1rem",
|
||||||
|
background: "red",
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
className="
|
||||||
|
btn btn-sm
|
||||||
|
waves-effect waves-light
|
||||||
|
btn-table
|
||||||
|
mx-1
|
||||||
|
mt-1
|
||||||
|
"
|
||||||
|
onClick={() => handleDelete(item._id)}
|
||||||
|
>
|
||||||
|
Delete
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ display: "flex", justifyContent: "right" }}>
|
||||||
|
<Pagination
|
||||||
|
style={{ margin: "2rem" }}
|
||||||
|
variant="outlined"
|
||||||
|
size="large"
|
||||||
|
count={getPageCount()}
|
||||||
|
color="primary"
|
||||||
|
onChange={(event, value) => setPage(value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Brands;
|
@ -13,8 +13,6 @@ import {
|
|||||||
import CloseIcon from "@mui/icons-material/Close";
|
import CloseIcon from "@mui/icons-material/Close";
|
||||||
import { ClipLoader } from "react-spinners";
|
import { ClipLoader } from "react-spinners";
|
||||||
import swal from "sweetalert";
|
import swal from "sweetalert";
|
||||||
import CloudUploadIcon from "@mui/icons-material/CloudUpload";
|
|
||||||
import DeleteSharpIcon from "@mui/icons-material/DeleteSharp";
|
|
||||||
|
|
||||||
const style = {
|
const style = {
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
@ -31,20 +29,17 @@ const style = {
|
|||||||
const Categories = () => {
|
const Categories = () => {
|
||||||
const token = isAutheticated();
|
const token = isAutheticated();
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [updating, setUpdating] = useState(true); // for loading state
|
const [updating, setUpdating] = useState(true);
|
||||||
// const [isUpdate, setIsUpdate] = useState(false); // for edit state
|
|
||||||
const [saveLoding, setSaveLoading] = useState(true);
|
const [saveLoding, setSaveLoading] = useState(true);
|
||||||
const [edit, setEdit] = useState(false);
|
const [edit, setEdit] = useState(false);
|
||||||
const [categoryName, setCategoryName] = useState("");
|
const [categoryName, setCategoryName] = useState("");
|
||||||
const [categoryImage, setCategoryImage] = useState("");
|
|
||||||
const [error, setError] = useState("");
|
|
||||||
const [categoryId, setCategoryId] = useState("");
|
const [categoryId, setCategoryId] = useState("");
|
||||||
const [category, setCategory] = useState([]);
|
const [category, setCategory] = useState([]);
|
||||||
const [itemPerPage, setItemPerPage] = useState(10);
|
const [itemPerPage, setItemPerPage] = useState(10);
|
||||||
const [page, setPage] = useState(1);
|
const [page, setPage] = useState(1);
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const [olderCategoryName, setOlderCategoruName] = useState("");
|
const [olderCategoryName, setOlderCategoruName] = useState("");
|
||||||
const [olderImage, setOlderImage] = useState("");
|
|
||||||
|
|
||||||
const handleOpen = () => setOpen(true);
|
const handleOpen = () => setOpen(true);
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
@ -54,8 +49,6 @@ const Categories = () => {
|
|||||||
|
|
||||||
setCategoryName("");
|
setCategoryName("");
|
||||||
setCategoryId("");
|
setCategoryId("");
|
||||||
setOlderImage("");
|
|
||||||
setCategoryImage("");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const getCategories = async () => {
|
const getCategories = async () => {
|
||||||
@ -71,47 +64,30 @@ const Categories = () => {
|
|||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
swal({
|
console.error("Failed to fetch brands:", error);
|
||||||
title: error,
|
|
||||||
text: " please login to access the resource ",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getCategories();
|
getCategories();
|
||||||
}, [token]);
|
}, []);
|
||||||
|
|
||||||
const handleEditClick = (_id, categoryName, categoryImage) => {
|
const handleEditClick = (_id, categoryName) => {
|
||||||
setOpen(true);
|
setOpen(true);
|
||||||
setOlderImage(categoryImage);
|
|
||||||
setCategoryName(categoryName);
|
setCategoryName(categoryName);
|
||||||
setCategoryId(_id);
|
setCategoryId(_id);
|
||||||
setOlderCategoruName(categoryName);
|
setOlderCategoruName(categoryName);
|
||||||
setEdit(true);
|
setEdit(true);
|
||||||
// setUpdating(false);
|
// setUpdating(false);
|
||||||
};
|
};
|
||||||
const categoryNamesArray = [];
|
|
||||||
const setCategoryNamesArray = () => {
|
|
||||||
category &&
|
|
||||||
category.map((category) => {
|
|
||||||
categoryNamesArray.push(category.categoryName.toLowerCase());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
setCategoryNamesArray();
|
|
||||||
|
|
||||||
const handleUpdate = () => {
|
const handleUpdate = async () => {
|
||||||
const filteredArrayNames = categoryNamesArray.filter(
|
const filteredArrayNames = category.filter(
|
||||||
(item) => item !== olderCategoryName.toLowerCase()
|
(item) => item.categoryName.toLowerCase() !== olderCategoryName.toLowerCase())
|
||||||
|
.map((item) => item.categoryName.toLowerCase()
|
||||||
);
|
);
|
||||||
console.log(filteredArrayNames, "filter");
|
// console.log(filteredArrayNames, "filter");
|
||||||
const categoryExits = filteredArrayNames.includes(
|
if(filteredArrayNames.includes(categoryName.toLowerCase())){
|
||||||
categoryName.toLowerCase()
|
|
||||||
);
|
|
||||||
if (categoryExits) {
|
|
||||||
swal({
|
swal({
|
||||||
title: "Warning",
|
title: "Warning",
|
||||||
text: "Category already exists ",
|
text: "Category already exists ",
|
||||||
@ -119,10 +95,8 @@ const Categories = () => {
|
|||||||
button: "Retry",
|
button: "Retry",
|
||||||
dangerMode: true,
|
dangerMode: true,
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
if (!categoryName) {
|
||||||
if (!categoryName || (!categoryImage && !olderImage)) {
|
|
||||||
swal({
|
swal({
|
||||||
title: "Warning",
|
title: "Warning",
|
||||||
text: "Please fill all the required fields!",
|
text: "Please fill all the required fields!",
|
||||||
@ -135,45 +109,32 @@ const Categories = () => {
|
|||||||
setUpdating(false);
|
setUpdating(false);
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("categoryName", categoryName);
|
formData.append("categoryName", categoryName);
|
||||||
|
try{
|
||||||
formData.append("categoryImage", categoryImage);
|
await axios
|
||||||
|
|
||||||
formData.append("olderImage", JSON.stringify(olderImage));
|
|
||||||
|
|
||||||
axios
|
|
||||||
.patch(`/api/category/update/${categoryId}`, formData, {
|
.patch(`/api/category/update/${categoryId}`, formData, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then((res) => {
|
|
||||||
// setUpdating(true);
|
|
||||||
// setIsUpdate(false);
|
|
||||||
handleClose();
|
handleClose();
|
||||||
setCategoryId("");
|
|
||||||
setCategoryName("");
|
|
||||||
setCategoryImage("");
|
|
||||||
setOlderImage("");
|
|
||||||
setUpdating(true);
|
|
||||||
setEdit(false);
|
|
||||||
swal({
|
swal({
|
||||||
title: "Congratulations!!",
|
title: "Congratulations!!",
|
||||||
text: "The category was updated successfully!",
|
text: "The category was updated successfully!",
|
||||||
icon: "success",
|
icon: "success",
|
||||||
button: "OK",
|
button: "OK",
|
||||||
});
|
});
|
||||||
// getCategories(); // Refresh the category list after updating
|
getCategories();
|
||||||
})
|
}catch(err){
|
||||||
.catch((err) => {
|
|
||||||
swal({
|
swal({
|
||||||
title: "Sorry, please try again",
|
title: "",
|
||||||
text: err,
|
text: "Something went wrong!",
|
||||||
icon: "error",
|
icon: "error",
|
||||||
button: "Retry",
|
button: "Retry",
|
||||||
dangerMode: true,
|
dangerMode: true,
|
||||||
});
|
});
|
||||||
|
}finally{
|
||||||
setUpdating(true);
|
setUpdating(true);
|
||||||
});
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDelete = (_id) => {
|
const handleDelete = (_id) => {
|
||||||
@ -184,24 +145,23 @@ const Categories = () => {
|
|||||||
Yes: { text: "Yes", value: true },
|
Yes: { text: "Yes", value: true },
|
||||||
Cancel: { text: "Cancel", value: "cancel" },
|
Cancel: { text: "Cancel", value: "cancel" },
|
||||||
},
|
},
|
||||||
}).then((value) => {
|
}).then(async (value) => {
|
||||||
if (value === true) {
|
if (value === true) {
|
||||||
axios
|
try {
|
||||||
|
await axios
|
||||||
.delete(`/api/category/delete/${_id}`, {
|
.delete(`/api/category/delete/${_id}`, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
.then((res) => {
|
|
||||||
swal({
|
swal({
|
||||||
title: "Congratulations!!",
|
title: "Congratulations!!",
|
||||||
text: "The category was deleted successfully!",
|
text: "The category was deleted successfully!",
|
||||||
icon: "success",
|
icon: "success",
|
||||||
button: "OK",
|
button: "OK",
|
||||||
});
|
});
|
||||||
// getCategories(); // Refresh the category list after deleting
|
getCategories();
|
||||||
})
|
}catch(err) {
|
||||||
.catch((err) => {
|
|
||||||
swal({
|
swal({
|
||||||
title: "",
|
title: "",
|
||||||
text: "Something went wrong!",
|
text: "Something went wrong!",
|
||||||
@ -209,26 +169,22 @@ const Categories = () => {
|
|||||||
button: "Retry",
|
button: "Retry",
|
||||||
dangerMode: true,
|
dangerMode: true,
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
}});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSaveCategory = async () => {
|
const handleSaveCategory = async () => {
|
||||||
const categoryExits = categoryNamesArray.includes(
|
if(category.some((item) => item.categoryName.toLowerCase() === categoryName.toLowerCase())){
|
||||||
categoryName.toLowerCase()
|
|
||||||
);
|
|
||||||
if (categoryExits) {
|
|
||||||
swal({
|
swal({
|
||||||
title: "Warning",
|
title: "Warning",
|
||||||
text: "Category Already exits.",
|
text: "Category already exists ",
|
||||||
icon: "error",
|
icon: "error",
|
||||||
button: "Retry",
|
button: "Retry",
|
||||||
dangerMode: true,
|
dangerMode: true,
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!categoryName || !categoryImage) {
|
if (!categoryName) {
|
||||||
swal({
|
swal({
|
||||||
title: "Warning",
|
title: "Warning",
|
||||||
text: "Please fill all the required fields!",
|
text: "Please fill all the required fields!",
|
||||||
@ -242,59 +198,38 @@ const Categories = () => {
|
|||||||
setLoading(true);
|
setLoading(true);
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("categoryName", categoryName);
|
formData.append("categoryName", categoryName);
|
||||||
formData.append("categoryImage", categoryImage);
|
try{
|
||||||
|
await axios
|
||||||
axios
|
|
||||||
.post("/api/category/add", formData, {
|
.post("/api/category/add", formData, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
"Content-Type": "multipart/formdata",
|
"Content-Type": "multipart/formdata",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then((response) => {
|
handleClose();
|
||||||
if (response.status === 201) {
|
|
||||||
setOpen(false);
|
|
||||||
setLoading(false);
|
|
||||||
setSaveLoading(true);
|
|
||||||
setCategoryName("");
|
|
||||||
setCategoryImage("");
|
|
||||||
setOlderImage("");
|
|
||||||
swal({
|
swal({
|
||||||
title: "Added",
|
title: "Congratulations!!",
|
||||||
text: "New category added successfully!",
|
text: "The category was added successfully!",
|
||||||
icon: "success",
|
icon: "success",
|
||||||
button: "OK",
|
button: "OK",
|
||||||
});
|
});
|
||||||
// getCategories(); // Refresh the category list after adding
|
getCategories();
|
||||||
}
|
}catch(err){
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
setSaveLoading(true);
|
|
||||||
swal({
|
swal({
|
||||||
title: error,
|
title: "",
|
||||||
text: "something went wrong",
|
text: "Something went wrong!",
|
||||||
icon: "error",
|
icon: "error",
|
||||||
button: "Retry",
|
button: "Retry",
|
||||||
dangerMode: true,
|
dangerMode: true,
|
||||||
});
|
});
|
||||||
});
|
}finally{
|
||||||
|
setSaveLoading(true);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
const getPageCount = () => {
|
const getPageCount = () => {
|
||||||
return Math.max(1, Math.ceil(category.length / itemPerPage));
|
return Math.max(1, Math.ceil(category.length / itemPerPage));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFileChange = (e) => {
|
|
||||||
const files = e.target.files[0];
|
|
||||||
|
|
||||||
// Check file types and append to selectedFiles
|
|
||||||
const allowedTypes = ["image/jpeg", "image/png", "image/jpg"];
|
|
||||||
if (allowedTypes.includes(files.type)) {
|
|
||||||
setCategoryImage(files);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const handeldeleteImage = () => {
|
|
||||||
setCategoryImage("");
|
|
||||||
};
|
|
||||||
return (
|
return (
|
||||||
<div className="main-content">
|
<div className="main-content">
|
||||||
<div className="page-content">
|
<div className="page-content">
|
||||||
@ -377,111 +312,6 @@ const Categories = () => {
|
|||||||
<></>
|
<></>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Box
|
|
||||||
style={{
|
|
||||||
padding: "1rem",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<label htmlFor="upload-Image">
|
|
||||||
<TextField
|
|
||||||
style={{
|
|
||||||
display: "none",
|
|
||||||
width: "350px",
|
|
||||||
height: "350px",
|
|
||||||
borderRadius: "10%",
|
|
||||||
}}
|
|
||||||
fullWidth
|
|
||||||
id="upload-Image"
|
|
||||||
type="file"
|
|
||||||
accept=".jpg , .png ,.jpeg"
|
|
||||||
label="file"
|
|
||||||
variant="outlined"
|
|
||||||
onChange={(e) => handleFileChange(e)}
|
|
||||||
/>
|
|
||||||
<Box
|
|
||||||
style={{ borderRadius: "10%" }}
|
|
||||||
sx={{
|
|
||||||
margin: "1rem 0rem",
|
|
||||||
cursor: "pointer",
|
|
||||||
width: "140px",
|
|
||||||
height: "140px",
|
|
||||||
border: "2px solid grey",
|
|
||||||
// borderRadius: '50%',
|
|
||||||
|
|
||||||
"&:hover": {
|
|
||||||
background: "rgba(112,112,112,0.5)",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<CloudUploadIcon
|
|
||||||
style={{
|
|
||||||
color: "grey",
|
|
||||||
margin: "auto",
|
|
||||||
fontSize: "5rem",
|
|
||||||
}}
|
|
||||||
fontSize="large"
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</label>
|
|
||||||
{categoryImage && (
|
|
||||||
<Box>
|
|
||||||
<img
|
|
||||||
src={URL.createObjectURL(categoryImage)}
|
|
||||||
alt="categoryImage"
|
|
||||||
style={{
|
|
||||||
width: 100,
|
|
||||||
height: 100,
|
|
||||||
borderRadius: "1rem",
|
|
||||||
marginLeft: "1rem",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<DeleteSharpIcon
|
|
||||||
onClick={() => handeldeleteImage()}
|
|
||||||
fontSize="small"
|
|
||||||
sx={{
|
|
||||||
color: "white",
|
|
||||||
position: "absolute",
|
|
||||||
cursor: "pointer",
|
|
||||||
padding: "0.2rem",
|
|
||||||
background: "black",
|
|
||||||
borderRadius: "50%",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
{olderImage && (
|
|
||||||
<Box>
|
|
||||||
<img
|
|
||||||
src={olderImage?.secure_url}
|
|
||||||
alt="categoryImage"
|
|
||||||
style={{
|
|
||||||
width: 100,
|
|
||||||
height: 100,
|
|
||||||
borderRadius: "1rem",
|
|
||||||
marginLeft: "1rem",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<DeleteSharpIcon
|
|
||||||
onClick={() => setOlderImage("")}
|
|
||||||
fontSize="small"
|
|
||||||
sx={{
|
|
||||||
color: "white",
|
|
||||||
position: "absolute",
|
|
||||||
cursor: "pointer",
|
|
||||||
padding: "0.2rem",
|
|
||||||
background: "black",
|
|
||||||
borderRadius: "50%",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{error && <p style={{ color: "red" }}>{error}</p>}
|
|
||||||
<p className="pt-1 pl-2 text-secondary">
|
|
||||||
Upload jpg, jpeg and png only*
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
p={2}
|
p={2}
|
||||||
display={"flex"}
|
display={"flex"}
|
||||||
@ -593,9 +423,8 @@ const Categories = () => {
|
|||||||
style={{ background: "rgb(140, 213, 213)" }}
|
style={{ background: "rgb(140, 213, 213)" }}
|
||||||
>
|
>
|
||||||
<tr>
|
<tr>
|
||||||
<th> Image</th>
|
|
||||||
|
|
||||||
<th> Categories Name</th>
|
<th> Category Name</th>
|
||||||
|
|
||||||
<th>Action</th>
|
<th>Action</th>
|
||||||
</tr>
|
</tr>
|
||||||
@ -623,15 +452,6 @@ const Categories = () => {
|
|||||||
)
|
)
|
||||||
.map((item, i) => (
|
.map((item, i) => (
|
||||||
<tr key={i}>
|
<tr key={i}>
|
||||||
<td>
|
|
||||||
<img
|
|
||||||
className="me-2"
|
|
||||||
src={item?.categoryImage?.secure_url}
|
|
||||||
width="40"
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
<h5>{ } </h5>
|
|
||||||
</td>
|
|
||||||
<td>
|
<td>
|
||||||
<h5>{item.categoryName} </h5>
|
<h5>{item.categoryName} </h5>
|
||||||
</td>
|
</td>
|
||||||
@ -653,7 +473,6 @@ const Categories = () => {
|
|||||||
handleEditClick(
|
handleEditClick(
|
||||||
item._id,
|
item._id,
|
||||||
item.categoryName,
|
item.categoryName,
|
||||||
item.categoryImage
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -166,113 +166,6 @@ const Inventory = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="table-responsive table-shoot mt-3">
|
<div className="table-responsive table-shoot mt-3">
|
||||||
{/* <table
|
|
||||||
className="table table-centered table-nowrap"
|
|
||||||
style={{ border: "1px solid" }}
|
|
||||||
>
|
|
||||||
<thead
|
|
||||||
className="thead-light"
|
|
||||||
style={{ background: "#ecdddd" }}
|
|
||||||
>
|
|
||||||
<tr>
|
|
||||||
<th className="text-start">ID</th>
|
|
||||||
<th className="text-start">Date</th>
|
|
||||||
<th className="text-start">Time</th>
|
|
||||||
<th className="text-start">Trade Name</th>
|
|
||||||
<th className="text-start">PD/RD</th>
|
|
||||||
<th className="text-start">Product SKU</th>
|
|
||||||
<th className="text-start">Product Name</th>
|
|
||||||
<th className="text-start">Sale</th>
|
|
||||||
<th className="text-start">Inventory</th>
|
|
||||||
<th className="text-start">Actions</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
|
|
||||||
<tbody>
|
|
||||||
{loading ? (
|
|
||||||
<tr>
|
|
||||||
<td className="text-center" colSpan="10">
|
|
||||||
Loading...
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
) : inventoryData.length > 0 ? (
|
|
||||||
inventoryData.map((entry, i) =>
|
|
||||||
entry.products.map((product, j) => (
|
|
||||||
<tr key={`${i}-${j}`}>
|
|
||||||
<td className="text-start">{entry.uniqueId}</td>
|
|
||||||
<td className="text-start">
|
|
||||||
{new Date(entry.createdAt).toLocaleString(
|
|
||||||
"en-IN",
|
|
||||||
{
|
|
||||||
month: "short",
|
|
||||||
day: "numeric",
|
|
||||||
year: "numeric",
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
</td>
|
|
||||||
<td className="text-start">
|
|
||||||
{new Date(entry.createdAt).toLocaleString(
|
|
||||||
"en-IN",
|
|
||||||
{
|
|
||||||
hour: "numeric",
|
|
||||||
minute: "numeric",
|
|
||||||
hour12: true,
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
</td>
|
|
||||||
<td className="text-start">
|
|
||||||
{entry.tradeName}
|
|
||||||
</td>
|
|
||||||
<td className="text-start">
|
|
||||||
{entry.designation}
|
|
||||||
</td>
|
|
||||||
<td className="text-start">{product.SKU}</td>
|
|
||||||
<td className="text-start">
|
|
||||||
{product.ProductName}
|
|
||||||
</td>
|
|
||||||
<td className="text-start">{product.Sale}</td>
|
|
||||||
<td className="text-center">
|
|
||||||
{product.Inventory}
|
|
||||||
</td>
|
|
||||||
<td className="text-start">
|
|
||||||
<Link
|
|
||||||
to={`/inventory/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>
|
|
||||||
))
|
|
||||||
)
|
|
||||||
) : (
|
|
||||||
!loading &&
|
|
||||||
filteredData.length === 0 && (
|
|
||||||
<tr className="text-center">
|
|
||||||
<td colSpan="10">
|
|
||||||
<h5>No Data Available...</h5>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)
|
|
||||||
)}
|
|
||||||
</tbody>
|
|
||||||
</table> */}
|
|
||||||
|
|
||||||
<table
|
<table
|
||||||
className="table table-centered table-nowrap"
|
className="table table-centered table-nowrap"
|
||||||
style={{
|
style={{
|
||||||
@ -478,7 +371,6 @@ const Inventory = () => {
|
|||||||
)}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div className="row mt-20">
|
<div className="row mt-20">
|
||||||
<div className="col-sm-12 col-md-6 mb-20">
|
<div className="col-sm-12 col-md-6 mb-20">
|
||||||
|
@ -198,6 +198,7 @@ const AddMultiplePd = () => {
|
|||||||
<table className="table table-bordered">
|
<table className="table table-bordered">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
<th>uniqueId</th>
|
||||||
<th>Principal Distributor Name</th>
|
<th>Principal Distributor Name</th>
|
||||||
<th>Email</th>
|
<th>Email</th>
|
||||||
<th>Phone</th>
|
<th>Phone</th>
|
||||||
@ -208,11 +209,12 @@ const AddMultiplePd = () => {
|
|||||||
<tbody>
|
<tbody>
|
||||||
{newlyCreated.map((distributor, index) => (
|
{newlyCreated.map((distributor, index) => (
|
||||||
<tr key={index}>
|
<tr key={index}>
|
||||||
<td>{distributor.name || "N/A"}</td>
|
<td>{distributor?.distributor?.uniqueId || "N/A"}</td>
|
||||||
<td>{distributor.email || "N/A"}</td>
|
<td>{distributor?.distributor?.name || "N/A"}</td>
|
||||||
<td>{distributor.phone || "N/A"}</td>
|
<td>{distributor?.distributor?.email || "N/A"}</td>
|
||||||
<td>{distributor.panNumber || "N/A"}</td>
|
<td>{distributor?.distributor?.phone || "N/A"}</td>
|
||||||
<td>{distributor.gstNumber || "N/A"}</td>
|
<td>{distributor?.address?.panNumber || "N/A"}</td>
|
||||||
|
<td>{distributor?.address?.gstNumber || "N/A"}</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -8,6 +8,8 @@ import {
|
|||||||
FormHelperText,
|
FormHelperText,
|
||||||
Autocomplete,
|
Autocomplete,
|
||||||
CircularProgress,
|
CircularProgress,
|
||||||
|
FormControl,
|
||||||
|
InputLabel,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { toast } from "react-hot-toast";
|
import { toast } from "react-hot-toast";
|
||||||
@ -21,6 +23,7 @@ const AddPrincipalDistributor = () => {
|
|||||||
|
|
||||||
const [user, setUser] = useState({
|
const [user, setUser] = useState({
|
||||||
PD_ID: "",
|
PD_ID: "",
|
||||||
|
SBU: "",
|
||||||
name: "",
|
name: "",
|
||||||
email: "",
|
email: "",
|
||||||
phone: "",
|
phone: "",
|
||||||
@ -165,11 +168,22 @@ const AddPrincipalDistributor = () => {
|
|||||||
Add Principal Distributor
|
Add Principal Distributor
|
||||||
</Typography>
|
</Typography>
|
||||||
<form onSubmit={handleFormSubmit}>
|
<form onSubmit={handleFormSubmit}>
|
||||||
<Typography variant="h6" sx={{ mb: 2 }}>
|
<Typography variant="h5" sx={{ mb: 2 }}>
|
||||||
Basic Information
|
Basic Information
|
||||||
</Typography>
|
</Typography>
|
||||||
<Grid container spacing={2} sx={{ mb: 2 }}>
|
<Grid container spacing={2} sx={{ mb: 2 }}>
|
||||||
<Grid item xs={6}>
|
{/* Principal Distributor ID */}
|
||||||
|
<Grid item xs={12} className="d-flex align-items-center">
|
||||||
|
<Grid item xs={2}>
|
||||||
|
<Typography
|
||||||
|
variant="body1"
|
||||||
|
htmlFor="PD_ID"
|
||||||
|
className="form-label"
|
||||||
|
>
|
||||||
|
Principal Distributor ID*
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={10}>
|
||||||
<TextField
|
<TextField
|
||||||
id="PD_ID"
|
id="PD_ID"
|
||||||
required
|
required
|
||||||
@ -177,12 +191,49 @@ const AddPrincipalDistributor = () => {
|
|||||||
fullWidth
|
fullWidth
|
||||||
name="PD_ID"
|
name="PD_ID"
|
||||||
value={user.PD_ID}
|
value={user.PD_ID}
|
||||||
label="Principal Distributor ID"
|
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onChange={handleInputChange}
|
onChange={handleInputChange}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6}>
|
</Grid>
|
||||||
|
|
||||||
|
{/* Principal Distributor SBU */}
|
||||||
|
<Grid item xs={12} className="d-flex align-items-center">
|
||||||
|
<Grid item xs={2}>
|
||||||
|
<Typography
|
||||||
|
variant="body1"
|
||||||
|
htmlFor="SBU"
|
||||||
|
className="form-label"
|
||||||
|
>
|
||||||
|
SBU*
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={10}>
|
||||||
|
<TextField
|
||||||
|
id="SBU"
|
||||||
|
required
|
||||||
|
type="text"
|
||||||
|
fullWidth
|
||||||
|
name="SBU"
|
||||||
|
value={user.SBU}
|
||||||
|
variant="outlined"
|
||||||
|
onChange={handleInputChange}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Name */}
|
||||||
|
<Grid item xs={12} className="d-flex align-items-center">
|
||||||
|
<Grid item xs={2}>
|
||||||
|
<Typography
|
||||||
|
variant="body1"
|
||||||
|
htmlFor="name"
|
||||||
|
className="form-label"
|
||||||
|
>
|
||||||
|
Name*
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={10}>
|
||||||
<TextField
|
<TextField
|
||||||
id="name"
|
id="name"
|
||||||
required
|
required
|
||||||
@ -190,12 +241,24 @@ const AddPrincipalDistributor = () => {
|
|||||||
fullWidth
|
fullWidth
|
||||||
name="name"
|
name="name"
|
||||||
value={user.name}
|
value={user.name}
|
||||||
label="Name"
|
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onChange={handleInputChange}
|
onChange={handleInputChange}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6}>
|
</Grid>
|
||||||
|
|
||||||
|
{/* Email */}
|
||||||
|
<Grid item xs={12} className="d-flex align-items-center">
|
||||||
|
<Grid item xs={2}>
|
||||||
|
<Typography
|
||||||
|
variant="body1"
|
||||||
|
htmlFor="email"
|
||||||
|
className="form-label"
|
||||||
|
>
|
||||||
|
Email*
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={10}>
|
||||||
<TextField
|
<TextField
|
||||||
id="email"
|
id="email"
|
||||||
required
|
required
|
||||||
@ -203,12 +266,24 @@ const AddPrincipalDistributor = () => {
|
|||||||
fullWidth
|
fullWidth
|
||||||
name="email"
|
name="email"
|
||||||
value={user.email}
|
value={user.email}
|
||||||
label="Email"
|
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onChange={handleInputChange}
|
onChange={handleInputChange}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6}>
|
</Grid>
|
||||||
|
|
||||||
|
{/* Phone Number */}
|
||||||
|
<Grid item xs={12} className="d-flex align-items-center">
|
||||||
|
<Grid item xs={2}>
|
||||||
|
<Typography
|
||||||
|
variant="body1"
|
||||||
|
htmlFor="phone"
|
||||||
|
className="form-label"
|
||||||
|
>
|
||||||
|
Phone Number*
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={10}>
|
||||||
<TextField
|
<TextField
|
||||||
id="phone"
|
id="phone"
|
||||||
required
|
required
|
||||||
@ -216,18 +291,29 @@ const AddPrincipalDistributor = () => {
|
|||||||
fullWidth
|
fullWidth
|
||||||
name="phone"
|
name="phone"
|
||||||
value={user.phone}
|
value={user.phone}
|
||||||
label="Phone Number"
|
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onChange={handleInputChange}
|
onChange={handleInputChange}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<Typography variant="h6" sx={{ mb: 2 }}>
|
<Typography variant="h5" sx={{ mb: 2 }}>
|
||||||
Business Details
|
Business Details
|
||||||
</Typography>
|
</Typography>
|
||||||
<Grid container spacing={2} sx={{ mb: 2 }}>
|
<Grid container spacing={2} sx={{ mb: 2 }}>
|
||||||
<Grid item xs={12} sm={4}>
|
{/* PAN Number */}
|
||||||
|
<Grid item xs={12} className="d-flex align-items-center">
|
||||||
|
<Grid item xs={2}>
|
||||||
|
<Typography
|
||||||
|
variant="body1"
|
||||||
|
htmlFor="panNumber"
|
||||||
|
className="form-label"
|
||||||
|
>
|
||||||
|
PAN Number*
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={10}>
|
||||||
<TextField
|
<TextField
|
||||||
id="panNumber"
|
id="panNumber"
|
||||||
required
|
required
|
||||||
@ -235,12 +321,24 @@ const AddPrincipalDistributor = () => {
|
|||||||
fullWidth
|
fullWidth
|
||||||
name="panNumber"
|
name="panNumber"
|
||||||
value={data.panNumber}
|
value={data.panNumber}
|
||||||
label="PAN Number"
|
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onChange={handleDataChange}
|
onChange={handleDataChange}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} sm={4}>
|
</Grid>
|
||||||
|
|
||||||
|
{/* Trade Name */}
|
||||||
|
<Grid item xs={12} className="d-flex align-items-center">
|
||||||
|
<Grid item xs={2}>
|
||||||
|
<Typography
|
||||||
|
variant="body1"
|
||||||
|
htmlFor="tradeName"
|
||||||
|
className="form-label"
|
||||||
|
>
|
||||||
|
Trade Name*
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={10}>
|
||||||
<TextField
|
<TextField
|
||||||
id="tradeName"
|
id="tradeName"
|
||||||
required
|
required
|
||||||
@ -248,12 +346,24 @@ const AddPrincipalDistributor = () => {
|
|||||||
fullWidth
|
fullWidth
|
||||||
name="tradeName"
|
name="tradeName"
|
||||||
value={data.tradeName}
|
value={data.tradeName}
|
||||||
label="Trade Name"
|
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onChange={handleDataChange}
|
onChange={handleDataChange}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} sm={4}>
|
</Grid>
|
||||||
|
|
||||||
|
{/* GST Number */}
|
||||||
|
<Grid item xs={12} className="d-flex align-items-center">
|
||||||
|
<Grid item xs={2}>
|
||||||
|
<Typography
|
||||||
|
variant="body1"
|
||||||
|
htmlFor="gstNumber"
|
||||||
|
className="form-label"
|
||||||
|
>
|
||||||
|
GST Number*
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={10}>
|
||||||
<TextField
|
<TextField
|
||||||
id="gstNumber"
|
id="gstNumber"
|
||||||
required
|
required
|
||||||
@ -261,18 +371,29 @@ const AddPrincipalDistributor = () => {
|
|||||||
fullWidth
|
fullWidth
|
||||||
name="gstNumber"
|
name="gstNumber"
|
||||||
value={data.gstNumber}
|
value={data.gstNumber}
|
||||||
label="GST Number"
|
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onChange={handleDataChange}
|
onChange={handleDataChange}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<Typography variant="h6" sx={{ mb: 2 }}>
|
<Typography variant="h5" sx={{ mb: 2 }}>
|
||||||
Address
|
Address
|
||||||
</Typography>
|
</Typography>
|
||||||
<Grid container spacing={2} sx={{ mb: 2 }}>
|
<Grid container spacing={2} sx={{ mb: 2 }}>
|
||||||
<Grid item xs={12} sm={4}>
|
{/* Country */}
|
||||||
|
<Grid item xs={12} className="d-flex align-items-center">
|
||||||
|
<Grid item xs={2}>
|
||||||
|
<Typography
|
||||||
|
variant="body1"
|
||||||
|
htmlFor="country"
|
||||||
|
className="form-label"
|
||||||
|
>
|
||||||
|
Country*
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={10}>
|
||||||
<TextField
|
<TextField
|
||||||
id="country"
|
id="country"
|
||||||
required
|
required
|
||||||
@ -280,12 +401,24 @@ const AddPrincipalDistributor = () => {
|
|||||||
fullWidth
|
fullWidth
|
||||||
name="country"
|
name="country"
|
||||||
value={data.country}
|
value={data.country}
|
||||||
label="Country"
|
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
disabled
|
disabled
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} sm={4}>
|
</Grid>
|
||||||
|
|
||||||
|
{/* State */}
|
||||||
|
<Grid item xs={12} className="d-flex align-items-center">
|
||||||
|
<Grid item xs={2}>
|
||||||
|
<Typography
|
||||||
|
variant="body1"
|
||||||
|
htmlFor="state"
|
||||||
|
className="form-label"
|
||||||
|
>
|
||||||
|
State*
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={10}>
|
||||||
<Autocomplete
|
<Autocomplete
|
||||||
id="state"
|
id="state"
|
||||||
options={stateOptions}
|
options={stateOptions}
|
||||||
@ -296,15 +429,28 @@ const AddPrincipalDistributor = () => {
|
|||||||
<TextField
|
<TextField
|
||||||
{...params}
|
{...params}
|
||||||
fullWidth
|
fullWidth
|
||||||
label="State"
|
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
|
label="Select State"
|
||||||
error={!selectedState}
|
error={!selectedState}
|
||||||
helperText={!selectedState ? "Select a state" : null}
|
helperText={!selectedState ? "Select a state" : null}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} sm={4}>
|
</Grid>
|
||||||
|
|
||||||
|
{/* City */}
|
||||||
|
<Grid item xs={12} className="d-flex align-items-center">
|
||||||
|
<Grid item xs={2}>
|
||||||
|
<Typography
|
||||||
|
variant="body1"
|
||||||
|
htmlFor="city"
|
||||||
|
className="form-label"
|
||||||
|
>
|
||||||
|
City*
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={10}>
|
||||||
<Autocomplete
|
<Autocomplete
|
||||||
id="city"
|
id="city"
|
||||||
options={cityOptions}
|
options={cityOptions}
|
||||||
@ -315,15 +461,28 @@ const AddPrincipalDistributor = () => {
|
|||||||
<TextField
|
<TextField
|
||||||
{...params}
|
{...params}
|
||||||
fullWidth
|
fullWidth
|
||||||
label="City"
|
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
|
label="Select City"
|
||||||
error={!selectedCity}
|
error={!selectedCity}
|
||||||
helperText={!selectedCity ? "Select a city" : null}
|
helperText={!selectedCity ? "Select a city" : null}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6}>
|
</Grid>
|
||||||
|
|
||||||
|
{/* Street */}
|
||||||
|
<Grid item xs={12} className="d-flex align-items-center">
|
||||||
|
<Grid item xs={2}>
|
||||||
|
<Typography
|
||||||
|
variant="body1"
|
||||||
|
htmlFor="street"
|
||||||
|
className="form-label"
|
||||||
|
>
|
||||||
|
Street*
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={10}>
|
||||||
<TextField
|
<TextField
|
||||||
id="street"
|
id="street"
|
||||||
required
|
required
|
||||||
@ -331,12 +490,24 @@ const AddPrincipalDistributor = () => {
|
|||||||
fullWidth
|
fullWidth
|
||||||
name="street"
|
name="street"
|
||||||
value={data.street}
|
value={data.street}
|
||||||
label="Street"
|
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onChange={handleDataChange}
|
onChange={handleDataChange}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6}>
|
</Grid>
|
||||||
|
|
||||||
|
{/* Postal Code */}
|
||||||
|
<Grid item xs={12} className="d-flex align-items-center">
|
||||||
|
<Grid item xs={2}>
|
||||||
|
<Typography
|
||||||
|
variant="body1"
|
||||||
|
htmlFor="postalCode"
|
||||||
|
className="form-label"
|
||||||
|
>
|
||||||
|
Postal Code*
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={10}>
|
||||||
<TextField
|
<TextField
|
||||||
id="postalCode"
|
id="postalCode"
|
||||||
required
|
required
|
||||||
@ -344,12 +515,12 @@ const AddPrincipalDistributor = () => {
|
|||||||
fullWidth
|
fullWidth
|
||||||
name="postalCode"
|
name="postalCode"
|
||||||
value={data.postalCode}
|
value={data.postalCode}
|
||||||
label="Postal Code"
|
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onChange={handleDataChange}
|
onChange={handleDataChange}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
|
@ -148,7 +148,9 @@ const principalDistributor = () => {
|
|||||||
color="primary"
|
color="primary"
|
||||||
className="font-bold mb-2 capitalize"
|
className="font-bold mb-2 capitalize"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
navigate("/add-principal-distributor/multiple", { replace: true })
|
navigate("/add-principal-distributor/multiple", {
|
||||||
|
replace: true,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Upload Spreadsheet
|
Upload Spreadsheet
|
||||||
@ -199,6 +201,7 @@ const principalDistributor = () => {
|
|||||||
>
|
>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Unique Id </th>
|
<th>Unique Id </th>
|
||||||
|
<th>SBU</th>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Email</th>
|
<th>Email</th>
|
||||||
{/* <th>Profile Image</th> */}
|
{/* <th>Profile Image</th> */}
|
||||||
@ -228,6 +231,7 @@ const principalDistributor = () => {
|
|||||||
return (
|
return (
|
||||||
<tr key={i}>
|
<tr key={i}>
|
||||||
<td>{user.uniqueId}</td>
|
<td>{user.uniqueId}</td>
|
||||||
|
<td>{user.SBU?user.SBU:"N/A"}</td>
|
||||||
<td className="text-start">{user.name}</td>
|
<td className="text-start">{user.name}</td>
|
||||||
<td>{user.email}</td>
|
<td>{user.email}</td>
|
||||||
<td className="text-start">
|
<td className="text-start">
|
||||||
|
@ -137,35 +137,85 @@ const SinglePrincipalDistributorAllDetails = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="card" style={{ padding: "1rem" }}>
|
<div className="card" style={{ padding: "1rem" }}>
|
||||||
<h5 style={{ fontWeight: "bold" }}>• Principal Distributor Profile </h5>
|
<h5 style={{ fontWeight: "bold" }}>
|
||||||
|
• Principal Distributor Profile{" "}
|
||||||
|
</h5>
|
||||||
<div style={{ marginLeft: "1rem", marginTop: "1rem" }}>
|
<div style={{ marginLeft: "1rem", marginTop: "1rem" }}>
|
||||||
<Typography style={{ fontWeight: "bold", fontSize: "1.2rem" }}>
|
<Typography style={{ fontWeight: "bold", fontSize: "1.2rem" }}>
|
||||||
Principal Distributor ID:
|
Principal Distributor ID:
|
||||||
<Typography component="span" style={{ fontWeight: "normal", fontSize: "1.2rem",marginLeft: "0.5rem" }}>
|
<Typography
|
||||||
|
component="span"
|
||||||
|
style={{
|
||||||
|
fontWeight: "normal",
|
||||||
|
fontSize: "1.2rem",
|
||||||
|
marginLeft: "0.5rem",
|
||||||
|
}}
|
||||||
|
>
|
||||||
{user?.uniqueId}
|
{user?.uniqueId}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Typography>
|
</Typography>
|
||||||
|
<Typography style={{ fontWeight: "bold", fontSize: "1.2rem" }}>
|
||||||
|
SBU:
|
||||||
|
<Typography
|
||||||
|
component="span"
|
||||||
|
style={{
|
||||||
|
fontWeight: "normal",
|
||||||
|
fontSize: "1.2rem",
|
||||||
|
marginLeft: "0.5rem",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{user?.SBU}
|
||||||
|
</Typography>
|
||||||
|
</Typography>
|
||||||
<Typography style={{ fontWeight: "bold", fontSize: "1.2rem" }}>
|
<Typography style={{ fontWeight: "bold", fontSize: "1.2rem" }}>
|
||||||
Name:
|
Name:
|
||||||
<Typography component="span" style={{ fontWeight: "normal", fontSize: "1.2rem",marginLeft: "0.5rem"}}>
|
<Typography
|
||||||
|
component="span"
|
||||||
|
style={{
|
||||||
|
fontWeight: "normal",
|
||||||
|
fontSize: "1.2rem",
|
||||||
|
marginLeft: "0.5rem",
|
||||||
|
}}
|
||||||
|
>
|
||||||
{user?.name}
|
{user?.name}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography style={{ fontWeight: "bold", fontSize: "1.2rem" }}>
|
<Typography style={{ fontWeight: "bold", fontSize: "1.2rem" }}>
|
||||||
Email:
|
Email:
|
||||||
<Typography component="span" style={{ fontWeight: "normal", fontSize: "1.2rem" ,marginLeft: "0.5rem"}}>
|
<Typography
|
||||||
|
component="span"
|
||||||
|
style={{
|
||||||
|
fontWeight: "normal",
|
||||||
|
fontSize: "1.2rem",
|
||||||
|
marginLeft: "0.5rem",
|
||||||
|
}}
|
||||||
|
>
|
||||||
{user?.email}
|
{user?.email}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography style={{ fontWeight: "bold", fontSize: "1.2rem" }}>
|
<Typography style={{ fontWeight: "bold", fontSize: "1.2rem" }}>
|
||||||
Mobile Number:
|
Mobile Number:
|
||||||
<Typography component="span" style={{ fontWeight: "normal", fontSize: "1.2rem" ,marginLeft: "0.5rem"}}>
|
<Typography
|
||||||
|
component="span"
|
||||||
|
style={{
|
||||||
|
fontWeight: "normal",
|
||||||
|
fontSize: "1.2rem",
|
||||||
|
marginLeft: "0.5rem",
|
||||||
|
}}
|
||||||
|
>
|
||||||
{user?.phone}
|
{user?.phone}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography style={{ fontWeight: "bold", fontSize: "1.2rem" }}>
|
<Typography style={{ fontWeight: "bold", fontSize: "1.2rem" }}>
|
||||||
Date Registered:
|
Date Registered:
|
||||||
<Typography component="span" style={{ fontWeight: "normal", fontSize: "1.2rem" ,marginLeft: "0.5rem"}}>
|
<Typography
|
||||||
|
component="span"
|
||||||
|
style={{
|
||||||
|
fontWeight: "normal",
|
||||||
|
fontSize: "1.2rem",
|
||||||
|
marginLeft: "0.5rem",
|
||||||
|
}}
|
||||||
|
>
|
||||||
{new Date(user?.createdAt).toLocaleString("en-IN", {
|
{new Date(user?.createdAt).toLocaleString("en-IN", {
|
||||||
weekday: "short",
|
weekday: "short",
|
||||||
month: "short",
|
month: "short",
|
||||||
@ -179,7 +229,14 @@ const SinglePrincipalDistributorAllDetails = () => {
|
|||||||
</Typography>
|
</Typography>
|
||||||
<Typography style={{ fontWeight: "bold", fontSize: "1.2rem" }}>
|
<Typography style={{ fontWeight: "bold", fontSize: "1.2rem" }}>
|
||||||
Last Purchase:
|
Last Purchase:
|
||||||
<Typography component="span" style={{ fontWeight: "normal", fontSize: "1.2rem", marginLeft: "1.5rem" }}>
|
<Typography
|
||||||
|
component="span"
|
||||||
|
style={{
|
||||||
|
fontWeight: "normal",
|
||||||
|
fontSize: "1.2rem",
|
||||||
|
marginLeft: "1.5rem",
|
||||||
|
}}
|
||||||
|
>
|
||||||
{userOrder?.length > 0
|
{userOrder?.length > 0
|
||||||
? new Date(userOrder[0]?.createdAt).toLocaleString("en-IN", {
|
? new Date(userOrder[0]?.createdAt).toLocaleString("en-IN", {
|
||||||
weekday: "short",
|
weekday: "short",
|
||||||
@ -239,9 +296,8 @@ const SinglePrincipalDistributorAllDetails = () => {
|
|||||||
? `${address.tradeName},`
|
? `${address.tradeName},`
|
||||||
: "No tradeName "}
|
: "No tradeName "}
|
||||||
{address.gstNumber ? `${address.gstNumber},` : ""}
|
{address.gstNumber ? `${address.gstNumber},` : ""}
|
||||||
{address?.street},
|
{address?.street},{address?.city},{address?.state},
|
||||||
{address?.city},{address?.state},{address?.country},
|
{address?.country},{address?.postalCode}
|
||||||
{address?.postalCode}
|
|
||||||
</strong>
|
</strong>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -134,7 +134,9 @@ try{
|
|||||||
<tr>
|
<tr>
|
||||||
<th>Product Name</th>
|
<th>Product Name</th>
|
||||||
<th>Category</th>
|
<th>Category</th>
|
||||||
|
<th>Brand</th>
|
||||||
<th>GST</th>
|
<th>GST</th>
|
||||||
|
<th>HSN_Code</th>
|
||||||
<th>price</th>
|
<th>price</th>
|
||||||
<th>Message</th>
|
<th>Message</th>
|
||||||
</tr>
|
</tr>
|
||||||
@ -144,7 +146,9 @@ try{
|
|||||||
<tr key={index}>
|
<tr key={index}>
|
||||||
<td>{error.productName || "N/A"}</td>
|
<td>{error.productName || "N/A"}</td>
|
||||||
<td>{error.category || "N/A"}</td>
|
<td>{error.category || "N/A"}</td>
|
||||||
|
<td>{error.brand || "N/A"}</td>
|
||||||
<td>{error.GST || "N/A"}</td>
|
<td>{error.GST || "N/A"}</td>
|
||||||
|
<td>{error.HSN_Code || "N/A"}</td>
|
||||||
<td>{error.price || "N/A"}</td>
|
<td>{error.price || "N/A"}</td>
|
||||||
<td>{error.message}</td>
|
<td>{error.message}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -161,7 +165,9 @@ try{
|
|||||||
<tr>
|
<tr>
|
||||||
<th>Product Name</th>
|
<th>Product Name</th>
|
||||||
<th>Category</th>
|
<th>Category</th>
|
||||||
|
<th>Brand</th>
|
||||||
<th>GST</th>
|
<th>GST</th>
|
||||||
|
<th>HSN_Code</th>
|
||||||
<th>price</th>
|
<th>price</th>
|
||||||
<th>Message</th>
|
<th>Message</th>
|
||||||
</tr>
|
</tr>
|
||||||
@ -171,7 +177,9 @@ try{
|
|||||||
<tr key={index}>
|
<tr key={index}>
|
||||||
<td>{update.name || "N/A"}</td>
|
<td>{update.name || "N/A"}</td>
|
||||||
<td>{update.category || "N/A"}</td>
|
<td>{update.category || "N/A"}</td>
|
||||||
|
<td>{update.brand || "N/A"}</td>
|
||||||
<td>{update.GST || "N/A"}</td>
|
<td>{update.GST || "N/A"}</td>
|
||||||
|
<td>{update.HSN_Code || "N/A"}</td>
|
||||||
<td>{update.price || "N/A"}</td>
|
<td>{update.price || "N/A"}</td>
|
||||||
<td>{update.updatedFields}</td>
|
<td>{update.updatedFields}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -188,7 +196,9 @@ try{
|
|||||||
<tr>
|
<tr>
|
||||||
<th>Product Name</th>
|
<th>Product Name</th>
|
||||||
<th>Category</th>
|
<th>Category</th>
|
||||||
|
<th>Brand</th>
|
||||||
<th>GST</th>
|
<th>GST</th>
|
||||||
|
<th>HSN_Code</th>
|
||||||
<th>price</th>
|
<th>price</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -197,7 +207,9 @@ try{
|
|||||||
<tr key={index}>
|
<tr key={index}>
|
||||||
<td>{create.name || "N/A"}</td>
|
<td>{create.name || "N/A"}</td>
|
||||||
<td>{create.category || "N/A"}</td>
|
<td>{create.category || "N/A"}</td>
|
||||||
|
<td>{create.brand || "N/A"}</td>
|
||||||
<td>{create.GST || "N/A"}</td>
|
<td>{create.GST || "N/A"}</td>
|
||||||
|
<td>{create.HSN_Code || "N/A"}</td>
|
||||||
<td>{create.price || "N/A"}</td>
|
<td>{create.price || "N/A"}</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
|
@ -13,22 +13,21 @@ const AddProduct = () => {
|
|||||||
const [viewState, setViewState] = useState(1);
|
const [viewState, setViewState] = useState(1);
|
||||||
const [images, setImages] = useState([]);
|
const [images, setImages] = useState([]);
|
||||||
const [categories, setCategories] = useState([]);
|
const [categories, setCategories] = useState([]);
|
||||||
const [taxes, setTaxes] = useState([]);
|
const [brands, setBrands] = useState([]);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
const [data, setData] = useState({
|
const [data, setData] = useState({
|
||||||
SKU:"",
|
SKU:"",
|
||||||
name: "",
|
name: "",
|
||||||
category: "",
|
category: "",
|
||||||
|
brand: "",
|
||||||
description: "",
|
description: "",
|
||||||
price: "",
|
price: "",
|
||||||
GST: "",
|
GST: "",
|
||||||
product_Status: "",
|
HSN_Code: "",
|
||||||
special_instructions: "",
|
product_Status: "Active",
|
||||||
});
|
});
|
||||||
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
const getCategories = () => {
|
const getCategories = () => {
|
||||||
axios
|
axios
|
||||||
.get(`/api/category/getCategories`, {
|
.get(`/api/category/getCategories`, {
|
||||||
@ -46,22 +45,26 @@ const AddProduct = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const getTaxes = () => {
|
const getbrands = () => {
|
||||||
axios
|
axios
|
||||||
.get(`/api/tax/view_tax`, {
|
.get(`/api/brand/getBrands`, {
|
||||||
headers: {
|
headers: {
|
||||||
"Access-Control-Allow-Origin": "*",
|
"Access-Control-Allow-Origin": "*",
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
setTaxes(res.data);
|
setBrands(res?.data?.brands);
|
||||||
|
setLoading(false);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setLoading(false);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getCategories();
|
getCategories();
|
||||||
getTaxes();
|
getbrands();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleView = (n) => {
|
const handleView = (n) => {
|
||||||
@ -100,7 +103,7 @@ const AddProduct = () => {
|
|||||||
<ProductDetails
|
<ProductDetails
|
||||||
data={{ data, setData }}
|
data={{ data, setData }}
|
||||||
categories={categories}
|
categories={categories}
|
||||||
taxes={taxes}
|
brands={brands}
|
||||||
ProductId={{ productId, setProductId }}
|
ProductId={{ productId, setProductId }}
|
||||||
loading={{ loading, setLoading }}
|
loading={{ loading, setLoading }}
|
||||||
/>
|
/>
|
||||||
|
@ -22,19 +22,20 @@ const EditProduct = () => {
|
|||||||
const [viewState, setViewState] = useState(1);
|
const [viewState, setViewState] = useState(1);
|
||||||
const [images, setImages] = useState([]);
|
const [images, setImages] = useState([]);
|
||||||
const [categories, setCategories] = useState([]);
|
const [categories, setCategories] = useState([]);
|
||||||
const [taxes, setTaxes] = useState([]);
|
const [brands, setBrands] = useState([]);
|
||||||
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
const [data, setData] = useState({
|
const [data, setData] = useState({
|
||||||
|
SKU:"",
|
||||||
name: "",
|
name: "",
|
||||||
category: "",
|
category: "",
|
||||||
|
brand: "",
|
||||||
description: "",
|
description: "",
|
||||||
price: "",
|
price: "",
|
||||||
GST: "",
|
GST: "",
|
||||||
|
HSN_Code: "",
|
||||||
product_Status: "",
|
product_Status: "",
|
||||||
special_instructions: "",
|
|
||||||
});
|
});
|
||||||
|
|
||||||
///////////////
|
///////////////
|
||||||
@ -52,7 +53,7 @@ const EditProduct = () => {
|
|||||||
...prev,
|
...prev,
|
||||||
...res.data?.data,
|
...res.data?.data,
|
||||||
category: res.data?.data?.category?._id,
|
category: res.data?.data?.category?._id,
|
||||||
GST: res.data?.data?.GST?._id,
|
brand: res.data?.data?.brand?._id,
|
||||||
product_Status: res.data?.data?.product_Status,
|
product_Status: res.data?.data?.product_Status,
|
||||||
}));
|
}));
|
||||||
setProductId(res.data?.data?._id);
|
setProductId(res.data?.data?._id);
|
||||||
@ -80,23 +81,27 @@ const EditProduct = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const getTaxes = () => {
|
const getbrands = () => {
|
||||||
axios
|
axios
|
||||||
.get(`/api/tax/view_tax`, {
|
.get(`/api/brand/getBrands`, {
|
||||||
headers: {
|
headers: {
|
||||||
"Access-Control-Allow-Origin": "*",
|
"Access-Control-Allow-Origin": "*",
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
setTaxes(res.data);
|
setBrands(res?.data?.brands);
|
||||||
|
setLoading(false);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setLoading(false);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getProduct();
|
getProduct();
|
||||||
getCategories();
|
getCategories();
|
||||||
getTaxes();
|
getbrands();
|
||||||
}, []);
|
}, []);
|
||||||
const handleView = (n) => {
|
const handleView = (n) => {
|
||||||
if (viewState === n) return;
|
if (viewState === n) return;
|
||||||
@ -145,7 +150,7 @@ const EditProduct = () => {
|
|||||||
<ProductDetails
|
<ProductDetails
|
||||||
data={{ data, setData }}
|
data={{ data, setData }}
|
||||||
categories={categories}
|
categories={categories}
|
||||||
taxes={taxes}
|
brands={brands}
|
||||||
ProductId={{ productId, setProductId }}
|
ProductId={{ productId, setProductId }}
|
||||||
loading={{ loading, setLoading }}
|
loading={{ loading, setLoading }}
|
||||||
/>
|
/>
|
||||||
|
@ -8,31 +8,23 @@ const ProductDetails = (props) => {
|
|||||||
const { data, setData } = props.data;
|
const { data, setData } = props.data;
|
||||||
const { productId, setProductId } = props.ProductId;
|
const { productId, setProductId } = props.ProductId;
|
||||||
const { loading, setLoading } = props.loading;
|
const { loading, setLoading } = props.loading;
|
||||||
const taxes = props.taxes;
|
|
||||||
|
|
||||||
const categories = props?.categories || [];
|
const categories = props?.categories || [];
|
||||||
|
const brands = props?.brands || [];
|
||||||
|
|
||||||
const handleChange = (e) => {
|
const handleChange = (e) => {
|
||||||
if (e.target.id === "master_price" && /^\D+$/.test(e.target.value)) return;
|
|
||||||
if (e.target.id === "discontinue_on") {
|
|
||||||
if (new Date(e.target.value) < new Date()) {
|
|
||||||
return setData((prev) => ({
|
|
||||||
...prev,
|
|
||||||
[e.target.id]: new Date().toISOString().slice(0, 10),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setData((prev) => ({ ...prev, [e.target.id]: e.target.value }));
|
setData((prev) => ({ ...prev, [e.target.id]: e.target.value }));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = () => {
|
const handleSubmit = () => {
|
||||||
if (
|
if (
|
||||||
data.name.trim() === "" ||
|
data.name.trim() === "" ||
|
||||||
data.master_price === "" ||
|
data.price === "" ||
|
||||||
data.master_GST === "" ||
|
data.GST === "" ||
|
||||||
data.category === "" ||
|
data.category === "" ||
|
||||||
data.description === "" ||
|
data.description === "" ||
|
||||||
data.product_Status === ""
|
data.product_Status === ""||
|
||||||
|
data.HSN_Code === "" ||
|
||||||
|
data.brand === ""
|
||||||
) {
|
) {
|
||||||
swal({
|
swal({
|
||||||
title: "Warning",
|
title: "Warning",
|
||||||
@ -78,7 +70,7 @@ const ProductDetails = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="d-flex justify-content-between">
|
<div className="d-flex justify-content-between mb-3">
|
||||||
<h5>Product Details</h5>
|
<h5>Product Details</h5>
|
||||||
<button
|
<button
|
||||||
className="btn btn-primary btn-sm"
|
className="btn btn-primary btn-sm"
|
||||||
@ -89,10 +81,12 @@ const ProductDetails = (props) => {
|
|||||||
{loading ? "Loading" : "Save Details"}
|
{loading ? "Loading" : "Save Details"}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-3">
|
|
||||||
<label htmlFor="product" className="form-label">
|
<div className="mb-3 row d-flex align-items-center">
|
||||||
|
<label htmlFor="SKU" className="form-label col-sm-3">
|
||||||
Product SKU*
|
Product SKU*
|
||||||
</label>
|
</label>
|
||||||
|
<div className="col-sm-9">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="form-control"
|
className="form-control"
|
||||||
@ -102,10 +96,13 @@ const ProductDetails = (props) => {
|
|||||||
onChange={(e) => handleChange(e)}
|
onChange={(e) => handleChange(e)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-3">
|
</div>
|
||||||
<label htmlFor="product" className="form-label">
|
|
||||||
|
<div className="mb-3 row d-flex align-items-center">
|
||||||
|
<label htmlFor="name" className="form-label col-sm-3">
|
||||||
Product Name*
|
Product Name*
|
||||||
</label>
|
</label>
|
||||||
|
<div className="col-sm-9">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="form-control"
|
className="form-control"
|
||||||
@ -115,11 +112,13 @@ const ProductDetails = (props) => {
|
|||||||
onChange={(e) => handleChange(e)}
|
onChange={(e) => handleChange(e)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-3 row">
|
</div>
|
||||||
<div className="col-lg-6 ">
|
|
||||||
<label htmlFor="product" className="form-label">
|
<div className="mb-3 row d-flex align-items-center">
|
||||||
|
<label htmlFor="category" className="form-label col-sm-3">
|
||||||
Category *
|
Category *
|
||||||
</label>
|
</label>
|
||||||
|
<div className="col-sm-9">
|
||||||
<select
|
<select
|
||||||
id="category"
|
id="category"
|
||||||
onChange={(e) => handleChange(e)}
|
onChange={(e) => handleChange(e)}
|
||||||
@ -140,11 +139,55 @@ const ProductDetails = (props) => {
|
|||||||
)}
|
)}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3 row d-flex align-items-center">
|
||||||
|
<label htmlFor="brand" className="form-label col-sm-3">
|
||||||
|
Brand *
|
||||||
|
</label>
|
||||||
|
<div className="col-sm-9">
|
||||||
|
<select
|
||||||
|
id="brand"
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
className="form-control"
|
||||||
|
value={data.brand}
|
||||||
|
>
|
||||||
|
<option value="">---select---</option>
|
||||||
|
{brands ? (
|
||||||
|
brands.map((item, index) => (
|
||||||
|
<option value={item._id} key={index}>
|
||||||
|
{item.brandName}
|
||||||
|
</option>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<option value="" disabled>
|
||||||
|
Add Brand to select
|
||||||
|
</option>
|
||||||
|
)}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="col-lg-6">
|
<div className="mb-3 row d-flex align-items-center">
|
||||||
<label htmlFor="title" className="form-label">
|
<label htmlFor="price" className="form-label col-sm-3">
|
||||||
Product Status *
|
Price*
|
||||||
</label>{" "}
|
</label>
|
||||||
|
<div className="col-sm-9">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="price"
|
||||||
|
name="price"
|
||||||
|
value={data.price}
|
||||||
|
maxLength="6"
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3 row d-flex align-items-center">
|
||||||
|
<label htmlFor="product_Status" className="form-label col-sm-3">
|
||||||
|
Product Status
|
||||||
|
</label>
|
||||||
|
<div className="col-sm-9">
|
||||||
<select
|
<select
|
||||||
className="form-control"
|
className="form-control"
|
||||||
name="product_Status"
|
name="product_Status"
|
||||||
@ -158,48 +201,43 @@ const ProductDetails = (props) => {
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-3 row">
|
|
||||||
<div className="col-lg-6">
|
<div className="mb-3 row d-flex align-items-center">
|
||||||
<label htmlFor="product" className="form-label">
|
<label htmlFor="GST" className="form-label col-sm-3">
|
||||||
Price*
|
GST Rate (in %)*
|
||||||
</label>
|
</label>
|
||||||
|
<div className="col-sm-9">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="form-control"
|
className="form-control"
|
||||||
placeholder=""
|
id="GST"
|
||||||
id="price"
|
value={data.GST}
|
||||||
name="price"
|
maxLength="3"
|
||||||
value={data.price}
|
|
||||||
maxLength="6"
|
|
||||||
onChange={(e) => handleChange(e)}
|
onChange={(e) => handleChange(e)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-lg-6 ">
|
</div>
|
||||||
<label htmlFor="product" className="form-label">
|
<div className="mb-3 row d-flex align-items-center">
|
||||||
GST *
|
<label htmlFor="HSN" className="form-label col-sm-3">
|
||||||
|
HSN Code*
|
||||||
</label>
|
</label>
|
||||||
<select
|
<div className="col-sm-9">
|
||||||
name="GST"
|
<input
|
||||||
// value={r.gst_Id?._id ? r.gst_Id?._id : r.gst_Id}
|
type="text"
|
||||||
value={data?.GST}
|
|
||||||
onChange={(e) => handleChange(e)}
|
|
||||||
id="GST"
|
|
||||||
className="form-control"
|
className="form-control"
|
||||||
>
|
id="HSN_Code"
|
||||||
<option value="">---select---</option>
|
value={data.HSN_Code}
|
||||||
{taxes &&
|
maxLength="50"
|
||||||
taxes.map((item, index) => (
|
onChange={(e) => handleChange(e)}
|
||||||
<option value={item._id} key={index}>
|
/>
|
||||||
{item.tax} %{item.name}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-3">
|
|
||||||
<label htmlFor="product" className="form-label">
|
<div className="mb-3 row d-flex align-items-center">
|
||||||
Description*
|
<label htmlFor="description" className="form-label col-sm-3">
|
||||||
|
Description
|
||||||
</label>
|
</label>
|
||||||
|
<div className="col-sm-9">
|
||||||
<textarea
|
<textarea
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="description"
|
id="description"
|
||||||
@ -208,25 +246,10 @@ const ProductDetails = (props) => {
|
|||||||
onChange={(e) => handleChange(e)}
|
onChange={(e) => handleChange(e)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-3">
|
|
||||||
<label htmlFor="product" className="form-label">
|
|
||||||
Special Instructions
|
|
||||||
</label>
|
|
||||||
<textarea
|
|
||||||
className="form-control"
|
|
||||||
placeholder="Text..."
|
|
||||||
style={{
|
|
||||||
whiteSpace: "pre-wrap",
|
|
||||||
minHeight: "100px",
|
|
||||||
overflowWrap: "break-word",
|
|
||||||
}}
|
|
||||||
value={data.special_instructions}
|
|
||||||
onChange={handleChange}
|
|
||||||
id="special_instructions"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ProductDetails;
|
export default ProductDetails;
|
||||||
|
@ -13,9 +13,11 @@ const Products = () => {
|
|||||||
const [success, setSuccess] = useState(true);
|
const [success, setSuccess] = useState(true);
|
||||||
const [productsData, setProductsData] = useState([]);
|
const [productsData, setProductsData] = useState([]);
|
||||||
const [categories, setCategories] = useState([]);
|
const [categories, setCategories] = useState([]);
|
||||||
|
const [brands, setBrands] = useState([]);
|
||||||
|
|
||||||
const nameRef = useRef();
|
const nameRef = useRef();
|
||||||
const categoryRef = useRef();
|
const categoryRef = useRef();
|
||||||
|
const brandRef = useRef();
|
||||||
|
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const [itemPerPage, setItemPerPage] = useState(10);
|
const [itemPerPage, setItemPerPage] = useState(10);
|
||||||
@ -33,6 +35,7 @@ const Products = () => {
|
|||||||
show: itemPerPage,
|
show: itemPerPage,
|
||||||
name: nameRef.current?.value || "",
|
name: nameRef.current?.value || "",
|
||||||
category: categoryRef.current?.value || "",
|
category: categoryRef.current?.value || "",
|
||||||
|
brand: brandRef.current?.value || "",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
setProductsData(response.data?.products || []);
|
setProductsData(response.data?.products || []);
|
||||||
@ -64,6 +67,20 @@ const Products = () => {
|
|||||||
setCategories(res?.data?.categories);
|
setCategories(res?.data?.categories);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
const getBrands = () => {
|
||||||
|
axios
|
||||||
|
.get(`/api/brand/getBrands`, {
|
||||||
|
headers: {
|
||||||
|
"Access-Control-Allow-Origin": "*",
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
// console.log(res?.data?.brands);
|
||||||
|
setBrands(res?.data?.brands);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const [currencyDetails, setCurrencyDetails] = useState(null);
|
const [currencyDetails, setCurrencyDetails] = useState(null);
|
||||||
|
|
||||||
const getCurrency = async () => {
|
const getCurrency = async () => {
|
||||||
@ -84,6 +101,7 @@ const Products = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getCatagories();
|
getCatagories();
|
||||||
getCurrency();
|
getCurrency();
|
||||||
|
getBrands();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -276,6 +294,22 @@ const Products = () => {
|
|||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="col-lg-3">
|
||||||
|
<label>Filter by Brand:</label>
|
||||||
|
<select
|
||||||
|
className="form-control"
|
||||||
|
ref={brandRef}
|
||||||
|
onChange={handleSearchChange}
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
<option value="">All</option>
|
||||||
|
{brands?.map((e, i) => (
|
||||||
|
<option key={i} value={e._id}>
|
||||||
|
{e?.brandName}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="table-responsive table-shoot mt-3">
|
<div className="table-responsive table-shoot mt-3">
|
||||||
@ -291,8 +325,8 @@ const Products = () => {
|
|||||||
<th className="text-start">Image</th>
|
<th className="text-start">Image</th>
|
||||||
<th className="text-start">SKU</th>
|
<th className="text-start">SKU</th>
|
||||||
<th className="text-start">Product</th>
|
<th className="text-start">Product</th>
|
||||||
<th className="text-start">Category</th>
|
<th className="text-start">Category Name</th>
|
||||||
|
<th className="text-start">Brand Name</th>
|
||||||
<th className="text-start">Price</th>
|
<th className="text-start">Price</th>
|
||||||
<th className="text-start">Status</th>
|
<th className="text-start">Status</th>
|
||||||
|
|
||||||
@ -340,6 +374,11 @@ const Products = () => {
|
|||||||
? product.category?.categoryName
|
? product.category?.categoryName
|
||||||
: "Category Not selected "}
|
: "Category Not selected "}
|
||||||
</td>
|
</td>
|
||||||
|
<td className="text-start">
|
||||||
|
{product.brand?.brandName !== ""
|
||||||
|
? product.brand?.brandName
|
||||||
|
: "Brand Not selected "}
|
||||||
|
</td>
|
||||||
<th className="text-start">
|
<th className="text-start">
|
||||||
{currencyDetails?.CurrencySymbol}
|
{currencyDetails?.CurrencySymbol}
|
||||||
{product?.price}
|
{product?.price}
|
||||||
|
@ -78,6 +78,10 @@ const ViewProduct = () => {
|
|||||||
<th>Product Group</th>
|
<th>Product Group</th>
|
||||||
<td>{productData?.category?.categoryName}</td>
|
<td>{productData?.category?.categoryName}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Product Brand</th>
|
||||||
|
<td>{productData?.brand?.brandName}</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Images</th>
|
<th>Images</th>
|
||||||
<td>
|
<td>
|
||||||
@ -107,10 +111,17 @@ const ViewProduct = () => {
|
|||||||
)}
|
)}
|
||||||
{productData?.GST && (
|
{productData?.GST && (
|
||||||
<tr>
|
<tr>
|
||||||
<th>Master GST</th>
|
<th>GST</th>
|
||||||
<td>
|
<td>
|
||||||
{productData?.GST?.tax}%{" "}
|
{productData?.GST}%
|
||||||
{productData?.GST?.name}
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
{productData?.HSN_Code && (
|
||||||
|
<tr>
|
||||||
|
<th>HSN_Code</th>
|
||||||
|
<td>
|
||||||
|
{productData?.HSN_Code}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
)}
|
)}
|
||||||
@ -121,7 +132,7 @@ const ViewProduct = () => {
|
|||||||
{currencyDetails?.CurrencySymbol}
|
{currencyDetails?.CurrencySymbol}
|
||||||
{(
|
{(
|
||||||
(Number(productData?.price) *
|
(Number(productData?.price) *
|
||||||
Number(productData?.GST?.tax)) /
|
Number(productData?.GST)) /
|
||||||
100
|
100
|
||||||
)?.toFixed(2)}
|
)?.toFixed(2)}
|
||||||
</td>
|
</td>
|
||||||
@ -143,19 +154,6 @@ const ViewProduct = () => {
|
|||||||
{productData?.product_Status}
|
{productData?.product_Status}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<th>Special Instructions</th>
|
|
||||||
<td>
|
|
||||||
<p
|
|
||||||
style={{ whiteSpace: "pre-line" }}
|
|
||||||
className="m-0 p-0"
|
|
||||||
>
|
|
||||||
{productData?.special_instructions
|
|
||||||
? productData?.special_instructions
|
|
||||||
: "---"}
|
|
||||||
</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
</thead>
|
||||||
<tbody></tbody>
|
<tbody></tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { isAutheticated } from "src/auth";
|
import { isAutheticated } from "src/auth";
|
||||||
@ -17,9 +17,35 @@ const AddSalesCoOrdinator = () => {
|
|||||||
countryCode: "+91",
|
countryCode: "+91",
|
||||||
mobileNumber: "",
|
mobileNumber: "",
|
||||||
otp: "",
|
otp: "",
|
||||||
|
territoryManager: "", // Add territoryManager field
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const [territoryManagers, setTerritoryManagers] = useState([]); // State for storing fetched territory managers
|
||||||
const [showModal, setShowModal] = useState(false);
|
const [showModal, setShowModal] = useState(false);
|
||||||
|
const [loading, setLoading] = useState(false); // Loading state for the Territory Manager dropdown
|
||||||
|
|
||||||
|
// Fetch Territory Managers when the component mounts
|
||||||
|
useEffect(() => {
|
||||||
|
getTerritoryManagers();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const getTerritoryManagers = () => {
|
||||||
|
setLoading(true);
|
||||||
|
axios
|
||||||
|
.get(`/api/territorymanager/getAll/`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
setTerritoryManagers(res.data.territoryManager || []); // Store the response data
|
||||||
|
setLoading(false);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const handleChange = (e) => {
|
const handleChange = (e) => {
|
||||||
setFormData({ ...formData, [e.target.name]: e.target.value });
|
setFormData({ ...formData, [e.target.name]: e.target.value });
|
||||||
@ -81,9 +107,8 @@ const AddSalesCoOrdinator = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function to handle cancel button click
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
navigate("/salescoordinators"); // Navigate to '/salescoordinators'
|
navigate("/salescoordinators");
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -105,6 +130,26 @@ const AddSalesCoOrdinator = () => {
|
|||||||
<div className="card">
|
<div className="card">
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
<form onSubmit={handleRegister}>
|
<form onSubmit={handleRegister}>
|
||||||
|
<div className="form-group d-flex align-items-center">
|
||||||
|
<label className="mr-2">Add Territory Manager:</label>
|
||||||
|
<select
|
||||||
|
className="form-control"
|
||||||
|
name="territoryManager"
|
||||||
|
onChange={handleChange}
|
||||||
|
value={formData.territoryManager}
|
||||||
|
disabled={loading}
|
||||||
|
required
|
||||||
|
style={{ width: "auto", flex: 1 }}
|
||||||
|
>
|
||||||
|
<option value="">Select Territory Manager</option>
|
||||||
|
{territoryManagers.map((tm) => (
|
||||||
|
<option key={tm._id} value={tm._id}>
|
||||||
|
{tm.name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label>Name</label>
|
<label>Name</label>
|
||||||
<input
|
<input
|
||||||
|
@ -1,221 +0,0 @@
|
|||||||
import axios from "axios";
|
|
||||||
import React, { useState } from "react";
|
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
import swal from "sweetalert";
|
|
||||||
|
|
||||||
function Addtax() {
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const token = isAutheticated();
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
const [data, setData] = useState({
|
|
||||||
name: "",
|
|
||||||
tax: "",
|
|
||||||
hsn_code: "",
|
|
||||||
});
|
|
||||||
const [limiter, setLimiter] = useState({
|
|
||||||
name: 50,
|
|
||||||
namehas: 50,
|
|
||||||
tax: 2,
|
|
||||||
taxhas: 2,
|
|
||||||
hsn_code: 10,
|
|
||||||
hsn_codehas: 10,
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleChange = (e) => {
|
|
||||||
if (
|
|
||||||
(e.target.name === "tax" || e.target.name === "hsn_code") &&
|
|
||||||
/^\D+$/.test(e.target.value)
|
|
||||||
)
|
|
||||||
return;
|
|
||||||
setData((prev) => ({ ...prev, [e.target.name]: e.target.value }));
|
|
||||||
setLimiter((prev) => ({
|
|
||||||
...prev,
|
|
||||||
[e.target.name + "has"]: prev[e.target.name] - e.target.value.length,
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
async function handleSubmit() {
|
|
||||||
if (
|
|
||||||
(data.name.trim() === "" || data.tax.trim() === "",
|
|
||||||
data.hsn_code.trim() === "")
|
|
||||||
) {
|
|
||||||
return swal("Error", "All fields are required!", "error");
|
|
||||||
}
|
|
||||||
setLoading(true);
|
|
||||||
await axios
|
|
||||||
.post(`/api/tax/add_tax`, data, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
setLoading(false);
|
|
||||||
swal("Success", "Tax added successfully", "success");
|
|
||||||
navigate("/tax", { replace: true });
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
// console.log(err)
|
|
||||||
swal(
|
|
||||||
"Error",
|
|
||||||
err.response.data.message
|
|
||||||
? err.response.data.message
|
|
||||||
: "Something Went Wrong",
|
|
||||||
"error"
|
|
||||||
);
|
|
||||||
setLoading(false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<h4 className="mb-0">Add New GST Rate</h4>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row my-2">
|
|
||||||
<div className="col-12">
|
|
||||||
<div className="form-group text-right">
|
|
||||||
<button
|
|
||||||
onClick={() => handleSubmit()}
|
|
||||||
type="button"
|
|
||||||
disabled={loading}
|
|
||||||
className="
|
|
||||||
btn btn-success btn-login
|
|
||||||
waves-effect waves-light
|
|
||||||
me-3
|
|
||||||
"
|
|
||||||
>
|
|
||||||
Save
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<Link to="/tax">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-success btn-cancel
|
|
||||||
waves-effect waves-light
|
|
||||||
mr-3
|
|
||||||
"
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</button>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-lg-8">
|
|
||||||
<div className="card">
|
|
||||||
<div className="card-body">
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-md-12">
|
|
||||||
<form>
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-lg-12">
|
|
||||||
<div className="form-group">
|
|
||||||
<label
|
|
||||||
htmlFor="basicpill-phoneno-input"
|
|
||||||
className="label-100"
|
|
||||||
>
|
|
||||||
Name*
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
value={data.name}
|
|
||||||
onChange={(e) => handleChange(e)}
|
|
||||||
type="text"
|
|
||||||
name="name"
|
|
||||||
className="form-control input-field"
|
|
||||||
maxLength={limiter.name}
|
|
||||||
/>
|
|
||||||
<label
|
|
||||||
htmlFor="basicpill-phoneno-input"
|
|
||||||
className="label-100"
|
|
||||||
>
|
|
||||||
Remaining Characters: {limiter.namehas}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row mt-2">
|
|
||||||
<div className="col-lg-12">
|
|
||||||
<div className="form-group">
|
|
||||||
<label
|
|
||||||
htmlFor="basicpill-phoneno-input"
|
|
||||||
className="label-100"
|
|
||||||
>
|
|
||||||
HSN Code*
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
value={data.hsn_code}
|
|
||||||
onChange={(e) => handleChange(e)}
|
|
||||||
type="text"
|
|
||||||
name="hsn_code"
|
|
||||||
maxLength={limiter.hsn_code}
|
|
||||||
className="form-control input-field"
|
|
||||||
/>
|
|
||||||
<label
|
|
||||||
htmlFor="basicpill-phoneno-input"
|
|
||||||
className="label-100"
|
|
||||||
>
|
|
||||||
Remaining Characters: {limiter.hsn_codehas}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row mt-2">
|
|
||||||
<div className="col-lg-12">
|
|
||||||
<div className="form-group">
|
|
||||||
<label
|
|
||||||
htmlFor="basicpill-phoneno-input"
|
|
||||||
className="label-100"
|
|
||||||
>
|
|
||||||
GST Rate (in %)*
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
value={data.tax}
|
|
||||||
onChange={(e) => handleChange(e)}
|
|
||||||
type="text"
|
|
||||||
name="tax"
|
|
||||||
maxLength={limiter.tax}
|
|
||||||
className="form-control input-field"
|
|
||||||
/>
|
|
||||||
<label
|
|
||||||
htmlFor="basicpill-phoneno-input"
|
|
||||||
className="label-100"
|
|
||||||
>
|
|
||||||
Remaining Characters: {limiter.taxhas}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Addtax;
|
|
@ -1,231 +0,0 @@
|
|||||||
import axios from "axios";
|
|
||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { Link, useParams, useNavigate } from "react-router-dom";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
|
|
||||||
function Edittax() {
|
|
||||||
const { id } = useParams();
|
|
||||||
const token = isAutheticated();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
const [data, setData] = useState({
|
|
||||||
name: "",
|
|
||||||
tax: "",
|
|
||||||
hsn_code: "",
|
|
||||||
});
|
|
||||||
const [limiter, setLimiter] = useState({
|
|
||||||
name: 50,
|
|
||||||
namehas: 50,
|
|
||||||
tax: 2,
|
|
||||||
taxhas: 2,
|
|
||||||
hsn_code: 10,
|
|
||||||
hsn_codehas: 10,
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
function getTax() {
|
|
||||||
setLoading(true);
|
|
||||||
axios
|
|
||||||
.get(`/api/tax/view_tax/${id}`, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
setLoading(false);
|
|
||||||
setData((prev) => ({
|
|
||||||
...prev,
|
|
||||||
name: res.data?.name,
|
|
||||||
tax: res.data?.tax?.toString(),
|
|
||||||
hsn_code: res.data?.hsn_code?.toString(),
|
|
||||||
}));
|
|
||||||
setLimiter((prev) => ({
|
|
||||||
...prev,
|
|
||||||
namehas: prev.name - res.data?.name.length,
|
|
||||||
taxhas: prev.tax - res.data?.tax?.toString().length,
|
|
||||||
hsn_codehas: prev.hsn_code - res.data?.hsn_code.toString()?.length,
|
|
||||||
}));
|
|
||||||
})
|
|
||||||
.catch((res) => {
|
|
||||||
setLoading(false);
|
|
||||||
navigate("/tax", { replace: true });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
getTax();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleChange = (e) => {
|
|
||||||
if (
|
|
||||||
(e.target.name === "tax" || e.target.name === "hsn_code") &&
|
|
||||||
/^\D+$/.test(e.target.value)
|
|
||||||
)
|
|
||||||
return;
|
|
||||||
setData((prev) => ({ ...prev, [e.target.name]: e.target.value }));
|
|
||||||
setLimiter((prev) => ({
|
|
||||||
...prev,
|
|
||||||
[e.target.name + "has"]: prev[e.target.name] - e.target.value.length,
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
function handleSubmit() {
|
|
||||||
if (
|
|
||||||
(data.name.trim() === "" || data.tax.trim() === "",
|
|
||||||
data.hsn_code.trim() === "")
|
|
||||||
) {
|
|
||||||
return swal("Error", "All fields are required!", "error");
|
|
||||||
}
|
|
||||||
setLoading(true);
|
|
||||||
axios
|
|
||||||
.patch(`/api/tax/update_tax/${id}`, data, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
setLoading(false);
|
|
||||||
swal("Success", "Tax updated successfully", "success");
|
|
||||||
navigate("/tax", { replace: true });
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
swal("Error", "Something went wrong!", "error");
|
|
||||||
setLoading(false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="main-content">
|
|
||||||
<div className="page-content">
|
|
||||||
<div className="container-fluid">
|
|
||||||
<div className="row mb-2">
|
|
||||||
<div className="col-12">
|
|
||||||
<div className="form-group text-right">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => handleSubmit()}
|
|
||||||
disabled={loading}
|
|
||||||
className="
|
|
||||||
btn btn-success btn-login
|
|
||||||
waves-effect waves-light
|
|
||||||
me-3
|
|
||||||
"
|
|
||||||
>
|
|
||||||
Save
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<Link to="/tax">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-success btn-cancel
|
|
||||||
waves-effect waves-light
|
|
||||||
mr-3
|
|
||||||
"
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</button>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-lg-8">
|
|
||||||
<div className="card">
|
|
||||||
<div className="card-body">
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-md-12">
|
|
||||||
<form>
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-lg-12">
|
|
||||||
<div className="form-group">
|
|
||||||
<label
|
|
||||||
htmlFor="basicpill-phoneno-input"
|
|
||||||
className="label-100"
|
|
||||||
>
|
|
||||||
Name*
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
value={data.name}
|
|
||||||
onChange={(e) => handleChange(e)}
|
|
||||||
type="text"
|
|
||||||
name="name"
|
|
||||||
className="form-control input-field"
|
|
||||||
maxLength={limiter.name}
|
|
||||||
/>
|
|
||||||
<label
|
|
||||||
htmlFor="basicpill-phoneno-input"
|
|
||||||
className="label-100"
|
|
||||||
>
|
|
||||||
Remaining Characters: {limiter.namehas}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row mt-2">
|
|
||||||
<div className="col-lg-12">
|
|
||||||
<div className="form-group">
|
|
||||||
<label
|
|
||||||
htmlFor="basicpill-phoneno-input"
|
|
||||||
className="label-100"
|
|
||||||
>
|
|
||||||
HSN Code*
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
value={data.hsn_code}
|
|
||||||
onChange={(e) => handleChange(e)}
|
|
||||||
type="text"
|
|
||||||
name="hsn_code"
|
|
||||||
maxLength={limiter.hsn_code}
|
|
||||||
className="form-control input-field"
|
|
||||||
/>
|
|
||||||
<label
|
|
||||||
htmlFor="basicpill-phoneno-input"
|
|
||||||
className="label-100"
|
|
||||||
>
|
|
||||||
Remaining Characters: {limiter.hsn_codehas}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row mt-2">
|
|
||||||
<div className="col-lg-12">
|
|
||||||
<div className="form-group">
|
|
||||||
<label
|
|
||||||
htmlFor="basicpill-phoneno-input"
|
|
||||||
className="label-100"
|
|
||||||
>
|
|
||||||
GST Rate (in %)*
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
value={data.tax}
|
|
||||||
onChange={(e) => handleChange(e)}
|
|
||||||
type="text"
|
|
||||||
name="tax"
|
|
||||||
maxLength={limiter.tax}
|
|
||||||
className="form-control input-field"
|
|
||||||
/>
|
|
||||||
<label
|
|
||||||
htmlFor="basicpill-phoneno-input"
|
|
||||||
className="label-100"
|
|
||||||
>
|
|
||||||
Remaining Characters: {limiter.taxhas}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Edittax;
|
|
@ -1,224 +0,0 @@
|
|||||||
import axios from "axios";
|
|
||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
|
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
import swal from "sweetalert";
|
|
||||||
|
|
||||||
function Tax() {
|
|
||||||
const [taxList, settaxList] = useState([]);
|
|
||||||
const [success, setSuccess] = useState(true);
|
|
||||||
const [loading, setLoading] = useState(true);
|
|
||||||
const token = isAutheticated();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
function getTaxes() {
|
|
||||||
setLoading(true);
|
|
||||||
axios
|
|
||||||
.get(`/api/tax/view_tax`, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
setLoading(false);
|
|
||||||
settaxList(res.data);
|
|
||||||
})
|
|
||||||
.catch((err) => setLoading(false));
|
|
||||||
}
|
|
||||||
getTaxes();
|
|
||||||
}, [success]);
|
|
||||||
|
|
||||||
function handleDelete(id) {
|
|
||||||
axios
|
|
||||||
.delete(`/api/tax/delete_tax/${id}`, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => setSuccess((prev) => !prev))
|
|
||||||
.catch((err) => swal("Error!", "Something went wrong!", "error"));
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<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 ml-0 mr-0 mb-10">
|
|
||||||
<div className="col-sm-12 col-md-6"></div>
|
|
||||||
<div className="col-sm-12 col-md-6 text-end">
|
|
||||||
<div className="dropdown d-block">
|
|
||||||
<Link to="/tax/add">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-primary
|
|
||||||
add-btn
|
|
||||||
waves-effect waves-light
|
|
||||||
float-right
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-plus mb-2"
|
|
||||||
aria-hidden="true"
|
|
||||||
></i>{" "}
|
|
||||||
Add New GST Rate
|
|
||||||
</button>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="table-responsive table-shoot mt-2">
|
|
||||||
<table className="table table-centered table-nowrap mb-0">
|
|
||||||
<thead
|
|
||||||
className="thead"
|
|
||||||
style={{ background: "rgb(140, 213, 213)" }}
|
|
||||||
>
|
|
||||||
<tr>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>GST Rate</th>
|
|
||||||
<th>Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{loading && (
|
|
||||||
<tr>
|
|
||||||
<td colSpan="6" className="text-center">
|
|
||||||
Loading...
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
{taxList.map((tax, index) => {
|
|
||||||
return (
|
|
||||||
<tr key={index}>
|
|
||||||
<td>{tax.name}</td>
|
|
||||||
<td>{tax.tax}%</td>
|
|
||||||
<td>
|
|
||||||
<Link to={`/tax/edit/${tax._id}`}>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="btn btn-primary btn-sm waves-effect waves-light btn-table me-2"
|
|
||||||
>
|
|
||||||
Edit
|
|
||||||
</button>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className=" btn btn-danger btn-sm
|
|
||||||
waves-effect waves-light
|
|
||||||
btn-table
|
|
||||||
ml-2
|
|
||||||
"
|
|
||||||
onClick={() => handleDelete(tax._id)}
|
|
||||||
id="sa-params"
|
|
||||||
>
|
|
||||||
Delete
|
|
||||||
</button>
|
|
||||||
</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 1 to 10 of 57 entries
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="col-sm-12 col-md-6">
|
|
||||||
<div
|
|
||||||
className="
|
|
||||||
dataTables_paginate
|
|
||||||
paging_simple_numbers
|
|
||||||
float-right
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<ul className="pagination">
|
|
||||||
<li
|
|
||||||
className="
|
|
||||||
paginate_button
|
|
||||||
page-item
|
|
||||||
previous
|
|
||||||
disabled
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
href="#"
|
|
||||||
aria-controls="datatable"
|
|
||||||
data-dt-idx="0"
|
|
||||||
tabindex="0"
|
|
||||||
className="page-link"
|
|
||||||
>
|
|
||||||
Previous
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li className="paginate_button page-item active">
|
|
||||||
<a
|
|
||||||
href="#"
|
|
||||||
aria-controls="datatable"
|
|
||||||
data-dt-idx="1"
|
|
||||||
tabindex="0"
|
|
||||||
className="page-link"
|
|
||||||
>
|
|
||||||
1
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li className="paginate_button page-item">
|
|
||||||
<a
|
|
||||||
href="#"
|
|
||||||
aria-controls="datatable"
|
|
||||||
data-dt-idx="2"
|
|
||||||
tabindex="0"
|
|
||||||
className="page-link"
|
|
||||||
>
|
|
||||||
2
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li className="paginate_button page-item">
|
|
||||||
<a
|
|
||||||
href="#"
|
|
||||||
aria-controls="datatable"
|
|
||||||
data-dt-idx="3"
|
|
||||||
tabindex="0"
|
|
||||||
className="page-link"
|
|
||||||
>
|
|
||||||
3
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li className="paginate_button page-item next">
|
|
||||||
<a href="#" tabindex="0" className="page-link">
|
|
||||||
Next
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Tax;
|
|
Loading…
Reference in New Issue
Block a user