admin/src/views/Products/AddProduct.js
2024-03-29 16:31:25 +05:30

537 lines
17 KiB
JavaScript

import React, { useEffect, useState } from "react";
import Button from "@material-ui/core/Button";
import { Link, useNavigate } from "react-router-dom";
import swal from "sweetalert";
import axios from "axios";
import { isAutheticated } from "src/auth";
import CloudUploadIcon from "@mui/icons-material/CloudUpload";
import DeleteSharpIcon from "@mui/icons-material/DeleteSharp";
import {
Box,
FormControl,
IconButton,
MenuItem,
Select,
TextField,
} from "@mui/material";
// import { WebsiteURL } from '../WebsiteURL'
const AddProduct = () => {
const token = isAutheticated();
const navigate = useNavigate();
const [loading, setLoading] = useState(false);
const [allTax, setAllTax] = useState([]);
const [categories, setCategoies] = useState([]);
const [imagesPreview, setImagesPreview] = useState([]);
// const [allimage, setAllImage] = useState([]);
const [name, setName] = useState("");
const [description, setDescription] = useState("");
const [productImages, setProductImages] = useState([]);
const [price, setPrice] = useState(0);
const [category, setCategoryName] = useState("");
const [error, setError] = useState("");
const [selectedTax, setselectedTax] = useState();
const [totalAmt, setTotalAmt] = useState(0);
const [gst_amount, setGst_amount] = useState(0);
const handleFileChange = (e) => {
const files = e.target.files;
// Check the total number of selected files
if (productImages.length + files.length > 4) {
setError("You can only upload up to 4 images.");
return;
}
// Check file types and append to selectedFiles
const allowedTypes = ["image/jpeg", "image/png", "image/jpg"];
const selected = [];
for (let i = 0; i < files.length; i++) {
if (productImages.length + selected.length >= 4) {
break; // Don't allow more than 4 images
}
if (allowedTypes.includes(files[i].type)) {
selected.push(files[i]);
}
}
if (selected.length === 0) {
setError("Please upload only PNG, JPEG, or JPG files.");
} else {
setError("");
setProductImages([...productImages, ...selected]);
}
};
const handelDelete = (image) => {
const filtered = productImages.filter((item) => item !== image);
setProductImages(filtered);
};
// get All categories
const getCategories = async () => {
try {
const response = await axios.get("/api/category/getCategories", {
headers: {
Authorization: `Bearer ${token}`,
},
});
if (response.status === 200) {
setCategoies(response?.data?.categories);
}
} catch (error) {
swal({
title: error,
text: " please login to access the resource ",
icon: "error",
button: "Retry",
dangerMode: true,
});
}
};
// Get all tax
const getAllTax = async () => {
const res = await axios.get(`/api/tax/view_tax`, {
headers: {
"Access-Control-Allow-Origin": "*",
Authorization: `Bearer ${token}`,
},
});
if (res.data) {
setAllTax(res.data);
}
};
useEffect(() => {
getAllTax();
getCategories();
}, [token]);
const TaxRatechange = async (e) => {
let m = JSON.parse(e.target.value);
if (m?.tax) {
let totalprice = Number(price) + Number((price * m?.tax) / 100);
setGst_amount(Number((price * m?.tax) / 100)?.toFixed(2));
setTotalAmt(totalprice?.toFixed(2));
setselectedTax(m?._id);
}
};
const handleSubmit = () => {
if (
name === "" ||
description === "" ||
productImages.length == 0 ||
category === "" ||
selectedTax === "" ||
gst_amount === "" ||
price === ""
) {
swal({
title: "Warning",
text: "Fill all mandatory fields",
icon: "error",
button: "Close",
dangerMode: true,
});
return;
}
setLoading(true);
const formData = new FormData();
formData.append("name", name);
formData.append("description", description);
formData.append("price", price);
formData.append("category", category);
formData.append("total_amount", totalAmt);
formData.append("gst_amount", gst_amount);
formData.append("gst", selectedTax);
productImages.forEach((Singleimage) => {
// console.log(Singleimage)
formData.append("image", Singleimage);
});
axios
.post(`/api/product/create/`, formData, {
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "multipart/formdata",
"Access-Control-Allow-Origin": "*",
},
})
.then((res) => {
swal({
title: "Added",
text: "Product added successfully!",
icon: "success",
button: "ok",
});
setLoading(false);
navigate("/products", { replace: true });
})
.catch((err) => {
setLoading(false);
const message = err.response?.data?.message
? err.response?.data?.message
: "Something went wrong!";
swal({
title: "Warning",
text: message,
icon: "error",
button: "Retry",
dangerMode: true,
});
});
};
const handlePriceChange = (e) => {
const newPrice = e.target.value;
setPrice(newPrice);
const selectedTaxObj = allTax.find((t) => t._id === selectedTax);
if (selectedTaxObj && !isNaN(newPrice)) {
const gstAmount = (newPrice * selectedTaxObj.tax) / 100;
const totalAmount = Number(newPrice) + gstAmount;
setGst_amount(gstAmount.toFixed(2));
setTotalAmt(totalAmount.toFixed(2));
}
};
// console.log(data);
// console.log(productImages);
return (
<div className="container">
<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">
Add Product
</div>
<div style={{ display: "flex", gap: "1rem" }}>
<h4 className="mb-0"></h4>
</div>
<div className="page-title-right">
<Button
variant="contained"
color="primary"
style={{
fontWeight: "bold",
marginBottom: "1rem",
textTransform: "capitalize",
marginRight: "5px",
}}
onClick={() => handleSubmit()}
disabled={loading}
>
{loading ? "Loading" : "Save"}
</Button>
<Link to="/products">
<Button
variant="contained"
color="secondary"
style={{
fontWeight: "bold",
marginBottom: "1rem",
textTransform: "capitalize",
}}
>
Back
</Button>
</Link>
</div>
</div>
</div>
</div>
<div className="row">
<div className="col-lg-6 col-md-6 col-sm-12 my-1">
<div className="card h-100">
<div className="card-body px-5">
<div className="mb-3">
<label htmlFor="title" className="form-label">
Product Name*
</label>
<input
type="text"
className="form-control"
id="name"
value={name}
maxLength={35}
onChange={(e) => setName(e.target.value)}
/>
{name ? (
<>
<small className="charLeft mt-4 fst-italic">
{35 - name.length} characters left
</small>
</>
) : (
<></>
)}{" "}
</div>
<div className="mb-3">
<label htmlFor="title" className="form-label">
Description*
</label>
<textarea
type="text"
className="form-control"
id="description"
value={description}
rows={8}
maxLength="400"
onChange={(e) => setDescription(e.target.value)}
/>
{description ? (
<>
<small className="charLeft mt-4 fst-italic">
{400 - description.length} characters left
</small>
</>
) : (
<></>
)}
</div>
<div className="mb-3">
<label htmlFor="image" className="form-label">
Product Image*
</label>
<Box>
<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"
multiple
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>
</Box>
{error && <p style={{ color: "red" }}>{error}</p>}
<p className="pt-1 pl-2 text-secondary">
Upload jpg, jpeg and png only*
</p>
<Box style={{ display: "flex" }}>
{productImages &&
productImages.map((image, i) => (
<Box marginRight={"2rem"}>
<img
src={URL.createObjectURL(image)}
alt="profileImage"
style={{
width: 70,
height: 70,
marginBottom: "1rem",
}}
/>
<DeleteSharpIcon
onClick={() => handelDelete(image)}
fontSize="small"
sx={{
color: "white",
position: "absolute",
cursor: "pointer",
padding: "0.2rem",
background: "black",
borderRadius: "50%",
}}
/>
{/* </IconButton> */}
</Box>
))}
</Box>
</div>
<div>
<strong className="fs-6 fst-italic">
*You cannot upload more than 4 images !!
</strong>
</div>
<div id="createProductFormImage" className="w-25 d-flex">
{imagesPreview.map((image, index) => (
<img
className=" w-50 p-1 "
key={index}
src={image}
alt="Product Preview"
/>
))}
</div>
</div>
</div>
</div>
<div className="col-lg-6 col-md-6 col-sm-12 my-1">
<div className="card h-100">
<div className="card-body px-5">
<div className="mb-3 me-3">
<label htmlFor="title" className="form-label">
Price(Rs)*
</label>
<input
type="number"
className="form-control"
id="price"
value={price}
onChange={(e) => handlePriceChange(e)}
/>
</div>
<div className="">
<label htmlFor="categorySelect">Select a Category *:</label>
<select
id="category"
className="form-control"
style={{ width: "100%" }}
value={category}
onChange={(e) => setCategoryName(e.target.value)}
>
<option value={""}>None</option>
{categories.map((category, index) => (
<option key={index} value={category?._id}>
{category.categoryName}
</option>
))}
</select>
{/* <FormControl fullWidth>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={categoryName}
onChange={(e) => setCategoryName(e.target.value)}
>
<MenuItem
style={{
width: "100%",
display: "flex",
justifyContent: "left",
textAlign: "left",
padding: "0.5rem",
}}
value={""}
>
None
</MenuItem>
{categories.map((category, i) => (
<MenuItem
style={{
width: "100%",
display: "flex",
justifyContent: "left",
textAlign: "left",
padding: "0.5rem",
}}
key={i}
value={category.categoryName}
>
{category.categoryName}
</MenuItem>
))}
</Select>
</FormControl> */}
</div>
{allTax.length > 0 && (
<div className=" mb-3">
<label htmlFor="title" className="form-label">
GST*
</label>{" "}
<select
className="form-control"
name="gst"
id="gst"
onChange={(e) => TaxRatechange(e)}
>
<option value="">--Select--</option>
{allTax.map((t, i) => (
<option key={i} value={JSON.stringify(t)}>
{t.tax}% {t.name}
</option>
))}
</select>
</div>
)}
<div className="mb-3 me-3">
<label htmlFor="title" className="form-label">
GST Amount (Rs) *
</label>
<input
disabled
type="number"
name="gst_amount"
className="form-control"
id="gst_amount"
value={gst_amount}
// onChange={(e) => setPrice(e.target.value)}
/>
</div>
<div className="mb-3 me-3">
<label htmlFor="title" className="form-label">
Total Amount(Rs)*
</label>
<input
disabled
type="number"
name="total_amount"
className="form-control"
id="total_amount"
value={totalAmt}
// onChange={(e) => setPrice(e.target.value)}
/>
</div>
</div>
</div>
</div>
</div>
</div>
);
};
export default AddProduct;