From 185bda1261d7c5d753d6083d82e673c571aab621 Mon Sep 17 00:00:00 2001 From: Sibunnayak Date: Thu, 22 Aug 2024 16:33:04 +0530 Subject: [PATCH] categories,brands and product update and gst remove --- src/_nav.js | 12 +- src/routes.js | 30 +- src/views/Brands/Brands.js | 460 ++++++++++++++++++ src/views/Categories/categories.js | 293 +++-------- src/views/Inventory/Inventory.js | 108 ---- src/views/Products/AddMultipleProducts.js | 12 + src/views/Products/AddProduct.js | 21 +- src/views/Products/EditProduct.js | 23 +- .../Productcomponents/ProductDetails.js | 299 ++++++------ src/views/Products/Products.js | 43 +- src/views/Products/ViewProduct.js | 32 +- .../SalesCoOrdinators/AddSalesCoOrdinator.js | 51 +- src/views/configuration/tax/Addtax.js | 221 --------- src/views/configuration/tax/Edittax.js | 231 --------- src/views/configuration/tax/Tax.js | 224 --------- 15 files changed, 832 insertions(+), 1228 deletions(-) create mode 100644 src/views/Brands/Brands.js delete mode 100644 src/views/configuration/tax/Addtax.js delete mode 100644 src/views/configuration/tax/Edittax.js delete mode 100644 src/views/configuration/tax/Tax.js diff --git a/src/_nav.js b/src/_nav.js index f9ab4c0..bae00b7 100644 --- a/src/_nav.js +++ b/src/_nav.js @@ -54,16 +54,16 @@ const _nav = [ }, { component: CNavItem, - name: "Products", - icon: , - to: "/products", + name: "Brands", + icon: , + to: "/brands", group: "Product Management", }, { component: CNavItem, - name: "GST", - icon: , - to: "/tax", + name: "Products", + icon: , + to: "/products", group: "Product Management", }, ], diff --git a/src/routes.js b/src/routes.js index 8d26eaf..7d36ad9 100644 --- a/src/routes.js +++ b/src/routes.js @@ -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", diff --git a/src/views/Brands/Brands.js b/src/views/Brands/Brands.js new file mode 100644 index 0000000..bed3291 --- /dev/null +++ b/src/views/Brands/Brands.js @@ -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 ( +
+
+
+
+
+
+
+ Brands +
+ +
+ + + + + + Brand Name + + handleClose()}> + + + +
+ + setbrandName( + e.target.value.charAt(0).toUpperCase() + + e.target.value.slice(1) + ) + } + /> + {brandName ? ( + <> + + {25 - brandName.length} characters left + + + ) : ( + <> + )} + + + {!edit && ( + + )} + {edit && ( + + )} + + +
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+ + + + + + + + + + + {!loading && brand.length === 0 && ( + + + + )} + {loading ? ( + + + + ) : ( + brand && + brand + .slice( + (`${page}` - 1) * itemPerPage, + `${page}` * itemPerPage + ) + .map((item, i) => ( + + + + + )) + )} + +
Brand NameAction
+
No Data Available
+
+ Loading... +
+
{item.brandName}
+
+ + +
+
+ +
+ setPage(value)} + /> +
+
+
+
+
+
+
+
+ ); +}; + +export default Brands; diff --git a/src/views/Categories/categories.js b/src/views/Categories/categories.js index d4dec09..aa4c6c3 100644 --- a/src/views/Categories/categories.js +++ b/src/views/Categories/categories.js @@ -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 (
@@ -377,111 +312,6 @@ const Categories = () => { <> )} - - - {categoryImage && ( - - categoryImage - handeldeleteImage()} - fontSize="small" - sx={{ - color: "white", - position: "absolute", - cursor: "pointer", - padding: "0.2rem", - background: "black", - borderRadius: "50%", - }} - /> - - )} - {olderImage && ( - - categoryImage - setOlderImage("")} - fontSize="small" - sx={{ - color: "white", - position: "absolute", - cursor: "pointer", - padding: "0.2rem", - background: "black", - borderRadius: "50%", - }} - /> - - )} - - - {error &&

{error}

} -

