This commit is contained in:
pawan-dot 2022-11-02 15:53:32 +05:30
parent 0dc12038fd
commit 9180d8f7f4
8 changed files with 531 additions and 261 deletions

View File

@ -30,6 +30,8 @@
"coreui_library_short_version": "4.1"
},
"dependencies": {
"@ckeditor/ckeditor5-build-classic": "^35.2.1",
"@ckeditor/ckeditor5-react": "^5.0.2",
"@coreui/chartjs": "^3.0.0",
"@coreui/coreui": "^4.1.0",
"@coreui/icons": "^2.1.0",

View File

@ -11,7 +11,7 @@ import store from './store'
import axios from 'axios'
const setupAxios = () => {
axios.defaults.baseURL = 'https://cms-api-dashboard.herokuapp.com/';
axios.defaults.baseURL = 'https://cmp-all-api.herokuapp.com/'
// axios.defaults.baseURL = 'http://localhost:5000'
axios.defaults.headers = {
'Cache-Control': 'no-cache,no-store',

View File

@ -31,6 +31,7 @@ import EditBanner from './views/Banners/EditBanner'
import AddBanner from './views/Banners/AddBanner'
//cms
import CMS from './views/CMS/cms'
import AddNewPageCms from './views/CMS/AddNewPageCms'
import CMSView from './views/CMS/ViewCms'
import CMSEdit from './views/CMS/EditCms'
//cms
@ -98,10 +99,12 @@ const routes = [
{ path: '/banner/edit/:id', name: 'EditBanner', component: EditBanner },
{ path: '/banner', name: 'Banner', component: Banner },
//CMS
{ path: '/cms/view/:id', name: 'CMS', component: CMSView },
{ path: '/cms/edit/:id', name: 'CMS', component: CMSEdit },
{ path: '/cms/new', name: 'CMS New', component: AddNewPageCms },
{ path: '/cms', name: 'CMS', component: CMS },
//CMS
//feedback
{ path: '/feedback/view/:id', name: 'ViewFeedback', component: ViewFeedback },
{ path: '/feedback', name: 'Feedback', component: Feedback },
//Requirement

View File

@ -0,0 +1,183 @@
import React, { useEffect, useState } from 'react'
import { CKEditor } from '@ckeditor/ckeditor5-react'
import { Link, useHistory } from 'react-router-dom'
import { isAutheticated } from "../../auth";
import swal from 'sweetalert'
import axios from 'axios'
import ClassicEditor from '@ckeditor/ckeditor5-build-classic'
const AddNewPageCms = () => {
const token = isAutheticated()
const history = useHistory()
const [image, setImage] = useState()
const [data, setData] = useState({
title: '',
page_data: '',
})
const [loading, setLoading] = useState(false)
const handleChange = (e) => {
setData((prev) => ({ ...prev, [e.target.id]: e.target.value }))
}
const handleSubmit = async () => {
if (data.title.trim() === '' || data.page_data.trim() === '') {
swal({
title: 'Warning',
text: 'Fill all mandatory fields',
icon: 'error',
button: 'Close',
dangerMode: true,
})
return
}
setLoading(true)
const formData = new FormData()
formData.append('title', data.title)
formData.append('page_data', data.page_data)
formData.append('image', image)
try {
const res = await axios
.post(`/api/restriction/cms/create/`, formData, {
headers: {
'Access-Control-Allow-Origin': '*',
Authorization: `Bearer ${token}`,
'Content-Type': 'multipart/formdata',
},
})
if (res.data.success === true) {
setLoading(false)
swal({
title: 'Added',
text: 'Page added successfully!',
icon: 'success',
button: 'Return',
})
history.goBack()
}
} catch (error) {
const message = 'Something went wrong!'
setLoading(false)
swal({
title: 'Warning',
text: message,
icon: 'error',
button: 'Retry',
dangerMode: true,
})
}
}
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: '28px' }} className="fw-bold mb-3">
Add Page in CMS
</div>
<div className="page-title-right">
<button
type="button"
className="btn btn-success mt-1 mb-0 my-1 btn btn-success btn-login waves-effect waves-light mr-1"
onClick={() => handleSubmit()}
disabled={loading}
>
{loading ? 'Loading' : 'Save'}
</button>
<Link to="/cms">
<button
type="button"
className="btn btn-warning mt-1 mb-0 btn btn-success btn-login waves-effect waves-light"
>
Cancel
</button>
</Link>
</div>
</div>
</div>
</div>
<div className="card">
<div className="container bg-light">
<div className="card-body">
<div className="row ">
<div className="input-group mb-3">
<span className="input-group-text" id="inputGroup-sizing-default">
Title
</span>
<input
type="text"
className="form-control"
id="title"
value={data.title}
aria-label="Sizing example input"
aria-describedby="inputGroup-sizing-default"
onChange={(e) => {
handleChange(e)
}}
/>
</div>
</div>
<div>Page data *</div>
<div className="row ">
<div className="App">
<CKEditor
editor={ClassicEditor}
onReady={(editor) => {
editor.editing.view.change((writer) => {
writer.setStyle('height', '200px', editor.editing.view.document.getRoot())
})
}}
data={data.page_data}
// config={{
// extraPlugins: [MyCustomUploadAdapterPlugin],
// }}
placeholder='page data...'
onChange={(event, editor) => {
let e = { target: { value: editor.getData(), id: 'page_data' } }
handleChange(e)
}}
/>
</div>
</div>
<div className="row mt-3">
<div>image *</div>
<div className="col-md-8 ">
<input
type="file"
className="form-control"
id="file"
onChange={(e) => setImage(e.target.files[0])}
/>
{/* <p className="pt-1 pl-2 text-secondary">Upload videos, images and pdf only</p> */}
</div>
</div>
</div>
</div>
</div>
</div>
)
}
export default AddNewPageCms

View File

@ -1,131 +1,247 @@
import axios from "axios";
import React, { useEffect, useState, useCallback } from "react";
import React, { useEffect, useState } from 'react'
import { CKEditor } from '@ckeditor/ckeditor5-react'
import { Link, useHistory, useParams } from 'react-router-dom'
import { isAutheticated } from "../../auth";
import ClipLoader from "react-spinners/ClipLoader";
import swal from 'sweetalert';
import { Link, useParams } from "react-router-dom";
import { useHistory } from "react-router-dom";
import swal from 'sweetalert'
import axios from 'axios'
import ClassicEditor from '@ckeditor/ckeditor5-build-classic'
import { useCallback } from 'react';
const EditCms = () => {
const { id } = useParams()
const token = isAutheticated();
// console.log(token, id)
let history = useHistory();
const [state, setState] = useState({
About_Us: "",
Terms_and_Conditions: "",
Privacy_Policy: "",
loading: false,
});
const { loading } = state;
const changeState = (newState) =>
setState((prevState) => ({ ...prevState, ...newState }));
const token = isAutheticated()
const history = useHistory()
const [image, setImage] = useState()
const [imagesPreview, setImagesPreview] = useState();
const [data, setData] = useState({
title: '',
page_data: '',
})
const [loading, setLoading] = useState(false)
const handleChange = (e) => {
changeState({ ...state, [e.target.name]: e.target.value })
setData((prev) => ({ ...prev, [e.target.id]: e.target.value }))
}
const fetchRestriction = useCallback(async () => {
const res = await axios.get(`/api/restriction/getOne/${id}`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
const handleImage = (e) => {
const files = e.target.files[0];
setImage(files);
// only for file preview------------------------------------
const Reader = new FileReader();
Reader.readAsDataURL(files);
// console.log(res.data.CmpRes)
setState(res.data.CmpRestriction)
changeState({ loading: false });
if (res.status === 200) changeState({ ...res.data });
}, [token]);
Reader.onload = () => {
if (Reader.readyState === 2) {
setImagesPreview(Reader.result);
}
};
// -----------------------------------------------------------------------------
};
const getCms = useCallback(async () => {
let res = await axios.get(
`/api/restriction/getOne/${id}`,
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);
if (res.data.CmpRestriction) {
setData((prev) => ({ ...res.data.CmpRestriction }))
if (res.data.CmpRestriction.image) {
setImagesPreview(res.data.CmpRestriction.image.url)
}
}
}, [token]
)
useEffect(() => {
fetchRestriction();
}, [fetchRestriction]);
getCms();
}, []);
const handleSubmit = async () => {
changeState({ loading: true });
if (data.title.trim() === '' || data.page_data.trim() === '') {
swal({
title: 'Warning',
text: 'Fill all mandatory fields',
icon: 'error',
button: 'Close',
dangerMode: true,
})
return
}
setLoading(true)
const formData = new FormData()
formData.append('title', data.title)
formData.append('page_data', data.page_data)
formData.append('image', image)
try {
let res = await axios.put(
`/api/restriction/update/${id}`,
{
...state,
},
{
const res = await axios
.put(`/api/restriction/cms/update/${id}`, formData, {
headers: {
'Access-Control-Allow-Origin': '*',
Authorization: `Bearer ${token}`,
'Content-Type': 'multipart/formdata',
},
}
);
//if (res.status === 200) window.location.reload();
// console.log(res.data)
// console.log(res.status == 200)
if (res.data.success == true) {
changeState({ loading: false });
swal("Edit CMP-Condition successfully!");
})
if (res.data.success === true) {
setLoading(false)
swal({
title: 'Edited',
text: 'Page edited successfully!',
icon: 'success',
button: 'Return',
})
history.goBack()
}
} catch (error) {
swal('Error!', error, 'error')
changeState({ loading: false });
const message = error?.response?.data?.message || 'Something went wrong!'
setLoading(false)
swal({
title: 'Warning',
text: message,
icon: 'error',
button: 'Retry',
dangerMode: true,
})
}
}
};
const onCancel = () => {
// window.location = "/comproducts";
history.goBack()
};
return (
<>
<div className="shadow-sm w-75 p-3 mb-5 bg-body rounded form-floating justify-content-center">
<form>
<h4>EDIT-CMS</h4>
<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: '28px' }} className="fw-bold mb-3">
Edit Page
</div>
<div className="mb-3 ">
<label htmlFor="exampleFormControlTextarea1" className="form-label">About Us*</label>
<textarea
className="form-control" id="exampleFormControlTextarea1" name="About_Us"
value={state.About_Us}
required
onChange={handleChange}
rows="3">
<div className="page-title-right">
<button
</textarea>
</div>
<div className="mb-3 ">
<label htmlFor="exampleFormControlTextarea1" className="form-label">Terms and Conditions*</label>
<textarea className="form-control" id="exampleFormControlTextarea1" name="Terms_and_Conditions"
value={state.Terms_and_Conditions}
required
onChange={handleChange}
rows="3"></textarea>
</div>
<div className="mb-3 ">
<label htmlFor="exampleFormControlTextarea1" className="form-label">Privacy Policy*</label>
<textarea className="form-control" id="exampleFormControlTextarea1" name="Privacy_Policy"
value={state.Privacy_Policy}
required
onChange={handleChange}
rows="3"></textarea>
</div>
<div>
<button type="button" className=" mt-1 btn btn-success" onClick={handleSubmit}>
<ClipLoader loading={state.loading} size={18} />
{!loading && "Save"}
</button>
<button type="button" className="mt-1 mx-2 btn btn-warning" onClick={onCancel}>Cancel</button>
</div>
type="button"
className="btn btn-success mt-1 mb-0 my-1 btn btn-success btn-login waves-effect waves-light mr-1"
onClick={() => handleSubmit()}
disabled={loading}
>
{loading ? 'Loading' : 'Save'}
</button>
<Link to="/cms">
<button
</form>
type="button"
className="btn btn-warning mt-1 mb-0 btn btn-success btn-login waves-effect waves-light"
>
Cancel
</button>
</Link>
</div>
</div>
</div>
</div>
</>
<div className="card">
<div className="container bg-light">
<div className="card-body">
<div className="row ">
<div className="input-group mb-3">
<span className="input-group-text" id="inputGroup-sizing-default">
Title
</span>
<input
type="text"
className="form-control"
id="title"
value={data.title}
aria-label="Sizing example input"
aria-describedby="inputGroup-sizing-default"
onChange={(e) => {
handleChange(e)
}}
/>
</div>
</div>
<div>Page data *</div>
<div className="input-group mt-1 mb-3">
<textarea
rows="3" cols="40"
type="text"
placeholder='Page data...'
className="form-control row-145"
id="page_data"
value={data.page_data}
aria-label="Sizing example input"
aria-describedby="inputGroup-sizing-default"
onChange={(e) => {
handleChange(e)
}}
></textarea>
</div>
{/* <div className="row ">
<div className="App">
<CKEditor
editor={ClassicEditor}
onReady={(editor) => {
editor.editing.view.change((writer) => {
writer.setStyle('height', '200px', editor.editing.view.document.getRoot())
})
}}
data={data.page_data}
// config={{
// extraPlugins: [MyCustomUploadAdapterPlugin],
// }}
onChange={(event, editor) => {
let e = { target: { value: editor.getData(), id: 'page_data' } }
handleChange(e)
}}
/>
</div>
</div> */}
<div className="row mt-3">
<div>image *</div>
<div className="col-md-8 ">
<input
type="file"
className="form-control"
id="file"
onChange={handleImage}
/>
{/* <p className="pt-1 pl-2 text-secondary">Upload videos, images and pdf only</p> */}
</div>
<div id="createProductFormImage" className="w-50 d-flex mt-1">
{imagesPreview && <img className=" w-50 p-1 " src={imagesPreview} alt="Product Preview" />}
</div>
</div>
</div>
</div>
</div>
</div>
)
}
export default EditCms
export default EditCms

