first commit
This commit is contained in:
parent
db6109515a
commit
6688dc7674
@ -15,7 +15,7 @@
|
||||
<meta name="description" content="CoreUI for React - Open Source Bootstrap Admin Template">
|
||||
<meta name="author" content="Łukasz Holeczek">
|
||||
<meta name="keyword" content="Bootstrap,Admin,Template,Open,Source,CSS,SCSS,HTML,RWD,Dashboard,React">
|
||||
<title>CMP-Dashboard</title>
|
||||
<title>ATP-Dashboard</title>
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is added to the
|
||||
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
|
||||
|
@ -1,59 +0,0 @@
|
||||
import axios from "axios";
|
||||
|
||||
|
||||
|
||||
// };
|
||||
export const createCategory = (categoryData) => async (dispatch) => {
|
||||
try {
|
||||
dispatch({
|
||||
type: "NEW_CATEGORY_REQUEST",
|
||||
});
|
||||
|
||||
const { data } = await axios.post(
|
||||
`http://localhost:5000/api/category/create`,
|
||||
categoryData,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
dispatch({
|
||||
type: "NEW_CATEGORY_SUCCESS",
|
||||
payload: data,
|
||||
});
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: "NEW_CATEGORY_FAIL",
|
||||
payload: error.response.data.message,
|
||||
});
|
||||
}
|
||||
};
|
||||
export const viewAllCategory = () => async (dispatch) => {
|
||||
try {
|
||||
dispatch({
|
||||
type: "ALL_CATEGORY_REQUEST",
|
||||
});
|
||||
|
||||
const { data } = await axios.post(
|
||||
`http://localhost:5000/api/directory/getAll`,
|
||||
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
dispatch({
|
||||
type: "ALL_CATEGORY_SUCCESS",
|
||||
payload: data.data,
|
||||
});
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: "ALL_CATEGORY_FAIL",
|
||||
payload: error.response.data.message,
|
||||
});
|
||||
}
|
||||
};
|
@ -21,7 +21,7 @@ const DefaultLayout = React.lazy(() => import('./layout/DefaultLayout'))
|
||||
// Pages
|
||||
const Login = React.lazy(() => import('./views/pages/login/Login'))
|
||||
const Register = React.lazy(() => import('./views/pages/register/Change_password'))
|
||||
const Page404 = React.lazy(() => import('./views/pages/page404/Page404'))
|
||||
const Page404 = React.lazy(() => import('./views/pages/register/page404/Page404'))
|
||||
const Page500 = React.lazy(() => import('./views/pages/page500/Page500'))
|
||||
|
||||
const App = () => {
|
||||
@ -70,7 +70,7 @@ const App = () => {
|
||||
< Route exact path="/" name="Login Page" render={(props) => <Login {...props} />} />
|
||||
|
||||
<Route exact path="/forgot" name="Forgot Page" render={(props) => <ForgotPassword {...props} />} />
|
||||
<Route exact path="/newRegister" name="Register Page" render={(props) => <NewRegister {...props} />} />
|
||||
<Route exact path="/register" name="Register Page" render={(props) => <NewRegister {...props} />} />
|
||||
|
||||
<Route exact path="/404" name="Page 404" render={(props) => <Page404 {...props} />} />
|
||||
<Route exact path="/500" name="Page 500" render={(props) => <Page500 {...props} />} />
|
||||
|
54
src/_nav.js
54
src/_nav.js
@ -30,61 +30,7 @@ const _nav = [
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
component: CNavItem,
|
||||
name: 'Categories',
|
||||
icon: <CIcon icon={cilPencil} customClassName="nav-icon" />,
|
||||
to: '/category',
|
||||
},
|
||||
{
|
||||
component: CNavItem,
|
||||
name: 'Directory',
|
||||
icon: <CIcon icon={cilDrop} customClassName="nav-icon" />,
|
||||
to: '/bisuness',
|
||||
},
|
||||
{
|
||||
component: CNavItem,
|
||||
name: 'News',
|
||||
icon: <CIcon icon={cilNewspaper} customClassName="nav-icon" />,
|
||||
to: '/news',
|
||||
},
|
||||
{
|
||||
component: CNavItem,
|
||||
name: 'Events',
|
||||
icon: <CIcon icon={cilChartPie} customClassName="nav-icon" />,
|
||||
to: '/event',
|
||||
},
|
||||
{
|
||||
component: CNavItem,
|
||||
name: 'Offers',
|
||||
icon: <CIcon icon={cilMoney} customClassName="nav-icon" />,
|
||||
to: '/offer',
|
||||
},
|
||||
|
||||
{
|
||||
component: CNavItem,
|
||||
name: 'Home Screen Banners',
|
||||
icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
||||
to: '/banner',
|
||||
},
|
||||
{
|
||||
component: CNavItem,
|
||||
name: 'CMS',
|
||||
icon: <CIcon icon={cilCalculator} customClassName="nav-icon" />,
|
||||
to: '/cms',
|
||||
},
|
||||
{
|
||||
component: CNavItem,
|
||||
name: 'Customer Feedback',
|
||||
icon: <CIcon icon={cilPuzzle} customClassName="nav-icon" />,
|
||||
to: '/feedback',
|
||||
},
|
||||
{
|
||||
component: CNavItem,
|
||||
name: 'Requirements',
|
||||
icon: <CIcon icon={cilFilterSquare} customClassName="nav-icon" />,
|
||||
to: '/requirement',
|
||||
},
|
||||
// {
|
||||
// component: CNavItem,
|
||||
// name: 'FAQs',
|
||||
|
@ -6,7 +6,7 @@ const AppFooter = () => {
|
||||
<CFooter>
|
||||
<div>
|
||||
|
||||
<span className="ms-1">{new Date().getFullYear()} ©CMP.</span>
|
||||
<span className="ms-1">{new Date().getFullYear()} ©ATP.</span>
|
||||
</div>
|
||||
|
||||
</CFooter>
|
||||
|
@ -32,7 +32,7 @@ const AppHeader = () => {
|
||||
<CIcon icon={cilMenu} size="lg" />
|
||||
</CHeaderToggler>
|
||||
<CHeaderBrand className="mx-auto d-md-none" to="/">
|
||||
<h1>CMP</h1>
|
||||
<h1>ATP</h1>
|
||||
</CHeaderBrand>
|
||||
<CHeaderNav className="d-none d-md-flex me-auto">
|
||||
<CNavItem>
|
||||
|
@ -31,7 +31,7 @@ const AppSidebar = () => {
|
||||
>
|
||||
<CSidebarBrand className="d-none bg-info d-md-flex" to="/">
|
||||
{/* <CIcon className="sidebar-brand-full" icon={logoNegative} height={35} /> */}
|
||||
<h1>CMP</h1>
|
||||
<h1>ATP</h1>
|
||||
{/* <CIcon className="sidebar-brand-narrow" height={35} /> */}
|
||||
<CIcon className="sidebar-brand-narrow" icon={sygnet} height={35} />
|
||||
</CSidebarBrand>
|
||||
|
@ -72,8 +72,8 @@ const AppHeaderDropdown = () => {
|
||||
return (
|
||||
<CDropdown variant="nav-item">
|
||||
<CDropdownToggle placement="bottom-end" className="py-0" caret={false}>
|
||||
{userData && userData ? <CAvatar src={userData.avatar.url} size="md" /> :
|
||||
<CAvatar src={userImage} size="md" />}
|
||||
{/* {userData && userData ? <CAvatar src={userData.avatar.url} size="md" /> : */}
|
||||
<CAvatar src={userImage} size="md" />
|
||||
</CDropdownToggle>
|
||||
<CDropdownMenu className="pt-0" placement="bottom-end">
|
||||
<CDropdownHeader className="bg-light fw-semibold py-2">Account</CDropdownHeader>
|
||||
|
@ -11,8 +11,7 @@ import store from './store'
|
||||
import axios from 'axios'
|
||||
|
||||
const setupAxios = () => {
|
||||
axios.defaults.baseURL = 'https://cmp-all-api.herokuapp.com/'
|
||||
//axios.defaults.baseURL = 'http://localhost:5000'
|
||||
axios.defaults.baseURL = 'http://localhost:5000'
|
||||
axios.defaults.headers = {
|
||||
'Cache-Control': 'no-cache,no-store',
|
||||
'Pragma': 'no-cache',
|
||||
|
@ -1,46 +0,0 @@
|
||||
import { createReducer } from "@reduxjs/toolkit";
|
||||
|
||||
const initialState = {
|
||||
loading: true,
|
||||
};
|
||||
|
||||
export const newCategoryReducer = createReducer(
|
||||
{},
|
||||
{
|
||||
NEW_CATEGORY_REQUEST: (state) => {
|
||||
state.loading = true;
|
||||
},
|
||||
NEW_CATEGORY_SUCCESS: (state, action) => {
|
||||
state.loading = false;
|
||||
state.message = action.payload;
|
||||
},
|
||||
NEW_CATEGORY_FAIL: (state, action) => {
|
||||
state.loading = false;
|
||||
state.error = action.payload;
|
||||
},
|
||||
CLEAR_ERRORS: (state) => {
|
||||
state.error = null;
|
||||
},
|
||||
CLEAR_MESSAGE: (state) => {
|
||||
state.message = null;
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
///
|
||||
export const AllcategoryReducer = createReducer(initialState, {
|
||||
ALL_CATEGORY_REQUEST: (state) => {
|
||||
state.loading = true;
|
||||
},
|
||||
ALL_CATEGORY_SUCCESS: (state, action) => {
|
||||
state.loading = false;
|
||||
state.category = action.payload;
|
||||
},
|
||||
ALL_CATEGORY_FAIL: (state, action) => {
|
||||
state.loading = false;
|
||||
state.error = action.payload;
|
||||
},
|
||||
CLEAR_ERRORS: (state) => {
|
||||
state.error = null;
|
||||
},
|
||||
});
|
@ -1,61 +0,0 @@
|
||||
import { createReducer } from "@reduxjs/toolkit";
|
||||
|
||||
const initialState = {
|
||||
loading: true,
|
||||
};
|
||||
export const loginReducer = createReducer(
|
||||
{},
|
||||
{
|
||||
LOGIN_REQUEST: (state) => {
|
||||
state.loading = true;
|
||||
state.isAuthenticated = false;
|
||||
},
|
||||
LOGIN_SUCCESS: (state, action) => {
|
||||
state.loading = false;
|
||||
state.isAuthenticated = true;
|
||||
state.message = action.payload;
|
||||
},
|
||||
LOGIN_FAILURE: (state, action) => {
|
||||
state.loading = false;
|
||||
state.isAuthenticated = false;
|
||||
state.error = action.payload;
|
||||
},
|
||||
|
||||
LOAD_USER_REQUEST: (state) => {
|
||||
state.loading = true;
|
||||
state.isAuthenticated = false;
|
||||
},
|
||||
LOAD_USER_SUCCESS: (state, action) => {
|
||||
state.loading = false;
|
||||
state.isAuthenticated = true;
|
||||
state.user = action.payload;
|
||||
},
|
||||
LOAD_USER_FAILURE: (state, action) => {
|
||||
state.loading = false;
|
||||
state.isAuthenticated = false;
|
||||
state.error = action.payload;
|
||||
},
|
||||
|
||||
LOGOUT_REQUEST: (state) => {
|
||||
state.loading = true;
|
||||
},
|
||||
LOGOUT_SUCCESS: (state, action) => {
|
||||
state.loading = false;
|
||||
state.isAuthenticated = false;
|
||||
state.user = null;
|
||||
state.message = action.payload;
|
||||
},
|
||||
LOGOUT_FAILURE: (state, action) => {
|
||||
state.loading = false;
|
||||
state.isAuthenticated = true;
|
||||
state.error = action.payload;
|
||||
},
|
||||
|
||||
CLEAR_ERRORS: (state) => {
|
||||
state.error = null;
|
||||
},
|
||||
CLEAR_MESSAGE: (state) => {
|
||||
state.message = null;
|
||||
},
|
||||
}
|
||||
);
|
106
src/routes.js
106
src/routes.js
@ -1,55 +1,5 @@
|
||||
import React from 'react'
|
||||
//Category
|
||||
import Category from './views/Category/Category'
|
||||
import EditCategory from './views/Category/EditCategory'
|
||||
import AddCategeory from './views/Category/AddCategory'
|
||||
//Bisuness
|
||||
import Bisuness from './views/Directory/Bisuness'
|
||||
import EditBisuness from "./views/Directory/EditBisuness"
|
||||
import Add_Business from './views/Directory/Add_Business'
|
||||
import View_Business from './views/Directory/View_Bisuness'
|
||||
//news
|
||||
import AddNews from "./views/News/AddNews"
|
||||
import EditNews from "./views/News/EditNews"
|
||||
import News from "./views/News/News"
|
||||
import ViewNews from "./views/News/ViewNews"
|
||||
//Events
|
||||
import Event from './views/Events/Event'
|
||||
import AllRegisterUser from './views/Events/AllRegisterUser'
|
||||
import EditEvent from './views/Events/EditEvent'
|
||||
import AddEvent from './views/Events/AddEvent'
|
||||
import ViewEvent from './views/Events/ViewEvent'
|
||||
//offers Route
|
||||
import Offer from './views/Offers/Offer'
|
||||
import AddOffer from './views/Offers/AddOffer'
|
||||
import EditOffer from './views/Offers/EditOffer'
|
||||
import ViewOffer from './views/Offers/ViewOffer'
|
||||
//Banner
|
||||
import Banner from './views/Banners/Banner'
|
||||
import ViewBanner from './views/Banners/ViewBanner'
|
||||
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
|
||||
import Feedback from './views/Feedback/feedback'
|
||||
import ViewFeedback from './views/Feedback/ViewFeedback'
|
||||
//cms
|
||||
import Users from './views/Users/users'
|
||||
import ViewUsers from './views/Users/ViewUsers'
|
||||
//Requirement
|
||||
import ViewRequirement from './views/Requirement/ViewRequirement'
|
||||
import Requirement from './views/Requirement/Requirement'
|
||||
import AddRequirement from './views/Requirement/AddRequirement'
|
||||
import EditRequirement from './views/Requirement/EditRequirement'
|
||||
//FAQs
|
||||
import ViewFaqs from "./views/FAQs/ViewFaqs"
|
||||
import Faqs from './views/FAQs/Faqs'
|
||||
import AddFaqs from './views/FAQs/AddFaqs'
|
||||
import EditFaqs from './views/FAQs/EditFaqs'
|
||||
|
||||
|
||||
// DashBoard
|
||||
const Change_Password = React.lazy(() => import('./views/pages/register/Change_password'))
|
||||
@ -67,63 +17,9 @@ const routes = [
|
||||
{ path: '/profile/edit', name: 'Edit Profile', component: EditProfile },
|
||||
// { path: '/profile', name: 'Profile', component: Profile },
|
||||
|
||||
//Category route
|
||||
{ path: '/addCategory', name: 'AddCategeory', component: AddCategeory },
|
||||
{ path: '/category/edit/:id', name: 'EditCategory', component: EditCategory },
|
||||
{ path: '/category', name: 'Category', component: Category },
|
||||
|
||||
//Directory-Bisuness route
|
||||
{ path: '/view_bisuness/:id', name: 'view_bisuness_directory', component: View_Business },
|
||||
{ path: '/add_bisuness', name: 'Add_bisuness_directory', component: Add_Business },
|
||||
{ path: '/bisuness/edit/:id', name: 'EditBisuness', component: EditBisuness },
|
||||
{ path: '/bisuness', name: 'bisuness', component: Bisuness },
|
||||
//News route
|
||||
{ path: '/news/view/:id', name: 'ViewNews', component: ViewNews },
|
||||
{ path: '/addNews', name: 'addNews', component: AddNews },
|
||||
{ path: '/news/edit/:id', name: 'EditNews', component: EditNews },
|
||||
{ path: '/news', name: 'news', component: News },
|
||||
//Events route
|
||||
|
||||
{ path: '/event/registerUsers/view/:id', name: 'AllRegisterUser', component: AllRegisterUser },
|
||||
{ path: '/event/view/:id', name: 'ViewEvent', component: ViewEvent },
|
||||
{ path: '/addevent', name: 'AddEvent', component: AddEvent },
|
||||
{ path: '/event/edit/:id', name: 'EditEvent', component: EditEvent },
|
||||
{ path: '/event', name: 'Event', component: Event },
|
||||
|
||||
//Offers route
|
||||
{ path: '/offer/view/:id', name: 'Viewoffer', component: ViewOffer },
|
||||
{ path: '/addOffer', name: 'AddOffer', component: AddOffer },
|
||||
{ path: '/offer/edit/:id', name: 'EditOffer', component: EditOffer },
|
||||
{ path: '/offer', name: 'offer', component: Offer },
|
||||
|
||||
//BANNERS
|
||||
{ path: '/banner/view/:id', name: 'ViewBanner', component: ViewBanner },
|
||||
{ path: '/addbanner', name: 'AddBanner', component: AddBanner },
|
||||
{ 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 },
|
||||
//feedback
|
||||
{ path: '/feedback/view/:id', name: 'ViewFeedback', component: ViewFeedback },
|
||||
{ path: '/feedback', name: 'Feedback', component: Feedback },
|
||||
//Requirement
|
||||
{ path: '/requirement/view/:id', name: 'ViewRequirement', component: ViewRequirement },
|
||||
{ path: '/requirement/edit/:id', name: 'EditRequirement', component: EditRequirement },
|
||||
{ path: '/requirement/add/', name: 'AddRequirement', component: AddRequirement },
|
||||
{ path: '/requirement', name: 'Requirement', component: Requirement },
|
||||
//FAQs
|
||||
{ path: '/FAQs/view/:id', name: 'ViewFaqs', component: ViewFaqs },
|
||||
{ path: '/FAQs/edit/:id', name: 'EditFaqs', component: EditFaqs },
|
||||
{ path: '/FAQs/add/', name: 'AddFaqs', component: AddFaqs },
|
||||
{ path: '/FAQs', name: 'Faqs', component: Faqs },
|
||||
|
||||
//Users
|
||||
{ path: '/users/view/:id', name: 'ViewUsers', component: ViewUsers },
|
||||
{ path: '/users', name: 'users', component: Users },
|
||||
|
||||
|
||||
|
||||
|
@ -1,278 +0,0 @@
|
||||
import axios from "axios";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
import ClipLoader from "react-spinners/ClipLoader";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import swal from 'sweetalert';
|
||||
|
||||
|
||||
import {
|
||||
CButton,
|
||||
CCard,
|
||||
CCardBody,
|
||||
CCol,
|
||||
CContainer,
|
||||
CForm,
|
||||
CFormInput,
|
||||
CInputGroup,
|
||||
CInputGroupText,
|
||||
CRow,
|
||||
} from '@coreui/react'
|
||||
import CIcon from '@coreui/icons-react'
|
||||
import { cilPencil, cilNotes, cilCalendar, cilAddressBook, cil3d, cilActionUndo, cilNoteAdd } from '@coreui/icons'
|
||||
const AddBanner = () => {
|
||||
const token = isAutheticated();
|
||||
let history = useHistory();
|
||||
const [image, setImage] = useState("");
|
||||
const [title, setTitle] = useState("");
|
||||
const [subTitle, setSubTitle] = useState("");
|
||||
// const [section, setSection] = useState("");
|
||||
|
||||
const [startDate, setStartDate] = useState(new Date());
|
||||
const [endDate, setEndDate] = useState(new Date());
|
||||
// const [subSection, setSubSection] = useState("");
|
||||
// const [category, setCategory] = useState(false);
|
||||
|
||||
|
||||
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!(title && image && startDate && endDate)) {
|
||||
return swal('Error!', 'All fields are required', 'error')
|
||||
|
||||
}
|
||||
const myForm = new FormData();
|
||||
|
||||
myForm.set("title", title);
|
||||
// myForm.set("subTitle", subTitle);
|
||||
// myForm.set("section", section);
|
||||
// myForm.set("subSection", subSection);
|
||||
myForm.set("startDate", startDate);
|
||||
myForm.set("endDate", endDate);
|
||||
myForm.set("image", image);
|
||||
setLoading({ loading: true });
|
||||
// console.log(image)
|
||||
try {
|
||||
let res = await axios.post(
|
||||
`/api/banner/create`, myForm,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": 'multipart/form-data',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
// console.log(res.data)
|
||||
if (res.data) {
|
||||
swal("success!", "Banner Added Successfully!", "success");
|
||||
setLoading(false);
|
||||
history.goBack();
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
swal('Error!', error, 'error')
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
const handleImage = (e) => {
|
||||
const files = e.target.files[0];
|
||||
// console.log(files)
|
||||
setImage(files);
|
||||
|
||||
};
|
||||
//
|
||||
const onCancel = () => {
|
||||
// window.location = "/comproducts";
|
||||
history.goBack()
|
||||
|
||||
};
|
||||
|
||||
// useEffect(() => {
|
||||
// const getData = async () => {
|
||||
// let res = await axios.get(
|
||||
// `/api/category/getAll`,
|
||||
// {
|
||||
// headers: {
|
||||
// Authorization: `Bearer ${token}`,
|
||||
// },
|
||||
// }
|
||||
// );
|
||||
// // console.log(res.data)
|
||||
// setCategory(res.data.category)
|
||||
// }
|
||||
// if (section === "category") {
|
||||
// getData()
|
||||
// } else {
|
||||
// setCategory(false)
|
||||
// }
|
||||
// }, [section])
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-light min-vh-70 d-flex flex-row ">
|
||||
<CContainer>
|
||||
<CRow className="align-left w-140">
|
||||
<CCol md={19} lg={27} xl={16}>
|
||||
<CCard className="mx-4">
|
||||
<CCardBody className="p-4">
|
||||
<CForm>
|
||||
<h3 className="mb-4 justify-content-center">Add Banner</h3>
|
||||
<div>
|
||||
<div>
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilPencil} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
required
|
||||
onChange={(e) => setTitle(e.target.value)}
|
||||
value={title}
|
||||
placeholder="Title" />
|
||||
</CInputGroup>
|
||||
{/* <CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilPencil} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
required
|
||||
onChange={(e) => setSubTitle(e.target.value)}
|
||||
value={subTitle}
|
||||
placeholder="sub title" />
|
||||
</CInputGroup> */}
|
||||
|
||||
{/* <CInputGroup className="mb-3">
|
||||
<CInputGroupText >
|
||||
Section
|
||||
<CIcon icon={cilNotes} />
|
||||
</CInputGroupText>
|
||||
|
||||
<select
|
||||
name="section"
|
||||
value={section}
|
||||
onChange={(e) => setSection(e.target.value)}
|
||||
className="form-control input-field "
|
||||
>
|
||||
|
||||
<option value="1">--Select--</option>
|
||||
<option value="home">home</option>
|
||||
<option value="news">news</option>
|
||||
<option value="events">events</option>
|
||||
<option value="offers">offers</option>
|
||||
<option value="category" >category</option>
|
||||
|
||||
|
||||
|
||||
|
||||
</select>
|
||||
{category && <>
|
||||
<CInputGroupText className="ml-2 mt-1">
|
||||
SubSection
|
||||
<CIcon icon={cilNoteAdd} />
|
||||
</CInputGroupText>
|
||||
<select
|
||||
name="subSection"
|
||||
value={subSection}
|
||||
onChange={(e) => setSubSection(e.target.value)}
|
||||
className="form-control input-field mt-1"
|
||||
>
|
||||
<option value="1">--Select SubCategory--</option>
|
||||
{category.map((item, index) => (
|
||||
|
||||
<option key={index} value={item.name}>{item.name}</option>
|
||||
))}
|
||||
|
||||
|
||||
|
||||
</select></>}
|
||||
</CInputGroup> */}
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
Start Date*
|
||||
<CIcon icon={cilCalendar} />
|
||||
</CInputGroupText>
|
||||
{/* <DatePicker selected={startDate} /> */}
|
||||
|
||||
<CFormInput type="date"
|
||||
required
|
||||
onChange={(e) => setStartDate(e.target.value)}
|
||||
value={startDate}
|
||||
placeholder="Start Date" />
|
||||
</CInputGroup>
|
||||
<CInputGroup className="mb-3">
|
||||
|
||||
<CInputGroupText>
|
||||
End Date*
|
||||
<CIcon icon={cilCalendar} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="date"
|
||||
startDate
|
||||
required
|
||||
onChange={(e) => setEndDate(e.target.value)}
|
||||
value={endDate}
|
||||
placeholder="EndDate" />
|
||||
</CInputGroup>
|
||||
{/* <CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilLocationPin} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
required
|
||||
onChange={(e) => setLocation(e.target.value)}
|
||||
value={location}
|
||||
placeholder="Location" />
|
||||
</CInputGroup> */}
|
||||
|
||||
<CInputGroup className="mb-3">
|
||||
|
||||
{/* <CIcon icon={cilLockLocked} /> */}
|
||||
|
||||
<CFormInput
|
||||
type="file"
|
||||
placeholder="image"
|
||||
accept="image/*"
|
||||
required
|
||||
onChange={handleImage}
|
||||
|
||||
|
||||
/>
|
||||
</CInputGroup>
|
||||
</div>
|
||||
|
||||
<div className=" d-flex">
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
type="button"
|
||||
className="btn btn-success btn-login waves-effect waves-light"
|
||||
>
|
||||
<ClipLoader loading={loading} size={18} />
|
||||
{!loading && "Save"}
|
||||
</button>
|
||||
<button
|
||||
onClick={onCancel}
|
||||
type="button"
|
||||
className=" ml-2 btn btn-warning btn-cancel waves-effect waves-light"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</CForm>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CContainer>
|
||||
</div>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default AddBanner
|
@ -1,179 +0,0 @@
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useEffect, useState, useCallback, useMemo } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import swal from 'sweetalert';
|
||||
// import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
|
||||
function banner() {
|
||||
const [banner, setBanner] = useState([])
|
||||
|
||||
const token = isAutheticated();
|
||||
|
||||
const getEvent = useCallback(async () => {
|
||||
let res = await axios.get(
|
||||
`/api/banner/getAll`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
// console.log(res.data)
|
||||
setBanner(res.data.banner)
|
||||
|
||||
|
||||
}, [token]);
|
||||
|
||||
useEffect(() => {
|
||||
getEvent();
|
||||
}, [getEvent]);
|
||||
|
||||
|
||||
const handleDelete = async (id) => {
|
||||
let status = window.confirm("Do you want to delete");
|
||||
if (!status) return;
|
||||
|
||||
let res = await axios.delete(`/api/banner/delete/${id}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
console.log(res)
|
||||
if (res.data.success == true) {
|
||||
swal("success!", "Banner Deleted Successfully!", "success");
|
||||
window.location.reload();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//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">
|
||||
<div className="container-fluid">
|
||||
{/* <!-- start page title --> */}
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<div className="page-title-box d-flex align-items-center justify-content-between">
|
||||
<h4 className="mb-3">Home Screen Banners</h4>
|
||||
<Link to="/addbanner"><button type="button" className="btn btn-info float-end mb-3 ml-4"> + Add Banner</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> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- end page title --> */}
|
||||
|
||||
<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>
|
||||
<div className="table-responsive table-shoot">
|
||||
<table className="table table-centered table-nowrap mb-0">
|
||||
<thead className="thead-light">
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>Image</th>
|
||||
{/* <th>Section</th>
|
||||
<th>Sub Section</th> */}
|
||||
<th>Status</th>
|
||||
<th>Added On</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{banner && banner.map((item, index) =>
|
||||
<tr key={index}>
|
||||
<td>{item?.title}</td>
|
||||
<td>
|
||||
<img src={`${item?.image.url}`} width="50" alt="" /></td>
|
||||
|
||||
|
||||
{/* <td>{item?.section}</td>
|
||||
<th>{item?.subSection}</th> */}
|
||||
<td>
|
||||
<span
|
||||
className={`badge rounded-pill bg-${new Date(`${item?.endDate}`) > new Date() ? "success" : "danger"
|
||||
} font-size-10`}
|
||||
>
|
||||
{new Date(`${item?.endDate}`) > new Date() ? "Live" : "Suspended"}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
{/* {item?.addedOn} */}
|
||||
{new Date(`${item?.addedOn}`).toDateString()}<span> , {`${formatAMPM(item?.addedOn)}`}</span>
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
<td>
|
||||
<Link to={`/banner/view/${item._id}`}>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className=" mx-2 mt-1 btn btn-info btn-sm waves-effect waves-light btn-table ml-2"
|
||||
>
|
||||
View
|
||||
</button>
|
||||
</Link>
|
||||
<Link to={`/banner/edit/${item._id}`}>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className=" mx-2 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=" mt-1 btn btn-danger btn-sm waves-effect waves-light btn-table ml-2"
|
||||
id="sa-params"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
{/* <!-- end table-responsive --> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- container-fluid --> */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default banner;
|
@ -1,320 +0,0 @@
|
||||
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
import ClipLoader from "react-spinners/ClipLoader";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import swal from 'sweetalert';
|
||||
import { useParams } from "react-router-dom";
|
||||
|
||||
import {
|
||||
CButton,
|
||||
CCard,
|
||||
CCardBody,
|
||||
CCol,
|
||||
CContainer,
|
||||
CForm,
|
||||
CFormInput,
|
||||
CInputGroup,
|
||||
CInputGroupText,
|
||||
CRow,
|
||||
} from '@coreui/react'
|
||||
import CIcon from '@coreui/icons-react'
|
||||
import { cilPencil, cilNotes, cilCalendar, cilNoteAdd } from '@coreui/icons'
|
||||
const EditBanner = () => {
|
||||
const { id } = useParams();
|
||||
const token = isAutheticated();
|
||||
let history = useHistory();
|
||||
const [image, setImage] = useState("");
|
||||
const [title, setTitle] = useState("");
|
||||
// const [subTitle, setSubTitle] = useState("");
|
||||
const [imagesPreview, setImagesPreview] = useState();
|
||||
|
||||
// const [section, setSection] = useState("");
|
||||
|
||||
const [startDate, setStartDate] = useState("");
|
||||
const [endDate, setEndDate] = useState("");
|
||||
|
||||
// const [subSection, setSubSection] = useState("");
|
||||
// const [category, setCategory] = useState(false);
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
//fetch one Offer
|
||||
useEffect(async () => {
|
||||
const res = await axios.get(`/api/banner/getOne/${id}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
|
||||
// console.log(res.data.banner.startDate)
|
||||
setTitle(res.data.banner.title)
|
||||
// setSubTitle(res.data.banner.subTitle)
|
||||
// setSection(res.data.banner.section)
|
||||
// setSubSection(res.data.banner.subSection)
|
||||
setImagesPreview(res.data.banner.image.url)
|
||||
setStartDate(res.data.banner.startDate)
|
||||
setEndDate(res.data.banner.endDate)
|
||||
|
||||
}, [id]);
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!(title && startDate && endDate)) {
|
||||
return swal('Error!', 'All fields are required', 'error')
|
||||
|
||||
}
|
||||
const myForm = new FormData();
|
||||
|
||||
myForm.set("title", title);
|
||||
// myForm.set("subTitle", subTitle);
|
||||
// myForm.set("section", section);
|
||||
// myForm.set("subSection", subSection);
|
||||
myForm.set("startDate", startDate);
|
||||
myForm.set("endDate", endDate);
|
||||
myForm.set("image", image);
|
||||
setLoading({ loading: true });
|
||||
try {
|
||||
let res = await axios.put(
|
||||
`/api/banner/update/${id}`, myForm,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": 'multipart/form-data',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
// console.log(res.data)
|
||||
if (res.data) {
|
||||
swal("success!", "Banner Updated Successfully!", "success");
|
||||
setLoading(false);
|
||||
history.goBack();
|
||||
}
|
||||
} catch (error) {
|
||||
swal('Error!', error, 'error')
|
||||
setLoading(false);
|
||||
}
|
||||
// console.log(image)
|
||||
|
||||
|
||||
|
||||
};
|
||||
// const handleImage = (e) => {
|
||||
// const files = e.target.files[0];
|
||||
// // console.log(files)
|
||||
// setImage(files);
|
||||
|
||||
// };
|
||||
// //
|
||||
const handleImage = (e) => {
|
||||
const files = e.target.files[0];
|
||||
|
||||
// console.log(files)
|
||||
setImage(files);
|
||||
// only for file preview------------------------------------
|
||||
const Reader = new FileReader();
|
||||
Reader.readAsDataURL(files);
|
||||
|
||||
Reader.onload = () => {
|
||||
if (Reader.readyState === 2) {
|
||||
setImagesPreview(Reader.result);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
};
|
||||
const onCancel = () => {
|
||||
// window.location = "/comproducts";
|
||||
history.goBack()
|
||||
|
||||
};
|
||||
|
||||
|
||||
// useEffect(() => {
|
||||
// const getData = async () => {
|
||||
// let res = await axios.get(
|
||||
// `/api/category/getAll`,
|
||||
// {
|
||||
// headers: {
|
||||
// Authorization: `Bearer ${token}`,
|
||||
// },
|
||||
// }
|
||||
// );
|
||||
// console.log(res.data)
|
||||
// setCategory(res.data.category)
|
||||
// }
|
||||
// if (section === "category") {
|
||||
// getData()
|
||||
// } else {
|
||||
// setCategory(false)
|
||||
// }
|
||||
// }, [section])
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-light min-vh-70 d-flex flex-row ">
|
||||
<CContainer>
|
||||
<CRow className="align-left w-140">
|
||||
<CCol md={19} lg={27} xl={16}>
|
||||
<CCard className="mx-4">
|
||||
<CCardBody className="p-4">
|
||||
<CForm>
|
||||
<h3 className="mb-4 justify-content-center">Edit Banner</h3>
|
||||
<div>
|
||||
<div>
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilPencil} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
required
|
||||
onChange={(e) => setTitle(e.target.value)}
|
||||
value={title}
|
||||
placeholder="Title" />
|
||||
</CInputGroup>
|
||||
{/* <CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilPencil} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
required
|
||||
onChange={(e) => setSubTitle(e.target.value)}
|
||||
value={subTitle}
|
||||
placeholder="sub title" />
|
||||
</CInputGroup> */}
|
||||
|
||||
{/* <CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilNotes} />
|
||||
|
||||
</CInputGroupText>
|
||||
|
||||
<select
|
||||
name="section"
|
||||
value={section}
|
||||
onChange={(e) => setSection(e.target.value)}
|
||||
className="form-control input-field"
|
||||
>
|
||||
|
||||
<option value="1">--Select--</option>
|
||||
<option value="home">home</option>
|
||||
<option value="news">news</option>
|
||||
<option value="events">events</option>
|
||||
<option value="offers">offers</option>
|
||||
<option value="category" >category</option>
|
||||
|
||||
|
||||
</select>
|
||||
{category && <>
|
||||
<CInputGroupText className="ml-2 mt-1">
|
||||
SubSection
|
||||
<CIcon icon={cilNoteAdd} />
|
||||
</CInputGroupText>
|
||||
<select
|
||||
name="subSection"
|
||||
value={subSection}
|
||||
onChange={(e) => setSubSection(e.target.value)}
|
||||
className="form-control input-field mt-1"
|
||||
>
|
||||
<option value="1">--Select SubCategory--</option>
|
||||
{category.map((item, index) => (
|
||||
|
||||
<option key={index} value={item.name}>{item.name}</option>
|
||||
))}
|
||||
|
||||
|
||||
|
||||
</select></>}
|
||||
</CInputGroup> */}
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
Start Date*
|
||||
<CIcon icon={cilCalendar} />
|
||||
</CInputGroupText>
|
||||
{/* <DatePicker selected={startDate} /> */}
|
||||
|
||||
<CFormInput type="date"
|
||||
required
|
||||
onChange={(e) => setStartDate(e.target.value)}
|
||||
value={startDate}
|
||||
placeholder="Start Date" />
|
||||
</CInputGroup>
|
||||
<CInputGroup className="mb-3">
|
||||
|
||||
<CInputGroupText>
|
||||
End Date*
|
||||
<CIcon icon={cilCalendar} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="date"
|
||||
startDate
|
||||
required
|
||||
onChange={(e) => setEndDate(e.target.value)}
|
||||
value={endDate}
|
||||
placeholder="EndDate" />
|
||||
</CInputGroup>
|
||||
{/* <CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilLocationPin} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
required
|
||||
onChange={(e) => setLocation(e.target.value)}
|
||||
value={location}
|
||||
placeholder="Location" />
|
||||
</CInputGroup> */}
|
||||
|
||||
<CInputGroup className="mb-3">
|
||||
|
||||
{/* <CIcon icon={cilLockLocked} /> */}
|
||||
|
||||
<CFormInput
|
||||
type="file"
|
||||
placeholder="image"
|
||||
accept="image/*"
|
||||
required
|
||||
onChange={handleImage}
|
||||
|
||||
|
||||
/>
|
||||
</CInputGroup>
|
||||
<div id="createProductFormImage" className="w-50 d-flex">
|
||||
|
||||
|
||||
{imagesPreview && <img className=" w-50 p-1 " src={imagesPreview} alt="Product Preview" />}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className=" d-flex">
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
type="button"
|
||||
className="btn btn-success btn-login waves-effect waves-light"
|
||||
>
|
||||
<ClipLoader loading={loading} size={18} />
|
||||
{!loading && "Save"}
|
||||
</button>
|
||||
<button
|
||||
onClick={onCancel}
|
||||
type="button"
|
||||
className=" ml-2 btn btn-warning btn-cancel waves-effect waves-light"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</CForm>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CContainer>
|
||||
</div>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default EditBanner
|
@ -1,128 +0,0 @@
|
||||
|
||||
|
||||
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useEffect, useState, useCallback, useMemo } from "react";
|
||||
import swal from 'sweetalert';
|
||||
// import { API } from "../../data";
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import { isAutheticated } from "../../auth";
|
||||
|
||||
function ViewBanner() {
|
||||
const [banner, setBanner] = useState([])
|
||||
const { id } = useParams();
|
||||
// console.log(id)
|
||||
const token = isAutheticated();
|
||||
|
||||
const getBanner = useCallback(async () => {
|
||||
let res = await axios.get(
|
||||
`/api/banner/getOne/${id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
setBanner(res.data.banner)
|
||||
|
||||
|
||||
}, [token]);
|
||||
|
||||
useEffect(() => {
|
||||
getBanner();
|
||||
}, [getBanner]);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//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">
|
||||
<div className="container-fluid">
|
||||
{/* <!-- start page title --> */}
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<div className="page-title-box d-flex align-items-center justify-content-between">
|
||||
<h4 className="mb-3">Home Screen Banner</h4>
|
||||
<Link to="/addbanner"><button type="button" className="btn btn-info float-end mb-3 ml-4"> + Add New Banner</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> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- end page title --> */}
|
||||
|
||||
<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>
|
||||
<div className="table-responsive table-shoot">
|
||||
<table className="table table-centered table-nowrap mb-0">
|
||||
<thead className="thead-light">
|
||||
|
||||
<tr><th>Id</th><td>{banner?._id}</td></tr>
|
||||
<tr><th>Title</th><td>{banner?.title}</td></tr>
|
||||
|
||||
<tr> <th>Image</th> <td>
|
||||
<img src={`${banner.image?.url}`} width="50" alt="" />
|
||||
</td></tr>
|
||||
{/* <tr><th>Section</th><td>{banner?.section}</td></tr>
|
||||
<tr> <th>Sub Section</th><td>{banner?.subSection}</td></tr> */}
|
||||
<tr><th>Start Date</th> <td>
|
||||
{new Date(`${banner?.startDate}`).toDateString()}
|
||||
</td></tr>
|
||||
<tr><th>End Date</th><td>
|
||||
{new Date(`${banner?.endDate}`).toDateString()}</td></tr>
|
||||
<tr><th>Added On</th><td>
|
||||
{new Date(`${banner?.addedOn}`).toDateString()}<span> , {`${formatAMPM(banner?.addedOn)}`}</span>
|
||||
</td></tr>
|
||||
<tr> <th>Updated At</th><td>
|
||||
{new Date(`${banner?.updatedAt}`).toDateString()}<span> , {`${formatAMPM(banner?.updatedAt)}`}</span>
|
||||
</td></tr>
|
||||
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
{/* <!-- end table-responsive --> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- container-fluid --> */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ViewBanner;
|
@ -1,183 +0,0 @@
|
||||
|
||||
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
|
@ -1,247 +0,0 @@
|
||||
|
||||
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 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()
|
||||
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) => {
|
||||
|
||||
setData((prev) => ({ ...prev, [e.target.id]: e.target.value }))
|
||||
}
|
||||
const handleImage = (e) => {
|
||||
const files = e.target.files[0];
|
||||
setImage(files);
|
||||
// only for file preview------------------------------------
|
||||
const Reader = new FileReader();
|
||||
Reader.readAsDataURL(files);
|
||||
|
||||
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(() => {
|
||||
getCms();
|
||||
}, []);
|
||||
|
||||
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
|
||||
.put(`/api/restriction/cms/update/${id}`, formData, {
|
||||
headers: {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'multipart/formdata',
|
||||
},
|
||||
})
|
||||
if (res.data.success === true) {
|
||||
|
||||
setLoading(false)
|
||||
swal({
|
||||
title: 'Edited',
|
||||
text: 'Page edited successfully!',
|
||||
icon: 'success',
|
||||
button: 'Return',
|
||||
})
|
||||
history.goBack()
|
||||
|
||||
}
|
||||
} catch (error) {
|
||||
const message = error?.response?.data?.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">
|
||||
Edit Page
|
||||
</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="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
|
@ -1,25 +0,0 @@
|
||||
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;
|
@ -1,135 +0,0 @@
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useEffect, useState, useCallback, useMemo } from "react";
|
||||
import swal from 'sweetalert';
|
||||
// import { API } from "../../data";
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import { isAutheticated } from "../../auth";
|
||||
|
||||
function ViewOffer() {
|
||||
const [cmsRes, setCmsRes] = useState([])
|
||||
const { id } = useParams();
|
||||
// console.log(id)
|
||||
const token = isAutheticated();
|
||||
|
||||
const getOffer = useCallback(async () => {
|
||||
let res = await axios.get(
|
||||
`/api/restriction/getOne/${id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
//console.log(res.data)
|
||||
setCmsRes(res.data.CmpRestriction)
|
||||
|
||||
|
||||
}, [token]);
|
||||
|
||||
useEffect(() => {
|
||||
getOffer();
|
||||
}, [getOffer]);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//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">
|
||||
<div className="container-fluid">
|
||||
{/* <!-- start page title --> */}
|
||||
<div className="row">
|
||||
<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="/"><button type="button" className="btn btn-info float-end mb-3 ml-4"> + Edit Restriction</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> */}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- end page title --> */}
|
||||
|
||||
<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>
|
||||
<div className="table-responsive table-shoot">
|
||||
<table className="table table-centered table-nowrap mb-0">
|
||||
<thead className="thead-light">
|
||||
|
||||
{/* <th>Id</th> */}
|
||||
<tr><th>Title</th>
|
||||
<td>{cmsRes?.title}</td>
|
||||
</tr>
|
||||
<tr> <th>page Content</th>
|
||||
<td>{`${cmsRes?.page_data}`}</td>
|
||||
</tr>
|
||||
{/* <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>
|
||||
{new Date(`${cmsRes?.createdAt}`).toDateString()}<span> , {`${formatAMPM(cmsRes?.createdAt)}`}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><th>Updated At</th>
|
||||
<td>
|
||||
{new Date(`${cmsRes?.updatedAt}`).toDateString()}<span> , {`${formatAMPM(cmsRes?.updatedAt)}`}</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
{/* <!-- end table-responsive --> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- container-fluid --> */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ViewOffer;
|
||||
|
@ -1,178 +0,0 @@
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useEffect, useState, useCallback, useMemo } from "react";
|
||||
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 () => {
|
||||
let res = await axios.get(
|
||||
`/api/restriction/getAll`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
setCmsRes(res.data.CmpRestriction)
|
||||
|
||||
|
||||
}, [token]);
|
||||
|
||||
useEffect(() => {
|
||||
getRestriction();
|
||||
}, [getRestriction]);
|
||||
|
||||
|
||||
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">
|
||||
<div className="container-fluid">
|
||||
{/* <!-- start page title --> */}
|
||||
<div className="row">
|
||||
<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="/cms/new"><button type="button" className="btn btn-info float-end mb-3 ml-4"> + Add New Page</button></Link> */}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- end page title --> */}
|
||||
|
||||
<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>
|
||||
<div className="table-responsive table-shoot">
|
||||
<table className="table table-centered table-nowrap mb-0">
|
||||
<thead className="thead-light">
|
||||
<tr>
|
||||
|
||||
<th>Title</th>
|
||||
{/* <th>Page Data</th> */}
|
||||
|
||||
{/* <th>image</th> */}
|
||||
<th>Added On</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{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>
|
||||
{/* {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"
|
||||
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>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- container-fluid --> */}
|
||||
</div>
|
||||
<Pagination postsPerPage={postsPerPage}
|
||||
totalPosts={cmsRes.length}
|
||||
paginate={paginate} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default cms;
|
@ -1,171 +0,0 @@
|
||||
import axios from "axios";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
import ClipLoader from "react-spinners/ClipLoader";
|
||||
//import Footer from "../../Footer";
|
||||
import { Link } from "react-router-dom";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import swal from 'sweetalert';
|
||||
|
||||
import {
|
||||
CButton,
|
||||
CCard,
|
||||
CCardBody,
|
||||
CCol,
|
||||
CContainer,
|
||||
CForm,
|
||||
CFormInput,
|
||||
CInputGroup,
|
||||
CInputGroupText,
|
||||
CRow,
|
||||
} from '@coreui/react'
|
||||
import CIcon from '@coreui/icons-react'
|
||||
import { cilLockLocked, cilUser } from '@coreui/icons'
|
||||
const AddProduct = () => {
|
||||
const token = isAutheticated();
|
||||
let history = useHistory();
|
||||
const [image, setImage] = useState("");
|
||||
const [ctegoryBannerImage, setCtegoryBannerImage] = useState("");
|
||||
const [name, setName] = useState("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!(name && image && ctegoryBannerImage)) {
|
||||
return swal('Error!', 'All fields are required', 'error')
|
||||
|
||||
}
|
||||
const myForm = new FormData();
|
||||
|
||||
myForm.set("name", name);
|
||||
|
||||
|
||||
myForm.set("image", image);
|
||||
myForm.set("category_banner", ctegoryBannerImage);
|
||||
setLoading({ loading: true });
|
||||
// console.log(image)
|
||||
try {
|
||||
let res = await axios.post(
|
||||
`/api/category/create`, myForm,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": 'multipart/form-data',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
//console.log(res.data.data.name)
|
||||
if (res.data) {
|
||||
swal("success!", "Category Added Successfully!", "success");
|
||||
setLoading(false);
|
||||
history.goBack();
|
||||
}
|
||||
} catch (error) {
|
||||
swal('Error!', "something went wrong", 'error')
|
||||
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
const handleImage = (e) => {
|
||||
const files = e.target.files[0];
|
||||
// console.log(files)
|
||||
setImage(files);
|
||||
|
||||
};
|
||||
//
|
||||
const onCancel = () => {
|
||||
// window.location = "/comproducts";
|
||||
history.goBack()
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-light min-vh-70 d-flex flex-row ">
|
||||
<CContainer>
|
||||
<CRow className="align-left w-140">
|
||||
<CCol md={19} lg={27} xl={16}>
|
||||
<CCard className="mx-4">
|
||||
<CCardBody className="p-4">
|
||||
<CForm>
|
||||
<h3 className="mb-4 justify-content-center">Add Category</h3>
|
||||
<div>
|
||||
<div>
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilUser} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
required
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
value={name}
|
||||
placeholder="Name" />
|
||||
</CInputGroup>
|
||||
<div>category image *</div>
|
||||
|
||||
<CInputGroup className="mb-3 mt-2">
|
||||
|
||||
{/* <CIcon icon={cilLockLocked} /> */}
|
||||
|
||||
<CFormInput
|
||||
type="file"
|
||||
placeholder="image"
|
||||
accept="image/*"
|
||||
required
|
||||
onChange={handleImage}
|
||||
|
||||
|
||||
/>
|
||||
</CInputGroup>
|
||||
<div>category Banner image *</div>
|
||||
<CInputGroup className="mb-3 mt-2">
|
||||
|
||||
|
||||
|
||||
<CFormInput
|
||||
type="file"
|
||||
placeholder="image"
|
||||
accept="image/*"
|
||||
required
|
||||
onChange={(e) => setCtegoryBannerImage(e.target.files[0])}
|
||||
|
||||
|
||||
/>
|
||||
</CInputGroup>
|
||||
</div>
|
||||
|
||||
<div className=" d-flex">
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
type="button"
|
||||
className="btn btn-success btn-login waves-effect waves-light"
|
||||
>
|
||||
<ClipLoader loading={loading} size={18} />
|
||||
{!loading && "Save"}
|
||||
</button>
|
||||
<button
|
||||
onClick={onCancel}
|
||||
type="button"
|
||||
className=" ml-2 btn btn-warning btn-cancel waves-effect waves-light"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</CForm>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CContainer>
|
||||
</div>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default AddProduct
|
@ -1,188 +0,0 @@
|
||||
import axios from "axios";
|
||||
import React, { useEffect, useState, useCallback, useMemo } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import swal from 'sweetalert';
|
||||
// import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
|
||||
function Products() {
|
||||
const [category, setCategory] = useState([])
|
||||
const [state, setState] = useState({
|
||||
products: [],
|
||||
page: 1,
|
||||
limit: 10,
|
||||
totalProducts: 0,
|
||||
pages: 1,
|
||||
});
|
||||
|
||||
window.scrollTo({ behavior: "smooth", top: "0px" });
|
||||
|
||||
const { products, page, limit, totalProducts, pages } = state;
|
||||
|
||||
const changeState = (newState) =>
|
||||
setState((prevState) => ({ ...prevState, ...newState }));
|
||||
|
||||
const token = isAutheticated();
|
||||
|
||||
const getProducts = useCallback(async () => {
|
||||
let res = await axios.get(
|
||||
`/api/category/getAll`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
// console.log(res.data.category)
|
||||
setCategory(res.data.category)
|
||||
// console.log(category[0].addedOn)
|
||||
changeState({
|
||||
...res.data,
|
||||
pages: Math.ceil(res.data.totalProducts / limit),
|
||||
});
|
||||
}, [limit, page, token]);
|
||||
|
||||
useEffect(() => {
|
||||
getProducts();
|
||||
}, [getProducts]);
|
||||
|
||||
// const getTotalPages = useMemo(() => {
|
||||
// const length = pages > 1 ? pages : totalProducts ? 1 : 0;
|
||||
// return Array.from({ length }, (_, i) => i + 1);
|
||||
// }, [pages, totalProducts]);
|
||||
|
||||
// console.log(getTotalPages);
|
||||
|
||||
const handleDelete = async (id) => {
|
||||
let status = window.confirm("Do you want to delete");
|
||||
if (!status) return;
|
||||
|
||||
let res = await axios.delete(`/api/category/delete/${id}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
// console.log(res)
|
||||
if (res.data.success == true) {
|
||||
swal("success!", "Category 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">
|
||||
<div className="container-fluid">
|
||||
{/* <!-- start page title --> */}
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<div className="page-title-box d-flex align-items-center justify-content-between">
|
||||
<h4 className="mb-3">Categories</h4>
|
||||
<Link to="/addCategory"><button type="button" className="btn btn-info float-end mb-3 ml-4"> + Add Category</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> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- end page title --> */}
|
||||
|
||||
<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>
|
||||
<div className="table-responsive table-shoot">
|
||||
<table className="table table-centered table-nowrap mb-0">
|
||||
<thead className="thead-light">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Category Image</th>
|
||||
<th>Category Banner</th>
|
||||
<th>Added On</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{category && category.map((item, index) =>
|
||||
<tr key={index}>
|
||||
<td>{item?.name}</td>
|
||||
<td>
|
||||
<img src={`${item?.image.url}`} width="50" alt="" />
|
||||
</td>
|
||||
<td>
|
||||
|
||||
{item.category_banner && <img src={`${item?.category_banner.url}`} width="50" alt="" />}
|
||||
</td>
|
||||
<td>
|
||||
{/* {item?.addedOn} */}
|
||||
{new Date(`${item?.addedOn}`).toDateString()}<span> , {`${formatAMPM(item?.addedOn)}`}</span>
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
<td>
|
||||
<Link to={`/category/edit/${item._id}`}>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className=" mx-1 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="mx-1 mt-1 btn btn-danger btn-sm waves-effect waves-light btn-table ml-2"
|
||||
id="sa-params"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
{/* <!-- end table-responsive --> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- container-fluid --> */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Products;
|
@ -1,231 +0,0 @@
|
||||
import axios from "axios";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
import ClipLoader from "react-spinners/ClipLoader";
|
||||
//import Footer from "../../Footer";
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import swal from 'sweetalert';
|
||||
|
||||
import {
|
||||
CButton,
|
||||
CCard,
|
||||
CCardBody,
|
||||
CCol,
|
||||
CContainer,
|
||||
CForm,
|
||||
CFormInput,
|
||||
CInputGroup,
|
||||
CInputGroupText,
|
||||
CRow,
|
||||
} from '@coreui/react'
|
||||
import CIcon from '@coreui/icons-react'
|
||||
import { cilLockLocked, cilUser } from '@coreui/icons'
|
||||
const AddProduct = () => {
|
||||
const token = isAutheticated();
|
||||
let history = useHistory();
|
||||
const { id } = useParams();
|
||||
// console.log(id)
|
||||
const [image, setImage] = useState("");
|
||||
const [name, setName] = useState("");
|
||||
const [imagesPreview, setImagesPreview] = useState();
|
||||
const [ctegoryBannerImage, setCtegoryBannerImage] = useState("");
|
||||
const [ctegoryBannerImagePreview, setCtegoryBannerImagePreview] = useState("");
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
useEffect(async () => {
|
||||
const res = await axios.get(`/api/category/getOne/${id}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
|
||||
// setImage(res.data.category.image.url)
|
||||
setImagesPreview(res.data.category.image.url)
|
||||
setCtegoryBannerImagePreview(res.data.category.category_banner.url)
|
||||
setName(res.data.category.name)
|
||||
}, [id]);
|
||||
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!(name)) {
|
||||
return swal('Error!', 'Name fields are required', 'error')
|
||||
|
||||
}
|
||||
const myForm = new FormData();
|
||||
|
||||
myForm.set("name", name);
|
||||
|
||||
|
||||
myForm.set("image", image);
|
||||
myForm.set("category_banner", ctegoryBannerImage);
|
||||
|
||||
setLoading({ loading: true });
|
||||
// console.log(image)
|
||||
try {
|
||||
let res = await axios.put(
|
||||
`/api/category/update/${id}`, myForm,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": 'multipart/form-data',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
//console.log(res.data.data.name)
|
||||
if (res.data) {
|
||||
swal("success!", "Category Edited Successfully!", "success");
|
||||
setLoading(false);
|
||||
history.goBack();
|
||||
}
|
||||
} catch (error) {
|
||||
swal('Error!', "something went wrong", 'error')
|
||||
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
const handleImage = (e) => {
|
||||
const files = e.target.files[0];
|
||||
|
||||
// console.log(files)
|
||||
setImage(files);
|
||||
// only for file preview------------------------------------
|
||||
const Reader = new FileReader();
|
||||
Reader.readAsDataURL(files);
|
||||
|
||||
Reader.onload = () => {
|
||||
if (Reader.readyState === 2) {
|
||||
setImagesPreview(Reader.result);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
};
|
||||
const handleBannerImage = (e) => {
|
||||
const files = e.target.files[0];
|
||||
|
||||
// console.log(files)
|
||||
setCtegoryBannerImage(files);
|
||||
// only for file preview------------------------------------
|
||||
const Reader = new FileReader();
|
||||
Reader.readAsDataURL(files);
|
||||
|
||||
Reader.onload = () => {
|
||||
if (Reader.readyState === 2) {
|
||||
setCtegoryBannerImagePreview(Reader.result);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
const onCancel = () => {
|
||||
history.goBack()
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-light w-100 min-vh-70 d-flex flex-row ">
|
||||
<CContainer className="w-100 ">
|
||||
<CRow className="align-left w-140">
|
||||
<CCol md={19} lg={27} xl={16}>
|
||||
<CCard className="mr-4 mx-4">
|
||||
<CCardBody className="p-4">
|
||||
<CForm>
|
||||
<h3 className="mb-4 justify-content-center">Edit Category</h3>
|
||||
<div>
|
||||
<div>
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilUser} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
required
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
value={name}
|
||||
placeholder="Name" />
|
||||
</CInputGroup>
|
||||
|
||||
<div>category image *</div>
|
||||
|
||||
<CInputGroup className="mb-1 mt-2">
|
||||
|
||||
{/* <CIcon icon={cilLockLocked} /> */}
|
||||
|
||||
<CFormInput
|
||||
type="file"
|
||||
placeholder="image"
|
||||
accept="image/*"
|
||||
required
|
||||
onChange={handleImage}
|
||||
|
||||
|
||||
/>
|
||||
</CInputGroup>
|
||||
<div id="createProductFormImage" className="w-50 d-flex">
|
||||
|
||||
{imagesPreview && <img className=" w-25 p-1 " src={imagesPreview} alt="Product Preview" />}
|
||||
|
||||
</div>
|
||||
<div>category Banner image *</div>
|
||||
<CInputGroup className="mb-1 mt-2">
|
||||
|
||||
|
||||
|
||||
<CFormInput
|
||||
type="file"
|
||||
placeholder="image"
|
||||
accept="image/*"
|
||||
required
|
||||
onChange={handleBannerImage}
|
||||
|
||||
|
||||
/>
|
||||
</CInputGroup>
|
||||
<div id="createProductFormImage" className="w-50 d-flex">
|
||||
|
||||
{ctegoryBannerImagePreview && <img className=" w-25 p-1 " src={ctegoryBannerImagePreview} alt="Product Preview" />}
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div className="mt-3 d-flex">
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
type="button"
|
||||
className="btn btn-success btn-login waves-effect waves-light"
|
||||
>
|
||||
<ClipLoader loading={loading} size={18} />
|
||||
{!loading && "Save"}
|
||||
</button>
|
||||
<button
|
||||
onClick={onCancel}
|
||||
type="button"
|
||||
className=" ml-2 btn btn-warning btn-cancel waves-effect waves-light"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</CForm>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CContainer>
|
||||
</div>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default AddProduct
|
@ -1,549 +0,0 @@
|
||||
import axios from "axios";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
// import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
import ClipLoader from "react-spinners/ClipLoader";
|
||||
import { Country, State, City } from "country-state-city";
|
||||
import swal from 'sweetalert';
|
||||
|
||||
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import { useHistory } from "react-router-dom";
|
||||
|
||||
const Add_Business = () => {
|
||||
const [categoryName, setCategoryName] = useState([]);
|
||||
const [image, setImage] = useState();
|
||||
|
||||
|
||||
const token = isAutheticated();
|
||||
|
||||
let history = useHistory();
|
||||
const [state, setState] = useState({
|
||||
name: "",
|
||||
phone: "",
|
||||
email: "",
|
||||
Bname: "",
|
||||
Sname: "",
|
||||
country: "",
|
||||
city: "",
|
||||
loading: false,
|
||||
description: "",
|
||||
category: "",
|
||||
status: "",
|
||||
Glocation: "",
|
||||
LinkedinUrl: "",
|
||||
FacebookUrl: "",
|
||||
InstagramUrl: ""
|
||||
|
||||
});
|
||||
|
||||
|
||||
const { description, loading } = state;
|
||||
const changeState = (newState) =>
|
||||
setState((prevState) => ({ ...prevState, ...newState }));
|
||||
|
||||
|
||||
const handleChange = (e) => {
|
||||
changeState({ ...state, [e.target.name]: e.target.value })
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
const fetchCategory = useCallback(async () => {
|
||||
const res = await axios.get(`/api/category/getAll`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
|
||||
// console.log(res.data.category);
|
||||
setCategoryName(res.data.category)
|
||||
if (res.status === 200) changeState({ ...res.data });
|
||||
}, [token]);
|
||||
|
||||
useEffect(async () => {
|
||||
|
||||
|
||||
|
||||
|
||||
fetchCategory();
|
||||
|
||||
}, [fetchCategory]);
|
||||
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!(state.name && state.phone && state.email && state.Bname && state.Sname && state.country && state.city && state.description
|
||||
&& state.category && state.status && image)) {
|
||||
return swal('Error!', 'All fields are required', 'error')
|
||||
|
||||
}
|
||||
|
||||
const myForm = new FormData();
|
||||
myForm.set('name', state.name)
|
||||
myForm.set('phone', state.phone)
|
||||
myForm.set('email', state.email)
|
||||
myForm.set('Bname', state.Bname)
|
||||
myForm.set('Sname', state.Sname)
|
||||
myForm.set('country', state.country)
|
||||
myForm.set('city', state.city)
|
||||
myForm.set('description', state.description)
|
||||
|
||||
myForm.set('category', state.category)
|
||||
|
||||
myForm.set('status', state.status)
|
||||
|
||||
myForm.set('Glocation', state.Glocation)
|
||||
myForm.set('LinkedinUrl', state.Glocation)
|
||||
myForm.set('FacebookUrl', state.FacebookUrl)
|
||||
myForm.set('InstagramUrl', state.InstagramUrl)
|
||||
myForm.set("image", image);
|
||||
|
||||
|
||||
changeState({ loading: true });
|
||||
try {
|
||||
let res = await axios.post(
|
||||
`/api/directory/create/`,
|
||||
|
||||
myForm
|
||||
,
|
||||
{
|
||||
headers: {
|
||||
"content-Type": 'multipart/form-data',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
//if (res.status === 200) window.location.reload();
|
||||
// console.log(res.status == 201)
|
||||
if (res.status == 201) {
|
||||
changeState({ loading: false });
|
||||
swal("Add Business successfully!");
|
||||
history.goBack()
|
||||
}
|
||||
} catch (error) {
|
||||
swal('Error!', error, 'error')
|
||||
|
||||
changeState({ loading: false });
|
||||
}
|
||||
|
||||
};
|
||||
const onCancel = () => {
|
||||
// window.location = "/comproducts";
|
||||
history.goBack()
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// console.log(state)
|
||||
return (
|
||||
<>
|
||||
<div className=" main-content">
|
||||
<div className="page-content">
|
||||
<div className="container-fluid">
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<div className="form-group text-right">
|
||||
<span className=" fs-2 text-xl-start font-weight-bold float-start">Add Bisuness</span>
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
type="button"
|
||||
className="btn btn-success mt-1 mb-0 my-1 btn btn-success btn-login waves-effect waves-light mr-1"
|
||||
>
|
||||
<ClipLoader loading={loading} size={18} />
|
||||
{!loading && "Save"}
|
||||
</button>
|
||||
<button
|
||||
onClick={onCancel}
|
||||
type="button"
|
||||
className=" mt-1 ml-2 btn btn-warning btn-cancel waves-effect waves-light mr-3"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- Save options Ends--> */}
|
||||
|
||||
{/* <!-- Row 1 Begins --> */}
|
||||
<div className="row">
|
||||
{/* <!--Left Column Begins--> */}
|
||||
<div className="col-lg-8">
|
||||
<div className="card">
|
||||
<div className="card-body">
|
||||
<div className="row">
|
||||
<div className="col-md-12">
|
||||
<form>
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="form-group">
|
||||
<label
|
||||
htmlFor=" basicpill-phoneno-input"
|
||||
className=" label-100"
|
||||
>
|
||||
Name*
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="name"
|
||||
value={state.name}
|
||||
className="mt-0 my-3 form-control input-field"
|
||||
onChange={handleChange}
|
||||
placeholder="Name"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="form-group">
|
||||
<label
|
||||
htmlFor=" basicpill-phoneno-input"
|
||||
className=" label-100"
|
||||
>
|
||||
phone*
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
name="phone"
|
||||
value={state.phone}
|
||||
className="mt-0 my-3 form-control input-field"
|
||||
onChange={handleChange}
|
||||
placeholder="Phone"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="form-group">
|
||||
<label
|
||||
htmlFor=" basicpill-phoneno-input"
|
||||
className=" label-100"
|
||||
>
|
||||
Email*
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
name="email"
|
||||
value={state.email}
|
||||
className="mt-0 my-3 form-control input-field"
|
||||
onChange={handleChange}
|
||||
placeholder="Email"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="form-group">
|
||||
<label
|
||||
htmlFor=" basicpill-phoneno-input"
|
||||
className=" label-100"
|
||||
>
|
||||
Address*
|
||||
</label>
|
||||
<div className=" d-flex">
|
||||
<div><input
|
||||
type="text"
|
||||
name="Bname"
|
||||
value={state.Bname}
|
||||
className="mt-0 my-3 w-100 form-control input-field"
|
||||
onChange={handleChange}
|
||||
placeholder="Building Name*"
|
||||
/></div>
|
||||
<div> <input
|
||||
type="text"
|
||||
name="Sname"
|
||||
value={state.Sname}
|
||||
className="mt-0 ml-4 my-3 form-control input-field"
|
||||
onChange={handleChange}
|
||||
placeholder="Street Name*"
|
||||
/></div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
||||
<select
|
||||
className="mt-0 my-3 form-control input-field"
|
||||
required
|
||||
name="country"
|
||||
value={state.country}
|
||||
// onChange={(e) => setCountry(e.target.value)}
|
||||
onChange={handleChange}
|
||||
>
|
||||
<option value="">Country*</option>
|
||||
{Country &&
|
||||
Country.getAllCountries().map((item) => (
|
||||
<option key={item.isoCode} value={item.isoCode}>
|
||||
{item.name}
|
||||
</option>
|
||||
))}
|
||||
|
||||
|
||||
</select>
|
||||
<select
|
||||
className="mt-0 my-3 form-control input-field"
|
||||
requiredname='city'
|
||||
name="city"
|
||||
value={state.city}
|
||||
// onChange={(e) => setCity(e.target.value)}
|
||||
onChange={handleChange}
|
||||
>
|
||||
<option value="">City*</option>
|
||||
{City &&
|
||||
|
||||
City.getCitiesOfCountry(state.country).map((item) => (
|
||||
<option key={item.isoCode} value={item.isoCode}>
|
||||
{item.name}
|
||||
{/* {console.log(item)} */}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="form-group mb-30 width-100 row">
|
||||
<label className="my-3 col-md-4 control-label">
|
||||
Description
|
||||
</label>
|
||||
<div className="mt-0 col-md-10">
|
||||
<textarea
|
||||
value={state.description}
|
||||
onChange={handleChange}
|
||||
name="description"
|
||||
className="form-control input-field"
|
||||
rows="5"
|
||||
placeholder="Add description"
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- Left Column Ends --> */}
|
||||
|
||||
{/* <!--Right Column Begins --> */}
|
||||
<div className=" col-lg-4">
|
||||
<div className="card">
|
||||
<div className="card-body">
|
||||
<div className="row">
|
||||
<div className="col-md-12">
|
||||
<form>
|
||||
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="form-group">
|
||||
<label
|
||||
htmlFor="basicpill-phoneno-input"
|
||||
className="label-100"
|
||||
>
|
||||
Bisuness Image
|
||||
</label>
|
||||
<input
|
||||
required
|
||||
type="file"
|
||||
//name="image"
|
||||
accept="image/*"
|
||||
// value={image}
|
||||
className="mt-0 my-3 form-control input-field"
|
||||
// onChange={handleChange}
|
||||
onChange={(e) => setImage(e.target.files[0])}
|
||||
placeholder="Bisuness Image"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="form-group">
|
||||
<label
|
||||
htmlFor="basicpill-phoneno-input"
|
||||
className="label-100"
|
||||
>
|
||||
Category*
|
||||
</label>
|
||||
|
||||
<select
|
||||
name="category"
|
||||
value={state.category}
|
||||
onChange={handleChange}
|
||||
className="form-control input-field"
|
||||
>
|
||||
<option value="">--select--</option>
|
||||
{categoryName && categoryName.map((item, index) =>
|
||||
<option key={index}>{item?.name}</option>
|
||||
|
||||
)}
|
||||
</select>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="form-group">
|
||||
<label
|
||||
htmlFor="basicpill-phoneno-input"
|
||||
className="label-100"
|
||||
>
|
||||
Status*
|
||||
</label>
|
||||
<select
|
||||
name="status"
|
||||
value={state.status}
|
||||
onChange={handleChange}
|
||||
className="form-control input-field"
|
||||
>
|
||||
<option value="">--select--</option>
|
||||
<option value={true}>Active</option>
|
||||
<option value={false}>Inactive</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="form-group">
|
||||
<label
|
||||
htmlFor="basicpill-phoneno-input"
|
||||
className="label-100"
|
||||
>
|
||||
Google Location
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="Glocation"
|
||||
value={state.Glocation}
|
||||
className="mt-0 my-3 form-control input-field"
|
||||
onChange={handleChange}
|
||||
placeholder="Google Location(Optional)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="form-group">
|
||||
<label
|
||||
htmlFor="basicpill-phoneno-input"
|
||||
className="label-100"
|
||||
>
|
||||
Linkedin URL
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="LinkedinUrl"
|
||||
value={state.LinkedinUrl}
|
||||
className="mt-0 my-3 form-control input-field"
|
||||
onChange={handleChange}
|
||||
placeholder="Linkedin URL (Optional)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="form-group">
|
||||
<label
|
||||
htmlFor="basicpill-phoneno-input"
|
||||
className="label-100"
|
||||
>
|
||||
Facebook URL
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="FacebookUrl"
|
||||
value={state.FacebookUrl}
|
||||
className="mt-0 my-3 form-control input-field"
|
||||
onChange={handleChange}
|
||||
placeholder="Facebook URL (Optional)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="form-group">
|
||||
<label
|
||||
htmlFor="basicpill-phoneno-input"
|
||||
className="label-100"
|
||||
>
|
||||
Instagram URL
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="InstagramUrl"
|
||||
value={state.InstagramUrl}
|
||||
className="mt-0 my-3 form-control input-field"
|
||||
onChange={handleChange}
|
||||
placeholder="Instagram URL (Optional)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!--Right Column Ends --> */}
|
||||
</div>
|
||||
<div className=" mt-4 row">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- container-fluid --> */}
|
||||
</div>
|
||||
{/* <!-- End Page-content --> */}
|
||||
{/* <Footer /> */}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Add_Business
|
||||
|
||||
|
||||
//const myForm = new FormData();
|
||||
// myForm.set('name', state.name)
|
||||
// myForm.set('phone', state.phone)
|
||||
// myForm.set('email', state.email)
|
||||
// myForm.set('Bname', state.Bname)
|
||||
// myForm.set('Sname', state.Sname)
|
||||
// myForm.set('country', state.country)
|
||||
// myForm.set('city', state.city)
|
||||
// myForm.set('description', state.description)
|
||||
|
||||
// myForm.set('category', state.category)
|
||||
|
||||
// myForm.set('status', state.status)
|
||||
|
||||
// myForm.set('Glocation', state.Glocation)
|
||||
// myForm.set('LinkedinUrl', state.Glocation)
|
||||
// myForm.set('FacebookUrl', state.FacebookUrl)
|
||||
// myForm.set('InstagramUrl', state.InstagramUrl)
|
||||
// myForm.set("image", image);
|
||||
// changeState({ loading: true });
|
@ -1,267 +0,0 @@
|
||||
import axios from "axios";
|
||||
import React, { useEffect, useState, useCallback, useMemo } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
// import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
import Pagination from "./Pagination";
|
||||
|
||||
const Bisuness = () => {
|
||||
const [bisuness, setBisuness] = useState([])
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [postsPerPage] = useState(20);
|
||||
|
||||
|
||||
const token = isAutheticated();
|
||||
|
||||
const getProducts = useCallback(async () => {
|
||||
let res = await axios.get(
|
||||
`/api/directory/getAll`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
// console.log(res.data.directory)
|
||||
setBisuness(res.data.directory)
|
||||
// changeState({
|
||||
// ...res.data,
|
||||
// pages: Math.ceil(res.data.totalProducts / limit),
|
||||
// });
|
||||
}, [token]);
|
||||
|
||||
useEffect(() => {
|
||||
getProducts();
|
||||
}, [getProducts]);
|
||||
|
||||
// Get current posts
|
||||
//pagination
|
||||
const indexOfLastPost = currentPage * postsPerPage;
|
||||
const indexOfFirstPost = indexOfLastPost - postsPerPage;
|
||||
const currentPosts = bisuness.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/directory/delete/${id}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
// console.log(res)
|
||||
|
||||
if (res.data.success == true) {
|
||||
swal("success!", "Directory Deleted Successfully!", "success");
|
||||
window.location.reload();
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
const toggleStatus = async (id) => {
|
||||
let status = window.confirm("Do you want to change status");
|
||||
if (!status) {
|
||||
return;
|
||||
}
|
||||
let res = await axios.get(`/api/directory/admin/setStatus/${id}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
// console.log(res)
|
||||
if (res.status === 200) window.location.reload();
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className=" main-content">
|
||||
<div className=" my-3 page-content">
|
||||
<div className="container-fluid">
|
||||
{/* <!-- start page title --> */}
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<div className="page-title-box d-flex align-items-center justify-content-between">
|
||||
<h4 className="mb-3">Bisuness-Directory</h4>
|
||||
<Link to="/add_bisuness"><button type="button" className="btn btn-info float-end mb-3 ml-4"> + Add Bisuness</button></Link>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- end page title --> */}
|
||||
|
||||
<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>
|
||||
<div className="table-responsive table-shoot">
|
||||
<table className="table table-centered table-nowrap mb-0">
|
||||
<thead className="thead-light">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Category</th>
|
||||
<th>City</th>
|
||||
<th>Status</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{currentPosts.map((item, index) =>
|
||||
|
||||
<tr key={index}>
|
||||
<td>{item?.name} </td>
|
||||
<td>{item?.category}</td>
|
||||
<td>{item?.city}</td>
|
||||
<td>
|
||||
<span
|
||||
className={`badge rounded-pill bg-${item.status === "true" ? "success" : "danger"
|
||||
} font-size-10`}
|
||||
>
|
||||
{item.status === "true" ? "Live" : "Suspended"}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
type="button"
|
||||
className={`btn btn-${item.status === "true" ? "danger" : "success"
|
||||
} btn-sm waves-effect waves-light btn-table ml-1`}
|
||||
onClick={() => toggleStatus(item._id)}
|
||||
>
|
||||
{item.status === "true" ? "Suspend" : "Activate"}
|
||||
</button>
|
||||
<Link to={`/view_bisuness/${item._id}`}>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className=" mx-1 mt-1 btn btn-info btn-sm waves-effect waves-light btn-table ml-1"
|
||||
>
|
||||
View
|
||||
</button>
|
||||
</Link>
|
||||
|
||||
<Link to={`/bisuness/edit/${item._id}`}>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className=" mx-1 mt-1 btn btn-primary btn-sm waves-effect waves-light btn-table ml-1"
|
||||
>
|
||||
Edit
|
||||
</button>
|
||||
</Link>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleDelete(item._id)}
|
||||
className="mx-1 mt-1 btn btn-danger btn-sm waves-effect waves-light btn-table ml-1"
|
||||
id="sa-params"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{/* <div className="row mt-20">
|
||||
<div className="col-sm-12 col-md-6 mb-20">
|
||||
<div
|
||||
className="dataTables_info"
|
||||
id="datatable_info"
|
||||
role="status"
|
||||
aria-live="polite"
|
||||
>
|
||||
Showing{" "}
|
||||
{!totalProducts
|
||||
? totalProducts
|
||||
: page * limit - (limit - 1)}{" "}
|
||||
to{" "}
|
||||
{totalProducts > limit
|
||||
? limit * page > totalProducts
|
||||
? totalProducts
|
||||
: limit * page
|
||||
: totalProducts}{" "}
|
||||
of {totalProducts} entries
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col-sm-12 col-md-6">
|
||||
<div className="dataTables_paginate paging_simple_numbers float-right">
|
||||
<ul className="pagination">
|
||||
<li
|
||||
className={`paginate_button page-item previous ${page < 2 ? "disabled" : ""
|
||||
}`}
|
||||
>
|
||||
<button
|
||||
aria-controls="datatable"
|
||||
data-dt-idx="0"
|
||||
tabIndex={page - 1}
|
||||
onClick={() => changeState({ page: page - 1 })}
|
||||
className="page-link"
|
||||
>
|
||||
Previous
|
||||
</button>
|
||||
</li>
|
||||
|
||||
{getTotalPages.map((pageNo) => {
|
||||
return (
|
||||
<li
|
||||
className={`paginate_button page-item ${pageNo === page ? "active" : ""
|
||||
}`}
|
||||
>
|
||||
<button
|
||||
key={`page_no_${pageNo}`}
|
||||
value={pageNo}
|
||||
id={pageNo}
|
||||
aria-controls="datatable"
|
||||
data-dt-idx="1"
|
||||
tabIndex="0"
|
||||
className="page-link "
|
||||
onClick={() => changeState({ page: pageNo })}
|
||||
>
|
||||
{pageNo}
|
||||
</button>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
|
||||
<li
|
||||
className={`paginate_button page-item next ${page === getTotalPages.length ? "disabled" : ""
|
||||
}`}
|
||||
>
|
||||
<button
|
||||
onClick={() => changeState({ page: page + 1 })}
|
||||
tabIndex={page + 1}
|
||||
className="page-link"
|
||||
>
|
||||
Next
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
{/* <!-- end table-responsive --> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- container-fluid --> */}
|
||||
</div>
|
||||
</div>
|
||||
<Pagination postsPerPage={postsPerPage}
|
||||
totalPosts={bisuness.length}
|
||||
paginate={paginate} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Bisuness
|
@ -1,565 +0,0 @@
|
||||
import axios from "axios";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
// import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
import ClipLoader from "react-spinners/ClipLoader";
|
||||
import { Country, State, City } from "country-state-city";
|
||||
import swal from 'sweetalert';
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import { useHistory } from "react-router-dom";
|
||||
|
||||
const EditBisuness = () => {
|
||||
const [categoryName, setCategoryName] = useState([]);
|
||||
const [image, setImage] = useState();
|
||||
const token = isAutheticated();
|
||||
|
||||
let history = useHistory();
|
||||
const [state, setState] = useState({
|
||||
name: "",
|
||||
phone: "",
|
||||
email: "",
|
||||
Building_Name: "",
|
||||
Street_Name: "",
|
||||
country: "",
|
||||
city: "",
|
||||
loading: false,
|
||||
description: "",
|
||||
category: "",
|
||||
status: "",
|
||||
Glocation: "",
|
||||
LinkedinUrl: "",
|
||||
FacebookUrl: "",
|
||||
InstagramUrl: ""
|
||||
});
|
||||
|
||||
const { id } = useParams();
|
||||
// console.log(id)
|
||||
|
||||
const { description, loading } = state;
|
||||
|
||||
|
||||
const changeState = (newState) =>
|
||||
setState((prevState) => ({ ...prevState, ...newState }));
|
||||
|
||||
|
||||
|
||||
const handleChange = (e) => {
|
||||
changeState({ ...state, [e.target.name]: e.target.value })
|
||||
|
||||
};
|
||||
|
||||
|
||||
//category
|
||||
const fetchCategory = useCallback(async () => {
|
||||
const res = await axios.get(`/api/category/getAll`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
|
||||
// console.log(res.data.category);
|
||||
setCategoryName(res.data.category)
|
||||
if (res.status === 200) changeState({ ...res.data });
|
||||
}, [token]);
|
||||
|
||||
useEffect(async () => {
|
||||
|
||||
fetchCategory();
|
||||
|
||||
}, [fetchCategory]);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const fetchDirectory = useCallback(async () => {
|
||||
const res = await axios.get(`/api/directory/getOne/${id}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
setState(res.data.directory)
|
||||
changeState({ loading: false });
|
||||
if (res.status === 200) changeState({ ...res.data });
|
||||
}, [token]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchDirectory();
|
||||
}, [fetchDirectory]);
|
||||
|
||||
|
||||
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!(state.name && state.phone && state.email && state.Building_Name && state.Street_Name && state.country && state.city && state.description
|
||||
&& state.category && state.status)) {
|
||||
return swal('Error!', 'All fields are required', 'error')
|
||||
|
||||
}
|
||||
const myForm = new FormData();
|
||||
myForm.set('name', state.name)
|
||||
myForm.set('phone', state.phone)
|
||||
myForm.set('email', state.email)
|
||||
myForm.set('Building_Name', state.Building_Name)
|
||||
myForm.set('Street_Name', state.Street_Name)
|
||||
myForm.set('country', state.country)
|
||||
myForm.set('city', state.city)
|
||||
myForm.set('description', state.description)
|
||||
|
||||
myForm.set('category', state.category)
|
||||
|
||||
myForm.set('status', state.status)
|
||||
|
||||
myForm.set('Glocation', state.Glocation)
|
||||
myForm.set('LinkedinUrl', state.Glocation)
|
||||
myForm.set('FacebookUrl', state.FacebookUrl)
|
||||
myForm.set('InstagramUrl', state.InstagramUrl)
|
||||
myForm.set("image", image);
|
||||
|
||||
changeState({ loading: true });
|
||||
try {
|
||||
let res = await axios.put(
|
||||
`/api/directory/update/${id}`,
|
||||
myForm,
|
||||
{
|
||||
headers: {
|
||||
"content-Type": 'multipart/form-data',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (res.status == 200) {
|
||||
changeState({ loading: false });
|
||||
swal("Edit Business successfully!");
|
||||
history.goBack()
|
||||
}
|
||||
} catch (error) {
|
||||
swal('Error!', error, 'error')
|
||||
|
||||
changeState({ loading: false });
|
||||
}
|
||||
|
||||
};
|
||||
const onCancel = () => {
|
||||
history.goBack()
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// console.log(image)
|
||||
return (
|
||||
<>
|
||||
<div className=" main-content">
|
||||
<div className="page-content">
|
||||
<div className="container-fluid">
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<div className="form-group text-right">
|
||||
<span className=" fs-2 text-xl-start font-weight-bold float-start">Edit Bisuness</span>
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
type="button"
|
||||
className="btn btn-success mt-1 mb-0 my-1 btn btn-success btn-login waves-effect waves-light mr-1"
|
||||
>
|
||||
<ClipLoader loading={loading} size={18} />
|
||||
{!loading && "Save"}
|
||||
</button>
|
||||
<button
|
||||
onClick={onCancel}
|
||||
type="button"
|
||||
className=" mt-1 ml-2 btn btn-warning btn-cancel waves-effect waves-light mr-3"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- Save options Ends--> */}
|
||||
|
||||
{/* <!-- Row 1 Begins --> */}
|
||||
<div className="row">
|
||||
{/* <!--Left Column Begins--> */}
|
||||
<div className="col-lg-8">
|
||||
<div className="card">
|
||||
<div className="card-body">
|
||||
<div className="row">
|
||||
<div className="col-md-12">
|
||||
<form>
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="form-group">
|
||||
<label
|
||||
htmlFor=" basicpill-phoneno-input"
|
||||
className=" label-100"
|
||||
>
|
||||
Name*
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="name"
|
||||
value={state.name}
|
||||
className="mt-0 my-3 form-control input-field"
|
||||
onChange={handleChange}
|
||||
placeholder="Name"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="form-group">
|
||||
<label
|
||||
htmlFor=" basicpill-phoneno-input"
|
||||
className=" label-100"
|
||||
>
|
||||
phone*
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
name="phone"
|
||||
value={state.phone}
|
||||
className="mt-0 my-3 form-control input-field"
|
||||
onChange={handleChange}
|
||||
placeholder="Phone"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="form-group">
|
||||
<label
|
||||
htmlFor=" basicpill-phoneno-input"
|
||||
className=" label-100"
|
||||
>
|
||||
Email*
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
name="email"
|
||||
value={state.email}
|
||||
className="mt-0 my-3 form-control input-field"
|
||||
onChange={handleChange}
|
||||
placeholder="Email"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="form-group">
|
||||
<label
|
||||
htmlFor=" basicpill-phoneno-input"
|
||||
className=" label-100"
|
||||
>
|
||||
Address*
|
||||
</label>
|
||||
<div className=" d-flex">
|
||||
<div><input
|
||||
type="text"
|
||||
name="Building_Name"
|
||||
value={state.Building_Name}
|
||||
className="mt-0 my-3 w-100 form-control input-field"
|
||||
onChange={handleChange}
|
||||
placeholder="Building Name*"
|
||||
/></div>
|
||||
<div> <input
|
||||
type="text"
|
||||
name="Street_Name"
|
||||
value={state.Street_Name}
|
||||
className="mt-0 ml-4 my-3 form-control input-field"
|
||||
onChange={handleChange}
|
||||
placeholder="Street Name*"
|
||||
/></div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
||||
<select
|
||||
className="mt-0 my-3 form-control input-field"
|
||||
required
|
||||
name="country"
|
||||
value={state.country}
|
||||
// onChange={(e) => setCountry(e.target.value)}
|
||||
onChange={handleChange}
|
||||
>
|
||||
<option value="">Country*</option>
|
||||
{Country &&
|
||||
Country.getAllCountries().map((item) => (
|
||||
<option key={item.isoCode} value={item.isoCode}>
|
||||
{item.name}
|
||||
</option>
|
||||
))}
|
||||
|
||||
|
||||
</select>
|
||||
<select
|
||||
className="mt-0 my-3 form-control input-field"
|
||||
requiredname='city'
|
||||
name="city"
|
||||
value={state.city}
|
||||
// onChange={(e) => setCity(e.target.value)}
|
||||
onChange={handleChange}
|
||||
>
|
||||
<option value="">City*</option>
|
||||
{City &&
|
||||
|
||||
City.getCitiesOfCountry(state.country).map((item) => (
|
||||
<option key={item.isoCode} value={item.isoCode}>
|
||||
{item.name}
|
||||
{/* {console.log(item)} */}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="form-group mb-30 width-100 row">
|
||||
<label className="my-3 col-md-4 control-label">
|
||||
Description
|
||||
</label>
|
||||
<div className="mt-0 col-md-10">
|
||||
<textarea
|
||||
value={state.description}
|
||||
onChange={handleChange}
|
||||
name="description"
|
||||
className="form-control input-field"
|
||||
rows="5"
|
||||
placeholder="Add description"
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- Left Column Ends --> */}
|
||||
|
||||
{/* <!--Right Column Begins --> */}
|
||||
<div className=" col-lg-4">
|
||||
<div className="card">
|
||||
<div className="card-body">
|
||||
<div className="row">
|
||||
<div className="col-md-12">
|
||||
<form>
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="form-group">
|
||||
<label
|
||||
htmlFor="basicpill-phoneno-input"
|
||||
className="label-100"
|
||||
>
|
||||
Bisuness Image
|
||||
</label>
|
||||
<input
|
||||
required
|
||||
type="file"
|
||||
//name="image"
|
||||
accept="image/*"
|
||||
// value={image}
|
||||
className="mt-0 my-3 form-control input-field"
|
||||
// onChange={handleChange}
|
||||
onChange={(e) => setImage(e.target.files[0])}
|
||||
placeholder="Bisuness Image"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="form-group">
|
||||
<label
|
||||
htmlFor="basicpill-phoneno-input"
|
||||
className="label-100"
|
||||
>
|
||||
Category*
|
||||
</label>
|
||||
<select
|
||||
name="category"
|
||||
value={state.category}
|
||||
onChange={handleChange}
|
||||
className="form-control input-field"
|
||||
>
|
||||
<option value="">--select--</option>
|
||||
{categoryName && categoryName.map((item, index) =>
|
||||
<option key={index}>{item?.name}</option>
|
||||
|
||||
)}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="form-group">
|
||||
<label
|
||||
htmlFor="basicpill-phoneno-input"
|
||||
className="label-100"
|
||||
>
|
||||
Status*
|
||||
</label>
|
||||
<select
|
||||
name="status"
|
||||
value={state.status}
|
||||
onChange={handleChange}
|
||||
className="form-control input-field"
|
||||
>
|
||||
<option value="">--select--</option>
|
||||
<option value={true}>Active</option>
|
||||
<option value={false}>Inactive</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="form-group">
|
||||
<label
|
||||
htmlFor="basicpill-phoneno-input"
|
||||
className="label-100"
|
||||
>
|
||||
Google Location
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="Glocation"
|
||||
value={state.Glocation}
|
||||
className="mt-0 my-3 form-control input-field"
|
||||
onChange={handleChange}
|
||||
placeholder="Google Location(Optional)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="form-group">
|
||||
<label
|
||||
htmlFor="basicpill-phoneno-input"
|
||||
className="label-100"
|
||||
>
|
||||
Linkedin URL
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="LinkedinUrl"
|
||||
value={state.LinkedinUrl}
|
||||
className="mt-0 my-3 form-control input-field"
|
||||
onChange={handleChange}
|
||||
placeholder="Linkedin URL (Optional)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="form-group">
|
||||
<label
|
||||
htmlFor="basicpill-phoneno-input"
|
||||
className="label-100"
|
||||
>
|
||||
Facebook URL
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="FacebookUrl"
|
||||
value={state.FacebookUrl}
|
||||
className="mt-0 my-3 form-control input-field"
|
||||
onChange={handleChange}
|
||||
placeholder="Facebook URL (Optional)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="form-group">
|
||||
<label
|
||||
htmlFor="basicpill-phoneno-input"
|
||||
className="label-100"
|
||||
>
|
||||
Instagram URL
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="InstagramUrl"
|
||||
value={state.InstagramUrl}
|
||||
className="mt-0 my-3 form-control input-field"
|
||||
onChange={handleChange}
|
||||
placeholder="Instagram URL (Optional)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!--Right Column Ends --> */}
|
||||
</div>
|
||||
<div className=" mt-4 row">
|
||||
{/* <!--Left Column Begins--> */}
|
||||
{/* <div className="col-lg-8">
|
||||
<div className="card">
|
||||
<div className="card-body">
|
||||
<div className="row">
|
||||
<div className="col-md-12">
|
||||
<form className="">
|
||||
<div className="row">
|
||||
<div className="col-lg-4">
|
||||
<div className=" form-group">
|
||||
<label
|
||||
htmlFor=" basicpill-phoneno-input"
|
||||
className=" label-100"
|
||||
>
|
||||
Price*
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="price"
|
||||
value={price}
|
||||
onChange={handleChange}
|
||||
className="form-control input-field"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
{/* <!-- Left Column Ends --> */}
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- container-fluid --> */}
|
||||
</div>
|
||||
{/* <!-- End Page-content --> */}
|
||||
{/* <Footer /> */}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default EditBisuness
|
@ -1,25 +0,0 @@
|
||||
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="/bisuness" className='page-link'>
|
||||
{number}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</nav>
|
||||
);
|
||||
};
|
||||
|
||||
export default Pagination;
|
@ -1,119 +0,0 @@
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useEffect, useState, useCallback, useMemo } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
// import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
import { useParams } from "react-router-dom";
|
||||
const View_Bisuness = () => {
|
||||
const { id } = useParams();
|
||||
// console.log(id)
|
||||
const [bisuness, setBisuness] = useState([])
|
||||
|
||||
|
||||
// const { products, page, limit, totalProducts, pages } = state;
|
||||
|
||||
|
||||
const token = isAutheticated();
|
||||
|
||||
const view_business = useCallback(async () => {
|
||||
let res = await axios.get(
|
||||
`/api/directory/getOne/${id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
// console.log(res.data.directory)
|
||||
setBisuness(res.data.directory)
|
||||
// changeState({
|
||||
// ...res.data,
|
||||
// pages: Math.ceil(res.data.totalProducts / limit),
|
||||
// });
|
||||
// limit, page,
|
||||
}, [token]);
|
||||
|
||||
useEffect(() => {
|
||||
view_business();
|
||||
}, [view_business]);
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className=" main-content">
|
||||
<div className=" my-3 page-content">
|
||||
<div className="container-fluid">
|
||||
{/* <!-- start page title --> */}
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<div className="page-title-box d-flex align-items-center justify-content-between">
|
||||
<h4 className="mb-3">View Bisuness</h4>
|
||||
{/* <Link to="/add_bisuness"><button type="button" className="btn btn-info float-end mb-3 ml-4"> View Bisuness</button></Link> */}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- end page title --> */}
|
||||
|
||||
<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>
|
||||
<div className="table-responsive table-shoot">
|
||||
<table className="table table-centered table-nowrap mb-0">
|
||||
<thead className="thead-light">
|
||||
|
||||
|
||||
<tr><th>Name</th><td>{bisuness?.name} </td></tr>
|
||||
<tr><th>Bisuness image</th><td>
|
||||
<img src={`${bisuness.image?.url}`} width="50" alt="" />
|
||||
</td></tr>
|
||||
<tr><th>Category</th><td>{bisuness?.category}</td></tr>
|
||||
<tr><th>email</th> <td>{bisuness?.email}</td></tr>
|
||||
<tr><th>phone</th> <td>{bisuness?.phone}</td></tr>
|
||||
<tr><th>Building_Name</th><td>{bisuness?.Building_Name}</td></tr>
|
||||
<tr><th>Street_Name</th><td>{bisuness?.Street_Name}</td></tr>
|
||||
<tr><th>city</th> <td>{bisuness?.city}</td></tr>
|
||||
<tr><th>description</th> <td>{bisuness?.description}</td></tr>
|
||||
<tr><th>Status</th><td>
|
||||
<span
|
||||
className={`badge rounded-pill bg-${bisuness?.status ? "success" : "danger"
|
||||
} font-size-10`}
|
||||
>
|
||||
{bisuness?.status ? "Live" : "Suspended"}
|
||||
</span>
|
||||
</td></tr>
|
||||
<tr><th>Google Location</th><td>{bisuness?.Glocation}</td></tr>
|
||||
<tr><th>LinkedinUrl</th> <td>{bisuness?.LinkedinUrl}</td></tr>
|
||||
<tr> <th>FacebookUrl</th><td>{bisuness?.FacebookUrl}</td></tr>
|
||||
<tr><th>intagramUrl</th> <td>{bisuness?.InstagramUrl}</td></tr>
|
||||
|
||||
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{/* <!-- end table-responsive --> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- container-fluid --> */}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default View_Bisuness
|
@ -1,216 +0,0 @@
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
import ClipLoader from "react-spinners/ClipLoader";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import swal from 'sweetalert';
|
||||
|
||||
import {
|
||||
CButton,
|
||||
CCard,
|
||||
CCardBody,
|
||||
CCol,
|
||||
CContainer,
|
||||
CForm,
|
||||
CFormInput,
|
||||
CInputGroup,
|
||||
CInputGroupText,
|
||||
CRow,
|
||||
} from '@coreui/react'
|
||||
import CIcon from '@coreui/icons-react'
|
||||
import { cilPencil, cilSettings, cilLockLocked, cilUser, cilBell, cilLocationPin, cilAudioDescription, cilCalendar, cilWatch, cilAlarm } from '@coreui/icons'
|
||||
const AddEvent = () => {
|
||||
const token = isAutheticated();
|
||||
let history = useHistory();
|
||||
const [image, setImage] = useState("");
|
||||
const [title, setTitle] = useState("");
|
||||
const [description, setDescription] = useState("");
|
||||
const [location, setLocation] = useState("");
|
||||
const [date, setDate] = useState(new Date());
|
||||
const [time, setTime] = useState('');
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const handleSubmit = async () => {
|
||||
if (!(title && description && image && location && time && date)) {
|
||||
return swal('Error!', 'All fields are required', 'error')
|
||||
|
||||
}
|
||||
const myForm = new FormData();
|
||||
|
||||
myForm.set("title", title);
|
||||
myForm.set("description", description);
|
||||
myForm.set("location", location);
|
||||
myForm.set("date", date)
|
||||
myForm.set("time", time)
|
||||
myForm.set("image", image);
|
||||
setLoading({ loading: true });
|
||||
// console.log(image)
|
||||
try {
|
||||
let res = await axios.post(
|
||||
`/api/event/create`, myForm,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": 'multipart/form-data',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
// console.log(res.data)
|
||||
if (res.data) {
|
||||
swal("success!", "Event Added Successfully!", "success");
|
||||
setLoading(false);
|
||||
history.goBack();
|
||||
}
|
||||
} catch (error) {
|
||||
swal('Error!', 'Something went Wrong', 'error')
|
||||
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
const handleImage = (e) => {
|
||||
const files = e.target.files[0];
|
||||
// console.log(files)
|
||||
setImage(files);
|
||||
|
||||
};
|
||||
//
|
||||
const onCancel = () => {
|
||||
// window.location = "/comproducts";
|
||||
history.goBack()
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-light min-vh-70 d-flex flex-row ">
|
||||
<CContainer>
|
||||
<CRow className="align-left w-140">
|
||||
<CCol md={19} lg={27} xl={16}>
|
||||
<CCard className="mx-4">
|
||||
<CCardBody className="p-4">
|
||||
<CForm>
|
||||
<h3 className="mb-4 justify-content-center">Add Event</h3>
|
||||
<div>
|
||||
<div>
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilPencil} />
|
||||
</CInputGroupText>
|
||||
<CFormInput maxlength="50" mtype="text"
|
||||
required
|
||||
onChange={(e) => setTitle(e.target.value)}
|
||||
value={title}
|
||||
placeholder="Title (maximum 50 characters)" />
|
||||
|
||||
</CInputGroup>
|
||||
{title ? <><span className="charLeft mt-4 fst-italic">
|
||||
{50 - title.length} characters left
|
||||
</span></> : <></>
|
||||
|
||||
}
|
||||
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilAudioDescription} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
maxlength="250"
|
||||
required
|
||||
onChange={(e) => setDescription(e.target.value)}
|
||||
value={description}
|
||||
placeholder="Description (maximum 250 characters)" />
|
||||
</CInputGroup>
|
||||
{description ? <><span className="charLeft mt-4 fst-italic">
|
||||
{250 - description.length} characters left
|
||||
</span></> : <></>
|
||||
|
||||
}
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
{/* Date* */}
|
||||
<CIcon icon={cilCalendar} />
|
||||
</CInputGroupText>
|
||||
{/* <DatePicker selected={startDate} /> */}
|
||||
|
||||
<CFormInput type="date"
|
||||
required
|
||||
onChange={(e) => setDate(e.target.value)}
|
||||
value={date}
|
||||
placeholder="Event Date" />
|
||||
</CInputGroup>
|
||||
<CInputGroup className="mb-3">
|
||||
|
||||
<CInputGroupText>
|
||||
{/* Time* */}
|
||||
<CIcon icon={cilAlarm} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="time"
|
||||
startDate
|
||||
required
|
||||
onChange={(e) => setTime(e.target.value)}
|
||||
value={time}
|
||||
placeholder="Event Time" />
|
||||
</CInputGroup>
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilLocationPin} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
required
|
||||
onChange={(e) => setLocation(e.target.value)}
|
||||
value={location}
|
||||
placeholder="Location" />
|
||||
</CInputGroup>
|
||||
|
||||
<CInputGroup className="mb-3">
|
||||
|
||||
{/* <CIcon icon={cilLockLocked} /> */}
|
||||
|
||||
<CFormInput
|
||||
type="file"
|
||||
placeholder="image"
|
||||
accept="image/*"
|
||||
required
|
||||
onChange={handleImage}
|
||||
|
||||
|
||||
/>
|
||||
</CInputGroup>
|
||||
</div>
|
||||
|
||||
<div className=" d-flex">
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
type="button"
|
||||
className="btn btn-success btn-login waves-effect waves-light"
|
||||
>
|
||||
<ClipLoader loading={loading} size={18} />
|
||||
{!loading && "Save"}
|
||||
</button>
|
||||
<button
|
||||
onClick={onCancel}
|
||||
type="button"
|
||||
className=" ml-2 btn btn-warning btn-cancel waves-effect waves-light"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</CForm>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CContainer>
|
||||
</div>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default AddEvent
|
@ -1,115 +0,0 @@
|
||||
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useEffect, useState, useCallback, useMemo } from "react";
|
||||
import swal from 'sweetalert';
|
||||
// import { API } from "../../data";
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import { isAutheticated } from "../../auth";
|
||||
|
||||
const AllRegisterUser = () => {
|
||||
const { id } = useParams();
|
||||
const token = isAutheticated();
|
||||
const [registerUser, setRegisterUser] = useState([])
|
||||
const getRegisterUser = useCallback(async () => {
|
||||
let res = await axios.get(
|
||||
`/api/event/admin/registerUser/getAll/${id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
// console.log(res.data)
|
||||
setRegisterUser(res.data.user)
|
||||
|
||||
|
||||
}, [token]);
|
||||
|
||||
useEffect(() => {
|
||||
getRegisterUser();
|
||||
}, [getRegisterUser]);
|
||||
// console.log(registerUser)
|
||||
//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">
|
||||
<div className="container-fluid">
|
||||
{/* <!-- start page title --> */}
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<div className="page-title-box d-flex align-items-center justify-content-between">
|
||||
<h4 className="mb-3">CMP-Event Register Users</h4>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- end page title --> */}
|
||||
|
||||
<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>
|
||||
<div className="table-responsive table-shoot">
|
||||
<table className="table table-centered table-nowrap mb-0">
|
||||
<thead className="thead-light">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th> Profile Image</th>
|
||||
<th>Email</th>
|
||||
<th>Phone</th>
|
||||
<th>register At</th>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{registerUser && registerUser.map((item, index) =>
|
||||
<tr>
|
||||
<td>{item.userId?.name}</td>
|
||||
<td>
|
||||
<img src={`${item.userId.avatar?.url}`} width="50" alt="" /></td>
|
||||
<td>{item.userId?.email}</td>
|
||||
<td>{item.userId?.phone}</td>
|
||||
<td>
|
||||
{/* {item?.addedOn} */}
|
||||
{new Date(`${item.userId?.createdAt}`).toDateString()}<span> , {`${formatAMPM(item.userId?.createdAt)}`}</span>
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
{/* <!-- end table-responsive --> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- container-fluid --> */}
|
||||
</div>
|
||||
</div></>
|
||||
);
|
||||
}
|
||||
|
||||
export default AllRegisterUser;
|
@ -1,235 +0,0 @@
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
import ClipLoader from "react-spinners/ClipLoader";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import swal from 'sweetalert';
|
||||
|
||||
import {
|
||||
CButton,
|
||||
CCard,
|
||||
CCardBody,
|
||||
CCol,
|
||||
CContainer,
|
||||
CForm,
|
||||
CFormInput,
|
||||
CInputGroup,
|
||||
CInputGroupText,
|
||||
CRow,
|
||||
} from '@coreui/react'
|
||||
import CIcon from '@coreui/icons-react'
|
||||
import { cilPencil, cilSettings, cilLockLocked, cilUser, cilBell, cilLocationPin, cilAudioDescription, cilCalendar, cilAlarm } from '@coreui/icons'
|
||||
const EditEvent = () => {
|
||||
const { id } = useParams();
|
||||
// console.log(id)
|
||||
const token = isAutheticated();
|
||||
let history = useHistory();
|
||||
const [image, setImage] = useState("");
|
||||
const [title, setTitle] = useState("");
|
||||
const [description, setDescription] = useState("");
|
||||
const [location, setLocation] = useState("");
|
||||
const [date, setDate] = useState(new Date());
|
||||
const [time, setTime] = useState('');
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
//fetch one image
|
||||
useEffect(async () => {
|
||||
const res = await axios.get(`/api/event/getOne/${id}`, {
|
||||
// headers: {
|
||||
// Authorization: `Bearer ${token}`,
|
||||
// },
|
||||
});
|
||||
// console.log(res.data)
|
||||
setTitle(res.data.Event.title)
|
||||
setDescription(res.data.Event.description)
|
||||
setDate(res.data.Event.date)
|
||||
setTime(res.data.Event.time)
|
||||
setLocation(res.data.Event.location)
|
||||
|
||||
}, [id]);
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!(title && description && image && location && time && date)) {
|
||||
return swal('Error!', 'All fields are required', 'error')
|
||||
|
||||
}
|
||||
const myForm = new FormData();
|
||||
|
||||
myForm.set("title", title);
|
||||
myForm.set("description", description);
|
||||
myForm.set("date", date)
|
||||
myForm.set("time", time)
|
||||
myForm.set("location", location);
|
||||
myForm.set("image", image);
|
||||
setLoading({ loading: true });
|
||||
// console.log(image)
|
||||
try {
|
||||
let res = await axios.put(
|
||||
`/api/event/update/${id}`, myForm,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": 'multipart/form-data',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
// console.log(res.data)
|
||||
if (res.data) {
|
||||
swal("success!", "Event Edit Successfully!", "success");
|
||||
setLoading(false);
|
||||
history.goBack();
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
swal('Error!', 'Something went Wrong', 'error')
|
||||
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
const handleImage = (e) => {
|
||||
const files = e.target.files[0];
|
||||
// console.log(files)
|
||||
setImage(files);
|
||||
|
||||
};
|
||||
//
|
||||
const onCancel = () => {
|
||||
// window.location = "/comproducts";
|
||||
history.goBack()
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-light min-vh-70 d-flex flex-row ">
|
||||
<CContainer>
|
||||
<CRow className="align-left w-140">
|
||||
<CCol md={19} lg={27} xl={16}>
|
||||
<CCard className="mx-4">
|
||||
<CCardBody className="p-4">
|
||||
<CForm>
|
||||
<h3 className="mb-4 justify-content-center">Edit Event</h3>
|
||||
<div>
|
||||
<div>
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilPencil} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
maxlength="50"
|
||||
required
|
||||
onChange={(e) => setTitle(e.target.value)}
|
||||
value={title}
|
||||
placeholder="Title (maximum 50 characters)" />
|
||||
</CInputGroup>
|
||||
{title ? <><span className="charLeft mt-4 fst-italic">
|
||||
{50 - title.length} characters left
|
||||
</span></> : <></>
|
||||
|
||||
}
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilAudioDescription} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
maxlength="250"
|
||||
required
|
||||
onChange={(e) => setDescription(e.target.value)}
|
||||
value={description}
|
||||
placeholder="Description (maximum 250 characters)" />
|
||||
</CInputGroup>
|
||||
{description ? <><span className="charLeft mt-4 fst-italic">
|
||||
{250 - description.length} characters left
|
||||
</span></> : <></>
|
||||
|
||||
}
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
{/* Date* */}
|
||||
<CIcon icon={cilCalendar} />
|
||||
</CInputGroupText>
|
||||
{/* <DatePicker selected={startDate} /> */}
|
||||
|
||||
<CFormInput type="date"
|
||||
required
|
||||
onChange={(e) => setDate(e.target.value)}
|
||||
value={date}
|
||||
placeholder="Event Date" />
|
||||
</CInputGroup>
|
||||
<CInputGroup className="mb-3">
|
||||
|
||||
<CInputGroupText>
|
||||
{/* Time* */}
|
||||
<CIcon icon={cilAlarm} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="time"
|
||||
startDate
|
||||
required
|
||||
onChange={(e) => setTime(e.target.value)}
|
||||
value={time}
|
||||
placeholder=" Event time" />
|
||||
</CInputGroup>
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilLocationPin} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
required
|
||||
onChange={(e) => setLocation(e.target.value)}
|
||||
value={location}
|
||||
placeholder="Location" />
|
||||
</CInputGroup>
|
||||
|
||||
<CInputGroup className="mb-3">
|
||||
|
||||
{/* <CIcon icon={cilLockLocked} /> */}
|
||||
|
||||
<CFormInput
|
||||
type="file"
|
||||
placeholder="image"
|
||||
accept="image/*"
|
||||
required
|
||||
onChange={handleImage}
|
||||
|
||||
|
||||
/>
|
||||
</CInputGroup>
|
||||
</div>
|
||||
|
||||
<div className=" d-flex">
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
type="button"
|
||||
className="btn btn-success btn-login waves-effect waves-light"
|
||||
>
|
||||
<ClipLoader loading={loading} size={18} />
|
||||
{!loading && "Save"}
|
||||
</button>
|
||||
<button
|
||||
onClick={onCancel}
|
||||
type="button"
|
||||
className=" ml-2 btn btn-warning btn-cancel waves-effect waves-light"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</CForm>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CContainer>
|
||||
</div>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default EditEvent
|
@ -1,130 +0,0 @@
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useEffect, useState, useCallback, useMemo } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import swal from 'sweetalert';
|
||||
import RegisterUser from "./RegisterUser";
|
||||
// import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
|
||||
function Event() {
|
||||
const [event, setEvent] = useState([])
|
||||
|
||||
const token = isAutheticated();
|
||||
|
||||
const getEvent = useCallback(async () => {
|
||||
let res = await axios.get(
|
||||
`/api/event/getAll`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
// console.log(res.data)
|
||||
setEvent(res.data.Event)
|
||||
|
||||
|
||||
}, [token]);
|
||||
|
||||
useEffect(() => {
|
||||
getEvent();
|
||||
}, [getEvent]);
|
||||
|
||||
|
||||
const handleDelete = async (id) => {
|
||||
let status = window.confirm("Do you want to delete");
|
||||
if (!status) return;
|
||||
|
||||
let res = await axios.delete(`/api/event/delete/${id}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
// console.log(res)
|
||||
if (res.data.success == true) {
|
||||
swal("success!", "Event Deleted Successfully!", "success");
|
||||
window.location.reload();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//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">
|
||||
<div className="container-fluid">
|
||||
{/* <!-- start page title --> */}
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<div className="page-title-box d-flex align-items-center justify-content-between">
|
||||
<h4 className="mb-3">CMP-Event</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> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- end page title --> */}
|
||||
|
||||
<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>
|
||||
<div className="table-responsive table-shoot">
|
||||
<table className="table table-centered table-nowrap mb-0">
|
||||
<thead className="thead-light">
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>Image</th>
|
||||
<th>Event Date</th>
|
||||
<th>Event Time</th>
|
||||
<th>Location</th>
|
||||
<th>Added On</th>
|
||||
<th>Attended By</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{event && event.map((item, index) =>
|
||||
<RegisterUser key={index} item={item} handleDelete={handleDelete} formatAMPM={formatAMPM} />
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
{/* <!-- end table-responsive --> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- container-fluid --> */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Event;
|
@ -1,92 +0,0 @@
|
||||
import axios from "axios";
|
||||
import React, { useEffect, useState, useCallback, useMemo } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import swal from 'sweetalert';
|
||||
// import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
|
||||
const RegisterUser = ({ item, handleDelete, formatAMPM }) => {
|
||||
const [totalRegisterUser, setTotalRegisterUser] = useState([])
|
||||
const token = isAutheticated();
|
||||
const getRegisterUser = useCallback(async () => {
|
||||
let res = await axios.get(
|
||||
`/api/event/admin/registerUser/getAll/${item._id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
// console.log(res.data)
|
||||
setTotalRegisterUser(res.data.totalUserRegister)
|
||||
|
||||
|
||||
}, [token]);
|
||||
|
||||
useEffect(() => {
|
||||
getRegisterUser();
|
||||
}, [getRegisterUser, item]);
|
||||
return (
|
||||
<>
|
||||
<tr>
|
||||
<td>{item?.title}</td>
|
||||
<td>
|
||||
<img src={`${item?.image.url}`} width="50" alt="" /></td>
|
||||
<td>{new Date(`${item?.date}`).toDateString()}</td>
|
||||
<td>{item?.time}</td>
|
||||
<td>{item?.location}</td>
|
||||
<td>
|
||||
{/* {item?.addedOn} */}
|
||||
{new Date(`${item?.addedOn}`).toDateString()}<span> , {`${formatAMPM(item?.addedOn)}`}</span>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<Link to={`/event/registerUsers/view/${item._id}`}>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className=" mx-1 mt-1 btn btn-warning btn-sm waves-effect waves-light btn-table ml-2"
|
||||
>
|
||||
{totalRegisterUser}
|
||||
</button>
|
||||
|
||||
</Link>
|
||||
</td>
|
||||
|
||||
|
||||
<td>
|
||||
|
||||
<Link to={`/event/view/${item._id}`}>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className=" mx-1 mt-1 btn btn-info btn-sm waves-effect waves-light btn-table ml-2"
|
||||
>
|
||||
View
|
||||
</button>
|
||||
|
||||
</Link>
|
||||
<Link to={`/event/edit/${item._id}`}>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className=" mx-1 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="mx-1 mt-1 btn btn-danger btn-sm waves-effect waves-light btn-table ml-2"
|
||||
id="sa-params"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default RegisterUser
|
@ -1,123 +0,0 @@
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useEffect, useState, useCallback, useMemo } from "react";
|
||||
import swal from 'sweetalert';
|
||||
// import { API } from "../../data";
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import { isAutheticated } from "../../auth";
|
||||
|
||||
function ViewEvent() {
|
||||
const [event, setEvent] = useState([])
|
||||
const { id } = useParams();
|
||||
const token = isAutheticated();
|
||||
|
||||
const getEvent = useCallback(async () => {
|
||||
let res = await axios.get(
|
||||
`/api/event/getOne/${id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
// console.log(res.data.Event)
|
||||
setEvent(res.data.Event)
|
||||
|
||||
|
||||
}, [token]);
|
||||
|
||||
useEffect(() => {
|
||||
getEvent();
|
||||
}, [getEvent]);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//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">
|
||||
<div className="container-fluid">
|
||||
{/* <!-- start page title --> */}
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<div className="page-title-box d-flex align-items-center justify-content-between">
|
||||
<h4 className="mb-3">CMP-Event</h4>
|
||||
<Link to="/addNews"><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> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- end page title --> */}
|
||||
|
||||
<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>
|
||||
<div className="table-responsive table-shoot">
|
||||
<table className="table table-centered table-nowrap mb-0">
|
||||
<thead className="thead-light">
|
||||
|
||||
<tr><th>Id</th> <td>{event?._id}</td></tr>
|
||||
<tr><th>Title</th> <td>{event?.title}</td></tr>
|
||||
|
||||
<tr><th>Image</th><td>
|
||||
<img src={`${event.image?.url}`} width="50" alt="" />
|
||||
</td></tr>
|
||||
<tr><th>Description</th><td>{event?.description}</td></tr>
|
||||
<tr><th>Event Date</th><td>{new Date(`${event?.date}`).toDateString()}</td></tr>
|
||||
<tr><th>Event Time</th><td>{event?.time}</td></tr>
|
||||
<tr><th>Location</th><td>{event?.location}</td></tr>
|
||||
<tr><th>Added On</th><td>
|
||||
{new Date(`${event?.addedOn}`).toDateString()}<span> , {`${formatAMPM(event?.addedOn)}`}</span>
|
||||
</td></tr>
|
||||
<tr><th>Updated At</th>
|
||||
<td>
|
||||
{new Date(`${event?.updatedAt}`).toDateString()}<span> , {`${formatAMPM(event?.updatedAt)}`}</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
{/* <!-- end table-responsive --> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- container-fluid --> */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ViewEvent;
|
@ -1,174 +0,0 @@
|
||||
import axios from "axios";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
import ClipLoader from "react-spinners/ClipLoader";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import swal from 'sweetalert';
|
||||
|
||||
import {
|
||||
CButton,
|
||||
CCard,
|
||||
CCardBody,
|
||||
CCol,
|
||||
CContainer,
|
||||
CForm,
|
||||
CFormInput,
|
||||
CInputGroup,
|
||||
CInputGroupText,
|
||||
CRow,
|
||||
} from '@coreui/react'
|
||||
import CIcon from '@coreui/icons-react'
|
||||
import { cilPencil, cilSettings, cilLockLocked, cilUser, cilNoteAdd } from '@coreui/icons'
|
||||
const AddFaqs = () => {
|
||||
const token = isAutheticated();
|
||||
let history = useHistory();
|
||||
// const [image, setImage] = useState("");
|
||||
const [topic, setTopic] = useState("");
|
||||
const [description, setDescription] = useState("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!(topic && description)) {
|
||||
return swal('Error!', 'All fields are required', 'error')
|
||||
|
||||
}
|
||||
const myForm = new FormData();
|
||||
|
||||
myForm.set("topic", topic);
|
||||
myForm.set("description", description);
|
||||
// myForm.set("image", image);
|
||||
setLoading({ loading: true });
|
||||
// console.log(image)
|
||||
try {
|
||||
let res = await axios.post(
|
||||
`/api/faqs/create/`, myForm,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": 'multipart/form-data',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
console.log(res.data)
|
||||
if (res.data) {
|
||||
swal("success!", "FAQs Added Successfully!", "success");
|
||||
setLoading(false);
|
||||
history.goBack();
|
||||
}
|
||||
} catch (error) {
|
||||
swal('Error!', error, 'error')
|
||||
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
// const handleImage = (e) => {
|
||||
// const files = e.target.files[0];
|
||||
// // console.log(files)
|
||||
// setImage(files);
|
||||
|
||||
// };
|
||||
//
|
||||
const onCancel = () => {
|
||||
// window.location = "/comproducts";
|
||||
history.goBack()
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-light min-vh-70 d-flex flex-row ">
|
||||
<CContainer>
|
||||
<CRow className="align-left w-140">
|
||||
<CCol md={19} lg={27} xl={16}>
|
||||
<CCard className="mx-4">
|
||||
<CCardBody className="p-4">
|
||||
<CForm>
|
||||
<h3 className="mb-4 justify-content-center">Add FAQs</h3>
|
||||
<div>
|
||||
<div>
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilPencil} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
maxlength='50'
|
||||
required
|
||||
onChange={(e) => setTopic(e.target.value)}
|
||||
value={topic}
|
||||
placeholder="Topic ( maximum 50 character )" />
|
||||
</CInputGroup>
|
||||
{topic ? <><span className="charLeft mb-3 fst-italic">
|
||||
{50 - topic.length} characters left
|
||||
</span></> : <></>
|
||||
|
||||
}
|
||||
|
||||
<CInputGroup className="mb-3">
|
||||
|
||||
<label htmlFor="exampleFormControlTextarea1" className="form-label fw-bold">Description*</label>
|
||||
<textarea
|
||||
className="h-50 w-100"
|
||||
maxlength='500'
|
||||
required
|
||||
onChange={(e) => setDescription(e.target.value)}
|
||||
value={description}
|
||||
rows="5"
|
||||
placeholder="Description ( maximum 500 character )">ewf3g</textarea>
|
||||
</CInputGroup>
|
||||
{description ? <><span className="charLeft fst-italic mb-3">
|
||||
{500 - description.length} characters left
|
||||
</span></> : <></>
|
||||
|
||||
}
|
||||
{/* <CInputGroup className="mb-3">
|
||||
|
||||
|
||||
|
||||
<CFormInput
|
||||
type="file"
|
||||
placeholder="image"
|
||||
accept="image/*"
|
||||
required
|
||||
onChange={handleImage}
|
||||
|
||||
|
||||
/>
|
||||
</CInputGroup> */}
|
||||
</div>
|
||||
|
||||
<div className=" d-flex">
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
type="button"
|
||||
className="btn btn-success btn-login waves-effect waves-light"
|
||||
>
|
||||
<ClipLoader loading={loading} size={18} />
|
||||
{!loading && "Save"}
|
||||
</button>
|
||||
<button
|
||||
onClick={onCancel}
|
||||
type="button"
|
||||
className=" ml-2 btn btn-warning btn-cancel waves-effect waves-light"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</CForm>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CContainer>
|
||||
</div>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default AddFaqs
|
@ -1,185 +0,0 @@
|
||||
import axios from "axios";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
import ClipLoader from "react-spinners/ClipLoader";
|
||||
import { useHistory, useParams } from "react-router-dom";
|
||||
import swal from 'sweetalert';
|
||||
|
||||
import {
|
||||
CButton,
|
||||
CCard,
|
||||
CCardBody,
|
||||
CCol,
|
||||
CContainer,
|
||||
CForm,
|
||||
CFormInput,
|
||||
CInputGroup,
|
||||
CInputGroupText,
|
||||
CRow,
|
||||
} from '@coreui/react'
|
||||
import CIcon from '@coreui/icons-react'
|
||||
import { cilPencil, cilSettings, cilLockLocked, cilUser, cilNoteAdd } from '@coreui/icons'
|
||||
const EditFaqs = () => {
|
||||
const { id } = useParams()
|
||||
const token = isAutheticated();
|
||||
let history = useHistory();
|
||||
// const [image, setImage] = useState("");
|
||||
const [topic, setTopic] = useState("");
|
||||
const [description, setDescription] = useState("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
//fetch one image
|
||||
useEffect(async () => {
|
||||
const res = await axios.get(`/api/faqs/getOne/${id}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
setTopic(res.data.Faqs.topic)
|
||||
setDescription(res.data.Faqs.description)
|
||||
|
||||
}, [id]);
|
||||
const handleSubmit = async () => {
|
||||
if (!(topic && description)) {
|
||||
return swal('Error!', 'All fields are required', 'error')
|
||||
|
||||
}
|
||||
const myForm = new FormData();
|
||||
|
||||
myForm.set("topic", topic);
|
||||
myForm.set("description", description);
|
||||
// myForm.set("image", image);
|
||||
setLoading({ loading: true });
|
||||
// console.log(image)
|
||||
try {
|
||||
let res = await axios.put(
|
||||
`/api/faqs/update/${id}`, myForm,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": 'multipart/form-data',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
console.log(res.data)
|
||||
if (res.data) {
|
||||
swal("success!", "FAQs Edit Successfully!", "success");
|
||||
setLoading(false);
|
||||
history.goBack();
|
||||
}
|
||||
} catch (error) {
|
||||
swal('Error!', error, 'error')
|
||||
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
// const handleImage = (e) => {
|
||||
// const files = e.target.files[0];
|
||||
// // console.log(files)
|
||||
// setImage(files);
|
||||
|
||||
// };
|
||||
//
|
||||
const onCancel = () => {
|
||||
// window.location = "/comproducts";
|
||||
|
||||
history.goBack()
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-light min-vh-70 d-flex flex-row ">
|
||||
<CContainer>
|
||||
<CRow className="align-left w-140">
|
||||
<CCol md={19} lg={27} xl={16}>
|
||||
<CCard className="mx-4">
|
||||
<CCardBody className="p-4">
|
||||
<CForm>
|
||||
<h3 className="mb-4 justify-content-center">Edit FAQs</h3>
|
||||
<div>
|
||||
<div>
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilPencil} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
maxlength='50'
|
||||
required
|
||||
onChange={(e) => setTopic(e.target.value)}
|
||||
value={topic}
|
||||
placeholder="Topic ( maximum 50 character )" />
|
||||
</CInputGroup>
|
||||
{topic ? <><span className="charLeft mb-3 fst-italic">
|
||||
{50 - topic.length} characters left
|
||||
</span></> : <></>
|
||||
|
||||
}
|
||||
<CInputGroup className="mb-3 d-flex">
|
||||
|
||||
<label htmlFor="exampleFormControlTextarea1" className="form-label fw-bold">Description*</label>
|
||||
<textarea
|
||||
className="h-50 w-100"
|
||||
maxlength='500'
|
||||
required
|
||||
onChange={(e) => setDescription(e.target.value)}
|
||||
value={description}
|
||||
rows="5"
|
||||
placeholder="Description ( maximum 500 character )">ewf3g</textarea>
|
||||
</CInputGroup>
|
||||
{description ? <><span className="charLeft fst-italic mb-3">
|
||||
{500 - description.length} characters left
|
||||
</span></> : <></>
|
||||
|
||||
}
|
||||
{/* <CInputGroup className="mb-3">
|
||||
|
||||
|
||||
|
||||
<CFormInput
|
||||
type="file"
|
||||
placeholder="image"
|
||||
accept="image/*"
|
||||
required
|
||||
onChange={handleImage}
|
||||
|
||||
|
||||
/>
|
||||
</CInputGroup> */}
|
||||
</div>
|
||||
|
||||
<div className=" d-flex">
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
type="button"
|
||||
className="btn btn-success btn-login waves-effect waves-light"
|
||||
>
|
||||
<ClipLoader loading={loading} size={18} />
|
||||
{!loading && "Save"}
|
||||
</button>
|
||||
<button
|
||||
onClick={onCancel}
|
||||
type="button"
|
||||
className=" ml-2 btn btn-warning btn-cancel waves-effect waves-light"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</CForm>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CContainer>
|
||||
</div>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default EditFaqs
|
@ -1,164 +0,0 @@
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useEffect, useState, useCallback, useMemo } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import swal from 'sweetalert';
|
||||
// import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
|
||||
function Faqs() {
|
||||
const [faqs, setFeqs] = useState([])
|
||||
|
||||
const token = isAutheticated();
|
||||
|
||||
const getfaqs = useCallback(async () => {
|
||||
let res = await axios.get(
|
||||
`/api/faqs/getAll`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
// console.log(res.data)
|
||||
setFeqs(res.data.Faqs)
|
||||
|
||||
|
||||
}, [token]);
|
||||
|
||||
useEffect(() => {
|
||||
getfaqs();
|
||||
}, [getfaqs]);
|
||||
|
||||
|
||||
const handleDelete = async (id) => {
|
||||
let status = window.confirm("Do you want to delete");
|
||||
if (!status) return;
|
||||
|
||||
let res = await axios.delete(`/api/faqs/delete/${id}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
// console.log(res)
|
||||
if (res.data.success == true) {
|
||||
swal("success!", "FAQs Deleted Successfully!", "success");
|
||||
window.location.reload();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//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">
|
||||
<div className="container-fluid">
|
||||
{/* <!-- start page title --> */}
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<div className="page-title-box d-flex align-items-center justify-content-between">
|
||||
<h4 className="mb-3">CMP-FAQs</h4>
|
||||
<Link to="/FAQs/add/"><button type="button" className="btn btn-info float-end mb-3 ml-4"> + Add New FAQ</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> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- end page title --> */}
|
||||
|
||||
<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>
|
||||
<div className="table-responsive table-shoot">
|
||||
<table className="table table-centered table-nowrap mb-0">
|
||||
<thead className="thead-light">
|
||||
<tr>
|
||||
<th>Topic</th>
|
||||
{/* <th>Image</th> */}
|
||||
<th>Added On</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{faqs && faqs.map((item, index) =>
|
||||
<tr>
|
||||
<td>{item?.topic}</td>
|
||||
{/* <td>
|
||||
<img src={`${item?.image.url}`} width="50" alt="" /></td> */}
|
||||
<td>
|
||||
{/* {item?.addedOn} */}
|
||||
{new Date(`${item?.createdAt}`).toDateString()}<span> , {`${formatAMPM(item?.createdAt)}`}</span>
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
<td>
|
||||
<Link to={`/FAQs/view/${item._id}`}>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className=" mx-1 mt-1 btn btn-info btn-sm waves-effect waves-light btn-table ml-2"
|
||||
>
|
||||
View
|
||||
</button>
|
||||
</Link>
|
||||
<Link to={`/FAQs/edit/${item._id}`}>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className=" mx-1 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="mx-1 mt-1 btn btn-danger btn-sm waves-effect waves-light btn-table ml-2"
|
||||
id="sa-params"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
{/* <!-- end table-responsive --> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- container-fluid --> */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Faqs;
|
@ -1,132 +0,0 @@
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useEffect, useState, useCallback, useMemo } from "react";
|
||||
import swal from 'sweetalert';
|
||||
// import { API } from "../../data";
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import { isAutheticated } from "../../auth";
|
||||
|
||||
function ViewFaqs() {
|
||||
const [faqs, setFaqs] = useState([])
|
||||
const { id } = useParams();
|
||||
// console.log(id)
|
||||
const token = isAutheticated();
|
||||
|
||||
const getFaqs = useCallback(async () => {
|
||||
let res = await axios.get(
|
||||
`/api/faqs/getOne/${id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
// console.log(res.data.news)
|
||||
setFaqs(res.data.Faqs)
|
||||
|
||||
|
||||
}, [token]);
|
||||
|
||||
useEffect(() => {
|
||||
getFaqs();
|
||||
}, [getFaqs]);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//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">
|
||||
<div className="container-fluid">
|
||||
{/* <!-- start page title --> */}
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<div className="page-title-box d-flex align-items-center justify-content-between">
|
||||
<h4 className="mb-3">CMP-FAQs</h4>
|
||||
<Link to="/FAQs/add/"><button type="button" className="btn btn-info float-end mb-3 ml-4"> + Add FAQs</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> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- end page title --> */}
|
||||
|
||||
<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>
|
||||
<div className="table-responsive table-shoot">
|
||||
<table className="table table-centered table-nowrap mb-0">
|
||||
<thead className="thead-light">
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<td>{faqs?._id}</td>
|
||||
</tr>
|
||||
<tr><th>TOPIC</th>
|
||||
<td>{faqs?.topic}</td>
|
||||
</tr>
|
||||
|
||||
{/* <tr> <th>Image</th>
|
||||
<td>
|
||||
<img src={`${faqs.image?.url}`} width="50" alt="" />
|
||||
</td>
|
||||
</tr> */}
|
||||
|
||||
<tr> <th>Description</th>
|
||||
<td>{faqs?.description}</td>
|
||||
</tr>
|
||||
<tr><th>Added On</th>
|
||||
<td>
|
||||
{new Date(`${faqs?.createdAt}`).toDateString()}<span> , {`${formatAMPM(faqs?.createdAt)}`}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr> <th>Updated At</th>
|
||||
<td>
|
||||
{new Date(`${faqs?.updatedAt}`).toDateString()}<span> , {`${formatAMPM(faqs?.updatedAt)}`}</span>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
{/* <!-- end table-responsive --> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- container-fluid --> */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ViewFaqs;
|
@ -1,25 +0,0 @@
|
||||
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="/feedback" className='page-link'>
|
||||
{number}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</nav>
|
||||
);
|
||||
};
|
||||
|
||||
export default Pagination;
|
@ -1,123 +0,0 @@
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useEffect, useState, useCallback, useMemo } from "react";
|
||||
import swal from 'sweetalert';
|
||||
// import { API } from "../../data";
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import { isAutheticated } from "../../auth";
|
||||
|
||||
function ViewFeedback() {
|
||||
const [user, setUser] = useState([])
|
||||
|
||||
|
||||
const [feedback, setFeedback] = useState([])
|
||||
const { id } = useParams();
|
||||
// console.log(id)
|
||||
const token = isAutheticated();
|
||||
|
||||
const getFeedback = useCallback(async () => {
|
||||
let res = await axios.get(
|
||||
`/api/feedback/getOne/${id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
setFeedback(res.data.feedback)
|
||||
|
||||
let resp = await axios.get(
|
||||
`/api/v1/admin/user/${feedback.user}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
setUser(resp.data.user)
|
||||
|
||||
|
||||
}, [token, feedback.user]);
|
||||
|
||||
useEffect(() => {
|
||||
getFeedback();
|
||||
}, [getFeedback]);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//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">
|
||||
<div className="container-fluid">
|
||||
{/* <!-- start page title --> */}
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<div className="page-title-box d-flex align-items-center justify-content-between">
|
||||
<h4 className="mb-3">CMP-Customer feedback</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- end page title --> */}
|
||||
|
||||
<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>
|
||||
<div className="table-responsive table-shoot">
|
||||
<table className="table table-centered table-nowrap mb-0">
|
||||
<thead className="thead-light">
|
||||
|
||||
<tr><th>User_Id</th><td>{user?._id}</td></tr>
|
||||
<tr><th>Name</th><td>{feedback?.name}</td></tr>
|
||||
<tr><th>email</th><td>{user?.email}</td>
|
||||
</tr>
|
||||
<tr><th>Image</th> <td>
|
||||
<img src={`${user.avatar?.url}`} width="50" alt="" />
|
||||
</td></tr>
|
||||
<tr><th>Description</th><td>{feedback?.description}</td></tr>
|
||||
|
||||
<tr><th>Pnone No.</th><td>{user?.phone}</td></tr>
|
||||
<tr><th>Feedback Given At</th> <td>
|
||||
{new Date(`${feedback?.createdAt}`).toDateString()}<span> , {`${formatAMPM(feedback?.createdAt)}`}</span>
|
||||
</td></tr>
|
||||
|
||||
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
{/* <!-- end table-responsive --> */}
|
||||
</div>
|
||||
</div >
|
||||
</div >
|
||||
</div >
|
||||
</div >
|
||||
{/* <!-- container-fluid --> */}
|
||||
</div >
|
||||
</div >
|
||||
);
|
||||
}
|
||||
|
||||
export default ViewFeedback;
|
@ -1,146 +0,0 @@
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useEffect, useState, useCallback, useMemo } from "react";
|
||||
import Pagination from "./Pagination";
|
||||
import { Link } from "react-router-dom";
|
||||
import swal from 'sweetalert';
|
||||
// import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
|
||||
function feedback() {
|
||||
const [feedback, setFeedback] = useState([])
|
||||
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [postsPerPage] = useState(20);
|
||||
const token = isAutheticated();
|
||||
|
||||
const getRestriction = useCallback(async () => {
|
||||
let res = await axios.get(
|
||||
`/api/feedback/getAll`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
// console.log(res.data.feedback)
|
||||
setFeedback(res.data.feedback)
|
||||
|
||||
|
||||
}, [token]);
|
||||
|
||||
useEffect(() => {
|
||||
getRestriction();
|
||||
}, [getRestriction]);
|
||||
|
||||
|
||||
// console.log(cmsRes)
|
||||
|
||||
// Get current posts
|
||||
//pagination
|
||||
const indexOfLastPost = currentPage * postsPerPage;
|
||||
const indexOfFirstPost = indexOfLastPost - postsPerPage;
|
||||
const currentPosts = feedback.slice(indexOfFirstPost, indexOfLastPost);
|
||||
|
||||
// Change page
|
||||
const paginate = pageNumber => setCurrentPage(pageNumber);
|
||||
|
||||
//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">
|
||||
<div className="container-fluid">
|
||||
{/* <!-- start page title --> */}
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<div className="page-title-box d-flex align-items-center justify-content-between">
|
||||
<h4 className="mb-3">CMP-Feedback</h4>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- end page title --> */}
|
||||
|
||||
<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>
|
||||
<div className="table-responsive table-shoot">
|
||||
<table className="table table-centered table-nowrap mb-0">
|
||||
<thead className="thead-light">
|
||||
<tr>
|
||||
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
<th>Given At</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{currentPosts && currentPosts.map((item, index) =>
|
||||
<tr key={index}>
|
||||
|
||||
<td>{item?.name}</td>
|
||||
<td>{item?.description}</td>
|
||||
|
||||
<td>
|
||||
|
||||
{new Date(`${item?.createdAt}`).toDateString()}<span> , {`${formatAMPM(item?.createdAt)}`}</span>
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
<td>
|
||||
<Link to={`/feedback/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>
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{/* <!-- end table-responsive --> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- container-fluid --> */}
|
||||
</div>
|
||||
</div>
|
||||
<Pagination postsPerPage={postsPerPage}
|
||||
totalPosts={feedback.length}
|
||||
paginate={paginate} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default feedback;
|
@ -1,161 +0,0 @@
|
||||
import axios from "axios";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
import ClipLoader from "react-spinners/ClipLoader";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import swal from 'sweetalert';
|
||||
|
||||
import {
|
||||
CButton,
|
||||
CCard,
|
||||
CCardBody,
|
||||
CCol,
|
||||
CContainer,
|
||||
CForm,
|
||||
CFormInput,
|
||||
CInputGroup,
|
||||
CInputGroupText,
|
||||
CRow,
|
||||
} from '@coreui/react'
|
||||
import CIcon from '@coreui/icons-react'
|
||||
import { cilPencil, cilSettings, cilLockLocked, cilUser } from '@coreui/icons'
|
||||
const AddNews = () => {
|
||||
const token = isAutheticated();
|
||||
let history = useHistory();
|
||||
const [image, setImage] = useState("");
|
||||
const [title, setTitle] = useState("");
|
||||
const [description, setDescription] = useState("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!(title && description && image)) {
|
||||
return swal('Error!', 'All fields are required', 'error')
|
||||
|
||||
}
|
||||
const myForm = new FormData();
|
||||
|
||||
myForm.set("title", title);
|
||||
myForm.set("description", description);
|
||||
myForm.set("image", image);
|
||||
setLoading({ loading: true });
|
||||
// console.log(image)
|
||||
try {
|
||||
let res = await axios.post(
|
||||
`/api/news/create`, myForm,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": 'multipart/form-data',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
console.log(res.data)
|
||||
if (res.data) {
|
||||
swal("success!", "News Added Successfully!", "success");
|
||||
setLoading(false);
|
||||
history.goBack();
|
||||
}
|
||||
} catch (error) {
|
||||
swal('Error!', error, 'error')
|
||||
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
const handleImage = (e) => {
|
||||
const files = e.target.files[0];
|
||||
// console.log(files)
|
||||
setImage(files);
|
||||
|
||||
};
|
||||
//
|
||||
const onCancel = () => {
|
||||
// window.location = "/comproducts";
|
||||
history.goBack()
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-light min-vh-70 d-flex flex-row ">
|
||||
<CContainer>
|
||||
<CRow className="align-left w-140">
|
||||
<CCol md={19} lg={27} xl={16}>
|
||||
<CCard className="mx-4">
|
||||
<CCardBody className="p-4">
|
||||
<CForm>
|
||||
<h3 className="mb-4 justify-content-center">Add News</h3>
|
||||
<div>
|
||||
<div>
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilPencil} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
required
|
||||
onChange={(e) => setTitle(e.target.value)}
|
||||
value={title}
|
||||
placeholder="Title" />
|
||||
</CInputGroup>
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilSettings} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
required
|
||||
onChange={(e) => setDescription(e.target.value)}
|
||||
value={description}
|
||||
placeholder="Description" />
|
||||
</CInputGroup>
|
||||
|
||||
<CInputGroup className="mb-3">
|
||||
|
||||
{/* <CIcon icon={cilLockLocked} /> */}
|
||||
|
||||
<CFormInput
|
||||
type="file"
|
||||
placeholder="image"
|
||||
accept="image/*"
|
||||
required
|
||||
onChange={handleImage}
|
||||
|
||||
|
||||
/>
|
||||
</CInputGroup>
|
||||
</div>
|
||||
|
||||
<div className=" d-flex">
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
type="button"
|
||||
className="btn btn-success btn-login waves-effect waves-light"
|
||||
>
|
||||
<ClipLoader loading={loading} size={18} />
|
||||
{!loading && "Save"}
|
||||
</button>
|
||||
<button
|
||||
onClick={onCancel}
|
||||
type="button"
|
||||
className=" ml-2 btn btn-warning btn-cancel waves-effect waves-light"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</CForm>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CContainer>
|
||||
</div>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default AddNews
|
@ -1,176 +0,0 @@
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
import ClipLoader from "react-spinners/ClipLoader";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import swal from 'sweetalert';
|
||||
|
||||
import {
|
||||
CButton,
|
||||
CCard,
|
||||
CCardBody,
|
||||
CCol,
|
||||
CContainer,
|
||||
CForm,
|
||||
CFormInput,
|
||||
CInputGroup,
|
||||
CInputGroupText,
|
||||
CRow,
|
||||
} from '@coreui/react'
|
||||
import CIcon from '@coreui/icons-react'
|
||||
import { cilPencil, cilSettings, cilLockLocked, cilUser } from '@coreui/icons'
|
||||
const EditNews = () => {
|
||||
const { id } = useParams();
|
||||
// console.log(id)
|
||||
const token = isAutheticated();
|
||||
let history = useHistory();
|
||||
const [image, setImage] = useState("");
|
||||
const [title, setTitle] = useState("");
|
||||
const [description, setDescription] = useState("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
//fetch one image
|
||||
useEffect(async () => {
|
||||
const res = await axios.get(`/api/news/getOne/${id}`, {
|
||||
// headers: {
|
||||
// Authorization: `Bearer ${token}`,
|
||||
// },
|
||||
});
|
||||
setTitle(res.data.news.title)
|
||||
setDescription(res.data.news.description)
|
||||
|
||||
}, [id]);
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!(title && description && image)) {
|
||||
return swal('Error!', 'All fields are required', 'error')
|
||||
|
||||
}
|
||||
const myForm = new FormData();
|
||||
|
||||
myForm.set("title", title);
|
||||
myForm.set("description", description);
|
||||
myForm.set("image", image);
|
||||
setLoading({ loading: true });
|
||||
// console.log(image)
|
||||
try {
|
||||
let res = await axios.put(
|
||||
`/api/news/update/${id}`, myForm,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": 'multipart/form-data',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
// console.log(res.data)
|
||||
if (res.data) {
|
||||
swal("success!", "News Edit Successfully!", "success");
|
||||
setLoading(false);
|
||||
history.goBack();
|
||||
}
|
||||
} catch (error) {
|
||||
swal('Error!', error, 'error')
|
||||
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
const handleImage = (e) => {
|
||||
const files = e.target.files[0];
|
||||
// console.log(files)
|
||||
setImage(files);
|
||||
|
||||
};
|
||||
//
|
||||
const onCancel = () => {
|
||||
// window.location = "/comproducts";
|
||||
history.goBack()
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-light min-vh-70 d-flex flex-row ">
|
||||
<CContainer>
|
||||
<CRow className="align-left w-140">
|
||||
<CCol md={19} lg={27} xl={16}>
|
||||
<CCard className="mx-4">
|
||||
<CCardBody className="p-4">
|
||||
<CForm>
|
||||
<h3 className="mb-4 justify-content-center">Edit News</h3>
|
||||
<div>
|
||||
<div>
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilPencil} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
required
|
||||
onChange={(e) => setTitle(e.target.value)}
|
||||
value={title}
|
||||
placeholder="Title" />
|
||||
</CInputGroup>
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilSettings} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
required
|
||||
onChange={(e) => setDescription(e.target.value)}
|
||||
value={description}
|
||||
placeholder="Description" />
|
||||
</CInputGroup>
|
||||
|
||||
<CInputGroup className="mb-3">
|
||||
|
||||
{/* <CIcon icon={cilLockLocked} /> */}
|
||||
|
||||
<CFormInput
|
||||
type="file"
|
||||
placeholder="image"
|
||||
accept="image/*"
|
||||
required
|
||||
onChange={handleImage}
|
||||
|
||||
|
||||
/>
|
||||
</CInputGroup>
|
||||
</div>
|
||||
|
||||
<div className=" d-flex">
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
type="button"
|
||||
className="btn btn-success btn-login waves-effect waves-light"
|
||||
>
|
||||
<ClipLoader loading={loading} size={18} />
|
||||
{!loading && "Save"}
|
||||
</button>
|
||||
<button
|
||||
onClick={onCancel}
|
||||
type="button"
|
||||
className=" ml-2 btn btn-warning btn-cancel waves-effect waves-light"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</CForm>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CContainer>
|
||||
</div>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default EditNews
|
@ -1,164 +0,0 @@
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useEffect, useState, useCallback, useMemo } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import swal from 'sweetalert';
|
||||
// import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
|
||||
function News() {
|
||||
const [news, setNews] = useState([])
|
||||
|
||||
const token = isAutheticated();
|
||||
|
||||
const getNews = useCallback(async () => {
|
||||
let res = await axios.get(
|
||||
`/api/news/getAll`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
setNews(res.data.news)
|
||||
|
||||
|
||||
}, [token]);
|
||||
|
||||
useEffect(() => {
|
||||
getNews();
|
||||
}, [getNews]);
|
||||
|
||||
|
||||
const handleDelete = async (id) => {
|
||||
let status = window.confirm("Do you want to delete");
|
||||
if (!status) return;
|
||||
|
||||
let res = await axios.delete(`/api/news/delete/${id}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
console.log(res)
|
||||
if (res.data.success == true) {
|
||||
swal("success!", "News Deleted Successfully!", "success");
|
||||
window.location.reload();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//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">
|
||||
<div className="container-fluid">
|
||||
{/* <!-- start page title --> */}
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<div className="page-title-box d-flex align-items-center justify-content-between">
|
||||
<h4 className="mb-3">CMP-News</h4>
|
||||
<Link to="/addNews"><button type="button" className="btn btn-info float-end mb-3 ml-4"> + Add News</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> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- end page title --> */}
|
||||
|
||||
<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>
|
||||
<div className="table-responsive table-shoot">
|
||||
<table className="table table-centered table-nowrap mb-0">
|
||||
<thead className="thead-light">
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>Image</th>
|
||||
<th>Added On</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{news && news.map((item, index) =>
|
||||
<tr key={index}>
|
||||
<td>{item?.title}</td>
|
||||
<td>
|
||||
<img src={`${item?.image.url}`} width="50" alt="" /></td>
|
||||
<td>
|
||||
{/* {item?.addedOn} */}
|
||||
{new Date(`${item?.addedOn}`).toDateString()}<span> , {`${formatAMPM(item?.addedOn)}`}</span>
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
<td>
|
||||
<Link to={`/news/view/${item._id}`}>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className=" mx-1 mt-1 btn btn-info btn-sm waves-effect waves-light btn-table ml-2"
|
||||
>
|
||||
View
|
||||
</button>
|
||||
</Link>
|
||||
<Link to={`/news/edit/${item._id}`}>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className=" mx-1 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="mx-1 mt-1 btn btn-danger btn-sm waves-effect waves-light btn-table ml-2"
|
||||
id="sa-params"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
{/* <!-- end table-responsive --> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- container-fluid --> */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default News;
|
@ -1,131 +0,0 @@
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useEffect, useState, useCallback, useMemo } from "react";
|
||||
import swal from 'sweetalert';
|
||||
// import { API } from "../../data";
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import { isAutheticated } from "../../auth";
|
||||
|
||||
function ViewNews() {
|
||||
const [news, setNews] = useState([])
|
||||
const { id } = useParams();
|
||||
const token = isAutheticated();
|
||||
|
||||
const getNews = useCallback(async () => {
|
||||
let res = await axios.get(
|
||||
`/api/news/getOne/${id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
setNews(res.data.news)
|
||||
|
||||
|
||||
}, [token]);
|
||||
|
||||
useEffect(() => {
|
||||
getNews();
|
||||
}, [getNews]);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//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">
|
||||
<div className="container-fluid">
|
||||
{/* <!-- start page title --> */}
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<div className="page-title-box d-flex align-items-center justify-content-between">
|
||||
<h4 className="mb-3">CMP-News</h4>
|
||||
<Link to="/addNews"><button type="button" className="btn btn-info float-end mb-3 ml-4"> + Add News</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> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- end page title --> */}
|
||||
|
||||
<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>
|
||||
<div className="table-responsive table-shoot">
|
||||
<table className="table table-centered table-nowrap mb-0">
|
||||
<thead className="thead-light">
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<td>{news?._id}</td>
|
||||
</tr>
|
||||
<tr><th>Title</th>
|
||||
<td>{news?.title}</td>
|
||||
</tr>
|
||||
|
||||
<tr> <th>Image</th>
|
||||
<td>
|
||||
<img src={`${news.image?.url}`} width="50" alt="" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr> <th>Description</th>
|
||||
<td>{news?.description}</td>
|
||||
</tr>
|
||||
<tr><th>Added On</th>
|
||||
<td>
|
||||
{new Date(`${news?.addedOn}`).toDateString()}<span> , {`${formatAMPM(news?.addedOn)}`}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr> <th>Updated At</th>
|
||||
<td>
|
||||
{new Date(`${news?.updatedAt}`).toDateString()}<span> , {`${formatAMPM(news?.updatedAt)}`}</span>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
{/* <!-- end table-responsive --> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- container-fluid --> */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ViewNews;
|
@ -1,240 +0,0 @@
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
import ClipLoader from "react-spinners/ClipLoader";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import swal from 'sweetalert';
|
||||
|
||||
import {
|
||||
CButton,
|
||||
CCard,
|
||||
CCardBody,
|
||||
CCol,
|
||||
CContainer,
|
||||
CForm,
|
||||
CFormInput,
|
||||
CInputGroup,
|
||||
CInputGroupText,
|
||||
CRow,
|
||||
} from '@coreui/react'
|
||||
import CIcon from '@coreui/icons-react'
|
||||
import { cilPencil, cilSettings, cilLockLocked, cilUser, cilBell, cilLocationPin, cilAudioDescription } from '@coreui/icons'
|
||||
const AddOffer = () => {
|
||||
const token = isAutheticated();
|
||||
let history = useHistory();
|
||||
//console.log(token)
|
||||
const [image, setImage] = useState("");
|
||||
const [title, setTitle] = useState("");
|
||||
const [bisunessName, setBisunessName] = useState([]);
|
||||
const [sendBisunessName, setSendBisunessName] = useState('');
|
||||
|
||||
const [description, setDescription] = useState("");
|
||||
const [location, setLocation] = useState("");
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const changeState = (newState) =>
|
||||
setBisunessName((prevState) => ({ ...prevState, ...newState }));
|
||||
|
||||
const handleChange = (e) => {
|
||||
changeState({ ...bisunessName, [e.target.name]: e.target.value })
|
||||
|
||||
};
|
||||
const fetchBusuness = useCallback(async () => {
|
||||
const res = await axios.get(`/api/directory/getAll`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
|
||||
// console.log(res.data.directory);
|
||||
setBisunessName(res.data.directory)
|
||||
|
||||
}, [token]);
|
||||
|
||||
useEffect(async () => {
|
||||
fetchBusuness();
|
||||
|
||||
}, [fetchBusuness]);
|
||||
|
||||
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!(title && description && image && location && sendBisunessName)) {
|
||||
return swal('Error!', 'All fields are required', 'error')
|
||||
|
||||
}
|
||||
const myForm = new FormData();
|
||||
|
||||
myForm.set("title", title);
|
||||
myForm.set("description", description);
|
||||
myForm.set("bisunessName", sendBisunessName);
|
||||
myForm.set("location", location);
|
||||
myForm.set("image", image);
|
||||
setLoading({ loading: true });
|
||||
// console.log(image)
|
||||
try {
|
||||
let res = await axios.post(
|
||||
`/api/offer/create`, myForm,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": 'multipart/form-data',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
// console.log(res.data)
|
||||
if (res.data) {
|
||||
swal("success!", "Event Added Successfully!", "success");
|
||||
setLoading(false);
|
||||
history.goBack();
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
swal('Error!', 'something Went Wrong', 'error')
|
||||
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
const handleImage = (e) => {
|
||||
const files = e.target.files[0];
|
||||
// console.log(files)
|
||||
setImage(files);
|
||||
|
||||
};
|
||||
//
|
||||
const onCancel = () => {
|
||||
// window.location = "/comproducts";
|
||||
history.goBack()
|
||||
|
||||
};
|
||||
// console.log(bisunessName)
|
||||
return (
|
||||
<>
|
||||
<div className="bg-light min-vh-70 d-flex flex-row ">
|
||||
<CContainer>
|
||||
<CRow className="align-left w-140">
|
||||
<CCol md={19} lg={27} xl={16}>
|
||||
<CCard className="mx-4">
|
||||
<CCardBody className="p-4">
|
||||
<CForm>
|
||||
<h3 className="mb-4 justify-content-center">Add New Offer</h3>
|
||||
<div>
|
||||
<div>
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilPencil} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
maxlength="250"
|
||||
required
|
||||
onChange={(e) => setTitle(e.target.value)}
|
||||
value={title}
|
||||
placeholder="Title (maximum 50 characters)" />
|
||||
|
||||
</CInputGroup>
|
||||
{title ? <><span className="charLeft mt-4 fst-italic">
|
||||
{50 - title.length} characters left
|
||||
</span></> : <></>
|
||||
|
||||
}
|
||||
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilAudioDescription} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
maxlength="250"
|
||||
required
|
||||
onChange={(e) => setDescription(e.target.value)}
|
||||
value={description}
|
||||
placeholder="Description (maximum 250 characters)" />
|
||||
</CInputGroup>
|
||||
{description ? <><span className="charLeft mt-4 fst-italic">
|
||||
{250 - description.length} characters left
|
||||
</span></> : <></>
|
||||
|
||||
}
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilBell} />
|
||||
</CInputGroupText>
|
||||
|
||||
<select
|
||||
name="bisunessName"
|
||||
value={sendBisunessName}
|
||||
// onChange={handleChange}
|
||||
// //onChange={(e) => setBisunessName(e.target.value)}
|
||||
onChange={(e) => setSendBisunessName(e.target.value)}
|
||||
className="form-control input-field"
|
||||
>
|
||||
|
||||
<option value="1">--select--</option>
|
||||
{bisunessName.map((item, index) =>
|
||||
<option key={index}>{item?.name}</option>
|
||||
|
||||
)}
|
||||
</select>
|
||||
</CInputGroup>
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilLocationPin} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
required
|
||||
onChange={(e) => setLocation(e.target.value)}
|
||||
value={location}
|
||||
placeholder="Location" />
|
||||
</CInputGroup>
|
||||
|
||||
<CInputGroup className="mb-3">
|
||||
|
||||
{/* <CIcon icon={cilLockLocked} /> */}
|
||||
|
||||
<CFormInput
|
||||
type="file"
|
||||
placeholder="image"
|
||||
accept="image/*"
|
||||
required
|
||||
onChange={handleImage}
|
||||
|
||||
|
||||
/>
|
||||
</CInputGroup>
|
||||
</div>
|
||||
|
||||
<div className=" d-flex">
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
type="button"
|
||||
className="btn btn-success btn-login waves-effect waves-light"
|
||||
>
|
||||
<ClipLoader loading={loading} size={18} />
|
||||
{!loading && "Save"}
|
||||
</button>
|
||||
<button
|
||||
onClick={onCancel}
|
||||
type="button"
|
||||
className=" ml-2 btn btn-warning btn-cancel waves-effect waves-light"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</CForm>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CContainer>
|
||||
</div>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default AddOffer
|
@ -1,247 +0,0 @@
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
import ClipLoader from "react-spinners/ClipLoader";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import swal from 'sweetalert';
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import {
|
||||
CButton,
|
||||
CCard,
|
||||
CCardBody,
|
||||
CCol,
|
||||
CContainer,
|
||||
CForm,
|
||||
CFormInput,
|
||||
CInputGroup,
|
||||
CInputGroupText,
|
||||
CRow,
|
||||
} from '@coreui/react'
|
||||
import CIcon from '@coreui/icons-react'
|
||||
import { cilPencil, cilSettings, cilLockLocked, cilUser, cilBell, cilLocationPin, cilAudioDescription } from '@coreui/icons'
|
||||
const EditOffer = () => {
|
||||
const { id } = useParams();
|
||||
const token = isAutheticated();
|
||||
// console.log(token)
|
||||
let history = useHistory();
|
||||
const [image, setImage] = useState("");
|
||||
const [title, setTitle] = useState("");
|
||||
const [bisunessName, setBisunessName] = useState([]);
|
||||
const [sendBisunessName, setSendBisunessName] = useState('');
|
||||
|
||||
const [description, setDescription] = useState("");
|
||||
const [location, setLocation] = useState("");
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
|
||||
//fetch one Offer
|
||||
useEffect(async () => {
|
||||
const res = await axios.get(`/api/offer/getOne/${id}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
// console.log(res.data)
|
||||
setTitle(res.data.offer.title)
|
||||
setDescription(res.data.offer.description)
|
||||
setLocation(res.data.offer.location)
|
||||
setSendBisunessName(res.data.offer.bisunessName)
|
||||
|
||||
}, [id]);
|
||||
const fetchBusuness = useCallback(async () => {
|
||||
const res = await axios.get(`/api/directory/getAll`, {
|
||||
// headers: {
|
||||
// Authorization: `Bearer ${token}`,
|
||||
// },
|
||||
});
|
||||
|
||||
// console.log(res.data.directory);
|
||||
setBisunessName(res.data.directory)
|
||||
|
||||
}, [token]);
|
||||
|
||||
useEffect(async () => {
|
||||
fetchBusuness();
|
||||
|
||||
}, [fetchBusuness]);
|
||||
|
||||
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!(title && description && image && location && sendBisunessName)) {
|
||||
return swal('Error!', 'All fields are required', 'error')
|
||||
|
||||
}
|
||||
const myForm = new FormData();
|
||||
|
||||
myForm.set("title", title);
|
||||
myForm.set("description", description);
|
||||
myForm.set("bisunessName", sendBisunessName);
|
||||
myForm.set("location", location);
|
||||
myForm.set("image", image);
|
||||
setLoading({ loading: true });
|
||||
// console.log(image)
|
||||
try {
|
||||
let res = await axios.put(
|
||||
`/api/offer/update/${id}`, myForm,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": 'multipart/form-data',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
// console.log(res.data)
|
||||
if (res.data) {
|
||||
swal("success!", "Event Added Successfully!", "success");
|
||||
setLoading(false);
|
||||
history.goBack();
|
||||
}
|
||||
} catch (error) {
|
||||
swal('Error!', 'something Went Wrong', 'error')
|
||||
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
const handleImage = (e) => {
|
||||
const files = e.target.files[0];
|
||||
// console.log(files)
|
||||
setImage(files);
|
||||
|
||||
};
|
||||
//
|
||||
const onCancel = () => {
|
||||
// window.location = "/comproducts";
|
||||
history.goBack()
|
||||
|
||||
};
|
||||
// console.log(bisunessName)
|
||||
return (
|
||||
<>
|
||||
<div className="bg-light min-vh-70 d-flex flex-row ">
|
||||
<CContainer>
|
||||
<CRow className="align-left w-140">
|
||||
<CCol md={19} lg={27} xl={16}>
|
||||
<CCard className="mx-4">
|
||||
<CCardBody className="p-4">
|
||||
<CForm>
|
||||
<h3 className="mb-4 justify-content-center">Edit Offer</h3>
|
||||
<div>
|
||||
<div>
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilPencil} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
maxlength="50"
|
||||
required
|
||||
onChange={(e) => setTitle(e.target.value)}
|
||||
value={title}
|
||||
placeholder="Title (maximum 50 characters)" />
|
||||
</CInputGroup>
|
||||
{title ? <><span className="charLeft mt-4 fst-italic">
|
||||
{50 - title.length} characters left
|
||||
</span></> : <></>
|
||||
|
||||
}
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilAudioDescription} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
maxlength="250"
|
||||
required
|
||||
onChange={(e) => setDescription(e.target.value)}
|
||||
value={description}
|
||||
placeholder="Description (maximum 250 characters)" />
|
||||
</CInputGroup>
|
||||
{description ? <><span className="charLeft mt-4 fst-italic">
|
||||
{250 - description.length} characters left
|
||||
</span></> : <></>
|
||||
|
||||
}
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilBell} />
|
||||
</CInputGroupText>
|
||||
|
||||
<select
|
||||
name="bisunessName"
|
||||
value={sendBisunessName}
|
||||
// onChange={handleChange}
|
||||
// //onChange={(e) => setBisunessName(e.target.value)}
|
||||
onChange={(e) => setSendBisunessName(e.target.value)}
|
||||
className="form-control input-field"
|
||||
>
|
||||
|
||||
<option value="1">--select--</option>
|
||||
{bisunessName.map((item, index) =>
|
||||
<option key={index}>{item?.name}</option>
|
||||
|
||||
)}
|
||||
</select>
|
||||
</CInputGroup>
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilLocationPin} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
required
|
||||
onChange={(e) => setLocation(e.target.value)}
|
||||
value={location}
|
||||
placeholder="Location" />
|
||||
</CInputGroup>
|
||||
|
||||
<CInputGroup className="mb-3">
|
||||
|
||||
{/* <CIcon icon={cilLockLocked} /> */}
|
||||
|
||||
<CFormInput
|
||||
type="file"
|
||||
placeholder="image"
|
||||
accept="image/*"
|
||||
required
|
||||
onChange={handleImage}
|
||||
|
||||
|
||||
/>
|
||||
</CInputGroup>
|
||||
</div>
|
||||
|
||||
<div className=" d-flex">
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
type="button"
|
||||
className="btn btn-success btn-login waves-effect waves-light"
|
||||
>
|
||||
<ClipLoader loading={loading} size={18} />
|
||||
{!loading && "Save"}
|
||||
</button>
|
||||
<button
|
||||
onClick={onCancel}
|
||||
type="button"
|
||||
className=" ml-2 btn btn-warning btn-cancel waves-effect waves-light"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</CForm>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CContainer>
|
||||
</div>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default EditOffer
|
@ -1,162 +0,0 @@
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useEffect, useState, useCallback, useMemo } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import swal from 'sweetalert';
|
||||
// import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
|
||||
function Offer() {
|
||||
const [offer, setOffer] = useState([])
|
||||
|
||||
const token = isAutheticated();
|
||||
|
||||
const getOffer = useCallback(async () => {
|
||||
let res = await axios.get(
|
||||
`/api/offer/getAll`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
// console.log(res.data)
|
||||
setOffer(res.data.offer)
|
||||
|
||||
|
||||
}, [token]);
|
||||
|
||||
useEffect(() => {
|
||||
getOffer();
|
||||
}, [getOffer]);
|
||||
|
||||
|
||||
const handleDelete = async (id) => {
|
||||
let status = window.confirm("Do you want to delete");
|
||||
if (!status) return;
|
||||
|
||||
let res = await axios.delete(`/api/offer/delete/${id}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
console.log(res)
|
||||
if (res.data.success == true) {
|
||||
swal("success!", "Offer Deleted Successfully!", "success");
|
||||
window.location.reload();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//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">
|
||||
<div className="container-fluid">
|
||||
{/* <!-- start page title --> */}
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<div className="page-title-box d-flex align-items-center justify-content-between">
|
||||
<h4 className="mb-3">CMP-Offers</h4>
|
||||
<Link to="/addOffer"><button type="button" className="btn btn-info float-end mb-3 ml-4"> + Add New Offer</button></Link>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- end page title --> */}
|
||||
|
||||
<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>
|
||||
<div className="table-responsive table-shoot">
|
||||
<table className="table table-centered table-nowrap mb-0">
|
||||
<thead className="thead-light">
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>Image</th>
|
||||
<th>Business Name</th>
|
||||
<th>Location</th>
|
||||
<th>Added On</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{offer && offer.map((item, index) =>
|
||||
<tr key={index}>
|
||||
<td>{item?.title}</td>
|
||||
|
||||
<td>
|
||||
<img src={`${item?.image.url}`} width="50" alt="" /></td>
|
||||
<td>{item?.bisunessName}</td>
|
||||
<td>{item?.location}</td>
|
||||
<td>
|
||||
{/* {item?.addedOn} */}
|
||||
{new Date(`${item?.addedOn}`).toDateString()}<span> , {`${formatAMPM(item?.addedOn)}`}</span>
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
<td>
|
||||
<Link to={`/offer/view/${item._id}`}>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className=" mx-1 mt-1 btn btn-info btn-sm waves-effect waves-light btn-table ml-2"
|
||||
>
|
||||
View
|
||||
</button>
|
||||
</Link>
|
||||
<Link to={`/offer/edit/${item._id}`}>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className=" mx-1 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="mx-1 mt-1 btn btn-danger btn-sm waves-effect waves-light btn-table ml-2"
|
||||
id="sa-params"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
{/* <!-- end table-responsive --> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- container-fluid --> */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Offer;
|
@ -1,136 +0,0 @@
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useEffect, useState, useCallback, useMemo } from "react";
|
||||
import swal from 'sweetalert';
|
||||
// import { API } from "../../data";
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import { isAutheticated } from "../../auth";
|
||||
|
||||
function ViewOffer() {
|
||||
const [offer, setOffer] = useState([])
|
||||
const { id } = useParams();
|
||||
const token = isAutheticated();
|
||||
|
||||
const getOffer = useCallback(async () => {
|
||||
let res = await axios.get(
|
||||
`/api/offer/getOne/${id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
setOffer(res.data.offer)
|
||||
|
||||
|
||||
}, [token]);
|
||||
|
||||
useEffect(() => {
|
||||
getOffer();
|
||||
}, [getOffer]);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//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">
|
||||
<div className="container-fluid">
|
||||
{/* <!-- start page title --> */}
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<div className="page-title-box d-flex align-items-center justify-content-between">
|
||||
<h4 className="mb-3">CMP-Offers</h4>
|
||||
<Link to="/addOffer"><button type="button" className="btn btn-info float-end mb-3 ml-4"> + Add New Offer</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> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- end page title --> */}
|
||||
|
||||
<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>
|
||||
<div className="table-responsive table-shoot">
|
||||
<table className="table table-centered table-nowrap mb-0">
|
||||
<thead className="thead-light">
|
||||
|
||||
<tr> <th>Id</th>
|
||||
<td>{offer?._id}</td>
|
||||
</tr>
|
||||
<tr><th>Title</th>
|
||||
<td>{offer?.title}</td>
|
||||
</tr>
|
||||
|
||||
<tr><th>Image</th>
|
||||
<td>
|
||||
<img src={`${offer.image?.url}`} width="50" alt="" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr><th>Bisuness Name</th>
|
||||
<td> {offer?.bisunessName}</td>
|
||||
</tr>
|
||||
<tr><th>Description</th>
|
||||
<td>{offer?.description}</td>
|
||||
</tr>
|
||||
<tr><th>Location</th>
|
||||
<td>{offer?.location}</td>
|
||||
</tr>
|
||||
<tr><th>Added On</th>
|
||||
<td>
|
||||
{new Date(`${offer?.addedOn}`).toDateString()}<span> , {`${formatAMPM(offer?.addedOn)}`}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><th>Updated At</th>
|
||||
<td>
|
||||
{new Date(`${offer?.updatedAt}`).toDateString()}<span> , {`${formatAMPM(offer?.updatedAt)}`}</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
{/* <!-- end table-responsive --> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- container-fluid --> */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ViewOffer;
|
@ -1,217 +0,0 @@
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
import ClipLoader from "react-spinners/ClipLoader";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import swal from 'sweetalert';
|
||||
|
||||
import {
|
||||
CButton,
|
||||
CCard,
|
||||
CCardBody,
|
||||
CCol,
|
||||
CContainer,
|
||||
CForm,
|
||||
CFormInput,
|
||||
CInputGroup,
|
||||
CInputGroupText,
|
||||
CRow,
|
||||
} from '@coreui/react'
|
||||
import CIcon from '@coreui/icons-react'
|
||||
import { cilPencil, cilSettings, cilLockLocked, cilUser, cilBell, cilLocationPin, cilAudioDescription, cilObjectGroup } from '@coreui/icons'
|
||||
const AddRequirement = () => {
|
||||
const token = isAutheticated();
|
||||
// console.log(token)
|
||||
let history = useHistory();
|
||||
|
||||
const [areaOfInterest, setAreaOfInterest] = useState("");
|
||||
const [description, setDescription] = useState("");
|
||||
const [title, setTitle] = useState("");
|
||||
const [imagesPreview, setImagesPreview] = useState([]);
|
||||
const [allimage, setAllImage] = useState([]);
|
||||
// const [images, setImages] = useState([]);
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const handleImage = (e) => {
|
||||
|
||||
setAllImage([...allimage, ...e.target.files]);
|
||||
|
||||
// only for file preview------------------------------------
|
||||
const files = Array.from(e.target.files);
|
||||
files.forEach((file) => {
|
||||
const reader = new FileReader();
|
||||
|
||||
reader.onload = () => {
|
||||
if (reader.readyState === 2) {
|
||||
setImagesPreview((old) => [...old, reader.result]);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
reader.readAsDataURL(file)
|
||||
});
|
||||
// -----------------------------------------------------------------------------
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
const myForm = new FormData();
|
||||
|
||||
myForm.set("title", title);
|
||||
myForm.set("description", description);
|
||||
myForm.set("areaOfInterest", areaOfInterest);
|
||||
allimage.forEach((Singleimage) => {
|
||||
myForm.append("image", Singleimage);
|
||||
|
||||
});
|
||||
if (!(title && description && areaOfInterest && allimage[0])) {
|
||||
return swal('Error!', 'All fields are required', 'error')
|
||||
|
||||
}
|
||||
setLoading(true);
|
||||
try {
|
||||
let res = await axios.post(
|
||||
`/api/requirement/create`, myForm,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": 'multipart/form-data',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
if (res.data.success === true) {
|
||||
swal("success!", "Requirements Added Successfully!", "success");
|
||||
history.goBack();
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
setLoading(false);
|
||||
swal('Error!', error, 'error')
|
||||
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const onCancel = () => {
|
||||
history.goBack()
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-light min-vh-70 d-flex flex-row ">
|
||||
<CContainer>
|
||||
<CRow className="align-left w-140">
|
||||
<CCol md={19} lg={27} xl={16}>
|
||||
<CCard className="mx-4">
|
||||
<CCardBody className="p-4">
|
||||
<CForm>
|
||||
<h3 className="mb-4 justify-content-center">Add Requirements</h3>
|
||||
<div>
|
||||
<div>
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilPencil} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
maxlength="50"
|
||||
required
|
||||
onChange={(e) => setTitle(e.target.value)}
|
||||
value={title}
|
||||
placeholder="Title (maximum 50 characters)" />
|
||||
</CInputGroup>
|
||||
{title ? <><span className="charLeft mt-4 fst-italic">
|
||||
{50 - title.length} characters left
|
||||
</span></> : <></>
|
||||
|
||||
}
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilObjectGroup} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
required
|
||||
onChange={(e) => setAreaOfInterest(e.target.value)}
|
||||
value={areaOfInterest}
|
||||
placeholder="Area Of Interest" />
|
||||
</CInputGroup>
|
||||
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilAudioDescription} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
maxlength="250"
|
||||
required
|
||||
onChange={(e) => setDescription(e.target.value)}
|
||||
value={description}
|
||||
placeholder="Description (maximum 250 characters)" />
|
||||
</CInputGroup>
|
||||
{description ? <><span className="charLeft mt-4 fst-italic">
|
||||
{250 - description.length} characters left
|
||||
</span></> : <></>
|
||||
|
||||
}
|
||||
|
||||
<CInputGroup className="mb-3">
|
||||
|
||||
{/* <CIcon icon={cilLockLocked} /> */}
|
||||
|
||||
<CFormInput
|
||||
type="file"
|
||||
placeholder="image"
|
||||
accept="image/*"
|
||||
name="image"
|
||||
required
|
||||
multiple
|
||||
onChange={handleImage}
|
||||
|
||||
|
||||
/>
|
||||
</CInputGroup>
|
||||
<div><strong className="fs-6 fst-italic">*Please Upload maximum four 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 className=" d-flex">
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
type="button"
|
||||
className="btn mt-1 btn-success btn-login waves-effect waves-light"
|
||||
>
|
||||
<ClipLoader loading={loading} size={18} />
|
||||
{!loading && "Save"}
|
||||
</button>
|
||||
<button
|
||||
onClick={onCancel}
|
||||
type="button"
|
||||
className=" ml-2 mt-1 btn btn-warning btn-cancel waves-effect waves-light"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</CForm>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CContainer>
|
||||
</div>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default AddRequirement
|
@ -1,232 +0,0 @@
|
||||
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
import ClipLoader from "react-spinners/ClipLoader";
|
||||
import { useHistory, useParams } from "react-router-dom";
|
||||
import swal from 'sweetalert';
|
||||
|
||||
import {
|
||||
CButton,
|
||||
CCard,
|
||||
CCardBody,
|
||||
CCol,
|
||||
CContainer,
|
||||
CForm,
|
||||
CFormInput,
|
||||
CInputGroup,
|
||||
CInputGroupText,
|
||||
CRow,
|
||||
} from '@coreui/react'
|
||||
import CIcon from '@coreui/icons-react'
|
||||
import { cilPencil, cilSettings, cilLockLocked, cilUser, cilBell, cilLocationPin, cilAudioDescription, cilObjectGroup } from '@coreui/icons'
|
||||
const EditRequirement = () => {
|
||||
const token = isAutheticated();
|
||||
const { id } = useParams()
|
||||
let history = useHistory();
|
||||
const [areaOfInterest, setAreaOfInterest] = useState("");
|
||||
const [description, setDescription] = useState("");
|
||||
const [title, setTitle] = useState("");
|
||||
const [imagesPreview, setImagesPreview] = useState([]);
|
||||
const [allimage, setAllImage] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
//fetch one requirement
|
||||
useEffect(async () => {
|
||||
const res = await axios.get(`/api/requirement/getOne/${id}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
// console.log(res.data)
|
||||
setTitle(res.data.Requirement.title)
|
||||
setDescription(res.data.Requirement.description)
|
||||
setAreaOfInterest(res.data.Requirement.areaOfInterest)
|
||||
|
||||
|
||||
}, [id]);
|
||||
|
||||
|
||||
const handleImage = (e) => {
|
||||
|
||||
setAllImage([...allimage, ...e.target.files]);
|
||||
|
||||
// only for file preview------------------------------------
|
||||
const files = Array.from(e.target.files);
|
||||
files.forEach((file) => {
|
||||
const reader = new FileReader();
|
||||
|
||||
reader.onload = () => {
|
||||
if (reader.readyState === 2) {
|
||||
setImagesPreview((old) => [...old, reader.result]);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
reader.readAsDataURL(file)
|
||||
});
|
||||
// -----------------------------------------------------------------------------
|
||||
};
|
||||
|
||||
|
||||
const handleSubmit = async () => {
|
||||
const myForm = new FormData();
|
||||
|
||||
myForm.set("title", title);
|
||||
myForm.set("description", description);
|
||||
myForm.set("areaOfInterest", areaOfInterest);
|
||||
allimage.forEach((Singleimage) => {
|
||||
myForm.append("image", Singleimage);
|
||||
|
||||
});
|
||||
if (!(title && description && areaOfInterest && allimage[0])) {
|
||||
return swal('Error!', 'All fields are required', 'error')
|
||||
|
||||
}
|
||||
setLoading(true);
|
||||
try {
|
||||
let res = await axios.put(
|
||||
`/api/requirement/update/${id}`, myForm,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": 'multipart/form-data',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
if (res.data.success === true) {
|
||||
swal("success!", "Requirements Updated Successfully!", "success");
|
||||
history.goBack();
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
setLoading(false);
|
||||
swal('Error!', error, 'error')
|
||||
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const onCancel = () => {
|
||||
history.goBack()
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-light min-vh-70 d-flex flex-row ">
|
||||
<CContainer>
|
||||
<CRow className="align-left w-140">
|
||||
<CCol md={19} lg={27} xl={16}>
|
||||
<CCard className="mx-4">
|
||||
<CCardBody className="p-4">
|
||||
<CForm>
|
||||
<h3 className="fst-italic mb-4 justify-content-center ">Edit Requirements</h3>
|
||||
<div>
|
||||
<div>
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilPencil} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
required
|
||||
maxlength="50"
|
||||
onChange={(e) => setTitle(e.target.value)}
|
||||
value={title}
|
||||
placeholder="Title (maximum 50 characters)" />
|
||||
</CInputGroup>
|
||||
{title ? <><i className="charLeft mt-4 fst-italic">
|
||||
{50 - title.length} characters left
|
||||
</i></> : <></>
|
||||
|
||||
}
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilObjectGroup} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
required
|
||||
onChange={(e) => setAreaOfInterest(e.target.value)}
|
||||
value={areaOfInterest}
|
||||
placeholder="Area Of Interest" />
|
||||
</CInputGroup>
|
||||
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilAudioDescription} />
|
||||
</CInputGroupText>
|
||||
<CFormInput type="text"
|
||||
maxlength="250"
|
||||
required
|
||||
onChange={(e) => setDescription(e.target.value)}
|
||||
value={description}
|
||||
placeholder="Description (maximum 250 characters)" />
|
||||
</CInputGroup>
|
||||
{description ? <><span className="charLeft mt-4 fst-italic">
|
||||
{250 - description.length} characters left
|
||||
</span></> : <></>
|
||||
|
||||
}
|
||||
|
||||
<CInputGroup className="mb-3">
|
||||
|
||||
{/* <CIcon icon={cilLockLocked} /> */}
|
||||
|
||||
<CFormInput
|
||||
type="file"
|
||||
required
|
||||
placeholder="image"
|
||||
accept="image/*"
|
||||
name="image"
|
||||
|
||||
multiple
|
||||
onChange={handleImage}
|
||||
|
||||
|
||||
/>
|
||||
</CInputGroup>
|
||||
<div><strong className="fs-6 fst-italic">*Please Upload maximum four 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 className=" d-flex">
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
type="button"
|
||||
className="btn btn-success btn-login waves-effect waves-light"
|
||||
|
||||
>
|
||||
<ClipLoader loading={loading} size={18} />
|
||||
{!loading && "Save"}
|
||||
</button>
|
||||
<button
|
||||
onClick={onCancel}
|
||||
type="button"
|
||||
className=" ml-2 btn btn-warning btn-cancel waves-effect waves-light"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</CForm>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CContainer>
|
||||
</div>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default EditRequirement
|
@ -1,25 +0,0 @@
|
||||
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="/requirement" className='page-link'>
|
||||
{number}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</nav>
|
||||
);
|
||||
};
|
||||
|
||||
export default Pagination;
|
@ -1,142 +0,0 @@
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useEffect, useState, useCallback, useMemo } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import swal from 'sweetalert';
|
||||
// import { API } from "../../data";
|
||||
import { isAutheticated } from "../../auth";
|
||||
import Pagination from "./Pagination";
|
||||
import RequirementOpt from "./RequirementOpt";
|
||||
|
||||
function Requirement() {
|
||||
const [requirement, setRequirement] = useState([])
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [postsPerPage] = useState(20);
|
||||
const token = isAutheticated();
|
||||
// console.log(token)
|
||||
const getRequirement = useCallback(async () => {
|
||||
let res = await axios.get(
|
||||
`/api/requirement/getAll`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
setRequirement(res.data.Requirement)
|
||||
|
||||
}, [token]);
|
||||
|
||||
useEffect(() => {
|
||||
getRequirement();
|
||||
}, [getRequirement]);
|
||||
|
||||
|
||||
const indexOfLastPost = currentPage * postsPerPage;
|
||||
const indexOfFirstPost = indexOfLastPost - postsPerPage;
|
||||
const currentPosts = requirement.slice(indexOfFirstPost, indexOfLastPost);
|
||||
|
||||
// Change page
|
||||
const paginate = pageNumber => setCurrentPage(pageNumber);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const handleApprove = async (id) => {
|
||||
let status = window.confirm("Do you want to Approve");
|
||||
if (!status) return;
|
||||
// console.log(email)
|
||||
try {
|
||||
let res = await axios.get(`/api/admin/requirement/approve/${id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
console.log(res.data)
|
||||
getRequirement()
|
||||
if (res.data.success == true) {
|
||||
swal("success!", "Requirement Approved !", "success");
|
||||
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
swal("Error:!", console.log(error), "error");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div className=" main-content">
|
||||
<div className=" my-3 page-content">
|
||||
<div className="container-fluid">
|
||||
{/* <!-- start page title --> */}
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<div className="page-title-box d-flex align-items-center justify-content-between">
|
||||
<h4 className="mb-3">CMP-Requirements</h4>
|
||||
<Link to="/requirement/add"><button type="button" className="btn btn-info float-end mb-3 ml-4"> + Add Requirements</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> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- end page title --> */}
|
||||
|
||||
<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>
|
||||
<div className="table-responsive table-shoot">
|
||||
<table className="table table-centered table-nowrap mb-0">
|
||||
<thead className="thead-light">
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>Image</th>
|
||||
<th>Area Of Interest</th>
|
||||
<th>Added By</th>
|
||||
<th>Added On</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{currentPosts && currentPosts.map((item, index) =>
|
||||
<RequirementOpt key={index} item={item} handleApprove={handleApprove} />
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
{/* <!-- end table-responsive --> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- container-fluid --> */}
|
||||
</div>
|
||||
<Pagination postsPerPage={postsPerPage}
|
||||
totalPosts={requirement.length}
|
||||
paginate={paginate} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Requirement;
|
@ -1,133 +0,0 @@
|
||||
import axios from "axios";
|
||||
import React, { useEffect, useState, useCallback, useMemo } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import swal from 'sweetalert';
|
||||
import { isAutheticated } from "../../auth";
|
||||
|
||||
|
||||
const RequirementOpt = ({ item, handleApprove }) => {
|
||||
const [user, setUser] = useState()
|
||||
const [approve, setApprove] = useState(false)
|
||||
const token = isAutheticated();
|
||||
|
||||
useEffect(async () => {
|
||||
let resp = await axios.get(
|
||||
`/api/v1/admin/user/${item.addedBy}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
setUser(resp.data.user)
|
||||
|
||||
///approved
|
||||
const getData = async () => {
|
||||
try {
|
||||
const response = await axios.get(`/api/requirement/getOne/${item._id}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
})
|
||||
// console.log(response.data)
|
||||
if (response.data.Requirement.approved === true) {
|
||||
setApprove(true)
|
||||
} else {
|
||||
setApprove(false)
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
setApprove(false)
|
||||
}
|
||||
}
|
||||
getData()
|
||||
}, [item]);
|
||||
|
||||
|
||||
|
||||
const handleDelete = async (id) => {
|
||||
let status = window.confirm("Do you want to delete");
|
||||
if (!status) return;
|
||||
|
||||
let res = await axios.delete(`/api/requirement/delete/${id}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
// console.log(res)
|
||||
if (res.data.success == true) {
|
||||
swal("success!", "Requirement Deleted Successfully!", "success");
|
||||
window.location.reload();
|
||||
}
|
||||
};
|
||||
//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 (
|
||||
<>
|
||||
<tr>
|
||||
<td>{item?.title}</td>
|
||||
<td>
|
||||
<img src={`${item.image[0]?.url}`} width="50" alt="" />
|
||||
</td>
|
||||
<td>{item?.areaOfInterest}</td>
|
||||
{user && <td>{user?.name}</td>}
|
||||
<td>
|
||||
{/* {item?.addedOn} */}
|
||||
{new Date(`${item?.createdAt}`).toDateString()}<span> , {`${formatAMPM(item?.createdAt)}`}</span>
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
<td>
|
||||
<button
|
||||
disabled={approve}
|
||||
type="button"
|
||||
onClick={() => handleApprove(`${item._id}`)}
|
||||
className={`mt-1 btn btn-${approve ? "success" : "warning"} btn-sm waves-effect waves-light btn-table ml-2`}
|
||||
id="sa-params"
|
||||
>
|
||||
{!approve ? "Approve" : "Approved"}
|
||||
</button>
|
||||
<Link to={`/requirement/view/${item._id}`}>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className=" mx-1 mt-1 btn btn-info btn-sm waves-effect waves-light btn-table ml-2"
|
||||
>
|
||||
View
|
||||
</button>
|
||||
</Link>
|
||||
<Link to={`/requirement/edit/${item._id}`}>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className=" mx-1 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="mx-1 mt-1 btn btn-danger btn-sm waves-effect waves-light btn-table ml-2"
|
||||
id="sa-params"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default RequirementOpt
|
@ -1,142 +0,0 @@
|
||||
|
||||
import axios from "axios";
|
||||
import React, { useEffect, useState, useCallback, useMemo } from "react";
|
||||
import swal from 'sweetalert';
|
||||
// import { API } from "../../data";
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import { isAutheticated } from "../../auth";
|
||||
|
||||
function ViewRequirement() {
|
||||
const [requirement, setRequirement] = useState([])
|
||||
const [allImage, setAllImage] = useState([])
|
||||
const { id } = useParams();
|
||||
// console.log(id)
|
||||
const token = isAutheticated();
|
||||
|
||||
const getUserDetails = useCallback(async () => {
|
||||
|
||||
|
||||
let resp = await axios.get(
|
||||
`/api/requirement/getOne/${id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
// console.log(resp.data.Requirement.image)
|
||||
setRequirement(resp.data.Requirement)
|
||||
setAllImage(resp.data.Requirement.image)
|
||||
|
||||
|
||||
}, [token]);
|
||||
|
||||
useEffect(() => {
|
||||
getUserDetails();
|
||||
}, [getUserDetails]);
|
||||
|
||||
|
||||
// allImage.map(item => {
|
||||
// console.log(item.url)
|
||||
// })
|
||||
|
||||
|
||||
//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">
|
||||
<div className="container-fluid">
|
||||
{/* <!-- start page title --> */}
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<div className="page-title-box d-flex align-items-center justify-content-between">
|
||||
<h4 className="mb-3">CMP-User Details</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- end page title --> */}
|
||||
|
||||
<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>
|
||||
<div className="table-responsive table-shoot">
|
||||
<table className="table table-centered table-nowrap mb-0">
|
||||
<thead className="thead-light">
|
||||
|
||||
<tr>
|
||||
<th>User_Id</th>
|
||||
|
||||
<td>{requirement?._id}</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr><th>Title</th>
|
||||
<td>{requirement?.title}</td></tr>
|
||||
|
||||
<tr><th>Area Of Interest</th>
|
||||
<td>{requirement?.areaOfInterest}</td></tr>
|
||||
|
||||
{/* <tr><th>Image</th>
|
||||
|
||||
<td className="d-flex">
|
||||
|
||||
<img src={`${requirement.image[0]?.url}`} width="50" alt="" />
|
||||
</td>
|
||||
|
||||
</tr> */}
|
||||
|
||||
|
||||
{/* <th>Description</th> */}
|
||||
|
||||
|
||||
<tr><th>Description</th>
|
||||
<td>{requirement?.description}</td></tr>
|
||||
|
||||
<tr><th>Added On</th>
|
||||
|
||||
<td>
|
||||
{new Date(`${requirement?.createdAt}`).toDateString()}<span> , {`${formatAMPM(requirement?.createdAt)}`}</span>
|
||||
</td></tr>
|
||||
<tr><th> Updated At</th>
|
||||
<td>
|
||||
{new Date(`${requirement?.updatedAt}`).toDateString()}<span> , {`${formatAMPM(requirement?.updatedAt)}`}</span>
|
||||
</td></tr>
|
||||
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
{/* <!-- end table-responsive --> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <!-- container-fluid --> */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ViewRequirement;
|
||||
|
@ -146,7 +146,7 @@ const Login = () => {
|
||||
<CCardBody>
|
||||
<CForm>
|
||||
<h1>Login</h1>
|
||||
<p className="text-medium-emphasis">Sign In to Your CMP Dashboard Account.</p>
|
||||
<p className="text-medium-emphasis">Sign In to Your ATP Dashboard Account.</p>
|
||||
<CInputGroup className="mb-3">
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilUser} />
|
||||
|
@ -40,7 +40,7 @@ const ForgotPassword = () => {
|
||||
|
||||
}
|
||||
} catch (e) {
|
||||
alert("Wrong Email ID. Enter valid email to get the password")
|
||||
swal('Error!', 'Wrong Email ID. Enter valid email to get the password', 'error')
|
||||
setLoading(false)
|
||||
|
||||
|
||||
|
@ -26,81 +26,10 @@ const WidgetsDropdown = ({ users, category, requirement, news, offer, event }) =
|
||||
</>
|
||||
}
|
||||
title="Total Users"
|
||||
// action={
|
||||
// <CDropdown alignment="end">
|
||||
// <CDropdownToggle color="transparent" caret={false} className="p-0">
|
||||
// <CIcon icon={cilOptions} className="text-high-emphasis-inverse" />
|
||||
// </CDropdownToggle>
|
||||
// <CDropdownMenu>
|
||||
// <CDropdownItem>Action</CDropdownItem>
|
||||
// <CDropdownItem>Another action</CDropdownItem>
|
||||
// <CDropdownItem>Something else here...</CDropdownItem>
|
||||
// <CDropdownItem disabled>Disabled action</CDropdownItem>
|
||||
// </CDropdownMenu>
|
||||
// </CDropdown>
|
||||
// }
|
||||
// chart={
|
||||
// <CChartLine
|
||||
// className="mt-3 mx-3"
|
||||
// style={{ height: '70px' }}
|
||||
// data={{
|
||||
// labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
|
||||
// datasets: [
|
||||
// {
|
||||
// label: 'My First dataset',
|
||||
// backgroundColor: 'transparent',
|
||||
// borderColor: 'rgba(255,255,255,.55)',
|
||||
// pointBackgroundColor: getStyle('--cui-primary'),
|
||||
// data: [65, 59, 84, 84, 51, 55, 40],
|
||||
// },
|
||||
// ],
|
||||
// }}
|
||||
// options={{
|
||||
// plugins: {
|
||||
// legend: {
|
||||
// display: false,
|
||||
// },
|
||||
// },
|
||||
// maintainAspectRatio: false,
|
||||
// scales: {
|
||||
// x: {
|
||||
// grid: {
|
||||
// display: false,
|
||||
// drawBorder: false,
|
||||
// },
|
||||
// ticks: {
|
||||
// display: false,
|
||||
// },
|
||||
// },
|
||||
// y: {
|
||||
// min: 30,
|
||||
// max: 89,
|
||||
// display: false,
|
||||
// grid: {
|
||||
// display: false,
|
||||
// },
|
||||
// ticks: {
|
||||
// display: false,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// elements: {
|
||||
// line: {
|
||||
// borderWidth: 1,
|
||||
// tension: 0.4,
|
||||
// },
|
||||
// point: {
|
||||
// radius: 4,
|
||||
// hitRadius: 10,
|
||||
// hoverRadius: 4,
|
||||
// },
|
||||
// },
|
||||
// }}
|
||||
// />
|
||||
// }
|
||||
|
||||
/>
|
||||
</CCol>
|
||||
<CCol sm={6} lg={3}>
|
||||
{/* <CCol sm={6} lg={3}>
|
||||
<CWidgetStatsA
|
||||
className="mb-4"
|
||||
color="info"
|
||||
@ -167,8 +96,8 @@ const WidgetsDropdown = ({ users, category, requirement, news, offer, event }) =
|
||||
}
|
||||
title="Total Events"
|
||||
|
||||
/>
|
||||
</CCol>
|
||||
/> */}
|
||||
{/* </CCol> */}
|
||||
</CRow>
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user