update
This commit is contained in:
parent
abc4feee63
commit
7bba1cdc22
@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect, useRef, useCallback } from "react";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { isAutheticated } from "src/auth";
|
import { isAutheticated } from "src/auth";
|
||||||
import {
|
import {
|
||||||
@ -13,7 +13,8 @@ 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 { toast } from "react-hot-toast";
|
||||||
|
import debounce from "lodash.debounce";
|
||||||
const style = {
|
const style = {
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
top: "50%",
|
top: "50%",
|
||||||
@ -28,54 +29,65 @@ const style = {
|
|||||||
|
|
||||||
const Brands = () => {
|
const Brands = () => {
|
||||||
const token = isAutheticated();
|
const token = isAutheticated();
|
||||||
|
const nameRef = useRef();
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [updating, setUpdating] = useState(true);
|
const [updating, setUpdating] = useState(true);
|
||||||
const [saveLoding, setSaveLoading] = useState(true);
|
const [saveLoading, setSaveLoading] = useState(true);
|
||||||
const [edit, setEdit] = useState(false);
|
const [edit, setEdit] = useState(false);
|
||||||
const [brandName, setbrandName] = useState("");
|
const [brandName, setBrandName] = useState("");
|
||||||
const [brandId, setbrandId] = useState("");
|
const [brandId, setBrandId] = useState("");
|
||||||
const [brand, setbrand] = useState([]);
|
const [brands, setBrands] = 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 [olderbrandName, setOlderBrandName] = useState("");
|
const [olderBrandName, setOlderBrandName] = useState("");
|
||||||
|
|
||||||
|
|
||||||
const handleOpen = () => setOpen(true);
|
const handleOpen = () => setOpen(true);
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
setEdit(false);
|
setEdit(false);
|
||||||
setbrandName("");
|
setBrandName("");
|
||||||
setbrandId("");
|
setBrandId("");
|
||||||
};
|
};
|
||||||
|
|
||||||
const getBrands = async () => {
|
const getBrands = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get("/api/brand/getBrands");
|
setLoading(true); // Set loading to true before fetching
|
||||||
|
const response = await axios.get("/api/brand/getBrands", {
|
||||||
|
params: {
|
||||||
|
page,
|
||||||
|
show: itemPerPage,
|
||||||
|
brandName: nameRef.current?.value || "",
|
||||||
|
}, // Include pagination and search
|
||||||
|
});
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
setbrand(response.data.brands);
|
setBrands(response.data.brands);
|
||||||
setLoading(false);
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to fetch brands:", error);
|
console.error("Failed to fetch brands:", error);
|
||||||
|
} finally {
|
||||||
|
setLoading(false); // Set loading to false after fetching
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getBrands();
|
getBrands();
|
||||||
}, []);
|
}, [page, itemPerPage]); // Trigger fetch when these values change
|
||||||
|
|
||||||
const handleEditClick = (_id, brandName) => {
|
const handleEditClick = (_id, brandName) => {
|
||||||
setOpen(true);
|
setOpen(true);
|
||||||
setbrandName(brandName);
|
setBrandName(brandName);
|
||||||
setbrandId(_id);
|
setBrandId(_id);
|
||||||
setOlderBrandName(brandName);
|
setOlderBrandName(brandName);
|
||||||
setEdit(true);
|
setEdit(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUpdate = async () => {
|
const handleUpdate = async () => {
|
||||||
const filteredBrandNames = brand
|
const filteredBrandNames = brands
|
||||||
.filter((brand) => brand.brandName.toLowerCase() !== olderbrandName.toLowerCase())
|
.filter(
|
||||||
|
(brand) =>
|
||||||
|
brand.brandName.toLowerCase() !== olderBrandName.toLowerCase()
|
||||||
|
)
|
||||||
.map((brand) => brand.brandName.toLowerCase());
|
.map((brand) => brand.brandName.toLowerCase());
|
||||||
|
|
||||||
if (filteredBrandNames.includes(brandName.toLowerCase())) {
|
if (filteredBrandNames.includes(brandName.toLowerCase())) {
|
||||||
@ -97,7 +109,7 @@ const Brands = () => {
|
|||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
});
|
});
|
||||||
handleClose();
|
handleClose();
|
||||||
swal("Success", "The brand was updated successfully!", "success");
|
toast.success("Brand updated successfully");
|
||||||
getBrands();
|
getBrands();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
swal("Error", "Failed to update brand", "error");
|
swal("Error", "Failed to update brand", "error");
|
||||||
@ -120,7 +132,7 @@ const Brands = () => {
|
|||||||
await axios.delete(`/api/brand/delete/${_id}`, {
|
await axios.delete(`/api/brand/delete/${_id}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
});
|
});
|
||||||
swal("Success", "The brand was deleted successfully!", "success");
|
toast.success("Brand deleted successfully");
|
||||||
getBrands();
|
getBrands();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
swal("Error", "Failed to delete brand", "error");
|
swal("Error", "Failed to delete brand", "error");
|
||||||
@ -129,8 +141,12 @@ const Brands = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSavebrand = async () => {
|
const handleSaveBrand = async () => {
|
||||||
if (brand.some((brand) => brand.brandName.toLowerCase() === brandName.toLowerCase())) {
|
if (
|
||||||
|
brands.some(
|
||||||
|
(brand) => brand.brandName.toLowerCase() === brandName.toLowerCase()
|
||||||
|
)
|
||||||
|
) {
|
||||||
swal("Warning", "Brand already exists.", "error");
|
swal("Warning", "Brand already exists.", "error");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -148,7 +164,7 @@ const Brands = () => {
|
|||||||
await axios.post("/api/brand/add", formData, {
|
await axios.post("/api/brand/add", formData, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
"Content-Type": "multipart/formdata",
|
"Content-Type": "multipart/form-data",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
handleClose();
|
handleClose();
|
||||||
@ -161,8 +177,19 @@ const Brands = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getPageCount = () => Math.max(1, Math.ceil(brand.length / itemPerPage));
|
const getPageCount = () =>
|
||||||
|
Math.max(1, Math.ceil(brands.length / itemPerPage));
|
||||||
|
const debouncedSearch = useCallback(
|
||||||
|
debounce(() => {
|
||||||
|
setPage(1);
|
||||||
|
getBrands();
|
||||||
|
}, 500),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleSearchChange = () => {
|
||||||
|
debouncedSearch();
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div className="main-content">
|
<div className="main-content">
|
||||||
<div className="page-content">
|
<div className="page-content">
|
||||||
@ -191,9 +218,6 @@ const Brands = () => {
|
|||||||
textTransform: "capitalize",
|
textTransform: "capitalize",
|
||||||
}}
|
}}
|
||||||
onClick={handleOpen}
|
onClick={handleOpen}
|
||||||
// onClick={() => {
|
|
||||||
// navigate("/testimonial/new", { replace: true });
|
|
||||||
// }}
|
|
||||||
>
|
>
|
||||||
Add New brand
|
Add New brand
|
||||||
</Button>
|
</Button>
|
||||||
@ -229,9 +253,9 @@ const Brands = () => {
|
|||||||
padding: "1rem",
|
padding: "1rem",
|
||||||
}}
|
}}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
setbrandName(
|
setBrandName(
|
||||||
e.target.value.charAt(0).toUpperCase() +
|
e.target.value.charAt(0).toUpperCase() +
|
||||||
e.target.value.slice(1)
|
e.target.value.slice(1)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@ -249,7 +273,7 @@ const Brands = () => {
|
|||||||
p={2}
|
p={2}
|
||||||
display={"flex"}
|
display={"flex"}
|
||||||
justifyContent={"right"}
|
justifyContent={"right"}
|
||||||
// width={"500px"}
|
// width={"500px"}
|
||||||
>
|
>
|
||||||
{!edit && (
|
{!edit && (
|
||||||
<button
|
<button
|
||||||
@ -257,7 +281,7 @@ const Brands = () => {
|
|||||||
color: "white",
|
color: "white",
|
||||||
marginRight: "1rem",
|
marginRight: "1rem",
|
||||||
}}
|
}}
|
||||||
onClick={() => handleSavebrand()}
|
onClick={() => handleSaveBrand()}
|
||||||
type="button"
|
type="button"
|
||||||
className="
|
className="
|
||||||
btn btn-primary btn-sm
|
btn btn-primary btn-sm
|
||||||
@ -267,8 +291,8 @@ const Brands = () => {
|
|||||||
mt-1
|
mt-1
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<ClipLoader loading={!saveLoding} size={18} />
|
<ClipLoader loading={!saveLoading} size={18} />
|
||||||
{saveLoding && "Save"}
|
{saveLoading && "Save"}
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
{edit && (
|
{edit && (
|
||||||
@ -322,18 +346,17 @@ const Brands = () => {
|
|||||||
<div className="card">
|
<div className="card">
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
<div className="row ml-0 mr-0 mb-10">
|
<div className="row ml-0 mr-0 mb-10">
|
||||||
<div className="col-sm-12 col-md-12">
|
<div className="col-lg-1">
|
||||||
<div className="dataTables_length">
|
<div className="dataTables_length">
|
||||||
<label className="w-100">
|
<label className="w-100">
|
||||||
Show
|
Show
|
||||||
<select
|
<select
|
||||||
style={{ width: "10%" }}
|
onChange={(e) => {
|
||||||
onChange={(e) => setItemPerPage(e.target.value)}
|
setItemPerPage(e.target.value);
|
||||||
className="
|
setPage(1);
|
||||||
select-w
|
}}
|
||||||
custom-select custom-select-sm
|
className="form-control"
|
||||||
form-control form-control-sm
|
disabled={loading}
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<option value="10">10</option>
|
<option value="10">10</option>
|
||||||
<option value="25">25</option>
|
<option value="25">25</option>
|
||||||
@ -344,6 +367,17 @@ const Brands = () => {
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="col-lg-3">
|
||||||
|
<label>Brand Name:</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="product name"
|
||||||
|
className="form-control"
|
||||||
|
ref={nameRef}
|
||||||
|
onChange={handleSearchChange}
|
||||||
|
disabled={loading}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="table-responsive table-shoot mt-3">
|
<div className="table-responsive table-shoot mt-3">
|
||||||
@ -356,16 +390,15 @@ const Brands = () => {
|
|||||||
style={{ background: "rgb(140, 213, 213)" }}
|
style={{ background: "rgb(140, 213, 213)" }}
|
||||||
>
|
>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
||||||
<th> Brand Name</th>
|
<th> Brand Name</th>
|
||||||
|
|
||||||
<th>Action</th>
|
<th>Action</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{!loading && brand.length === 0 && (
|
{!loading && brands.length === 0 && (
|
||||||
<tr className="text-center">
|
<tr className="text-center">
|
||||||
<td colSpan="6">
|
<td colSpan="2">
|
||||||
<h5>No Data Available</h5>
|
<h5>No Data Available</h5>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -377,61 +410,53 @@ const Brands = () => {
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
) : (
|
) : (
|
||||||
brand &&
|
brands &&
|
||||||
brand
|
brands.map((item, i) => (
|
||||||
.slice(
|
<tr key={i}>
|
||||||
(`${page}` - 1) * itemPerPage,
|
<td>
|
||||||
`${page}` * itemPerPage
|
<h5>{item.brandName} </h5>
|
||||||
)
|
</td>
|
||||||
.map((item, i) => (
|
<td className="text-start">
|
||||||
<tr key={i}>
|
<button
|
||||||
<td>
|
style={{
|
||||||
<h5>{item.brandName} </h5>
|
color: "white",
|
||||||
</td>
|
marginRight: "1rem",
|
||||||
<td className="text-start">
|
}}
|
||||||
<button
|
type="button"
|
||||||
style={{
|
className="
|
||||||
color: "white",
|
|
||||||
marginRight: "1rem",
|
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-primary btn-sm
|
btn btn-primary btn-sm
|
||||||
waves-effect waves-light
|
waves-effect waves-light
|
||||||
btn-table
|
btn-table
|
||||||
mx-1
|
mx-1
|
||||||
mt-1
|
mt-1
|
||||||
"
|
"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
handleEditClick(
|
handleEditClick(item._id, item.brandName)
|
||||||
item._id,
|
}
|
||||||
item.brandName,
|
>
|
||||||
)
|
Edit
|
||||||
}
|
</button>
|
||||||
>
|
<button
|
||||||
Edit
|
style={{
|
||||||
</button>
|
color: "white",
|
||||||
<button
|
marginRight: "1rem",
|
||||||
style={{
|
background: "red",
|
||||||
color: "white",
|
}}
|
||||||
marginRight: "1rem",
|
type="button"
|
||||||
background: "red",
|
className="
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-sm
|
btn btn-sm
|
||||||
waves-effect waves-light
|
waves-effect waves-light
|
||||||
btn-table
|
btn-table
|
||||||
mx-1
|
mx-1
|
||||||
mt-1
|
mt-1
|
||||||
"
|
"
|
||||||
onClick={() => handleDelete(item._id)}
|
onClick={() => handleDelete(item._id)}
|
||||||
>
|
>
|
||||||
Delete
|
Delete
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect, useRef, useCallback } from "react";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { isAutheticated } from "src/auth";
|
import { isAutheticated } from "src/auth";
|
||||||
import {
|
import {
|
||||||
@ -13,7 +13,8 @@ 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 { toast } from "react-hot-toast";
|
||||||
|
import debounce from "lodash.debounce";
|
||||||
const style = {
|
const style = {
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
top: "50%",
|
top: "50%",
|
||||||
@ -28,6 +29,7 @@ const style = {
|
|||||||
|
|
||||||
const Categories = () => {
|
const Categories = () => {
|
||||||
const token = isAutheticated();
|
const token = isAutheticated();
|
||||||
|
const nameRef = useRef();
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [updating, setUpdating] = useState(true);
|
const [updating, setUpdating] = useState(true);
|
||||||
const [saveLoding, setSaveLoading] = useState(true);
|
const [saveLoding, setSaveLoading] = useState(true);
|
||||||
@ -40,7 +42,6 @@ const Categories = () => {
|
|||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const [olderCategoryName, setOlderCategoruName] = useState("");
|
const [olderCategoryName, setOlderCategoruName] = useState("");
|
||||||
|
|
||||||
|
|
||||||
const handleOpen = () => setOpen(true);
|
const handleOpen = () => setOpen(true);
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
@ -53,24 +54,28 @@ const Categories = () => {
|
|||||||
|
|
||||||
const getCategories = async () => {
|
const getCategories = async () => {
|
||||||
try {
|
try {
|
||||||
|
setLoading(true);
|
||||||
const response = await axios.get("/api/category/getCategories", {
|
const response = await axios.get("/api/category/getCategories", {
|
||||||
// headers: {
|
params: {
|
||||||
// Authorization: `Bearer ${token}`,
|
page,
|
||||||
// },
|
show: itemPerPage,
|
||||||
|
categoryName: nameRef.current?.value || "",
|
||||||
|
}, // Include pagination and search
|
||||||
});
|
});
|
||||||
|
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
setCategory(response?.data?.categories);
|
setCategory(response?.data?.categories);
|
||||||
setLoading(false);
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to fetch brands:", error);
|
console.error("Failed to fetch brands:", error);
|
||||||
|
} finally {
|
||||||
|
setLoading(false); // Set loading to false after fetching
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getCategories();
|
getCategories();
|
||||||
}, []);
|
}, [page, itemPerPage]);
|
||||||
|
|
||||||
const handleEditClick = (_id, categoryName) => {
|
const handleEditClick = (_id, categoryName) => {
|
||||||
setOpen(true);
|
setOpen(true);
|
||||||
@ -82,12 +87,14 @@ const Categories = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleUpdate = async () => {
|
const handleUpdate = async () => {
|
||||||
const filteredArrayNames = category.filter(
|
const filteredArrayNames = category
|
||||||
(item) => item.categoryName.toLowerCase() !== olderCategoryName.toLowerCase())
|
.filter(
|
||||||
.map((item) => item.categoryName.toLowerCase()
|
(item) =>
|
||||||
);
|
item.categoryName.toLowerCase() !== olderCategoryName.toLowerCase()
|
||||||
|
)
|
||||||
|
.map((item) => item.categoryName.toLowerCase());
|
||||||
// console.log(filteredArrayNames, "filter");
|
// console.log(filteredArrayNames, "filter");
|
||||||
if(filteredArrayNames.includes(categoryName.toLowerCase())){
|
if (filteredArrayNames.includes(categoryName.toLowerCase())) {
|
||||||
swal({
|
swal({
|
||||||
title: "Warning",
|
title: "Warning",
|
||||||
text: "Category already exists ",
|
text: "Category already exists ",
|
||||||
@ -109,22 +116,16 @@ const Categories = () => {
|
|||||||
setUpdating(false);
|
setUpdating(false);
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("categoryName", categoryName);
|
formData.append("categoryName", categoryName);
|
||||||
try{
|
try {
|
||||||
await axios
|
await axios.patch(`/api/category/update/${categoryId}`, formData, {
|
||||||
.patch(`/api/category/update/${categoryId}`, formData, {
|
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
handleClose();
|
handleClose();
|
||||||
swal({
|
toast.success("Category updated successfully");
|
||||||
title: "Congratulations!!",
|
getCategories();
|
||||||
text: "The category was updated successfully!",
|
} catch (err) {
|
||||||
icon: "success",
|
|
||||||
button: "OK",
|
|
||||||
});
|
|
||||||
getCategories();
|
|
||||||
}catch(err){
|
|
||||||
swal({
|
swal({
|
||||||
title: "",
|
title: "",
|
||||||
text: "Something went wrong!",
|
text: "Something went wrong!",
|
||||||
@ -132,7 +133,7 @@ try{
|
|||||||
button: "Retry",
|
button: "Retry",
|
||||||
dangerMode: true,
|
dangerMode: true,
|
||||||
});
|
});
|
||||||
}finally{
|
} finally {
|
||||||
setUpdating(true);
|
setUpdating(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -148,33 +149,32 @@ try{
|
|||||||
}).then(async (value) => {
|
}).then(async (value) => {
|
||||||
if (value === true) {
|
if (value === true) {
|
||||||
try {
|
try {
|
||||||
await axios
|
await axios.delete(`/api/category/delete/${_id}`, {
|
||||||
.delete(`/api/category/delete/${_id}`, {
|
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
swal({
|
toast.success("Category deleted successfully");
|
||||||
title: "Congratulations!!",
|
getCategories();
|
||||||
text: "The category was deleted successfully!",
|
} catch (err) {
|
||||||
icon: "success",
|
swal({
|
||||||
button: "OK",
|
title: "",
|
||||||
});
|
text: "Something went wrong!",
|
||||||
getCategories();
|
icon: "error",
|
||||||
}catch(err) {
|
button: "Retry",
|
||||||
swal({
|
dangerMode: true,
|
||||||
title: "",
|
});
|
||||||
text: "Something went wrong!",
|
}
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSaveCategory = async () => {
|
const handleSaveCategory = async () => {
|
||||||
if(category.some((item) => item.categoryName.toLowerCase() === categoryName.toLowerCase())){
|
if (
|
||||||
|
category.some(
|
||||||
|
(item) => item.categoryName.toLowerCase() === categoryName.toLowerCase()
|
||||||
|
)
|
||||||
|
) {
|
||||||
swal({
|
swal({
|
||||||
title: "Warning",
|
title: "Warning",
|
||||||
text: "Category already exists ",
|
text: "Category already exists ",
|
||||||
@ -198,23 +198,17 @@ try{
|
|||||||
setLoading(true);
|
setLoading(true);
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("categoryName", categoryName);
|
formData.append("categoryName", categoryName);
|
||||||
try{
|
try {
|
||||||
await axios
|
await 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",
|
||||||
},
|
},
|
||||||
})
|
|
||||||
handleClose();
|
|
||||||
swal({
|
|
||||||
title: "Congratulations!!",
|
|
||||||
text: "The category was added successfully!",
|
|
||||||
icon: "success",
|
|
||||||
button: "OK",
|
|
||||||
});
|
});
|
||||||
|
handleClose();
|
||||||
|
toast.success("Category added successfully");
|
||||||
getCategories();
|
getCategories();
|
||||||
}catch(err){
|
} catch (err) {
|
||||||
swal({
|
swal({
|
||||||
title: "",
|
title: "",
|
||||||
text: "Something went wrong!",
|
text: "Something went wrong!",
|
||||||
@ -222,14 +216,24 @@ try{
|
|||||||
button: "Retry",
|
button: "Retry",
|
||||||
dangerMode: true,
|
dangerMode: true,
|
||||||
});
|
});
|
||||||
}finally{
|
} finally {
|
||||||
setSaveLoading(true);
|
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 debouncedSearch = useCallback(
|
||||||
|
debounce(() => {
|
||||||
|
setPage(1);
|
||||||
|
getCategories();
|
||||||
|
}, 500),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleSearchChange = () => {
|
||||||
|
debouncedSearch();
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div className="main-content">
|
<div className="main-content">
|
||||||
<div className="page-content">
|
<div className="page-content">
|
||||||
@ -258,9 +262,6 @@ try{
|
|||||||
textTransform: "capitalize",
|
textTransform: "capitalize",
|
||||||
}}
|
}}
|
||||||
onClick={handleOpen}
|
onClick={handleOpen}
|
||||||
// onClick={() => {
|
|
||||||
// navigate("/testimonial/new", { replace: true });
|
|
||||||
// }}
|
|
||||||
>
|
>
|
||||||
Add New Category
|
Add New Category
|
||||||
</Button>
|
</Button>
|
||||||
@ -298,7 +299,7 @@ try{
|
|||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
setCategoryName(
|
setCategoryName(
|
||||||
e.target.value.charAt(0).toUpperCase() +
|
e.target.value.charAt(0).toUpperCase() +
|
||||||
e.target.value.slice(1)
|
e.target.value.slice(1)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@ -316,7 +317,7 @@ try{
|
|||||||
p={2}
|
p={2}
|
||||||
display={"flex"}
|
display={"flex"}
|
||||||
justifyContent={"right"}
|
justifyContent={"right"}
|
||||||
// width={"500px"}
|
// width={"500px"}
|
||||||
>
|
>
|
||||||
{!edit && (
|
{!edit && (
|
||||||
<button
|
<button
|
||||||
@ -389,18 +390,17 @@ try{
|
|||||||
<div className="card">
|
<div className="card">
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
<div className="row ml-0 mr-0 mb-10">
|
<div className="row ml-0 mr-0 mb-10">
|
||||||
<div className="col-sm-12 col-md-12">
|
<div className="col-lg-1">
|
||||||
<div className="dataTables_length">
|
<div className="dataTables_length">
|
||||||
<label className="w-100">
|
<label className="w-100">
|
||||||
Show
|
Show
|
||||||
<select
|
<select
|
||||||
style={{ width: "10%" }}
|
onChange={(e) => {
|
||||||
onChange={(e) => setItemPerPage(e.target.value)}
|
setItemPerPage(e.target.value);
|
||||||
className="
|
setPage(1);
|
||||||
select-w
|
}}
|
||||||
custom-select custom-select-sm
|
className="form-control"
|
||||||
form-control form-control-sm
|
disabled={loading}
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<option value="10">10</option>
|
<option value="10">10</option>
|
||||||
<option value="25">25</option>
|
<option value="25">25</option>
|
||||||
@ -411,6 +411,17 @@ try{
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="col-lg-3">
|
||||||
|
<label>Category Name:</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="product name"
|
||||||
|
className="form-control"
|
||||||
|
ref={nameRef}
|
||||||
|
onChange={handleSearchChange}
|
||||||
|
disabled={loading}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="table-responsive table-shoot mt-3">
|
<div className="table-responsive table-shoot mt-3">
|
||||||
@ -423,7 +434,6 @@ try{
|
|||||||
style={{ background: "rgb(140, 213, 213)" }}
|
style={{ background: "rgb(140, 213, 213)" }}
|
||||||
>
|
>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
||||||
<th> Category Name</th>
|
<th> Category Name</th>
|
||||||
|
|
||||||
<th>Action</th>
|
<th>Action</th>
|
||||||
@ -432,7 +442,7 @@ try{
|
|||||||
<tbody>
|
<tbody>
|
||||||
{!loading && category.length === 0 && (
|
{!loading && category.length === 0 && (
|
||||||
<tr className="text-center">
|
<tr className="text-center">
|
||||||
<td colSpan="6">
|
<td colSpan="">
|
||||||
<h5>No Data Available</h5>
|
<h5>No Data Available</h5>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -445,60 +455,52 @@ try{
|
|||||||
</tr>
|
</tr>
|
||||||
) : (
|
) : (
|
||||||
category &&
|
category &&
|
||||||
category
|
category.map((item, i) => (
|
||||||
.slice(
|
<tr key={i}>
|
||||||
(`${page}` - 1) * itemPerPage,
|
<td>
|
||||||
`${page}` * itemPerPage
|
<h5>{item.categoryName} </h5>
|
||||||
)
|
</td>
|
||||||
.map((item, i) => (
|
<td className="text-start">
|
||||||
<tr key={i}>
|
<button
|
||||||
<td>
|
style={{
|
||||||
<h5>{item.categoryName} </h5>
|
color: "white",
|
||||||
</td>
|
marginRight: "1rem",
|
||||||
<td className="text-start">
|
}}
|
||||||
<button
|
type="button"
|
||||||
style={{
|
className="
|
||||||
color: "white",
|
|
||||||
marginRight: "1rem",
|
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-primary btn-sm
|
btn btn-primary btn-sm
|
||||||
waves-effect waves-light
|
waves-effect waves-light
|
||||||
btn-table
|
btn-table
|
||||||
mx-1
|
mx-1
|
||||||
mt-1
|
mt-1
|
||||||
"
|
"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
handleEditClick(
|
handleEditClick(item._id, item.categoryName)
|
||||||
item._id,
|
}
|
||||||
item.categoryName,
|
>
|
||||||
)
|
Edit
|
||||||
}
|
</button>
|
||||||
>
|
<button
|
||||||
Edit
|
style={{
|
||||||
</button>
|
color: "white",
|
||||||
<button
|
marginRight: "1rem",
|
||||||
style={{
|
background: "red",
|
||||||
color: "white",
|
}}
|
||||||
marginRight: "1rem",
|
type="button"
|
||||||
background: "red",
|
className="
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-sm
|
btn btn-sm
|
||||||
waves-effect waves-light
|
waves-effect waves-light
|
||||||
btn-table
|
btn-table
|
||||||
mx-1
|
mx-1
|
||||||
mt-1
|
mt-1
|
||||||
"
|
"
|
||||||
onClick={() => handleDelete(item._id)}
|
onClick={() => handleDelete(item._id)}
|
||||||
>
|
>
|
||||||
Delete
|
Delete
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -6,6 +6,7 @@ import { useNavigate } from "react-router-dom";
|
|||||||
import { isAutheticated } from "src/auth";
|
import { isAutheticated } from "src/auth";
|
||||||
import swal from "sweetalert";
|
import swal from "sweetalert";
|
||||||
import debounce from "lodash.debounce";
|
import debounce from "lodash.debounce";
|
||||||
|
import { toast } from "react-hot-toast";
|
||||||
const Products = () => {
|
const Products = () => {
|
||||||
const token = isAutheticated();
|
const token = isAutheticated();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -138,12 +139,7 @@ const Products = () => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
swal({
|
toast.success("Product deleted successfully!");
|
||||||
title: "Deleted",
|
|
||||||
text: "Product Deleted successfully!",
|
|
||||||
icon: "success",
|
|
||||||
button: "ok",
|
|
||||||
});
|
|
||||||
setSuccess((prev) => !prev);
|
setSuccess((prev) => !prev);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
@ -179,12 +175,7 @@ const Products = () => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
swal({
|
toast.success("Product status updated successfully!");
|
||||||
title: "Changed",
|
|
||||||
text: "Product status changed successfully!",
|
|
||||||
icon: "success",
|
|
||||||
button: "ok",
|
|
||||||
});
|
|
||||||
setSuccess((prev) => !prev);
|
setSuccess((prev) => !prev);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user