- Upload jpg, jpeg and png only* -

- { style={{ background: "rgb(140, 213, 213)" }} > - Image - Categories Name + Category Name Action @@ -623,15 +452,6 @@ const Categories = () => { ) .map((item, i) => ( - - -
{ }
-
{item.categoryName}
@@ -653,7 +473,6 @@ const Categories = () => { handleEditClick( item._id, item.categoryName, - item.categoryImage ) } > diff --git a/src/views/Inventory/Inventory.js b/src/views/Inventory/Inventory.js index d899253..5084ef3 100644 --- a/src/views/Inventory/Inventory.js +++ b/src/views/Inventory/Inventory.js @@ -166,113 +166,6 @@ const Inventory = () => {
- {/* - - - - - - - - - - - - - - - - - {loading ? ( - - - - ) : inventoryData.length > 0 ? ( - inventoryData.map((entry, i) => - entry.products.map((product, j) => ( - - - - - - - - - - - - - )) - ) - ) : ( - !loading && - filteredData.length === 0 && ( - - - - ) - )} - -
IDDateTimeTrade NamePD/RDProduct SKUProduct NameSaleInventoryActions
- Loading... -
{entry.uniqueId} - {new Date(entry.createdAt).toLocaleString( - "en-IN", - { - month: "short", - day: "numeric", - year: "numeric", - } - )} - - {new Date(entry.createdAt).toLocaleString( - "en-IN", - { - hour: "numeric", - minute: "numeric", - hour12: true, - } - )} - - {entry.tradeName} - - {entry.designation} - {product.SKU} - {product.ProductName} - {product.Sale} - {product.Inventory} - - - - -
-
No Data Available...
-
*/} - { )}
-
diff --git a/src/views/Products/AddMultipleProducts.js b/src/views/Products/AddMultipleProducts.js index d25fcc8..2abc357 100644 --- a/src/views/Products/AddMultipleProducts.js +++ b/src/views/Products/AddMultipleProducts.js @@ -134,7 +134,9 @@ try{ Product Name Category + Brand GST + HSN_Code price Message @@ -144,7 +146,9 @@ try{ {error.productName || "N/A"} {error.category || "N/A"} + {error.brand || "N/A"} {error.GST || "N/A"} + {error.HSN_Code || "N/A"} {error.price || "N/A"} {error.message} @@ -161,7 +165,9 @@ try{ Product Name Category + Brand GST + HSN_Code price Message @@ -171,7 +177,9 @@ try{ {update.name || "N/A"} {update.category || "N/A"} + {update.brand || "N/A"} {update.GST || "N/A"} + {update.HSN_Code || "N/A"} {update.price || "N/A"} {update.updatedFields} @@ -188,7 +196,9 @@ try{ Product Name Category + Brand GST + HSN_Code price @@ -197,7 +207,9 @@ try{ {create.name || "N/A"} {create.category || "N/A"} + {create.brand || "N/A"} {create.GST || "N/A"} + {create.HSN_Code || "N/A"} {create.price || "N/A"} ))} diff --git a/src/views/Products/AddProduct.js b/src/views/Products/AddProduct.js index d49672a..03da657 100644 --- a/src/views/Products/AddProduct.js +++ b/src/views/Products/AddProduct.js @@ -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 = () => { diff --git a/src/views/Products/EditProduct.js b/src/views/Products/EditProduct.js index 441741a..ab56f36 100644 --- a/src/views/Products/EditProduct.js +++ b/src/views/Products/EditProduct.js @@ -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 = () => { diff --git a/src/views/Products/Productcomponents/ProductDetails.js b/src/views/Products/Productcomponents/ProductDetails.js index d3a1509..1ae8f60 100644 --- a/src/views/Products/Productcomponents/ProductDetails.js +++ b/src/views/Products/Productcomponents/ProductDetails.js @@ -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 ( <> -
+
Product Details
-
-