View File

@ -0,0 +1,25 @@
import React from 'react';
import { Link } from "react-router-dom";
const Pagination = ({ postsPerPage, totalPosts, paginate }) => {
const pageNumbers = [];
for (let i = 1; i <= Math.ceil(totalPosts / postsPerPage); i++) {
pageNumbers.push(i);
}
return (
<nav>
<ul className='ml-3 pagination '>
{pageNumbers.map(number => (
<li key={number} className='page-item'>
<Link onClick={() => paginate(number)} to="/cms" className='page-link'>
{number}
</Link>
</li>
))}
</ul>
</nav>
);
};
export default Pagination;

View File

@ -66,6 +66,7 @@ function ViewOffer() {
<li className="breadcrumb-item">CMD-Category</li>
</ol>
</div> */}
</div>
</div>
</div>
@ -83,14 +84,21 @@ function ViewOffer() {
<thead className="thead-light">
{/* <th>Id</th> */}
<tr><th>About Us</th>
<td>{cmsRes?.About_Us}</td>
<tr><th>Title</th>
<td>{cmsRes?.title}</td>
</tr>
<tr> <th>Terms and Conditions</th>
<td>{cmsRes?.Terms_and_Conditions}</td>
<tr> <th>page Content</th>
<td>{`${cmsRes?.page_data}`}</td>
</tr>
<tr><th>Privacy Policy</th>
{/* <tr><th>Privacy Policy</th>
<td>{cmsRes?.Privacy_Policy}</td>
</tr> */}
<tr>
<th>image</th>
{cmsRes.image ? <td>
<img src={`${cmsRes?.image.url}`} width="50" alt="" /></td> :
<><p></p></>
}
</tr>
<tr><th>Added On</th>
<td>

View File

@ -5,10 +5,13 @@ import { Link } from "react-router-dom";
import swal from 'sweetalert';
// import { API } from "../../data";
import { isAutheticated } from "../../auth";
import Pagination from "./Pagination";
function cms() {
const [cmsRes, setCmsRes] = useState([])
const [currentPage, setCurrentPage] = useState(1);
const [postsPerPage] = useState(15);
const token = isAutheticated();
const getRestriction = useCallback(async () => {
@ -20,8 +23,8 @@ function cms() {
},
}
);
// console.log(res.data.CmpRestriction[0])
setCmsRes(res.data.CmpRestriction[0])
setCmsRes(res.data.CmpRestriction)
}, [token]);
@ -31,8 +34,43 @@ function cms() {
}, [getRestriction]);
// console.log(cmsRes)
const indexOfLastPost = currentPage * postsPerPage;
const indexOfFirstPost = indexOfLastPost - postsPerPage;
const currentPosts = cmsRes.slice(indexOfFirstPost, indexOfLastPost);
// Change page
const paginate = pageNumber => setCurrentPage(pageNumber);
const handleDelete = async (id) => {
let status = window.confirm("Do you want to delete");
if (!status) return;
let res = await axios.delete(`/api/restriction/cms/delete/${id}`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
// console.log(res)
if (res.data.success == true) {
swal("success!", "Cms Deleted Successfully!", "success");
window.location.reload();
// if (res.status === 200) window.location.reload();
}
else {
swal("error!", "failled!", "error");
}
};
//change time formate
function formatAMPM(date) {
var hours = new Date(date).getHours();
var minutes = new Date(date).getMinutes();
var ampm = hours >= 12 ? 'PM' : 'AM';
hours = hours % 12;
hours = hours ? hours : 12; // the hour '0' should be '12'
minutes = minutes < 10 ? '0' + minutes : minutes;
var strTime = hours + ':' + minutes + ' ' + ampm;
return strTime;
}
return (
<div className=" main-content">
<div className=" my-3 page-content">
@ -42,15 +80,8 @@ function cms() {
<div className="col-12">
<div className="page-title-box d-flex align-items-center justify-content-between">
<h4 className="mb-3">CMP-CMS</h4>
{/* <Link to="/addEvent"><button type="button" className="btn btn-info float-end mb-3 ml-4"> + Add Event</button></Link> */}
{/* <div className="page-title-right">
<ol className="breadcrumb m-0">
<li className="breadcrumb-item">
<Link to="/dashboard">CMD-App</Link>
</li>
<li className="breadcrumb-item">CMD-Category</li>
</ol>
</div> */}
{/* <Link to="/cms/new"><button type="button" className="btn btn-info float-end mb-3 ml-4"> + Add New Page</button></Link> */}
</div>
</div>
</div>
@ -68,169 +99,68 @@ function cms() {
<thead className="thead-light">
<tr>
<th>About Us</th>
<th>Terms and Conditions</th>
<th>Privacy Policy</th>
<th>Title</th>
{/* <th>Page Data</th> */}
{/* <th>image</th> */}
<th>Added On</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>{cmsRes?.About_Us}</td>
<td>{cmsRes?.Terms_and_Conditions}</td>
<td>{cmsRes?.Privacy_Policy}</td>
{currentPosts && currentPosts.map((item, index) =>
<tr key={index}>
<td>{item.title}</td>
{/* <td>{item?.page_data}</td> */}
{/* {item.image ? <td>
<img src={`${item?.image.url}`} width="50" alt="" /></td> :
<><p></p></>
} */}
<td>
<Link to={`/cms/view/${cmsRes._id}`}>
<td>
{/* {item?.addedOn} */}
{new Date(`${item?.createdAt}`).toDateString()}<span> , {`${formatAMPM(item?.createdAt)}`}</span>
</td>
<td>
<Link to={`/cms/view/${item._id}`}>
<button
type="button"
className="mt-1 btn btn-info btn-sm waves-effect waves-light btn-table ml-2"
>
View
</button>
</Link>
<Link to={`/cms/edit/${item._id}`}>
<button
type="button"
className="mt-1 btn btn-primary btn-sm waves-effect waves-light btn-table ml-2"
>
Edit
</button>
</Link>
<button
type="button"
className="mt-1 btn btn-info btn-sm waves-effect waves-light btn-table ml-2"
>
View
</button>
</Link>
<Link to={`/cms/edit/${cmsRes._id}`}>
<button
type="button"
className="mt-1 btn btn-primary btn-sm waves-effect waves-light btn-table ml-2"
>
Edit
</button>
</Link>
{/* <button
type="button"
onClick={() => handleDelete(`${item._id}`)}
className=" btn btn-danger btn-sm waves-effect waves-light btn-table ml-2"
id="sa-params"
>
Delete
</button> */}
</td>
</tr>
</button>
</td>
</tr>
)}
</tbody>
</table>
</div>
{/* second table */}
{/* <div className="table-responsive table-shoot mt-4">
<table className="table table-centered table-nowrap mb-0">
<thead className="thead-light">
<tr>
<th>Terms and Conditions</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>{cmsRes?.Terms_and_Conditions}</td>
<td>
<Link to={`/cms/view/${cmsRes._id}`}>
<button
type="button"
className="mt-1 btn btn-info btn-sm waves-effect waves-light btn-table ml-2"
>
View
</button>
</Link>
<Link to={`/cms/edit/${cmsRes._id}`}>
<button
type="button"
className="mt-1 btn btn-primary btn-sm waves-effect waves-light btn-table ml-2"
>
Edit
</button>
</Link>
{/* <button
type="button"
onClick={() => handleDelete(`${item._id}`)}
className=" btn btn-danger btn-sm waves-effect waves-light btn-table ml-2"
id="sa-params"
>
Delete
</button> */}
{/* </td>
</tr>
</tbody>
</table>
</div> */}
{/* end second table */}
{/* third table */}
{/* <div className="table-responsive table-shoot mt-4">
<table className="table table-centered table-nowrap mb-0">
<thead className="thead-light">
<tr>
<th>Privacy Policy</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>{cmsRes?.Privacy_Policy}</td>
<td>
<Link to={`/cms/view/${cmsRes._id}`}>
<button
type="button"
className="mt-1 btn btn-info btn-sm waves-effect waves-light btn-table ml-2"
>
View
</button>
</Link>
<Link to={`/cms/edit/${cmsRes._id}`}>
<button
type="button"
className=" mt-1 btn btn-primary btn-sm waves-effect waves-light btn-table ml-2"
>
Edit
</button>
</Link>
{/* <button
type="button"
onClick={() => handleDelete(`${item._id}`)}
className=" btn btn-danger btn-sm waves-effect waves-light btn-table ml-2"
id="sa-params"
>
Delete
</button> */}
{/* </td>
</tr>
</tbody>
</table>
</div> */}
{/* end third table */}
{/* <!-- end table-responsive --> */}
</div>
</div>
</div>
@ -238,6 +168,9 @@ function cms() {
</div>
{/* <!-- container-fluid --> */}
</div>
<Pagination postsPerPage={postsPerPage}
totalPosts={cmsRes.length}
paginate={paginate} />
</div>
);
}