api integration for delete category any updatecategory done

This commit is contained in:
print-signs 2023-10-17 12:35:21 +05:30
parent 23fa8bdb06
commit 06924cbaa1
6 changed files with 825 additions and 302 deletions

View File

@ -37,8 +37,11 @@
"@coreui/react": "^4.3.0", "@coreui/react": "^4.3.0",
"@coreui/react-chartjs": "^2.0.0", "@coreui/react-chartjs": "^2.0.0",
"@coreui/utils": "^1.3.1", "@coreui/utils": "^1.3.1",
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@material-ui/core": "^4.12.4", "@material-ui/core": "^4.12.4",
"@material-ui/data-grid": "^4.0.0-alpha.37", "@material-ui/data-grid": "^4.0.0-alpha.37",
"@mui/icons-material": "^5.14.13",
"@mui/material": "^5.11.12", "@mui/material": "^5.11.12",
"@reduxjs/toolkit": "^1.9.2", "@reduxjs/toolkit": "^1.9.2",
"axios": "^0.25.0", "axios": "^0.25.0",

View File

@ -5,6 +5,7 @@ import {
cilAppsSettings, cilAppsSettings,
cilBrush, cilBrush,
cilCart, cilCart,
cilCat,
cilClipboard, cilClipboard,
cilCommand, cilCommand,
cilCompress, cilCompress,
@ -34,6 +35,12 @@ const _nav = [
icon: <CIcon icon={cilTennisBall} customClassName="nav-icon" />, icon: <CIcon icon={cilTennisBall} customClassName="nav-icon" />,
to: "/users", to: "/users",
}, },
{
component: CNavItem,
name: "Categories",
icon: <CIcon icon={cilCat} customClassName="nav-icon" />,
to: "/categories",
},
{ {
component: CNavItem, component: CNavItem,
name: "Products", name: "Products",

View File

@ -15,7 +15,8 @@ import { createRoot } from "react-dom/client";
const setupAxios = () => { const setupAxios = () => {
//axios.defaults.baseURL = 'https://bolo-api.checkapp.one/' //axios.defaults.baseURL = 'https://bolo-api.checkapp.one/'
// axios.defaults.baseURL = "http://localhost:8000"; // axios.defaults.baseURL = "http://localhost:8000";
axios.defaults.baseURL = "https://happy-sombrero-ray.cyclic.app/"; //->latest deployed // axios.defaults.baseURL = "https://happy-sombrero-ray.cyclic.app/"; //->latest deployed
axios.defaults.baseURL = "https://printsigns.onrender.com/"; //->latest deployed
axios.defaults.headers = { axios.defaults.headers = {
"Cache-Control": "no-cache,no-store", "Cache-Control": "no-cache,no-store",

View File

@ -82,6 +82,7 @@ import AddNewAppointment from "./views/Appointments/AddNewAppointment";
import ViewHealthCareProvider from "./views/Business/ViewHealthCareProvider"; import ViewHealthCareProvider from "./views/Business/ViewHealthCareProvider";
import Campaign from "./views/Campaigns/Campaign.js"; import Campaign from "./views/Campaigns/Campaign.js";
import AddCampaign from "./views/Campaigns/AddCampaign.js"; import AddCampaign from "./views/Campaigns/AddCampaign.js";
import Categories from "./views/Categories/categories";
const routes = [ const routes = [
{ path: "/", exact: true, name: "Home" }, { path: "/", exact: true, name: "Home" },
{ {
@ -142,6 +143,12 @@ const routes = [
name: "view healthcare providers", name: "view healthcare providers",
element: ViewHealthCareProvider, element: ViewHealthCareProvider,
}, },
// Categories
{
path: "//categories",
name: "Categories",
element: Categories,
},
{ {
path: "//campaigns", path: "//campaigns",
name: "campaigns", name: "campaigns",

View File

@ -0,0 +1,496 @@
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: "20%",
left: "50%",
transform: "translate(-50%, -50%)",
width: 400,
bgcolor: "background.paper",
borderRadius: "0.5rem",
boxShadow: 24,
width: "500px",
};
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 [saveLoding, setSaveLoading] = useState(true);
const [edit, setEdit] = useState(false);
const [categoryName, setCategoryName] = useState("");
const [success, setSuccess] = useState(false);
const [categoryId, setCategoryId] = useState("");
const [category, setCategory] = useState([]);
const [itemPerPage, setItemPerPage] = useState(10);
const [page, setPage] = useState(1);
const [open, setOpen] = useState(false);
const handleOpen = () => setOpen(true);
const handleClose = () => {
setOpen(false);
// setUpdating(true)
setCategoryName("");
setCategoryId("");
// setUpdating(false);
// setIsUpdate(false);
};
const getCategories = async () => {
try {
const response = await axios.get("/api/category/getCategories", {
headers: {
Authorization: `Bearer ${token}`,
},
});
if (response.status === 200) {
setCategory(response?.data?.categories);
setLoading(false);
}
} catch (error) {
swal({
title: error,
text: " please login to access the resource ",
icon: "error",
button: "Retry",
dangerMode: true,
});
}
};
useEffect(() => {
getCategories();
}, [token, category]);
console.log(category.length);
const handleEditClick = (_id, categoryName) => {
setOpen(true);
setCategoryName(categoryName);
setCategoryId(_id);
setEdit(true);
// setUpdating(false);
};
const handleUpdate = () => {
setUpdating(false);
axios
.patch(
`/api/category/update/${categoryId}`,
{ categoryName },
{
headers: {
Authorization: `Bearer ${token}`,
},
}
)
.then((res) => {
// setUpdating(true);
// setIsUpdate(false);
handleClose();
setCategoryId("");
setCategoryName("");
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: "Something went wrong!",
icon: "error",
button: "Retry",
dangerMode: true,
});
});
};
const handleDelete = (_id) => {
swal({
title: "Are you sure?",
icon: "error",
buttons: {
Yes: { text: "Yes", value: true },
Cancel: { text: "Cancel", value: "cancel" },
},
}).then((value) => {
if (value === true) {
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) => {
swal({
title: "",
text: "Something went wrong!",
icon: "error",
button: "Retry",
dangerMode: true,
});
});
}
});
};
const handleSaveCategory = async () => {
if (!categoryName) {
swal({
title: "Warning",
text: "Category name is empty. Please enter the category name!",
icon: "error",
button: "Retry",
dangerMode: true,
});
return;
}
setSaveLoading(false);
setLoading(true);
axios
.post(
"/api/category/add",
{ categoryName },
{
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
}
)
.then((response) => {
if (response.status === 201) {
setOpen(false);
setLoading(false);
setSaveLoading(true);
setCategoryName("");
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,
});
});
};
const getPageCount = () => {
return Math.max(1, Math.ceil(category.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">
Categories
</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 Category
</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}
>
Category Name
</Typography>
<IconButton onClick={() => handleClose()}>
<CloseIcon />
</IconButton>
</Box>
<hr />
<TextField
placeholder="category name"
value={categoryName}
fullWidth
style={{
padding: "1rem",
}}
onChange={(e) => setCategoryName(e.target.value)}
/>
<Box
p={2}
display={"flex"}
justifyContent={"right"}
// width={"500px"}
>
{!edit && (
<button
style={{
color: "white",
marginRight: "1rem",
}}
onClick={() => handleSaveCategory()}
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> Categories Name</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{!loading && category.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>
) : (
category &&
category
.slice(
(`${page}` - 1) * itemPerPage,
`${page}` * itemPerPage
)
.map((item, i) => (
<tr key={i}>
<td>
<h5>{item.categoryName} </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.categoryName
)
}
>
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 Categories;

View File

@ -1,29 +1,25 @@
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import React, { useState, useEffect } from 'react' import Button from "@material-ui/core/Button";
import { Link } from 'react-router-dom' import { useNavigate } from "react-router-dom";
import Button from '@material-ui/core/Button' import axios from "axios";
import { useNavigate } from 'react-router-dom' import { isAutheticated } from "src/auth";
import axios from 'axios'
import { isAutheticated } from 'src/auth'
const Testimonials = () => { const Testimonials = () => {
const token = isAutheticated() const token = isAutheticated();
const navigate = useNavigate() const navigate = useNavigate();
const [loading, setLoading] = useState(true) const [loading, setLoading] = useState(true);
const [success, setSuccess] = useState(true) const [success, setSuccess] = useState(true);
const [TestimonialsData, setTestimonialsData] = useState([]) const [TestimonialsData, setTestimonialsData] = useState([]);
const [currentPage, setCurrentPage] = useState(1) const [currentPage, setCurrentPage] = useState(1);
const [itemPerPage, setItemPerPage] = useState(10) const [itemPerPage, setItemPerPage] = useState(10);
const [showData, setShowData] = useState(TestimonialsData) const [showData, setShowData] = useState(TestimonialsData);
const handleShowEntries = (e) => { const handleShowEntries = (e) => {
setCurrentPage(1) setCurrentPage(1);
setItemPerPage(e.target.value) setItemPerPage(e.target.value);
} };
const getTestimonialsData = async () => { const getTestimonialsData = async () => {
axios axios
@ -33,56 +29,59 @@ const Testimonials = () => {
}, },
}) })
.then((res) => { .then((res) => {
setTestimonialsData(res.data?.testimonial) setTestimonialsData(res.data?.testimonial);
setLoading(false) setLoading(false);
}) })
.catch((err) => { .catch((err) => {
setLoading(false) setLoading(false);
}) });
} };
useEffect(() => { useEffect(() => {
getTestimonialsData() getTestimonialsData();
}, [success]) }, [success]);
useEffect(() => { useEffect(() => {
const loadData = () => { const loadData = () => {
const indexOfLastPost = currentPage * itemPerPage const indexOfLastPost = currentPage * itemPerPage;
const indexOfFirstPost = indexOfLastPost - itemPerPage const indexOfFirstPost = indexOfLastPost - itemPerPage;
setShowData(TestimonialsData.slice(indexOfFirstPost, indexOfLastPost)) setShowData(TestimonialsData.slice(indexOfFirstPost, indexOfLastPost));
} };
loadData() loadData();
}, [currentPage, itemPerPage, TestimonialsData]) }, [currentPage, itemPerPage, TestimonialsData]);
const handleDelete = (id) => { const handleDelete = (id) => {
swal({ swal({
title: 'Are you sure?', title: "Are you sure?",
icon: 'error', icon: "error",
buttons: { Yes: { text: 'Yes', value: true }, Cancel: { text: 'Cancel', value: 'cancel' } }, buttons: {
Yes: { text: "Yes", value: true },
Cancel: { text: "Cancel", value: "cancel" },
},
}).then((value) => { }).then((value) => {
if (value === true) { if (value === true) {
axios axios
.delete(`/api/item/delete/${id}`, { .delete(`/api/item/delete/${id}`, {
headers: { headers: {
'Access-Control-Allow-Origin': '*', "Access-Control-Allow-Origin": "*",
Authorization: `Bearer ${token}`, Authorization: `Bearer ${token}`,
}, },
}) })
.then((res) => { .then((res) => {
setSuccess((prev) => !prev) setSuccess((prev) => !prev);
}) })
.catch((err) => { .catch((err) => {
swal({ swal({
title: 'Warning', title: "Warning",
text: 'Something went wrong!', text: "Something went wrong!",
icon: 'error', icon: "error",
button: 'Retry', button: "Retry",
dangerMode: true, dangerMode: true,
}) });
}) });
}
})
} }
});
};
return ( return (
<div className="main-content"> <div className="main-content">
@ -98,7 +97,7 @@ const Testimonials = () => {
justify-content-between justify-content-between
" "
> >
<div style={{ fontSize: '22px' }} className="fw-bold"> <div style={{ fontSize: "22px" }} className="fw-bold">
Testimonials Testimonials
</div> </div>
@ -107,12 +106,12 @@ const Testimonials = () => {
variant="contained" variant="contained"
color="primary" color="primary"
style={{ style={{
fontWeight: 'bold', fontWeight: "bold",
marginBottom: '1rem', marginBottom: "1rem",
textTransform: 'capitalize', textTransform: "capitalize",
}} }}
onClick={() => { onClick={() => {
navigate('/testimonial/new', { replace: true }) navigate("/testimonial/new", { replace: true });
}} }}
> >
Add New Testimonial Add New Testimonial
@ -132,7 +131,7 @@ const Testimonials = () => {
<label className="w-100"> <label className="w-100">
Show Show
<select <select
style={{ width: '10%' }} style={{ width: "10%" }}
name="" name=""
onChange={(e) => handleShowEntries(e)} onChange={(e) => handleShowEntries(e)}
className=" className="
@ -155,19 +154,17 @@ const Testimonials = () => {
<div className="table-responsive table-shoot mt-3"> <div className="table-responsive table-shoot mt-3">
<table <table
className="table table-centered table-nowrap" className="table table-centered table-nowrap"
style={{ border: '1px solid' }} style={{ border: "1px solid" }}
>
<thead
className="thead-info"
style={{ background: "rgb(140, 213, 213)" }}
> >
<thead className="thead-info" style={{ background: 'rgb(140, 213, 213)' }}>
<tr> <tr>
<th className="text-start">Name</th> <th className="text-start">Name</th>
<th className="text-start">Testimonials</th> <th className="text-start">Testimonials</th>
<th className="text-start">Date & Time</th> <th className="text-start">Date & Time</th>
<th className="text-start">Action</th> <th className="text-start">Action</th>
</tr> </tr>
</thead> </thead>
@ -193,21 +190,26 @@ const Testimonials = () => {
<td className="text-start">{item.company}</td> <td className="text-start">{item.company}</td>
<td className="text-start"> <td className="text-start">
{new Date(item.createdAt).toLocaleString('en-IN', { {new Date(item.createdAt).toLocaleString(
weekday: 'short', "en-IN",
month: 'short', {
day: 'numeric', weekday: "short",
year: 'numeric', month: "short",
hour: 'numeric', day: "numeric",
minute: 'numeric', year: "numeric",
hour: "numeric",
minute: "numeric",
hour12: true, hour12: true,
})} }
)}
</td> </td>
<td className="text-start"> <td className="text-start">
<Link to={`/testimonial/view/${item._id}`}> <Link to={`/testimonial/view/${item._id}`}>
<button <button
style={{ color: 'white', marginRight: '1rem' }} style={{
color: "white",
marginRight: "1rem",
}}
type="button" type="button"
className=" className="
btn btn-primary btn-sm btn btn-primary btn-sm
@ -221,9 +223,8 @@ const Testimonials = () => {
</button> </button>
</Link> </Link>
</td> </td>
</tr> </tr>
) );
}) })
)} )}
</tbody> </tbody>
@ -238,9 +239,12 @@ const Testimonials = () => {
role="status" role="status"
aria-live="polite" aria-live="polite"
> >
Showing {currentPage * itemPerPage - itemPerPage + 1} to{' '} Showing {currentPage * itemPerPage - itemPerPage + 1} to{" "}
{Math.min(currentPage * itemPerPage, TestimonialsData.length)} of{' '} {Math.min(
{TestimonialsData.length} entries currentPage * itemPerPage,
TestimonialsData.length
)}{" "}
of {TestimonialsData.length} entries
</div> </div>
</div> </div>
@ -250,13 +254,13 @@ const Testimonials = () => {
<li <li
className={ className={
currentPage === 1 currentPage === 1
? 'paginate_button page-item previous disabled' ? "paginate_button page-item previous disabled"
: 'paginate_button page-item previous' : "paginate_button page-item previous"
} }
> >
<span <span
className="page-link" className="page-link"
style={{ cursor: 'pointer' }} style={{ cursor: "pointer" }}
onClick={() => setCurrentPage((prev) => prev - 1)} onClick={() => setCurrentPage((prev) => prev - 1)}
> >
Previous Previous
@ -267,8 +271,10 @@ const Testimonials = () => {
<li className="paginate_button page-item"> <li className="paginate_button page-item">
<span <span
className="page-link" className="page-link"
style={{ cursor: 'pointer' }} style={{ cursor: "pointer" }}
onClick={(e) => setCurrentPage((prev) => prev - 1)} onClick={(e) =>
setCurrentPage((prev) => prev - 1)
}
> >
{currentPage - 1} {currentPage - 1}
</span> </span>
@ -276,7 +282,10 @@ const Testimonials = () => {
)} )}
<li className="paginate_button page-item active"> <li className="paginate_button page-item active">
<span className="page-link" style={{ cursor: 'pointer' }}> <span
className="page-link"
style={{ cursor: "pointer" }}
>
{currentPage} {currentPage}
</span> </span>
</li> </li>
@ -288,9 +297,9 @@ const Testimonials = () => {
<li className="paginate_button page-item "> <li className="paginate_button page-item ">
<span <span
className="page-link" className="page-link"
style={{ cursor: 'pointer' }} style={{ cursor: "pointer" }}
onClick={() => { onClick={() => {
setCurrentPage((prev) => prev + 1) setCurrentPage((prev) => prev + 1);
}} }}
> >
{currentPage + 1} {currentPage + 1}
@ -304,13 +313,13 @@ const Testimonials = () => {
(currentPage + 1) * itemPerPage - itemPerPage > (currentPage + 1) * itemPerPage - itemPerPage >
TestimonialsData.length - 1 TestimonialsData.length - 1
) )
? 'paginate_button page-item next' ? "paginate_button page-item next"
: 'paginate_button page-item next disabled' : "paginate_button page-item next disabled"
} }
> >
<span <span
className="page-link" className="page-link"
style={{ cursor: 'pointer' }} style={{ cursor: "pointer" }}
onClick={() => setCurrentPage((prev) => prev + 1)} onClick={() => setCurrentPage((prev) => prev + 1)}
> >
Next Next
@ -327,7 +336,7 @@ const Testimonials = () => {
</div> </div>
</div> </div>
</div> </div>
) );
} };
export default Testimonials export default Testimonials;