categories,brands and product update and gst remove

This commit is contained in:
Sibunnayak 2024-08-22 16:33:04 +05:30
parent 3ada9ea922
commit 185bda1261
15 changed files with 832 additions and 1228 deletions

View File

@ -54,16 +54,16 @@ const _nav = [
},
{
component: CNavItem,
name: "Products",
icon: <CIcon icon={cilClipboard} customClassName="nav-icon" />,
to: "/products",
name: "Brands",
icon: <CIcon icon={cilCat} customClassName="nav-icon" />,
to: "/brands",
group: "Product Management",
},
{
component: CNavItem,
name: "GST",
icon: <CIcon icon={cilTablet} customClassName="nav-icon" />,
to: "/tax",
name: "Products",
icon: <CIcon icon={cilClipboard} customClassName="nav-icon" />,
to: "/products",
group: "Product Management",
},
],

View File

@ -42,10 +42,6 @@ import DeliveredOrders from "./views/orders/DeliveredOrders.js";
import CancelledOrders from "./views/orders/CancelledOrders.js";
import ReturnedOrders from "./views/orders/ReturnedOrders.js";
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 ViewOrders from "./views/orders/ViewOrders";
import Departures from "./views/Departures/Departures";
@ -81,6 +77,7 @@ import AddNewAppointment from "./views/Appointments/AddNewAppointment";
import Campaign from "./views/Campaigns/Campaign.js";
import AddCampaign from "./views/Campaigns/AddCampaign.js";
import Categories from "./views/Categories/categories";
import Brands from "./views/Brands/Brands";
import Content from "./views/Content/content";
import EditPrivacyPolicy from "./views/Content/editPrivacyPolicy";
@ -199,6 +196,12 @@ const routes = [
element: Categories,
navName: "Product Management",
},
{
path: "/brands",
name: "Brands",
element: Brands,
navName: "Product Management",
},
//SalesCoOrdinator
{
path: "/salescoordinator/edit/:id",
@ -287,25 +290,6 @@ const routes = [
element: SingleUserleave,
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
{
path: "/retail-distributor",

460
src/views/Brands/Brands.js Normal file
View 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;

View File

@ -13,8 +13,6 @@ import {
import CloseIcon from "@mui/icons-material/Close";
import { ClipLoader } from "react-spinners";
import swal from "sweetalert";
import CloudUploadIcon from "@mui/icons-material/CloudUpload";
import DeleteSharpIcon from "@mui/icons-material/DeleteSharp";
const style = {
position: "absolute",
@ -31,20 +29,17 @@ const style = {
const Categories = () => {
const token = isAutheticated();
const [loading, setLoading] = useState(true);
const [updating, setUpdating] = useState(true); // for loading state
// const [isUpdate, setIsUpdate] = useState(false); // for edit state
const [updating, setUpdating] = useState(true);
const [saveLoding, setSaveLoading] = useState(true);
const [edit, setEdit] = useState(false);
const [categoryName, setCategoryName] = useState("");
const [categoryImage, setCategoryImage] = useState("");
const [error, setError] = useState("");
const [categoryId, setCategoryId] = useState("");
const [category, setCategory] = useState([]);
const [itemPerPage, setItemPerPage] = useState(10);
const [page, setPage] = useState(1);
const [open, setOpen] = useState(false);
const [olderCategoryName, setOlderCategoruName] = useState("");
const [olderImage, setOlderImage] = useState("");
const handleOpen = () => setOpen(true);
const handleClose = () => {
@ -54,8 +49,6 @@ const Categories = () => {
setCategoryName("");
setCategoryId("");
setOlderImage("");
setCategoryImage("");
};
const getCategories = async () => {
@ -71,47 +64,30 @@ const Categories = () => {
setLoading(false);
}
} catch (error) {
swal({
title: error,
text: " please login to access the resource ",
icon: "error",
button: "Retry",
dangerMode: true,
});
console.error("Failed to fetch brands:", error);
}
};
useEffect(() => {
getCategories();
}, [token]);
}, []);
const handleEditClick = (_id, categoryName, categoryImage) => {
const handleEditClick = (_id, categoryName) => {
setOpen(true);
setOlderImage(categoryImage);
setCategoryName(categoryName);
setCategoryId(_id);
setOlderCategoruName(categoryName);
setEdit(true);
// setUpdating(false);
};
const categoryNamesArray = [];
const setCategoryNamesArray = () => {
category &&
category.map((category) => {
categoryNamesArray.push(category.categoryName.toLowerCase());
});
};
setCategoryNamesArray();
const handleUpdate = () => {
const filteredArrayNames = categoryNamesArray.filter(
(item) => item !== olderCategoryName.toLowerCase()
const handleUpdate = async () => {
const filteredArrayNames = category.filter(
(item) => item.categoryName.toLowerCase() !== olderCategoryName.toLowerCase())
.map((item) => item.categoryName.toLowerCase()
);
console.log(filteredArrayNames, "filter");
const categoryExits = filteredArrayNames.includes(
categoryName.toLowerCase()
);
if (categoryExits) {
// console.log(filteredArrayNames, "filter");
if(filteredArrayNames.includes(categoryName.toLowerCase())){
swal({
title: "Warning",
text: "Category already exists ",
@ -119,10 +95,8 @@ const Categories = () => {
button: "Retry",
dangerMode: true,
});
return;
}
if (!categoryName || (!categoryImage && !olderImage)) {
if (!categoryName) {
swal({
title: "Warning",
text: "Please fill all the required fields!",
@ -135,45 +109,32 @@ const Categories = () => {
setUpdating(false);
const formData = new FormData();
formData.append("categoryName", categoryName);
formData.append("categoryImage", categoryImage);
formData.append("olderImage", JSON.stringify(olderImage));
axios
try{
await axios
.patch(`/api/category/update/${categoryId}`, formData, {
headers: {
Authorization: `Bearer ${token}`,
},
})
.then((res) => {
// setUpdating(true);
// setIsUpdate(false);
handleClose();
setCategoryId("");
setCategoryName("");
setCategoryImage("");
setOlderImage("");
setUpdating(true);
setEdit(false);
swal({
title: "Congratulations!!",
text: "The category was updated successfully!",
icon: "success",
button: "OK",
});
// getCategories(); // Refresh the category list after updating
})
.catch((err) => {
swal({
title: "Sorry, please try again",
text: err,
icon: "error",
button: "Retry",
dangerMode: true,
});
setUpdating(true);
getCategories();
}catch(err){
swal({
title: "",
text: "Something went wrong!",
icon: "error",
button: "Retry",
dangerMode: true,
});
}finally{
setUpdating(true);
}
};
const handleDelete = (_id) => {
@ -184,24 +145,23 @@ const Categories = () => {
Yes: { text: "Yes", value: true },
Cancel: { text: "Cancel", value: "cancel" },
},
}).then((value) => {
}).then(async (value) => {
if (value === true) {
axios
try {
await axios
.delete(`/api/category/delete/${_id}`, {
headers: {
Authorization: `Bearer ${token}`,
},
})
.then((res) => {
});
swal({
title: "Congratulations!!",
text: "The category was deleted successfully!",
icon: "success",
button: "OK",
});
// getCategories(); // Refresh the category list after deleting
})
.catch((err) => {
getCategories();
}catch(err) {
swal({
title: "",
text: "Something went wrong!",
@ -209,26 +169,22 @@ const Categories = () => {
button: "Retry",
dangerMode: true,
});
});
}
});
}});
};
const handleSaveCategory = async () => {
const categoryExits = categoryNamesArray.includes(
categoryName.toLowerCase()
);
if (categoryExits) {
if(category.some((item) => item.categoryName.toLowerCase() === categoryName.toLowerCase())){
swal({
title: "Warning",
text: "Category Already exits.",
text: "Category already exists ",
icon: "error",
button: "Retry",
dangerMode: true,
});
return;
}
if (!categoryName || !categoryImage) {
if (!categoryName) {
swal({
title: "Warning",
text: "Please fill all the required fields!",
@ -242,59 +198,38 @@ const Categories = () => {
setLoading(true);
const formData = new FormData();
formData.append("categoryName", categoryName);
formData.append("categoryImage", categoryImage);
axios
try{
await axios
.post("/api/category/add", formData, {
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "multipart/formdata",
},
})
.then((response) => {
if (response.status === 201) {
setOpen(false);
setLoading(false);
setSaveLoading(true);
setCategoryName("");
setCategoryImage("");
setOlderImage("");
swal({
title: "Added",
text: "New category added successfully!",
icon: "success",
button: "OK",
});
// getCategories(); // Refresh the category list after adding
}
})
.catch((error) => {
setSaveLoading(true);
swal({
title: error,
text: "something went wrong",
icon: "error",
button: "Retry",
dangerMode: true,
});
handleClose();
swal({
title: "Congratulations!!",
text: "The category was added successfully!",
icon: "success",
button: "OK",
});
getCategories();
}catch(err){
swal({
title: "",
text: "Something went wrong!",
icon: "error",
button: "Retry",
dangerMode: true,
});
}finally{
setSaveLoading(true);
}
};
const getPageCount = () => {
return Math.max(1, Math.ceil(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 (
<div className="main-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
p={2}
display={"flex"}
@ -593,9 +423,8 @@ const Categories = () => {
style={{ background: "rgb(140, 213, 213)" }}
>
<tr>
<th> Image</th>
<th> Categories Name</th>
<th> Category Name</th>
<th>Action</th>
</tr>
@ -623,15 +452,6 @@ const Categories = () => {
)
.map((item, i) => (
<tr key={i}>
<td>
<img
className="me-2"
src={item?.categoryImage?.secure_url}
width="40"
alt=""
/>
<h5>{ } </h5>
</td>
<td>
<h5>{item.categoryName} </h5>
</td>
@ -653,7 +473,6 @@ const Categories = () => {
handleEditClick(
item._id,
item.categoryName,
item.categoryImage
)
}
>

View File

@ -166,113 +166,6 @@ const Inventory = () => {
</div>
<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
className="table table-centered table-nowrap"
style={{
@ -478,7 +371,6 @@ const Inventory = () => {
)}
</tbody>
</table>
</div>
<div className="row mt-20">
<div className="col-sm-12 col-md-6 mb-20">

View File

@ -134,7 +134,9 @@ try{
<tr>
<th>Product Name</th>
<th>Category</th>
<th>Brand</th>
<th>GST</th>
<th>HSN_Code</th>
<th>price</th>
<th>Message</th>
</tr>
@ -144,7 +146,9 @@ try{
<tr key={index}>
<td>{error.productName || "N/A"}</td>
<td>{error.category || "N/A"}</td>
<td>{error.brand || "N/A"}</td>
<td>{error.GST || "N/A"}</td>
<td>{error.HSN_Code || "N/A"}</td>
<td>{error.price || "N/A"}</td>
<td>{error.message}</td>
</tr>
@ -161,7 +165,9 @@ try{
<tr>
<th>Product Name</th>
<th>Category</th>
<th>Brand</th>
<th>GST</th>
<th>HSN_Code</th>
<th>price</th>
<th>Message</th>
</tr>
@ -171,7 +177,9 @@ try{
<tr key={index}>
<td>{update.name || "N/A"}</td>
<td>{update.category || "N/A"}</td>
<td>{update.brand || "N/A"}</td>
<td>{update.GST || "N/A"}</td>
<td>{update.HSN_Code || "N/A"}</td>
<td>{update.price || "N/A"}</td>
<td>{update.updatedFields}</td>
</tr>
@ -188,7 +196,9 @@ try{
<tr>
<th>Product Name</th>
<th>Category</th>
<th>Brand</th>
<th>GST</th>
<th>HSN_Code</th>
<th>price</th>
</tr>
</thead>
@ -197,7 +207,9 @@ try{
<tr key={index}>
<td>{create.name || "N/A"}</td>
<td>{create.category || "N/A"}</td>
<td>{create.brand || "N/A"}</td>
<td>{create.GST || "N/A"}</td>
<td>{create.HSN_Code || "N/A"}</td>
<td>{create.price || "N/A"}</td>
</tr>
))}

View File

@ -13,22 +13,21 @@ const AddProduct = () => {
const [viewState, setViewState] = useState(1);
const [images, setImages] = useState([]);
const [categories, setCategories] = useState([]);
const [taxes, setTaxes] = useState([]);
const [brands, setBrands] = useState([]);
const [loading, setLoading] = useState(false);
const [data, setData] = useState({
SKU:"",
name: "",
category: "",
brand: "",
description: "",
price: "",
GST: "",
HSN_Code: "",
product_Status: "",
special_instructions: "",
});
const navigate = useNavigate();
const getCategories = () => {
axios
.get(`/api/category/getCategories`, {
@ -46,22 +45,26 @@ const AddProduct = () => {
});
};
const getTaxes = () => {
const getbrands = () => {
axios
.get(`/api/tax/view_tax`, {
.get(`/api/brand/getBrands`, {
headers: {
"Access-Control-Allow-Origin": "*",
Authorization: `Bearer ${token}`,
},
})
.then((res) => {
setTaxes(res.data);
setBrands(res?.data?.brands);
setLoading(false);
})
.catch(() => {
setLoading(false);
});
};
useEffect(() => {
getCategories();
getTaxes();
getbrands();
}, []);
const handleView = (n) => {
@ -100,7 +103,7 @@ const AddProduct = () => {
<ProductDetails
data={{ data, setData }}
categories={categories}
taxes={taxes}
brands={brands}
ProductId={{ productId, setProductId }}
loading={{ loading, setLoading }}
/>

View File

@ -22,19 +22,20 @@ const EditProduct = () => {
const [viewState, setViewState] = useState(1);
const [images, setImages] = useState([]);
const [categories, setCategories] = useState([]);
const [taxes, setTaxes] = useState([]);
const [brands, setBrands] = useState([]);
const navigate = useNavigate();
const [loading, setLoading] = useState(false);
const [data, setData] = useState({
SKU:"",
name: "",
category: "",
brand: "",
description: "",
price: "",
GST: "",
HSN_Code: "",
product_Status: "",
special_instructions: "",
});
///////////////
@ -52,7 +53,7 @@ const EditProduct = () => {
...prev,
...res.data?.data,
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,
}));
setProductId(res.data?.data?._id);
@ -80,23 +81,27 @@ const EditProduct = () => {
});
};
const getTaxes = () => {
const getbrands = () => {
axios
.get(`/api/tax/view_tax`, {
.get(`/api/brand/getBrands`, {
headers: {
"Access-Control-Allow-Origin": "*",
Authorization: `Bearer ${token}`,
},
})
.then((res) => {
setTaxes(res.data);
setBrands(res?.data?.brands);
setLoading(false);
})
.catch(() => {
setLoading(false);
});
};
useEffect(() => {
getProduct();
getCategories();
getTaxes();
getbrands();
}, []);
const handleView = (n) => {
if (viewState === n) return;
@ -145,7 +150,7 @@ const EditProduct = () => {
<ProductDetails
data={{ data, setData }}
categories={categories}
taxes={taxes}
brands={brands}
ProductId={{ productId, setProductId }}
loading={{ loading, setLoading }}
/>

View File

@ -8,31 +8,23 @@ const ProductDetails = (props) => {
const { data, setData } = props.data;
const { productId, setProductId } = props.ProductId;
const { loading, setLoading } = props.loading;
const taxes = props.taxes;
const categories = props?.categories || [];
const brands = props?.brands || [];
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 }));
};
const handleSubmit = () => {
if (
data.name.trim() === "" ||
data.master_price === "" ||
data.master_GST === "" ||
data.price === "" ||
data.GST === "" ||
data.category === "" ||
data.description === "" ||
data.product_Status === ""
data.product_Status === ""||
data.HSN_Code === "" ||
data.brand === ""
) {
swal({
title: "Warning",
@ -78,7 +70,7 @@ const ProductDetails = (props) => {
return (
<>
<div className="d-flex justify-content-between">
<div className="d-flex justify-content-between mb-3">
<h5>Product Details</h5>
<button
className="btn btn-primary btn-sm"
@ -89,144 +81,175 @@ const ProductDetails = (props) => {
{loading ? "Loading" : "Save Details"}
</button>
</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*
</label>
<input
type="text"
className="form-control"
id="SKU"
value={data.SKU}
maxLength="50"
onChange={(e) => handleChange(e)}
/>
</div>
<div className="mb-3">
<label htmlFor="product" className="form-label">
Product Name*
</label>
<input
type="text"
className="form-control"
id="name"
value={data.name}
maxLength="50"
onChange={(e) => handleChange(e)}
/>
</div>
<div className="mb-3 row">
<div className="col-lg-6 ">
<label htmlFor="product" className="form-label">
Category *
</label>
<select
id="category"
onChange={(e) => handleChange(e)}
className="form-control"
value={data.category}
>
<option value="">---select---</option>
{categories ? (
categories.map((item, index) => (
<option value={item._id} key={index}>
{item.categoryName}
</option>
))
) : (
<option value="" disabled>
Add Category to select
</option>
)}
</select>
</div>
<div className="col-lg-6">
<label htmlFor="title" className="form-label">
Product Status *
</label>{" "}
<select
className="form-control"
name="product_Status"
id="product_Status"
value={data.product_Status}
onChange={(e) => handleChange(e)}
>
<option value="">--Select--</option>
<option value="Active">Active</option>
<option value="inActive">inActive</option>
</select>
</div>
</div>
<div className="mb-3 row">
<div className="col-lg-6">
<label htmlFor="product" className="form-label">
Price*
</label>
<div className="col-sm-9">
<input
type="text"
className="form-control"
placeholder=""
id="price"
name="price"
value={data.price}
maxLength="6"
id="SKU"
value={data.SKU}
maxLength="50"
onChange={(e) => handleChange(e)}
/>
</div>
<div className="col-lg-6 ">
<label htmlFor="product" className="form-label">
GST *
</label>
<select
name="GST"
// value={r.gst_Id?._id ? r.gst_Id?._id : r.gst_Id}
value={data?.GST}
onChange={(e) => handleChange(e)}
id="GST"
</div>
<div className="mb-3 row d-flex align-items-center">
<label htmlFor="name" className="form-label col-sm-3">
Product Name*
</label>
<div className="col-sm-9">
<input
type="text"
className="form-control"
>
<option value="">---select---</option>
{taxes &&
taxes.map((item, index) => (
<option value={item._id} key={index}>
{item.tax} %{item.name}
</option>
))}
</select>
id="name"
value={data.name}
maxLength="50"
onChange={(e) => handleChange(e)}
/>
</div>
</div>
<div className="mb-3">
<label htmlFor="product" className="form-label">
Description*
<div className="mb-3 row d-flex align-items-center">
<label htmlFor="category" className="form-label col-sm-3">
Category *
</label>
<div className="col-sm-9">
<select
id="category"
onChange={(e) => handleChange(e)}
className="form-control"
value={data.category}
>
<option value="">---select---</option>
{categories ? (
categories.map((item, index) => (
<option value={item._id} key={index}>
{item.categoryName}
</option>
))
) : (
<option value="" disabled>
Add Category to select
</option>
)}
</select>
</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="mb-3 row d-flex align-items-center">
<label htmlFor="price" className="form-label col-sm-3">
Price*
</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
className="form-control"
name="product_Status"
id="product_Status"
value={data.product_Status}
onChange={(e) => handleChange(e)}
>
<option value="">--Select--</option>
<option value="Active">Active</option>
<option value="inActive">inActive</option>
</select>
</div>
</div>
<div className="mb-3 row d-flex align-items-center">
<label htmlFor="GST" className="form-label col-sm-3">
GST Rate (in %)*
</label>
<div className="col-sm-9">
<input
type="text"
className="form-control"
id="GST"
value={data.GST}
maxLength="3"
onChange={(e) => handleChange(e)}
/>
</div>
</div>
<div className="mb-3 row d-flex align-items-center">
<label htmlFor="HSN" className="form-label col-sm-3">
HSN Code*
</label>
<div className="col-sm-9">
<input
type="text"
className="form-control"
id="HSN_Code"
value={data.HSN_Code}
maxLength="50"
onChange={(e) => handleChange(e)}
/>
</div>
</div>
<div className="mb-3 row d-flex align-items-center">
<label htmlFor="description" className="form-label col-sm-3">
Description
</label>
<textarea
className="form-control"
id="description"
placeholder="Text..."
value={data.description}
onChange={(e) => handleChange(e)}
/>
</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 className="col-sm-9">
<textarea
className="form-control"
id="description"
placeholder="Text..."
value={data.description}
onChange={(e) => handleChange(e)}
/>
</div>
</div>
</>
);
};
export default ProductDetails;

View File

@ -13,9 +13,11 @@ const Products = () => {
const [success, setSuccess] = useState(true);
const [productsData, setProductsData] = useState([]);
const [categories, setCategories] = useState([]);
const [brands, setBrands] = useState([]);
const nameRef = useRef();
const categoryRef = useRef();
const brandRef = useRef();
const [currentPage, setCurrentPage] = useState(1);
const [itemPerPage, setItemPerPage] = useState(10);
@ -33,6 +35,7 @@ const Products = () => {
show: itemPerPage,
name: nameRef.current?.value || "",
category: categoryRef.current?.value || "",
brand: brandRef.current?.value || "",
},
});
setProductsData(response.data?.products || []);
@ -64,6 +67,20 @@ const Products = () => {
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 getCurrency = async () => {
@ -84,6 +101,7 @@ const Products = () => {
useEffect(() => {
getCatagories();
getCurrency();
getBrands();
}, []);
useEffect(() => {
@ -276,6 +294,22 @@ const Products = () => {
))}
</select>
</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 className="table-responsive table-shoot mt-3">
@ -291,8 +325,8 @@ const Products = () => {
<th className="text-start">Image</th>
<th className="text-start">SKU</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">Status</th>
@ -340,6 +374,11 @@ const Products = () => {
? product.category?.categoryName
: "Category Not selected "}
</td>
<td className="text-start">
{product.brand?.brandName !== ""
? product.brand?.brandName
: "Brand Not selected "}
</td>
<th className="text-start">
{currencyDetails?.CurrencySymbol}
{product?.price}

View File

@ -78,6 +78,10 @@ const ViewProduct = () => {
<th>Product Group</th>
<td>{productData?.category?.categoryName}</td>
</tr>
<tr>
<th>Product Brand</th>
<td>{productData?.brand?.brandName}</td>
</tr>
<tr>
<th>Images</th>
<td>
@ -107,10 +111,17 @@ const ViewProduct = () => {
)}
{productData?.GST && (
<tr>
<th>Master GST</th>
<th>GST</th>
<td>
{productData?.GST?.tax}%{" "}
{productData?.GST?.name}
{productData?.GST}%
</td>
</tr>
)}
{productData?.HSN_Code && (
<tr>
<th>HSN_Code</th>
<td>
{productData?.HSN_Code}
</td>
</tr>
)}
@ -121,7 +132,7 @@ const ViewProduct = () => {
{currencyDetails?.CurrencySymbol}
{(
(Number(productData?.price) *
Number(productData?.GST?.tax)) /
Number(productData?.GST)) /
100
)?.toFixed(2)}
</td>
@ -143,19 +154,6 @@ const ViewProduct = () => {
{productData?.product_Status}
</td>
</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>
<tbody></tbody>
</table>

View File

@ -1,4 +1,4 @@
import React, { useState } from "react";
import React, { useState, useEffect } from "react";
import axios from "axios";
import { useNavigate } from "react-router-dom";
import { isAutheticated } from "src/auth";
@ -17,9 +17,35 @@ const AddSalesCoOrdinator = () => {
countryCode: "+91",
mobileNumber: "",
otp: "",
territoryManager: "", // Add territoryManager field
});
const [territoryManagers, setTerritoryManagers] = useState([]); // State for storing fetched territory managers
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) => {
setFormData({ ...formData, [e.target.name]: e.target.value });
@ -81,9 +107,8 @@ const AddSalesCoOrdinator = () => {
}
};
// Function to handle cancel button click
const handleCancel = () => {
navigate("/salescoordinators"); // Navigate to '/salescoordinators'
navigate("/salescoordinators");
};
return (
@ -105,6 +130,26 @@ const AddSalesCoOrdinator = () => {
<div className="card">
<div className="card-body">
<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">
<label>Name</label>
<input

View File

@ -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;

View File

@ -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;

View File

@ -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;