Merge pull request 'main' (#1) from main into master
Reviewed-on: http://128.199.30.231/possibillion/atp-admin/pulls/1
This commit is contained in:
commit
236dea4729
4
.env
4
.env
@ -1,2 +1,2 @@
|
|||||||
PORT=3000
|
PORT = 3000
|
||||||
CHOKIDAR_USEPOLLING=true
|
CHOKIDAR_USEPOLLING = true
|
BIN
.gitignore
vendored
BIN
.gitignore
vendored
Binary file not shown.
19
package.json
19
package.json
@ -25,18 +25,21 @@
|
|||||||
"test:cov": "npm test -- --coverage --watchAll=false",
|
"test:cov": "npm test -- --coverage --watchAll=false",
|
||||||
"test:debug": "react-scripts --inspect-brk test --runInBand",
|
"test:debug": "react-scripts --inspect-brk test --runInBand",
|
||||||
"heroku-postbuild": "npm run build"
|
"heroku-postbuild": "npm run build"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"coreui_library_short_version": "4.1"
|
"coreui_library_short_version": "4.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@ckeditor/ckeditor5-build-classic": "^35.2.1",
|
||||||
|
"@ckeditor/ckeditor5-react": "^5.0.2",
|
||||||
"@coreui/chartjs": "^3.0.0",
|
"@coreui/chartjs": "^3.0.0",
|
||||||
"@coreui/coreui": "^4.1.0",
|
"@coreui/coreui": "^4.1.0",
|
||||||
"@coreui/icons": "^2.1.0",
|
"@coreui/icons": "^2.1.0",
|
||||||
"@coreui/icons-react": "^2.0.0",
|
"@coreui/icons-react": "^2.0.0",
|
||||||
"@coreui/react": "^4.1.0",
|
"@coreui/react": "^4.3.0",
|
||||||
"@coreui/react-chartjs": "^2.0.0",
|
"@coreui/react-chartjs": "^2.0.0",
|
||||||
"@coreui/utils": "^1.3.1",
|
"@coreui/utils": "^1.3.1",
|
||||||
|
"@material-ui/core": "^4.12.4",
|
||||||
"@reduxjs/toolkit": "^1.8.2",
|
"@reduxjs/toolkit": "^1.8.2",
|
||||||
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.5",
|
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.5",
|
||||||
"axios": "^0.25.0",
|
"axios": "^0.25.0",
|
||||||
@ -48,19 +51,23 @@
|
|||||||
"enzyme": "^3.11.0",
|
"enzyme": "^3.11.0",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"react": "^17.0.2",
|
"react": "18.2",
|
||||||
"react-app-polyfill": "^2.0.0",
|
"react-app-polyfill": "^2.0.0",
|
||||||
|
"react-bootstrap": "^2.7.0",
|
||||||
"react-date-picker": "^8.4.0",
|
"react-date-picker": "^8.4.0",
|
||||||
"react-dom": "^17.0.2",
|
"react-datepicker": "^4.8.0",
|
||||||
|
"react-dom": "^18.0.0",
|
||||||
|
"react-paginate": "^8.1.3",
|
||||||
"react-redux": "^7.2.6",
|
"react-redux": "^7.2.6",
|
||||||
"react-router-dom": "^5.3.0",
|
"react-router-dom": "^6.7.0",
|
||||||
"react-spinners": "^0.11.0",
|
"react-spinners": "^0.11.0",
|
||||||
|
"react-time-picker": "^4.5.0",
|
||||||
"redux": "4.1.2",
|
"redux": "4.1.2",
|
||||||
"serve": "^13.0.2",
|
"serve": "^13.0.2",
|
||||||
"simplebar-react": "^2.3.6",
|
"simplebar-react": "^2.3.6",
|
||||||
"sweetalert": "^2.1.2",
|
"sweetalert": "^2.1.2",
|
||||||
"sweetalert2": "^11.4.0",
|
"sweetalert2": "^11.4.0",
|
||||||
"webpack": "^4.44.2",
|
"webpack": "4.44.2",
|
||||||
"xlsx": "^0.18.0"
|
"xlsx": "^0.18.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
<meta name="description" content="CoreUI for React - Open Source Bootstrap Admin Template">
|
<meta name="description" content="CoreUI for React - Open Source Bootstrap Admin Template">
|
||||||
<meta name="author" content="Łukasz Holeczek">
|
<meta name="author" content="Łukasz Holeczek">
|
||||||
<meta name="keyword" content="Bootstrap,Admin,Template,Open,Source,CSS,SCSS,HTML,RWD,Dashboard,React">
|
<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
|
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/
|
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
|
||||||
@ -23,6 +23,8 @@
|
|||||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
||||||
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
|
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
|
||||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
|
||||||
|
<link rel="react" href="https://coreui.io/react/">
|
||||||
|
|
||||||
<!-- <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script> -->
|
<!-- <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script> -->
|
||||||
<!--
|
<!--
|
||||||
Notice the use of %PUBLIC_URL% in the tags above.
|
Notice the use of %PUBLIC_URL% in the tags above.
|
||||||
|
@ -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,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
87
src/App.js
87
src/App.js
@ -1,11 +1,13 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component, Suspense } from 'react'
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { BrowserRouter, Route, Switch } from 'react-router-dom'
|
import { Router, Route, Routes, HashRouter } from 'react-router-dom'
|
||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import './scss/style.scss'
|
import './scss/style.scss'
|
||||||
import ForgotPassword from './views/pages/register/ForgotPassword'
|
import ForgotPassword from './views/pages/register/ForgotPassword'
|
||||||
import NewRegister from './views/pages/register/NewRegister'
|
import NewRegister from './views/pages/register/NewRegister'
|
||||||
import ProtectedRoute from './components/ProtectedRoute';
|
import ProtectedRoute from './components/ProtectedRoute';
|
||||||
|
import { isAutheticated } from './auth';
|
||||||
|
|
||||||
|
|
||||||
const loading = (
|
const loading = (
|
||||||
<div className="pt-3 text-center">
|
<div className="pt-3 text-center">
|
||||||
@ -19,36 +21,69 @@ const DefaultLayout = React.lazy(() => import('./layout/DefaultLayout'))
|
|||||||
// Pages
|
// Pages
|
||||||
const Login = React.lazy(() => import('./views/pages/login/Login'))
|
const Login = React.lazy(() => import('./views/pages/login/Login'))
|
||||||
const Register = React.lazy(() => import('./views/pages/register/Change_password'))
|
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 Page500 = React.lazy(() => import('./views/pages/page500/Page500'))
|
||||||
|
|
||||||
class App extends Component {
|
const App = () => {
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<BrowserRouter>
|
|
||||||
<React.Suspense fallback={loading}>
|
|
||||||
<Switch>
|
|
||||||
< Route exact path="/" name="Login Page" render={(props) => <Login {...props} />} />
|
|
||||||
|
|
||||||
<Route exact path="/forgot" name="Forgot Page" render={(props) => <ForgotPassword {...props} />} />
|
const [userdata, setUserData] = useState(null)
|
||||||
<Route exact path="/newRegister" name="Register Page" render={(props) => <NewRegister {...props} />} />
|
const token = isAutheticated();
|
||||||
|
|
||||||
<Route exact path="/404" name="Page 404" render={(props) => <Page404 {...props} />} />
|
useEffect(() => {
|
||||||
<Route exact path="/500" name="Page 500" render={(props) => <Page500 {...props} />} />
|
const getUser = async () => {
|
||||||
|
let existanceData = localStorage.getItem("authToken");
|
||||||
|
if (!existanceData) {
|
||||||
|
// console.log(existanceData.userData)
|
||||||
|
setUserData(false)
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
// console.log('requesting user data from server')
|
||||||
|
let response = await axios.get(`/api/v1/user/details`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
// console.log(response.data)
|
||||||
|
const data = response.data
|
||||||
|
if (data.success && data.user.role === 'admin') {
|
||||||
|
|
||||||
|
setUserData(data.user);
|
||||||
|
} else {
|
||||||
|
setUserData(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
setUserData(false)
|
||||||
|
console.log(err);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
getUser()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
|
||||||
|
<HashRouter>
|
||||||
|
<Suspense fallback={loading}>
|
||||||
|
<Routes>
|
||||||
|
<Route exact path="/" name="Login Page" element={<Login />} />
|
||||||
|
<Route exact path="/register" name="Register Page" element={<NewRegister />} />
|
||||||
|
<Route exact path="/password/forgot" name="Forgot Page" element={<ForgotPassword />} />
|
||||||
|
<Route exact path="/404" name="Page 404" element={<Page404 />} />
|
||||||
|
<Route exact path="/500" name="Page 500" element={<Page500 />} />
|
||||||
|
|
||||||
|
<Route path="/" name="Home" element={userdata?.role === "admin" ? <DefaultLayout />
|
||||||
|
:
|
||||||
|
userdata === false ? <Login /> : <div></div>} />
|
||||||
|
|
||||||
|
|
||||||
{/* localStorage.getItem('authToken') ? */}
|
<Route path="*" name="Home" element={<DefaultLayout />} />
|
||||||
<Route path="/" name="Home" render={(props) => <DefaultLayout {...props} />} />
|
</Routes>
|
||||||
{/* < ProtectedRoute path="/" name="Home" render={(props) => <DefaultLayout {...props} />} /> */}
|
</Suspense>
|
||||||
|
</HashRouter>
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
</Switch>
|
|
||||||
</React.Suspense>
|
|
||||||
</BrowserRouter>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//@coreui/coreui-free-react-admin-template@4.1.1
|
|
||||||
export default App
|
export default App
|
||||||
|
106
src/_nav.js
106
src/_nav.js
@ -1,19 +1,32 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import CIcon from '@coreui/icons-react'
|
import CIcon from '@coreui/icons-react'
|
||||||
import {
|
import {
|
||||||
|
cilAddressBook,
|
||||||
|
cilAppsSettings,
|
||||||
cilBell,
|
cilBell,
|
||||||
cilCalculator,
|
cilCalculator,
|
||||||
cilChartPie,
|
cilChartPie,
|
||||||
|
cilClipboard,
|
||||||
|
cilCommand,
|
||||||
cilCursor,
|
cilCursor,
|
||||||
cilDrop,
|
cilDrop,
|
||||||
|
cilFace,
|
||||||
|
cilFilterSquare,
|
||||||
|
cilMedicalCross,
|
||||||
cilMoney,
|
cilMoney,
|
||||||
|
cilMugTea,
|
||||||
cilNewspaper,
|
cilNewspaper,
|
||||||
cilNotes,
|
cilNotes,
|
||||||
cilPencil,
|
cilPencil,
|
||||||
cilPuzzle,
|
cilPuzzle,
|
||||||
|
cilSitemap,
|
||||||
cilSpeedometer,
|
cilSpeedometer,
|
||||||
cilStar,
|
cilStar,
|
||||||
|
cilTablet,
|
||||||
|
cilTennisBall,
|
||||||
cilUser,
|
cilUser,
|
||||||
|
|
||||||
|
|
||||||
} from '@coreui/icons'
|
} from '@coreui/icons'
|
||||||
import { CNavGroup, CNavItem, CNavTitle } from '@coreui/react'
|
import { CNavGroup, CNavItem, CNavTitle } from '@coreui/react'
|
||||||
|
|
||||||
@ -28,22 +41,97 @@ const _nav = [
|
|||||||
|
|
||||||
{
|
{
|
||||||
component: CNavItem,
|
component: CNavItem,
|
||||||
name: 'Category',
|
name: 'Products',
|
||||||
icon: <CIcon icon={cilPencil} customClassName="nav-icon" />,
|
icon: <CIcon icon={cilClipboard} customClassName="nav-icon" />,
|
||||||
to: '/category',
|
to: '/products',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: CNavItem,
|
component: CNavItem,
|
||||||
name: 'Directory',
|
name: 'Temples',
|
||||||
icon: <CIcon icon={cilDrop} customClassName="nav-icon" />,
|
icon: <CIcon icon={cilTennisBall} customClassName="nav-icon" />,
|
||||||
to: '/bisuness',
|
to: '/temples',
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
component: CNavItem,
|
component: CNavItem,
|
||||||
name: 'News',
|
name: 'Users',
|
||||||
icon: <CIcon icon={cilNewspaper} customClassName="nav-icon" />,
|
icon: <CIcon icon={cilUser} customClassName="nav-icon" />,
|
||||||
to: '/news',
|
to: '/users',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
component: CNavGroup,
|
||||||
|
name: 'Configuration',
|
||||||
|
icon: <CIcon icon={cilAppsSettings} customClassName="nav-icon" />,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
component: CNavItem,
|
||||||
|
name: 'Cities',
|
||||||
|
icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
||||||
|
to: '/cities',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: CNavItem,
|
||||||
|
name: 'States',
|
||||||
|
icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
||||||
|
to: '/states',
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// component: CNavItem,
|
||||||
|
// name: 'Standard Shipping',
|
||||||
|
// icon: <CIcon icon={cilCommand} customClassName="nav-icon" />,
|
||||||
|
// to: '/shipping',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// component: CNavItem,
|
||||||
|
// name: 'Custom Shipping',
|
||||||
|
// icon: <CIcon icon={cilCommand} customClassName="nav-icon" />,
|
||||||
|
// to: '/custom-shipping',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// component: CNavItem,
|
||||||
|
// name: 'Pincode',
|
||||||
|
// icon: <CIcon icon={cilCommand} customClassName="nav-icon" />,
|
||||||
|
// to: '/pincode',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// component: CNavItem,
|
||||||
|
// name: 'Tax Rates',
|
||||||
|
// icon: <CIcon icon={cilCommand} customClassName="nav-icon" />,
|
||||||
|
// to: '/tax',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// component: CNavItem,
|
||||||
|
// name: 'Pages',
|
||||||
|
// icon: <CIcon icon={cilCommand} customClassName="nav-icon" />,
|
||||||
|
// to: '/page',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// component: CNavItem,
|
||||||
|
// name: 'Terms of Use',
|
||||||
|
// icon: <CIcon icon={cilCommand} customClassName="nav-icon" />,
|
||||||
|
// to: '/terms_of_use',
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
component: CNavItem,
|
||||||
|
name: 'Social Media',
|
||||||
|
icon: <CIcon icon={cilMedicalCross} customClassName="nav-icon" />,
|
||||||
|
to: '/socialmedia',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: CNavItem,
|
||||||
|
name: 'Address',
|
||||||
|
icon: <CIcon icon={cilAddressBook} customClassName="nav-icon" />,
|
||||||
|
to: '/address',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: CNavItem,
|
||||||
|
name: 'Logos',
|
||||||
|
icon: <CIcon icon={cilCommand} customClassName="nav-icon" />,
|
||||||
|
to: '/logo',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
]
|
]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { Suspense } from 'react'
|
import React, { Suspense } from 'react'
|
||||||
import { Redirect, Route, Switch } from 'react-router-dom'
|
import { Navigate, Route, Routes } from 'react-router-dom'
|
||||||
import { CContainer, CSpinner } from '@coreui/react'
|
import { CContainer, CSpinner } from '@coreui/react'
|
||||||
|
|
||||||
// routes config
|
// routes config
|
||||||
@ -9,26 +9,22 @@ const AppContent = () => {
|
|||||||
return (
|
return (
|
||||||
<CContainer lg>
|
<CContainer lg>
|
||||||
<Suspense fallback={<CSpinner color="primary" />}>
|
<Suspense fallback={<CSpinner color="primary" />}>
|
||||||
<Switch>
|
<Routes>
|
||||||
{routes.map((route, idx) => {
|
{routes.map((route, idx) => {
|
||||||
return (
|
return (
|
||||||
route.component && (
|
route.element && (
|
||||||
<Route
|
<Route
|
||||||
key={idx}
|
key={idx}
|
||||||
path={route.path}
|
path={route.path}
|
||||||
exact={route.exact}
|
exact={route.exact}
|
||||||
name={route.name}
|
name={route.name}
|
||||||
render={(props) => (
|
element={<route.element />}
|
||||||
<>
|
|
||||||
<route.component {...props} />
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
<Redirect from="/" to="/dashboard" />
|
<Route path="/" element={<Navigate to="dashboard" replace />} />
|
||||||
</Switch>
|
</Routes>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</CContainer>
|
</CContainer>
|
||||||
)
|
)
|
||||||
|
@ -6,9 +6,9 @@ const AppFooter = () => {
|
|||||||
<CFooter>
|
<CFooter>
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
<span className="ms-1">{new Date().getFullYear()} © CMP.</span>
|
<span className="ms-1">{new Date().getFullYear()} © Any Time Prasad ( ATP ) .</span>
|
||||||
</div>
|
</div>
|
||||||
\
|
|
||||||
</CFooter>
|
</CFooter>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -32,12 +32,12 @@ const AppHeader = () => {
|
|||||||
<CIcon icon={cilMenu} size="lg" />
|
<CIcon icon={cilMenu} size="lg" />
|
||||||
</CHeaderToggler>
|
</CHeaderToggler>
|
||||||
<CHeaderBrand className="mx-auto d-md-none" to="/">
|
<CHeaderBrand className="mx-auto d-md-none" to="/">
|
||||||
<h1>Courier</h1>
|
<h3>Any Time Prasad</h3>
|
||||||
</CHeaderBrand>
|
</CHeaderBrand>
|
||||||
<CHeaderNav className="d-none d-md-flex me-auto">
|
<CHeaderNav className="d-none d-md-flex me-auto">
|
||||||
<CNavItem>
|
<CNavItem>
|
||||||
<CNavLink to="/dashboard" component={NavLink} activeClassName="active">
|
<CNavLink to="/dashboard" component={NavLink} activeClassName="active">
|
||||||
Dashboard
|
ATP Dashboard
|
||||||
</CNavLink>
|
</CNavLink>
|
||||||
</CNavItem>
|
</CNavItem>
|
||||||
{/* <CNavItem>
|
{/* <CNavItem>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import { useSelector, useDispatch } from 'react-redux'
|
import { useSelector, useDispatch } from 'react-redux'
|
||||||
|
|
||||||
import { CSidebar, CSidebarBrand, CSidebarNav, CSidebarToggler } from '@coreui/react'
|
import { CSidebar, CSidebarBrand, CSidebarNav, CSidebarToggler } from '@coreui/react'
|
||||||
@ -14,12 +14,45 @@ import 'simplebar/dist/simplebar.min.css'
|
|||||||
|
|
||||||
// sidebar nav config
|
// sidebar nav config
|
||||||
import navigation from '../_nav'
|
import navigation from '../_nav'
|
||||||
|
import { isAutheticated } from 'src/auth'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
|
||||||
const AppSidebar = () => {
|
const AppSidebar = () => {
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
const unfoldable = useSelector((state) => state.sidebarUnfoldable)
|
const unfoldable = useSelector((state) => state.sidebarUnfoldable)
|
||||||
const sidebarShow = useSelector((state) => state.sidebarShow)
|
const sidebarShow = useSelector((state) => state.sidebarShow)
|
||||||
|
|
||||||
|
///----------------------//
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
|
||||||
|
const token = isAutheticated()
|
||||||
|
|
||||||
|
// urlcreated images
|
||||||
|
|
||||||
|
const [HeaderlogoUrl, setHeaderlogoUrl] = useState('')
|
||||||
|
const [FooterlogoUrl, setFooterlogoUrl] = useState('')
|
||||||
|
const [AdminlogoUrl, setAdminlogoUrl] = useState('')
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
async function getConfiguration() {
|
||||||
|
const configDetails = await axios.get(`/api/config`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
console.log(configDetails.data.result)
|
||||||
|
configDetails.data.result.map((item) => {
|
||||||
|
setHeaderlogoUrl(item?.logo[0]?.Headerlogo)
|
||||||
|
setFooterlogoUrl(item?.logo[0]?.Footerlogo)
|
||||||
|
setAdminlogoUrl(item?.logo[0]?.Adminlogo)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
getConfiguration()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
console.log(HeaderlogoUrl)
|
||||||
|
//---------------------------//
|
||||||
return (
|
return (
|
||||||
<CSidebar
|
<CSidebar
|
||||||
position="fixed"
|
position="fixed"
|
||||||
@ -29,9 +62,10 @@ const AppSidebar = () => {
|
|||||||
dispatch({ type: 'set', sidebarShow: visible })
|
dispatch({ type: 'set', sidebarShow: visible })
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CSidebarBrand className="d-none bg-info d-md-flex" to="/">
|
<CSidebarBrand className="d-none d-md-flex" style={{ background: 'rgb(140, 213, 213)' }} to="/">
|
||||||
{/* <CIcon className="sidebar-brand-full" icon={logoNegative} height={35} /> */}
|
{/* <CIcon className="sidebar-brand-full" icon={logoNegative} height={35} /> */}
|
||||||
<h1>CMP</h1>
|
|
||||||
|
{HeaderlogoUrl ? <Link to='/dashboard'><img src={HeaderlogoUrl} alt={`${<h1>ATP Dashboard</h1>}`} /></Link> : <h1>ATP Dashboard</h1>}
|
||||||
{/* <CIcon className="sidebar-brand-narrow" height={35} /> */}
|
{/* <CIcon className="sidebar-brand-narrow" height={35} /> */}
|
||||||
<CIcon className="sidebar-brand-narrow" icon={sygnet} height={35} />
|
<CIcon className="sidebar-brand-narrow" icon={sygnet} height={35} />
|
||||||
</CSidebarBrand>
|
</CSidebarBrand>
|
||||||
|
@ -53,6 +53,7 @@ export const AppSidebarNav = ({ items }) => {
|
|||||||
{...rest}
|
{...rest}
|
||||||
>
|
>
|
||||||
{item.items?.map((item, index) =>
|
{item.items?.map((item, index) =>
|
||||||
|
|
||||||
item.items ? navGroup(item, index) : navItem(item, index),
|
item.items ? navGroup(item, index) : navItem(item, index),
|
||||||
)}
|
)}
|
||||||
</Component>
|
</Component>
|
||||||
@ -62,7 +63,8 @@ export const AppSidebarNav = ({ items }) => {
|
|||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{items &&
|
{items &&
|
||||||
items.map((item, index) => (item.items ? navGroup(item, index) : navItem(item, index)))}
|
items.map((item, index) =>
|
||||||
|
(item.items ? navGroup(item, index) : navItem(item, index)))}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import React, { useEffect, useState, } from "react";
|
import React, { useEffect, useState, } from "react";
|
||||||
import { useHistory } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
const ProtectedRoute = (props) => {
|
const ProtectedRoute = (props) => {
|
||||||
let Cmp = props;
|
let Cmp = props;
|
||||||
const history = useHistory();
|
const history = useNavigate();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!localStorage.getItem('authToken'))
|
if (!localStorage.getItem('authToken'))
|
||||||
history.push('/')
|
history('/')
|
||||||
}, [])
|
}, [])
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -24,26 +24,56 @@ import {
|
|||||||
import CIcon from '@coreui/icons-react'
|
import CIcon from '@coreui/icons-react'
|
||||||
import swal from 'sweetalert';
|
import swal from 'sweetalert';
|
||||||
|
|
||||||
import avatar8 from './../../assets/images/avatars/8.jpg'
|
import userImage from './../../assets/images/avatars/1.jpg'
|
||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
// import { signout } from 'src/auth'
|
// import { signout } from 'src/auth'
|
||||||
import { useHistory } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
|
||||||
const AppHeaderDropdown = () => {
|
const AppHeaderDropdown = () => {
|
||||||
let history = useHistory();
|
const [userData, setUserData] = useState()
|
||||||
|
let history = useNavigate();
|
||||||
const signout = async () => {
|
const signout = async () => {
|
||||||
localStorage.removeItem('authToken')
|
localStorage.removeItem('authToken')
|
||||||
// let res = await axios.get(
|
|
||||||
// `http://localhost:5000/api/user/logOut`
|
|
||||||
// );
|
|
||||||
// if (res.success == true) {
|
|
||||||
swal("success!", "Logged Out", "success");
|
swal("success!", "Logged Out", "success");
|
||||||
history.push("/");
|
history("/");
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//for user image
|
||||||
|
|
||||||
|
const getUser = async () => {
|
||||||
|
let token = localStorage.getItem("authToken");
|
||||||
|
try {
|
||||||
|
let response = await axios.get(`/api/v1/user/details`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if (response.data.success === true) {
|
||||||
|
setUserData(response.data.user)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
|
||||||
|
console.log(err);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getUser()
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CDropdown variant="nav-item">
|
<CDropdown variant="nav-item">
|
||||||
<CDropdownToggle placement="bottom-end" className="py-0" caret={false}>
|
<CDropdownToggle placement="bottom-end" className="py-0" caret={false}>
|
||||||
<CAvatar src={avatar8} size="md" />
|
{/* {userData && userData ? <CAvatar src={userData.avatar.url} size="md" /> : */}
|
||||||
|
<CAvatar src={userImage} size="md" />
|
||||||
</CDropdownToggle>
|
</CDropdownToggle>
|
||||||
<CDropdownMenu className="pt-0" placement="bottom-end">
|
<CDropdownMenu className="pt-0" placement="bottom-end">
|
||||||
<CDropdownHeader className="bg-light fw-semibold py-2">Account</CDropdownHeader>
|
<CDropdownHeader className="bg-light fw-semibold py-2">Account</CDropdownHeader>
|
||||||
@ -99,6 +129,12 @@ const AppHeaderDropdown = () => {
|
|||||||
</CBadge> */}
|
</CBadge> */}
|
||||||
</CDropdownItem>
|
</CDropdownItem>
|
||||||
{/* <CDropdownDivider /> */}
|
{/* <CDropdownDivider /> */}
|
||||||
|
<Link to='/profile/edit'>
|
||||||
|
<CDropdownItem>
|
||||||
|
<CIcon icon={cilUser} className="me-2" />
|
||||||
|
Edit Profile
|
||||||
|
</CDropdownItem>
|
||||||
|
</Link>
|
||||||
<Link to='/change_password'>
|
<Link to='/change_password'>
|
||||||
<CDropdownItem>
|
<CDropdownItem>
|
||||||
<CIcon icon={cilPencil} className="me-2" />
|
<CIcon icon={cilPencil} className="me-2" />
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
|
import '@coreui/coreui/dist/css/coreui.min.css';
|
||||||
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
import 'react-app-polyfill/stable'
|
import 'react-app-polyfill/stable'
|
||||||
import 'core-js'
|
import 'core-js'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
@ -10,7 +11,7 @@ import store from './store'
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
const setupAxios = () => {
|
const setupAxios = () => {
|
||||||
axios.defaults.baseURL = 'https://cms-api-dashboard.herokuapp.com/';
|
axios.defaults.baseURL = 'https://atpapi.checkapp.one'
|
||||||
//axios.defaults.baseURL = 'http://localhost:5000'
|
//axios.defaults.baseURL = 'http://localhost:5000'
|
||||||
axios.defaults.headers = {
|
axios.defaults.headers = {
|
||||||
'Cache-Control': 'no-cache,no-store',
|
'Cache-Control': 'no-cache,no-store',
|
||||||
|
@ -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;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
101
src/routes.js
101
src/routes.js
@ -1,50 +1,83 @@
|
|||||||
import React from 'react'
|
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"
|
|
||||||
|
|
||||||
// DashBoard
|
// DashBoard
|
||||||
const Change_Password = React.lazy(() => import('./views/pages/register/Change_password'))
|
const Change_Password = React.lazy(() => import('./views/pages/register/Change_password'))
|
||||||
const EditProfile = React.lazy(() => import('./views/Profile/EditProfile'))
|
|
||||||
const Dashboard = React.lazy(() => import('./views/dashboard/Dashboard'))
|
|
||||||
|
|
||||||
|
|
||||||
|
import Profile from './views/Profile/Profile'
|
||||||
|
import EditProfile from './views/Profile/EditProfile'
|
||||||
|
const Dashboard = React.lazy(() => import('./views/dashboard/Dashboard'))
|
||||||
|
///
|
||||||
|
//Cities
|
||||||
|
import Cities from './views/configuration/cities/Cities.js'
|
||||||
|
import AddCity from './views/configuration/cities/AddCity.js'
|
||||||
|
import EditCity from './views/configuration/cities/EditCity.js'
|
||||||
|
//states
|
||||||
|
import EditState from './views/configuration/states/EditStates.js'
|
||||||
|
import AddState from './views/configuration/states/AddState.js'
|
||||||
|
import States from './views/configuration/states/States.js'
|
||||||
|
//social media,address,logo
|
||||||
|
import Socialmedia from './views/configuration/Socialmedia.js'
|
||||||
|
import Address from './views/configuration/Address.js'
|
||||||
|
import Logo from './views/configuration/Logo.js'
|
||||||
|
import Login from './views/pages/login/Login'
|
||||||
|
//temple
|
||||||
|
import Temples from './views/Temples/Temples'
|
||||||
|
import AddTemple from './views/Temples/AddTemple'
|
||||||
|
import EditTemple from './views/Temples/EditTemple'
|
||||||
|
import Products from './views/Products/Products'
|
||||||
|
//product
|
||||||
|
import AddProduct from './views/Products/AddProduct'
|
||||||
|
import EditProduct from './views/Products/EditProduct'
|
||||||
|
import ViewProduct from './views/Products/ViewProduct'
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
|
|
||||||
{ path: '/', exact: true, name: 'Home' },
|
{ path: '/', exact: true, name: 'Home' },
|
||||||
{ path: '/change_password', name: 'Change Password', component: Change_Password },
|
{ path: '/change_password', name: 'Change Password', element: Change_Password },
|
||||||
{ path: '/edit', name: 'Change Password', component: EditProfile },
|
{ path: '/profile/edit', name: 'Edit Profile', element: EditProfile },
|
||||||
// { path: '/profile', name: 'Change Password', component: Profile },
|
// { path: '/profile', name: 'Profile', element: 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
|
//Product
|
||||||
{ path: '/view_bisuness/:id', name: 'view_bisuness_directory', component: View_Business },
|
{ path: '/products', name: 'products', element: Products },
|
||||||
{ path: '/add_bisuness', name: 'Add_bisuness_directory', component: Add_Business },
|
{ path: '/product/add', name: 'Add products', element: AddProduct },
|
||||||
{ path: '/bisuness/edit/:id', name: 'EditBisuness', component: EditBisuness },
|
{ path: '/product/edit/:id', name: 'Edit products', element: EditProduct },
|
||||||
{ path: '/bisuness', name: 'bisuness', component: Bisuness },
|
{ path: '/product/view/:id', name: 'view products', element: ViewProduct },
|
||||||
//News route
|
|
||||||
{ path: '/news/view/:id', name: 'ViewNews', component: ViewNews },
|
|
||||||
{ path: '/addNews', name: 'addNews', component: AddNews },
|
|
||||||
{ path: '/news/edit/:id', name: 'EditNews', component: EditNews },
|
//Temple
|
||||||
{ path: '/news', name: 'news', component: News },
|
{ path: '/temples', name: 'Temples', element: Temples },
|
||||||
|
{ path: '/temple/add', name: 'Add Temple', element: AddTemple },
|
||||||
|
{ path: '/temple/edit/:id', name: 'Edit Temples', element: EditTemple },
|
||||||
|
|
||||||
//dashboard
|
//dashboard
|
||||||
{ path: '/dashboard', name: 'Dashboard', component: Dashboard },
|
|
||||||
|
{ path: '/dashboard', name: 'Dashboard', element: Dashboard },
|
||||||
|
|
||||||
|
//------------settings------------------------//
|
||||||
|
//cities
|
||||||
|
{ path: '/cities', name: 'Cities', element: Cities },
|
||||||
|
{ path: '/cities/add', name: 'Add City', element: AddCity },
|
||||||
|
{ path: '/cities/edit/:id', name: 'Edit City', element: EditCity },
|
||||||
|
//states
|
||||||
|
{ path: '/states', name: 'States', element: States },
|
||||||
|
{ path: '/states/add', name: 'Add State', element: AddState },
|
||||||
|
{ path: '/states/edit/:id', name: 'Edit State', element: EditState },
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
{ path: '/socialmedia', name: 'Social Media', element: Socialmedia },
|
||||||
|
{ path: '/address', name: 'Address', element: Address },
|
||||||
|
{ path: '/logo', name: 'Logo', element: Logo },
|
||||||
|
// -------------------------------------------//
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
export default routes
|
export default routes
|
||||||
|
@ -2,5 +2,5 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
@include ltr-rtl("padding-left", var(--cui-sidebar-occupy-start, 0));
|
@include ltr-rtl("padding-left", var(--cui-sidebar-occupy-start, 0));
|
||||||
will-change: auto;
|
will-change: auto;
|
||||||
@include transition(padding .15s);
|
@include transition(padding .15s);
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
// If you want to override variables do it here
|
|
||||||
@import "variables";
|
@import "variables";
|
||||||
|
|
||||||
$enable-ltr: true;
|
$enable-ltr: true;
|
||||||
$enable-rtl: true;
|
$enable-rtl: true;
|
||||||
|
|
||||||
// Import CoreUI for React components library
|
|
||||||
@import "@coreui/coreui/scss/coreui";
|
|
||||||
|
|
||||||
|
// Import CoreUI for React components library
|
||||||
|
//@import "@coreui/coreui/scss/coreui";
|
||||||
// Import Chart.js custom tooltips styles
|
// Import Chart.js custom tooltips styles
|
||||||
@import "@coreui/chartjs/scss/coreui-chartjs";
|
@import "@coreui/chartjs/scss/coreui-chartjs";
|
||||||
|
//@import "@coreui/chartjs";
|
||||||
|
|
||||||
@import "layout";
|
@import "layout";
|
||||||
@import "example";
|
@import "example";
|
||||||
|
|
||||||
// If you want to add custom CSS you can put it here.
|
// If you want to add custom CSS you can put it here.
|
||||||
@import "custom";
|
@import "custom";
|
48
src/store.js
48
src/store.js
@ -1,31 +1,31 @@
|
|||||||
// import { createStore } from 'redux'
|
import { createStore } from 'redux'
|
||||||
|
|
||||||
// const initialState = {
|
const initialState = {
|
||||||
// sidebarShow: true,
|
sidebarShow: true,
|
||||||
// }
|
}
|
||||||
|
|
||||||
// const changeState = (state = initialState, { type, ...rest }) => {
|
const changeState = (state = initialState, { type, ...rest }) => {
|
||||||
// switch (type) {
|
switch (type) {
|
||||||
// case 'set':
|
case 'set':
|
||||||
// return { ...state, ...rest }
|
return { ...state, ...rest }
|
||||||
// default:
|
default:
|
||||||
// return state
|
return state
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// const store = createStore(changeState)
|
const store = createStore(changeState)
|
||||||
// export default store
|
export default store
|
||||||
import { configureStore } from "@reduxjs/toolkit";
|
// import { configureStore } from "@reduxjs/toolkit";
|
||||||
import { newCategoryReducer, AllcategoryReducer } from "./reducers/categoryReducer.js";
|
// import { newCategoryReducer, AllcategoryReducer } from "./reducers/categoryReducer.js";
|
||||||
import { loginReducer } from "./reducers/directoryReducer.js";
|
// import { loginReducer } from "./reducers/directoryReducer.js";
|
||||||
|
|
||||||
const store = configureStore({
|
// const store = configureStore({
|
||||||
reducer: {
|
// reducer: {
|
||||||
|
|
||||||
newCategory: newCategoryReducer,
|
// newCategory: newCategoryReducer,
|
||||||
AllCategory: AllcategoryReducer,
|
// AllCategory: AllcategoryReducer,
|
||||||
|
|
||||||
},
|
// },
|
||||||
});
|
// });
|
||||||
|
|
||||||
export default store;
|
// export default store;
|
@ -1,141 +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 [name, setName] = useState("");
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
|
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
|
||||||
const myForm = new FormData();
|
|
||||||
|
|
||||||
myForm.set("name", name);
|
|
||||||
|
|
||||||
|
|
||||||
myForm.set("image", image);
|
|
||||||
setLoading({ loading: true });
|
|
||||||
// console.log(image)
|
|
||||||
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");
|
|
||||||
history.goBack();
|
|
||||||
}
|
|
||||||
|
|
||||||
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>
|
|
||||||
|
|
||||||
<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 AddProduct
|
|
@ -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";
|
|
||||||
|
|
||||||
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[0].image.url)
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//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-Category</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>Image</th>
|
|
||||||
<th>Added On</th>
|
|
||||||
<th>Actions</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{category && category.map((item, index) =>
|
|
||||||
<tr>
|
|
||||||
<td>{item?.name}</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={`/category/edit/${item._id}`}>
|
|
||||||
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className=" mx-2 btn btn-primary btn-sm waves-effect waves-light btn-table ml-2"
|
|
||||||
>
|
|
||||||
Edit
|
|
||||||
</button>
|
|
||||||
</Link>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => handleDelete(`${item._id}`)}
|
|
||||||
className=" btn btn-danger btn-sm waves-effect waves-light btn-table ml-2"
|
|
||||||
id="sa-params"
|
|
||||||
>
|
|
||||||
Delete
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{/* <!-- end table-responsive --> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/* <!-- container-fluid --> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Products;
|
|
@ -1,152 +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 [loading, setLoading] = useState(false);
|
|
||||||
useEffect(async () => {
|
|
||||||
const res = await axios.get(`/api/category/getOne/${id}`, {
|
|
||||||
// headers: {
|
|
||||||
// Authorization: `Bearer ${token}`,
|
|
||||||
// },
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
setName(res.data.category.name)
|
|
||||||
}, [id]);
|
|
||||||
|
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
|
||||||
const myForm = new FormData();
|
|
||||||
|
|
||||||
myForm.set("name", name);
|
|
||||||
|
|
||||||
|
|
||||||
myForm.set("image", image);
|
|
||||||
setLoading({ loading: true });
|
|
||||||
// console.log(image)
|
|
||||||
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");
|
|
||||||
history.goBack();
|
|
||||||
}
|
|
||||||
|
|
||||||
setLoading(false);
|
|
||||||
};
|
|
||||||
const handleImage = (e) => {
|
|
||||||
const files = e.target.files[0];
|
|
||||||
// console.log(files)
|
|
||||||
setImage(files);
|
|
||||||
|
|
||||||
};
|
|
||||||
//
|
|
||||||
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 {name} 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>
|
|
||||||
|
|
||||||
<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 AddProduct
|
|
@ -1,464 +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 { 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 (!(name || description || phone || email || Bname || Sname || city)) {
|
|
||||||
alert("Please fill required field ");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
changeState({ loading: true });
|
|
||||||
|
|
||||||
let res = await axios.post(
|
|
||||||
`/api/directory/create/`,
|
|
||||||
{
|
|
||||||
...state,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
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"
|
|
||||||
>
|
|
||||||
Category*
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<select
|
|
||||||
name="category"
|
|
||||||
value={state.category}
|
|
||||||
onChange={handleChange}
|
|
||||||
className="form-control input-field"
|
|
||||||
>
|
|
||||||
<option value="">--select--</option>
|
|
||||||
{categoryName && categoryName.map(item =>
|
|
||||||
<option>{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
|
|
@ -1,292 +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";
|
|
||||||
|
|
||||||
const Bisuness = () => {
|
|
||||||
const [bisuness, setBisuness] = useState([])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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]);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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 delete");
|
|
||||||
if (!status) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let res = await axios.get(`/api/product/setStatus/${id}`, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
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 className="page-title-right">
|
|
||||||
<ol className="breadcrumb m-0">
|
|
||||||
<li className="breadcrumb-item">
|
|
||||||
<Link to="/dashboard">Dating App</Link>
|
|
||||||
</li>
|
|
||||||
<li className="breadcrumb-item">Commerce - Products</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 className="col-sm-12 col-md-6">
|
|
||||||
<div className="dataTables_length">
|
|
||||||
<label className="w-100">
|
|
||||||
Show{" "}
|
|
||||||
<select
|
|
||||||
onChange={(e) =>
|
|
||||||
changeState({ limit: e.target.value, page: 1 })
|
|
||||||
}
|
|
||||||
className="select-w custom-select custom-select-sm form-control form-control-sm"
|
|
||||||
>
|
|
||||||
<option value="10">10</option>
|
|
||||||
<option value="25">25</option>
|
|
||||||
<option value="50">50</option>
|
|
||||||
<option value="100">100</option>
|
|
||||||
</select>{" "}
|
|
||||||
entries
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div> */}
|
|
||||||
{/* <div className="col-sm-12 col-md-6">
|
|
||||||
<div className="dropdown d-block">
|
|
||||||
<a href="/comproducts/add">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="btn btn-primary add-btn waves-effect waves-light float-right"
|
|
||||||
>
|
|
||||||
<i className="fa fa-plus" aria-hidden="true"></i>{" "}
|
|
||||||
Add New Product
|
|
||||||
</button>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div> */}
|
|
||||||
</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>
|
|
||||||
{bisuness.map((item) =>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>{item?.name} </td>
|
|
||||||
<td>{item?.category}</td>
|
|
||||||
<td>{item?.city}</td>
|
|
||||||
<td>
|
|
||||||
<span
|
|
||||||
className={`badge rounded-pill bg-${status ? "success" : "danger"
|
|
||||||
} font-size-10`}
|
|
||||||
>
|
|
||||||
{status ? "Live" : "Suspended"}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className={`btn btn-${status ? "danger" : "success"
|
|
||||||
} btn-sm waves-effect waves-light btn-table ml-1`}
|
|
||||||
onClick={() => toggleStatus('_id')}
|
|
||||||
>
|
|
||||||
{status ? "Suspend" : "Activate"}
|
|
||||||
</button>
|
|
||||||
<Link to={`/view_bisuness/${item._id}`}>
|
|
||||||
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className=" mx-2 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-2 btn btn-primary btn-sm waves-effect waves-light btn-table ml-1"
|
|
||||||
>
|
|
||||||
Edit
|
|
||||||
</button>
|
|
||||||
</Link>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => handleDelete(item._id)}
|
|
||||||
className=" 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>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Bisuness
|
|
@ -1,515 +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 { 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 (!(name || description || phone || email || Bname || Sname || city)) {
|
|
||||||
alert("Please fill required field ");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
changeState({ loading: true });
|
|
||||||
|
|
||||||
let res = await axios.put(
|
|
||||||
`/api/directory/update/${id}`,
|
|
||||||
{
|
|
||||||
...state,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if (res.status == 200) {
|
|
||||||
changeState({ loading: false });
|
|
||||||
swal("Edit Business successfully!");
|
|
||||||
history.goBack()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const onCancel = () => {
|
|
||||||
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">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"
|
|
||||||
>
|
|
||||||
Category*
|
|
||||||
</label>
|
|
||||||
<select
|
|
||||||
name="category"
|
|
||||||
value={state.category}
|
|
||||||
onChange={handleChange}
|
|
||||||
className="form-control input-field"
|
|
||||||
>
|
|
||||||
<option value="">--select--</option>
|
|
||||||
{categoryName && categoryName.map(item =>
|
|
||||||
<option>{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,134 +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.name)
|
|
||||||
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>
|
|
||||||
<th>Category</th>
|
|
||||||
<th>email</th>
|
|
||||||
<th>phone</th>
|
|
||||||
<th>Building_Name</th>
|
|
||||||
<th>Street_Name</th>
|
|
||||||
<th>city</th>
|
|
||||||
<th>description</th>
|
|
||||||
<th>Status</th>
|
|
||||||
<th>Google Location</th>
|
|
||||||
<th>LinkedinUrl</th>
|
|
||||||
<th>FacebookUrl</th>
|
|
||||||
<th>intagramUrl</th>
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>{bisuness?.name} </td>
|
|
||||||
<td>{bisuness?.category}</td>
|
|
||||||
<td>{bisuness?.email}</td>
|
|
||||||
<td>{bisuness?.phone}</td>
|
|
||||||
<td>{bisuness?.Building_Name}</td>
|
|
||||||
<td>{bisuness?.Street_Name}</td>
|
|
||||||
<td>{bisuness?.city}</td>
|
|
||||||
<td>{bisuness?.description}</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
<span
|
|
||||||
className={`badge rounded-pill bg-${bisuness?.status ? "success" : "danger"
|
|
||||||
} font-size-10`}
|
|
||||||
>
|
|
||||||
{bisuness?.status ? "Live" : "Suspended"}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td>{bisuness?.Glocation}</td>
|
|
||||||
<td>{bisuness?.LinkedinUrl}</td>
|
|
||||||
<td>{bisuness?.FacebookUrl}</td>
|
|
||||||
<td>{bisuness?.InstagramUrl}</td>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* <!-- end table-responsive --> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/* <!-- container-fluid --> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default View_Bisuness
|
|
@ -1,149 +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 () => {
|
|
||||||
const myForm = new FormData();
|
|
||||||
|
|
||||||
myForm.set("title", title);
|
|
||||||
myForm.set("description", description);
|
|
||||||
myForm.set("image", image);
|
|
||||||
setLoading({ loading: true });
|
|
||||||
// console.log(image)
|
|
||||||
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");
|
|
||||||
history.goBack();
|
|
||||||
}
|
|
||||||
|
|
||||||
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,165 +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}`,
|
|
||||||
// },
|
|
||||||
});
|
|
||||||
// console.log(res.data.news.title)
|
|
||||||
setTitle(res.data.news.title)
|
|
||||||
setDescription(res.data.news.description)
|
|
||||||
|
|
||||||
}, [id]);
|
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
|
||||||
const myForm = new FormData();
|
|
||||||
|
|
||||||
myForm.set("title", title);
|
|
||||||
myForm.set("description", description);
|
|
||||||
myForm.set("image", image);
|
|
||||||
setLoading({ loading: true });
|
|
||||||
// console.log(image)
|
|
||||||
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");
|
|
||||||
history.goBack();
|
|
||||||
}
|
|
||||||
|
|
||||||
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>
|
|
||||||
<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-2 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-2 btn btn-primary btn-sm waves-effect waves-light btn-table ml-2"
|
|
||||||
>
|
|
||||||
Edit
|
|
||||||
</button>
|
|
||||||
</Link>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => handleDelete(`${item._id}`)}
|
|
||||||
className=" btn btn-danger btn-sm waves-effect waves-light btn-table ml-2"
|
|
||||||
id="sa-params"
|
|
||||||
>
|
|
||||||
Delete
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{/* <!-- end table-responsive --> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/* <!-- container-fluid --> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default News;
|
|
298
src/views/Products/AddProduct.js
Normal file
298
src/views/Products/AddProduct.js
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import Button from '@material-ui/core/Button'
|
||||||
|
import { Link, useNavigate } from 'react-router-dom'
|
||||||
|
import swal from 'sweetalert'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { isAutheticated } from 'src/auth'
|
||||||
|
// import { WebsiteURL } from '../WebsiteURL'
|
||||||
|
|
||||||
|
const AddProduct = () => {
|
||||||
|
const token = isAutheticated()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const [data, setData] = useState({
|
||||||
|
image: '',
|
||||||
|
imageURL: '',
|
||||||
|
name: '',
|
||||||
|
description: '',
|
||||||
|
|
||||||
|
base_Price: '',
|
||||||
|
price_Level_2: '',
|
||||||
|
price_Level_3: ''
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const handleChange = (e) => {
|
||||||
|
|
||||||
|
if (e.target.id === 'image') {
|
||||||
|
if (
|
||||||
|
e.target.files[0]?.type === 'image/jpeg' ||
|
||||||
|
e.target.files[0]?.type === 'image/png' ||
|
||||||
|
e.target.files[0]?.type === 'image/jpg'
|
||||||
|
) {
|
||||||
|
setData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
imageURL: URL.createObjectURL(e.target.files[0]),
|
||||||
|
image: e.target.files[0],
|
||||||
|
}))
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
swal({
|
||||||
|
title: 'Warning',
|
||||||
|
text: 'Upload jpg, jpeg, png only.',
|
||||||
|
icon: 'error',
|
||||||
|
button: 'Close',
|
||||||
|
dangerMode: true,
|
||||||
|
})
|
||||||
|
setData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
imageURL: '',
|
||||||
|
image: '',
|
||||||
|
}))
|
||||||
|
e.target.value = null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setData((prev) => ({ ...prev, [e.target.id]: e.target.value }))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
if (
|
||||||
|
data.name.trim() === '' ||
|
||||||
|
|
||||||
|
data.description.trim() === '' ||
|
||||||
|
data.base_Price === '' ||
|
||||||
|
data.price_Level_2 === '' ||
|
||||||
|
data.price_Level_3 === '' ||
|
||||||
|
data.imageURL.trim() === ''
|
||||||
|
) {
|
||||||
|
swal({
|
||||||
|
title: 'Warning',
|
||||||
|
text: 'Fill all mandatory fields',
|
||||||
|
icon: 'error',
|
||||||
|
button: 'Close',
|
||||||
|
dangerMode: true,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setLoading(true)
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.set('name', data.name)
|
||||||
|
|
||||||
|
formData.set('description', data.description)
|
||||||
|
formData.set('base_Price', data.base_Price)
|
||||||
|
formData.set('price_Level_2', data.price_Level_2)
|
||||||
|
formData.set('price_Level_3', data.price_Level_3)
|
||||||
|
formData.append('image', data.image)
|
||||||
|
|
||||||
|
|
||||||
|
axios
|
||||||
|
.post(`/api/product/create/`, formData, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
'Content-Type': 'multipart/formdata',
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
swal({
|
||||||
|
title: 'Added',
|
||||||
|
text: 'Product added successfully!',
|
||||||
|
icon: 'success',
|
||||||
|
button: 'Return',
|
||||||
|
})
|
||||||
|
setLoading(false)
|
||||||
|
navigate('/products', { replace: true })
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
setLoading(false)
|
||||||
|
const message = err.response?.data?.message || 'Something went wrong!'
|
||||||
|
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: '22px' }} className="fw-bold">
|
||||||
|
Add Product
|
||||||
|
</div>
|
||||||
|
<div style={{ display: 'flex', gap: '1rem' }}>
|
||||||
|
<h4 className="mb-0"></h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="page-title-right">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
style={{
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: '1rem',
|
||||||
|
textTransform: 'capitalize',
|
||||||
|
marginRight: '5px',
|
||||||
|
}}
|
||||||
|
onClick={() => handleSubmit()}
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
{loading ? 'Loading' : 'Save'}
|
||||||
|
</Button>
|
||||||
|
<Link to="/products">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
style={{
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: '1rem',
|
||||||
|
textTransform: 'capitalize',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-6 col-md-6 col-sm-12 my-1">
|
||||||
|
<div className="card h-100">
|
||||||
|
<div className="card-body px-5">
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Product Name*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="name"
|
||||||
|
value={data.name}
|
||||||
|
maxLength={25}
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
{data.name ? <><small className="charLeft mt-4 fst-italic">
|
||||||
|
{25 - data.name.length} characters left
|
||||||
|
</small></> : <></>
|
||||||
|
|
||||||
|
} </div>
|
||||||
|
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Description*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="description"
|
||||||
|
value={data.description}
|
||||||
|
maxLength="100"
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
{data.description ? <><small className="charLeft mt-4 fst-italic">
|
||||||
|
{100 - data.description.length} characters left
|
||||||
|
</small></> : <></>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="image" className="form-label">
|
||||||
|
Product Image*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
className="form-control"
|
||||||
|
id="image"
|
||||||
|
accept="image/*"
|
||||||
|
multiple
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
<p className="pt-1 pl-2 text-secondary">Upload jpg, jpeg and png only*</p>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3" style={{ height: '200px', maxWdth: '100%' }}>
|
||||||
|
<img
|
||||||
|
src={data.imageURL}
|
||||||
|
alt="Uploaded Image will be shown here"
|
||||||
|
style={{ maxHeight: '200px', maxWidth: '100%' }}
|
||||||
|
/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-lg-6 col-md-6 col-sm-12 my-1">
|
||||||
|
<div className="card h-100">
|
||||||
|
<div className="card-body px-5">
|
||||||
|
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Base Price*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
className="form-control"
|
||||||
|
id="base_Price"
|
||||||
|
value={data.base_Price}
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Price Level 2*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
className="form-control"
|
||||||
|
id="price_Level_2"
|
||||||
|
value={data.price_Level_2}
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
|
||||||
|
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Price Level 3*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
className="form-control"
|
||||||
|
id="price_Level_3"
|
||||||
|
value={data.price_Level_3}
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
|
||||||
|
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AddProduct
|
333
src/views/Products/EditProduct.js
Normal file
333
src/views/Products/EditProduct.js
Normal file
@ -0,0 +1,333 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import Button from '@material-ui/core/Button'
|
||||||
|
import { Link, useNavigate, useParams } from 'react-router-dom'
|
||||||
|
import swal from 'sweetalert'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { isAutheticated } from 'src/auth'
|
||||||
|
// import { WebsiteURL } from '../WebsiteURL'
|
||||||
|
|
||||||
|
const EditProduct = () => {
|
||||||
|
const token = isAutheticated()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const id = useParams()?.id
|
||||||
|
const [data, setData] = useState({
|
||||||
|
image: '',
|
||||||
|
imageURL: '',
|
||||||
|
name: '',
|
||||||
|
description: '',
|
||||||
|
|
||||||
|
base_Price: '',
|
||||||
|
price_Level_2: '',
|
||||||
|
price_Level_3: ''
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
|
||||||
|
//get Productdata
|
||||||
|
const getProduct = async () => {
|
||||||
|
|
||||||
|
axios
|
||||||
|
.get(`/api/product/getOne/${id}`, {
|
||||||
|
headers: {
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
setData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
...res.data?.product,
|
||||||
|
imageURL: res.data?.product?.image?.url,
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
.catch((err) => { })
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getProduct()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const handleChange = (e) => {
|
||||||
|
|
||||||
|
if (e.target.id === 'image') {
|
||||||
|
if (
|
||||||
|
e.target.files[0]?.type === 'image/jpeg' ||
|
||||||
|
e.target.files[0]?.type === 'image/png' ||
|
||||||
|
e.target.files[0]?.type === 'image/jpg'
|
||||||
|
) {
|
||||||
|
setData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
imageURL: URL.createObjectURL(e.target.files[0]),
|
||||||
|
image: e.target.files[0],
|
||||||
|
}))
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
swal({
|
||||||
|
title: 'Warning',
|
||||||
|
text: 'Upload jpg, jpeg, png only.',
|
||||||
|
icon: 'error',
|
||||||
|
button: 'Close',
|
||||||
|
dangerMode: true,
|
||||||
|
})
|
||||||
|
setData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
imageURL: '',
|
||||||
|
image: '',
|
||||||
|
}))
|
||||||
|
e.target.value = null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setData((prev) => ({ ...prev, [e.target.id]: e.target.value }))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
if (
|
||||||
|
data.name.trim() === '' ||
|
||||||
|
|
||||||
|
data.description.trim() === '' ||
|
||||||
|
data.base_Price === '' ||
|
||||||
|
data.price_Level_2 === '' ||
|
||||||
|
data.price_Level_3 === '' ||
|
||||||
|
data.imageURL.trim() === ''
|
||||||
|
) {
|
||||||
|
swal({
|
||||||
|
title: 'Warning',
|
||||||
|
text: 'Fill all mandatory fields',
|
||||||
|
icon: 'error',
|
||||||
|
button: 'Close',
|
||||||
|
dangerMode: true,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setLoading(true)
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.set('name', data.name)
|
||||||
|
|
||||||
|
formData.set('description', data.description)
|
||||||
|
formData.set('base_Price', data.base_Price)
|
||||||
|
formData.set('price_Level_2', data.price_Level_2)
|
||||||
|
formData.set('price_Level_3', data.price_Level_3)
|
||||||
|
formData.append('image', data.image)
|
||||||
|
|
||||||
|
|
||||||
|
axios
|
||||||
|
.put(`/api//product/update/${id}`, formData, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
'Content-Type': 'multipart/formdata',
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
swal({
|
||||||
|
title: 'Added',
|
||||||
|
text: 'Product Edited successfully!',
|
||||||
|
icon: 'success',
|
||||||
|
button: 'Return',
|
||||||
|
})
|
||||||
|
setLoading(false)
|
||||||
|
navigate('/products', { replace: true })
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
setLoading(false)
|
||||||
|
const message = err.response?.data?.message || 'Something went wrong!'
|
||||||
|
swal({
|
||||||
|
title: 'Warning',
|
||||||
|
text: message,
|
||||||
|
icon: 'error',
|
||||||
|
button: 'Retry',
|
||||||
|
dangerMode: true,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
console.log(data)
|
||||||
|
return (
|
||||||
|
<div className="container">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-12">
|
||||||
|
<div
|
||||||
|
className="
|
||||||
|
page-title-box
|
||||||
|
d-flex
|
||||||
|
align-items-center
|
||||||
|
justify-content-between
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div style={{ fontSize: '22px' }} className="fw-bold">
|
||||||
|
Edit Product
|
||||||
|
</div>
|
||||||
|
<div style={{ display: 'flex', gap: '1rem' }}>
|
||||||
|
<h4 className="mb-0"></h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="page-title-right">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
style={{
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: '1rem',
|
||||||
|
textTransform: 'capitalize',
|
||||||
|
marginRight: '5px',
|
||||||
|
}}
|
||||||
|
onClick={() => handleSubmit()}
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
{loading ? 'Loading' : 'Save'}
|
||||||
|
</Button>
|
||||||
|
<Link to="/products">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
style={{
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: '1rem',
|
||||||
|
textTransform: 'capitalize',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-6 col-md-6 col-sm-12 my-1">
|
||||||
|
<div className="card h-100">
|
||||||
|
<div className="card-body px-5">
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Product Name*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="name"
|
||||||
|
value={data.name}
|
||||||
|
maxLength={25}
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
{data.name ? <><small className="charLeft mt-4 fst-italic">
|
||||||
|
{25 - data.name.length} characters left
|
||||||
|
</small></> : <></>
|
||||||
|
|
||||||
|
} </div>
|
||||||
|
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Description*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="description"
|
||||||
|
value={data.description}
|
||||||
|
maxLength="100"
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
{data.description ? <><small className="charLeft mt-4 fst-italic">
|
||||||
|
{100 - data.description.length} characters left
|
||||||
|
</small></> : <></>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="image" className="form-label">
|
||||||
|
Product Image*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
className="form-control"
|
||||||
|
id="image"
|
||||||
|
accept="image/*"
|
||||||
|
multiple
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
<p className="pt-1 pl-2 text-secondary">Upload jpg, jpeg and png only*</p>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3" style={{ height: '200px', maxWdth: '100%' }}>
|
||||||
|
<img
|
||||||
|
src={data.imageURL}
|
||||||
|
alt="Uploaded Image will be shown here"
|
||||||
|
style={{ maxHeight: '200px', maxWidth: '100%' }}
|
||||||
|
/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-lg-6 col-md-6 col-sm-12 my-1">
|
||||||
|
<div className="card h-100">
|
||||||
|
<div className="card-body px-5">
|
||||||
|
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Base Price*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
className="form-control"
|
||||||
|
id="base_Price"
|
||||||
|
value={data.base_Price}
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Price Level 2*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
className="form-control"
|
||||||
|
id="price_Level_2"
|
||||||
|
value={data.price_Level_2}
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
|
||||||
|
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Price Level 3*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
className="form-control"
|
||||||
|
id="price_Level_3"
|
||||||
|
value={data.price_Level_3}
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
|
||||||
|
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EditProduct
|
371
src/views/Products/Products.js
Normal file
371
src/views/Products/Products.js
Normal file
@ -0,0 +1,371 @@
|
|||||||
|
import React, { useState, useEffect } from 'react'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
import Button from '@material-ui/core/Button'
|
||||||
|
import { useNavigate } from 'react-router-dom'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { isAutheticated } from 'src/auth'
|
||||||
|
|
||||||
|
const Products = () => {
|
||||||
|
const token = isAutheticated()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const [loading, setLoading] = useState(true)
|
||||||
|
const [success, setSuccess] = useState(true)
|
||||||
|
const [productsData, setProductsData] = useState([])
|
||||||
|
|
||||||
|
const [currentPage, setCurrentPage] = useState(1)
|
||||||
|
const [itemPerPage, setItemPerPage] = useState(10)
|
||||||
|
const [showData, setShowData] = useState(productsData)
|
||||||
|
|
||||||
|
const handleShowEntries = (e) => {
|
||||||
|
setCurrentPage(1)
|
||||||
|
setItemPerPage(e.target.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const getProductsData = async () => {
|
||||||
|
axios
|
||||||
|
.get(`/api/product/getAll/`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
setProductsData(res.data?.product)
|
||||||
|
setLoading(false)
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
setLoading(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getProductsData()
|
||||||
|
}, [success])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const loadData = () => {
|
||||||
|
const indexOfLastPost = currentPage * itemPerPage
|
||||||
|
const indexOfFirstPost = indexOfLastPost - itemPerPage
|
||||||
|
setShowData(productsData.slice(indexOfFirstPost, indexOfLastPost))
|
||||||
|
}
|
||||||
|
loadData()
|
||||||
|
}, [currentPage, itemPerPage, productsData])
|
||||||
|
|
||||||
|
const handleDelete = (id) => {
|
||||||
|
swal({
|
||||||
|
title: 'Are you sure?',
|
||||||
|
icon: 'error',
|
||||||
|
buttons: { Yes: { text: 'Yes', value: true }, Cancel: { text: 'Cancel', value: 'cancel' } },
|
||||||
|
}).then((value) => {
|
||||||
|
if (value === true) {
|
||||||
|
axios
|
||||||
|
.delete(`/api/product/delete/${id}`, {
|
||||||
|
headers: {
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
setSuccess((prev) => !prev)
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
swal({
|
||||||
|
title: 'Warning',
|
||||||
|
text: 'Something went wrong!',
|
||||||
|
icon: 'error',
|
||||||
|
button: 'Retry',
|
||||||
|
dangerMode: true,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="main-content">
|
||||||
|
<div className="page-content">
|
||||||
|
<div className="container-fluid">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-12">
|
||||||
|
<div
|
||||||
|
className="
|
||||||
|
page-title-box
|
||||||
|
d-flex
|
||||||
|
align-items-center
|
||||||
|
justify-content-between
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div style={{ fontSize: '22px' }} className="fw-bold">
|
||||||
|
Products
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="page-title-right">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
style={{
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: '1rem',
|
||||||
|
textTransform: 'capitalize',
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
navigate('/product/add', { replace: true })
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Add Product
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="card">
|
||||||
|
<div className="card-body">
|
||||||
|
<div className="row ml-0 mr-0 mb-10">
|
||||||
|
<div className="col-sm-12 col-md-12">
|
||||||
|
<div className="dataTables_length">
|
||||||
|
<label className="w-100">
|
||||||
|
Show
|
||||||
|
<select
|
||||||
|
style={{ width: '10%' }}
|
||||||
|
name=""
|
||||||
|
onChange={(e) => handleShowEntries(e)}
|
||||||
|
className="
|
||||||
|
select-w
|
||||||
|
custom-select custom-select-sm
|
||||||
|
form-control form-control-sm
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<option value="10">10</option>
|
||||||
|
<option value="25">25</option>
|
||||||
|
<option value="50">50</option>
|
||||||
|
<option value="100">100</option>
|
||||||
|
</select>
|
||||||
|
entries
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="table-responsive table-shoot mt-3">
|
||||||
|
<table
|
||||||
|
className="table table-centered table-nowrap"
|
||||||
|
style={{ border: '1px solid' }}
|
||||||
|
>
|
||||||
|
<thead className="thead-info" style={{ background: 'rgb(140, 213, 213)' }}>
|
||||||
|
<tr>
|
||||||
|
|
||||||
|
<th className="text-start">Product Name</th>
|
||||||
|
<th className="text-start">Thumbnail</th>
|
||||||
|
<th className="text-start">Base Price</th>
|
||||||
|
<th className="text-start">Added On</th>
|
||||||
|
<th className="text-start">Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{!loading && showData.length === 0 && (
|
||||||
|
<tr className="text-center">
|
||||||
|
<td colSpan="6">
|
||||||
|
<h5>No Data Available</h5>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
{loading ? (
|
||||||
|
<tr>
|
||||||
|
<td className="text-center" colSpan="6">
|
||||||
|
Loading...
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
) : (
|
||||||
|
showData.map((product, i) => {
|
||||||
|
return (
|
||||||
|
<tr key={i}>
|
||||||
|
<td className="text-start">{product.name}</td>
|
||||||
|
<th>
|
||||||
|
{product?.image && (
|
||||||
|
<>
|
||||||
|
<img src={product.image?.url} width="50" alt="preview" />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</th>
|
||||||
|
<th className="text-start">₹{product.base_Price}</th>
|
||||||
|
<td className="text-start">
|
||||||
|
{new Date(product.createdAt).toLocaleString('en-IN', {
|
||||||
|
weekday: 'short',
|
||||||
|
month: 'short',
|
||||||
|
day: 'numeric',
|
||||||
|
year: 'numeric',
|
||||||
|
hour: 'numeric',
|
||||||
|
minute: 'numeric',
|
||||||
|
hour12: true,
|
||||||
|
})}
|
||||||
|
</td>
|
||||||
|
<td className="text-start">
|
||||||
|
|
||||||
|
<Link to={`/product/view/${product._id}`}>
|
||||||
|
<button
|
||||||
|
style={{ color: 'white', marginRight: '1rem' }}
|
||||||
|
type="button"
|
||||||
|
className="
|
||||||
|
btn btn-primary btn-sm
|
||||||
|
waves-effect waves-light
|
||||||
|
btn-table
|
||||||
|
mx-1
|
||||||
|
mt-1
|
||||||
|
"
|
||||||
|
>
|
||||||
|
View
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
<Link to={`/product/edit/${product._id}`}>
|
||||||
|
<button
|
||||||
|
style={{ color: 'white', marginRight: '1rem' }}
|
||||||
|
type="button"
|
||||||
|
className="
|
||||||
|
btn btn-info btn-sm
|
||||||
|
waves-effect waves-light
|
||||||
|
btn-table
|
||||||
|
mt-1
|
||||||
|
mx-1
|
||||||
|
"
|
||||||
|
>
|
||||||
|
Edit
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
to={'#'}
|
||||||
|
style={{
|
||||||
|
marginRight: '1rem',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
style={{ color: 'white' }}
|
||||||
|
type="button"
|
||||||
|
className="
|
||||||
|
btn btn-danger btn-sm
|
||||||
|
waves-effect waves-light
|
||||||
|
btn-table
|
||||||
|
mt-1
|
||||||
|
mx-1
|
||||||
|
|
||||||
|
"
|
||||||
|
onClick={() => {
|
||||||
|
handleDelete(product._id)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Delete
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
</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 {currentPage * itemPerPage - itemPerPage + 1} to{' '}
|
||||||
|
{Math.min(currentPage * itemPerPage, productsData.length)} of{' '}
|
||||||
|
{productsData.length} entries
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-sm-12 col-md-6">
|
||||||
|
<div className="d-flex">
|
||||||
|
<ul className="pagination ms-auto">
|
||||||
|
<li
|
||||||
|
className={
|
||||||
|
currentPage === 1
|
||||||
|
? 'paginate_button page-item previous disabled'
|
||||||
|
: 'paginate_button page-item previous'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: 'pointer' }}
|
||||||
|
onClick={() => setCurrentPage((prev) => prev - 1)}
|
||||||
|
>
|
||||||
|
Previous
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{!(currentPage - 1 < 1) && (
|
||||||
|
<li className="paginate_button page-item">
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: 'pointer' }}
|
||||||
|
onClick={(e) => setCurrentPage((prev) => prev - 1)}
|
||||||
|
>
|
||||||
|
{currentPage - 1}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<li className="paginate_button page-item active">
|
||||||
|
<span className="page-link" style={{ cursor: 'pointer' }}>
|
||||||
|
{currentPage}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{!(
|
||||||
|
(currentPage + 1) * itemPerPage - itemPerPage >
|
||||||
|
productsData.length - 1
|
||||||
|
) && (
|
||||||
|
<li className="paginate_button page-item ">
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: 'pointer' }}
|
||||||
|
onClick={() => {
|
||||||
|
setCurrentPage((prev) => prev + 1)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{currentPage + 1}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<li
|
||||||
|
className={
|
||||||
|
!(
|
||||||
|
(currentPage + 1) * itemPerPage - itemPerPage >
|
||||||
|
productsData.length - 1
|
||||||
|
)
|
||||||
|
? 'paginate_button page-item next'
|
||||||
|
: 'paginate_button page-item next disabled'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: 'pointer' }}
|
||||||
|
onClick={() => setCurrentPage((prev) => prev + 1)}
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Products
|
@ -1,35 +1,35 @@
|
|||||||
|
|
||||||
|
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import React, { useEffect, useState, useCallback, useMemo } from "react";
|
import React, { useEffect, useState, useCallback, useMemo } from "react";
|
||||||
import swal from 'sweetalert';
|
import swal from 'sweetalert';
|
||||||
// import { API } from "../../data";
|
|
||||||
import { Link, useParams } from "react-router-dom";
|
import { Link, useParams } from "react-router-dom";
|
||||||
import { isAutheticated } from "../../auth";
|
import { isAutheticated } from "src/auth";
|
||||||
|
|
||||||
function ViewNews() {
|
function ViewProduct() {
|
||||||
const [news, setNews] = useState([])
|
const [product, setProduct] = useState([])
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
console.log(id)
|
const token = isAutheticated();
|
||||||
const { token } = isAutheticated();
|
|
||||||
|
|
||||||
const getNews = useCallback(async () => {
|
const getProduct = useCallback(async () => {
|
||||||
let res = await axios.get(
|
let res = await axios.get(
|
||||||
`/api/news/getOne/${id}`,
|
`/api/product/getOne/${id}`,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
console.log(res.data.news)
|
console.log(res.data.product)
|
||||||
setNews(res.data.news)
|
setProduct(res.data.product)
|
||||||
|
|
||||||
|
|
||||||
}, [token]);
|
}, [token]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getNews();
|
getProduct();
|
||||||
}, [getNews]);
|
}, [getProduct]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -56,8 +56,8 @@ function ViewNews() {
|
|||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
<div className="page-title-box d-flex align-items-center justify-content-between">
|
<div className="page-title-box d-flex align-items-center justify-content-between">
|
||||||
<h4 className="mb-3">CMP-News</h4>
|
<h4 className="mb-3">Product</h4>
|
||||||
<Link to="/addNews"><button type="button" className="btn btn-info float-end mb-3 ml-4"> + Add News</button></Link>
|
<Link to="/product/add"><button type="button" className="btn btn-info float-end mb-3 ml-4"> + Add Product</button></Link>
|
||||||
{/* <div className="page-title-right">
|
{/* <div className="page-title-right">
|
||||||
<ol className="breadcrumb m-0">
|
<ol className="breadcrumb m-0">
|
||||||
<li className="breadcrumb-item">
|
<li className="breadcrumb-item">
|
||||||
@ -81,36 +81,33 @@ function ViewNews() {
|
|||||||
<div className="table-responsive table-shoot">
|
<div className="table-responsive table-shoot">
|
||||||
<table className="table table-centered table-nowrap mb-0">
|
<table className="table table-centered table-nowrap mb-0">
|
||||||
<thead className="thead-light">
|
<thead className="thead-light">
|
||||||
<tr>
|
|
||||||
<th>Id</th>
|
|
||||||
<th>Title</th>
|
|
||||||
|
|
||||||
<th>Image</th>
|
<tr><th>Id</th> <td>{product?._id}</td></tr>
|
||||||
<th>Description</th>
|
<tr><th>Name</th> <td>{product?.name}</td></tr>
|
||||||
<th>Added On</th>
|
|
||||||
<th>Updated At</th>
|
<tr><th>image</th><td>
|
||||||
|
<img src={`${product.image?.url}`} width="50" alt="" />
|
||||||
|
</td></tr>
|
||||||
|
<tr><th>Description</th><td>{product?.description}</td></tr>
|
||||||
|
<tr><th>Base Price</th><td>{product?.base_Price}</td></tr>
|
||||||
|
<tr><th>Price Level 2</th><td>{product?.price_Level_2}</td></tr>
|
||||||
|
|
||||||
|
<tr><th>Price Level 3</th><td>{product?.price_Level_3}</td></tr>
|
||||||
|
|
||||||
|
{/* <tr><th>Product Time</th><td>{product?.time}</td></tr>
|
||||||
|
<tr><th>Location</th><td>{product?.location}</td></tr> */}
|
||||||
|
<tr><th>Created On</th><td>
|
||||||
|
{new Date(`${product?.createdAt}`).toDateString()}<span> , {`${formatAMPM(product?.createdAt)}`}</span>
|
||||||
|
</td></tr>
|
||||||
|
<tr><th>Updated At</th>
|
||||||
|
<td>
|
||||||
|
{new Date(`${product?.updatedAt}`).toDateString()}<span> , {`${formatAMPM(product?.updatedAt)}`}</span>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{news &&
|
|
||||||
<tr>
|
|
||||||
<td>{news?._id}</td>
|
|
||||||
<td>{news?.title}</td>
|
|
||||||
<td>
|
|
||||||
<img src={`${news.image?.url}`} width="50" alt="" />
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>{news?.description}</td>
|
|
||||||
<td>
|
|
||||||
{new Date(`${news?.addedOn}`).toDateString()}<span> , {`${formatAMPM(news?.addedOn)}`}</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{new Date(`${news?.updatedAt}`).toDateString()}<span> , {`${formatAMPM(news?.updatedAt)}`}</span>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@ -128,4 +125,4 @@ function ViewNews() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ViewNews;
|
export default ViewProduct;
|
@ -1,66 +1,127 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { CForm, CCol, CFormLabel, CContainer, CRow, CCardGroup, CCard, CCardBody, CFormInput, CFormSelect, CFormCheck, CButton } from '@coreui/react'
|
import { CForm, CCol, CFormLabel, CContainer, CRow, CCardGroup, CCard, CCardBody, CFormInput, CButton } from '@coreui/react'
|
||||||
import { Country, City } from 'country-state-city'
|
|
||||||
import { useState, useEffect } from 'react'
|
import { useState, useEffect } from 'react'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { useHistory } from 'react-router-dom'
|
import { useNavigate } from 'react-router-dom'
|
||||||
import { isAutheticated } from 'src/auth'
|
import { isAutheticated } from 'src/auth'
|
||||||
const EditProfile = () => {
|
|
||||||
const [cities, setCities] = useState([])
|
|
||||||
const { token } = isAutheticated()
|
|
||||||
const [ownerDetails, setOwnerDetails] = useState({
|
|
||||||
cafeName: '',
|
|
||||||
email: '',
|
|
||||||
location: '',
|
|
||||||
country: 'India',
|
|
||||||
city: ''
|
|
||||||
})
|
|
||||||
const history = useHistory()
|
|
||||||
const [processing, setProcessing] = useState(false)
|
|
||||||
const countries = Country.getAllCountries()
|
|
||||||
useEffect(() => {
|
|
||||||
const countryCode = countries.find(item => item.name === ownerDetails.country)
|
|
||||||
setCities(() => City.getCitiesOfCountry(countryCode?.isoCode))
|
|
||||||
getData()
|
|
||||||
|
|
||||||
}, [ownerDetails.country])
|
const EditProfile = () => {
|
||||||
|
|
||||||
|
const [image, setImage] = useState("");
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const [imagesPreview, setImagesPreview] = useState();
|
||||||
|
const token = isAutheticated()
|
||||||
|
|
||||||
|
const [ownerDetails, setOwnerDetails] = useState({
|
||||||
|
name: '',
|
||||||
|
email: '',
|
||||||
|
phone: ''
|
||||||
|
|
||||||
|
})
|
||||||
|
const history = useNavigate()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const getData = async () => {
|
const getData = async () => {
|
||||||
let res = await axios.get('/owner', {
|
let res = await axios.get(`/api/v1/user/details`, {
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Bearer ${token}`
|
Authorization: `Bearer ${token}`,
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
if (res) {
|
if (res.data.success) {
|
||||||
|
|
||||||
setOwnerDetails({ ...res.data.user })
|
setOwnerDetails({ ...res.data.user })
|
||||||
|
|
||||||
|
if (res.data.user.avatar) {
|
||||||
|
setImagesPreview(res.data.user.avatar.url)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
console.log(ownerDetails);
|
|
||||||
const handleChange = (event) => {
|
const handleChange = (event) => {
|
||||||
const { name, value } = event.target;
|
const { name, value } = event.target;
|
||||||
setOwnerDetails({ ...ownerDetails, [name]: value });
|
setOwnerDetails({ ...ownerDetails, [name]: value });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleImage = (e) => {
|
||||||
|
const files = e.target.files[0];
|
||||||
|
|
||||||
async function handleSubmit() {
|
// console.log(files)
|
||||||
|
setImage(files);
|
||||||
|
// only for file preview------------------------------------
|
||||||
|
const Reader = new FileReader();
|
||||||
|
Reader.readAsDataURL(files);
|
||||||
|
|
||||||
let res = await axios.put(`/owner`, ownerDetails, {
|
Reader.onload = () => {
|
||||||
headers: {
|
if (Reader.readyState === 2) {
|
||||||
'Content-Type': 'application/json',
|
setImagesPreview(Reader.result);
|
||||||
'Authorization': `Bearer ${token}`,
|
|
||||||
}
|
}
|
||||||
})
|
};
|
||||||
setProcessing(true)
|
|
||||||
console.log(res.data);
|
|
||||||
|
|
||||||
if (res) {
|
|
||||||
// localStorage.setItem("auth", JSON.stringify({
|
|
||||||
|
|
||||||
// token: res.data.token,
|
// -----------------------------------------------------------------------------
|
||||||
// }));
|
};
|
||||||
history.push('/profile')
|
async function handleSubmit() {
|
||||||
|
if (ownerDetails.name === '' || ownerDetails.email === '' || ownerDetails.phone === '') {
|
||||||
|
swal({
|
||||||
|
title: 'Warning',
|
||||||
|
text: 'Fill all mandatory fields',
|
||||||
|
icon: 'error',
|
||||||
|
button: 'Close',
|
||||||
|
dangerMode: true,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('name', ownerDetails.name)
|
||||||
|
formData.append('email', ownerDetails.email)
|
||||||
|
formData.append('phone', ownerDetails.phone)
|
||||||
|
formData.append('avatar', image)
|
||||||
|
setLoading(true)
|
||||||
|
try {
|
||||||
|
const res = await axios
|
||||||
|
.put(`/api/v1/user/update/profile`, formData, {
|
||||||
|
headers: {
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
'Content-Type': 'multipart/formdata',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if (res.data.success === true) {
|
||||||
|
|
||||||
|
setLoading(false)
|
||||||
|
swal({
|
||||||
|
title: 'Edited',
|
||||||
|
text: 'Profile Edited Successfully!',
|
||||||
|
icon: 'success',
|
||||||
|
button: 'Return',
|
||||||
|
})
|
||||||
|
history(-1)
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
const message = error?.response?.data?.message || 'Something went wrong!'
|
||||||
|
setLoading(false)
|
||||||
|
swal({
|
||||||
|
title: 'Warning',
|
||||||
|
text: message,
|
||||||
|
icon: 'error',
|
||||||
|
button: 'Retry',
|
||||||
|
dangerMode: true,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const handleCancle = () => {
|
||||||
|
history.push('/dashboard')
|
||||||
|
}
|
||||||
|
useEffect(() => {
|
||||||
|
|
||||||
|
getData()
|
||||||
|
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div >
|
<div >
|
||||||
@ -70,49 +131,46 @@ const EditProfile = () => {
|
|||||||
<CCol md={8} className='mt-5'>
|
<CCol md={8} className='mt-5'>
|
||||||
<CCardGroup>
|
<CCardGroup>
|
||||||
<CCard className="p-4">
|
<CCard className="p-4">
|
||||||
|
<h2 >Edit Profile</h2>
|
||||||
<CCardBody>
|
<CCardBody>
|
||||||
<h1 >Edit Profile</h1>
|
|
||||||
<CForm className="row g-3">
|
<CForm className="row g-3">
|
||||||
<CCol xs={12}>
|
<CCol xs={12}>
|
||||||
<CFormLabel htmlFor="inputAddress">Cafe Name</CFormLabel>
|
<CFormLabel htmlFor="inputAddress">Name *</CFormLabel>
|
||||||
<CFormInput id="inputAddress" placeholder="" name='cafeName' value={ownerDetails.cafeName} onChange={handleChange} />
|
<CFormInput id="inputAddress" placeholder="" name='name' value={ownerDetails.name} onChange={handleChange} />
|
||||||
</CCol>
|
</CCol>
|
||||||
|
|
||||||
<CCol md={6}>
|
<CCol md={6}>
|
||||||
<CFormLabel htmlFor="inputEmail4">Email</CFormLabel>
|
<CFormLabel htmlFor="inputEmail4">Email *</CFormLabel>
|
||||||
<CFormInput type="email" id="inputEmail4" name='email' value={ownerDetails.email} onChange={handleChange} />
|
<CFormInput type="email" id="inputEmail4" name='email' value={ownerDetails.email} onChange={handleChange} />
|
||||||
</CCol>
|
</CCol>
|
||||||
{/* <CCol md={6}>
|
|
||||||
<CFormLabel htmlFor="inputPassword4">Password</CFormLabel>
|
|
||||||
<CFormInput type="password" id="inputPassword4" name='password' value={ownerDetails.password} onChange={handleChange} />
|
|
||||||
</CCol> */}
|
|
||||||
|
|
||||||
|
|
||||||
<CCol md={12}>
|
|
||||||
<CFormLabel htmlFor="inputCity">Location</CFormLabel>
|
|
||||||
<CFormInput id="inputCity" name='location' value={ownerDetails.location} onChange={handleChange} />
|
|
||||||
</CCol>
|
|
||||||
<CCol md={6}>
|
<CCol md={6}>
|
||||||
<CFormLabel htmlFor="inputState">Country</CFormLabel>
|
<CFormLabel htmlFor="inputPassword4">Phone *</CFormLabel>
|
||||||
<CFormSelect id="inputState" name='country' onChange={handleChange}>
|
<CFormInput type="number" id="inputPassword4" minLength={8} name='phone' value={ownerDetails.phone} onChange={handleChange} />
|
||||||
<option>Select a country</option>
|
|
||||||
{countries.map(item => <option value={item.name}>{item.name}</option>)}
|
|
||||||
|
|
||||||
</CFormSelect>
|
|
||||||
</CCol>
|
|
||||||
<CCol md={6}>
|
|
||||||
<CFormLabel htmlFor="inputState">City</CFormLabel>
|
|
||||||
<CFormSelect id="inputState" name='city' onChange={handleChange}>
|
|
||||||
<option>Select a city</option>
|
|
||||||
{cities.map(item => <option value={item.name}>{item.name}</option>)}
|
|
||||||
|
|
||||||
</CFormSelect>
|
|
||||||
</CCol>
|
</CCol>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<CFormInput
|
||||||
|
type="file"
|
||||||
|
placeholder="image"
|
||||||
|
accept="image/*"
|
||||||
|
required
|
||||||
|
onChange={handleImage}
|
||||||
|
|
||||||
|
|
||||||
|
/>
|
||||||
|
<div id="createProductFormImage" className="w-50 d-flex">
|
||||||
|
|
||||||
|
{imagesPreview && <img className=" w-50 p-1 " src={imagesPreview} alt="Product Preview" />}
|
||||||
|
|
||||||
|
</div>
|
||||||
<CCol xs={12}>
|
<CCol xs={12}>
|
||||||
<CButton onClick={handleSubmit} color='dark'>Submit</CButton>
|
<CButton onClick={handleSubmit} color='primary'>{loading ? 'Loading...' : 'Submit'}</CButton>
|
||||||
|
<CButton className='ml-2' onClick={handleCancle} color='warning'>Cancel</CButton>
|
||||||
|
|
||||||
</CCol>
|
</CCol>
|
||||||
|
|
||||||
</CForm>
|
</CForm>
|
||||||
</CCardBody>
|
</CCardBody>
|
||||||
</CCard>
|
</CCard>
|
||||||
|
@ -1,7 +1,13 @@
|
|||||||
import React, { useEffect } from 'react'
|
import React, { useEffect } from 'react'
|
||||||
import {
|
import {
|
||||||
CButton,
|
CButton,
|
||||||
|
CCard,
|
||||||
|
CCardBody,
|
||||||
CCol,
|
CCol,
|
||||||
|
CForm,
|
||||||
|
CFormInput,
|
||||||
|
CFormLabel,
|
||||||
|
CFormSelect,
|
||||||
CRow,
|
CRow,
|
||||||
CTable,
|
CTable,
|
||||||
CTableBody,
|
CTableBody,
|
||||||
@ -13,13 +19,13 @@ import {
|
|||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { isAutheticated } from 'src/auth';
|
import { isAutheticated } from 'src/auth';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
const Profile = () => {
|
const Profile = () => {
|
||||||
// const user = JSON.parse(localStorage.getItem('auth')).user
|
// const user = JSON.parse(localStorage.getItem('auth')).user
|
||||||
const [user, setUser] = useState({});
|
const [user, setUser] = useState({});
|
||||||
const { token } = isAutheticated();
|
const { token } = isAutheticated();
|
||||||
const history = useHistory()
|
const history = useNavigate()
|
||||||
// console.log(token);
|
// console.log(token);
|
||||||
useEffect(async () => {
|
useEffect(async () => {
|
||||||
let res = await axios.get('/owner', {
|
let res = await axios.get('/owner', {
|
||||||
@ -45,35 +51,68 @@ const Profile = () => {
|
|||||||
</CCol>
|
</CCol>
|
||||||
<CCol>
|
<CCol>
|
||||||
<CButton color='dark'
|
<CButton color='dark'
|
||||||
className="float-right" onClick={() => history.push('/edit')}>Edit Profile</CButton>
|
className="float-right" onClick={() => history('/edit')}>Edit Profile</CButton>
|
||||||
</CCol>
|
</CCol>
|
||||||
</CRow>
|
</CRow>
|
||||||
<CTable color="white" striped>
|
<CCard className="p-4">
|
||||||
<CTableHead>
|
<CCardBody>
|
||||||
<CTableRow>
|
{/* <h1 >Edit Profile</h1> */}
|
||||||
<CTableHeaderCell scope="col">Cafe Name</CTableHeaderCell>
|
<CForm className="row g-3">
|
||||||
<CTableDataCell scope="col">{user.cafeName}</CTableDataCell>
|
<CCol xs={12}>
|
||||||
</CTableRow>
|
<CFormLabel htmlFor="inputAddress">Cafe Name</CFormLabel>
|
||||||
</CTableHead>
|
<CFormInput id="inputAddress" placeholder="" name='cafeName' value={"jsw"} />
|
||||||
<CTableBody>
|
</CCol>
|
||||||
<CTableRow>
|
|
||||||
<CTableHeaderCell scope="col">Email</CTableHeaderCell>
|
|
||||||
<CTableDataCell scope="col">{user.email}</CTableDataCell>
|
|
||||||
</CTableRow>
|
|
||||||
|
|
||||||
<CTableRow>
|
<CCol md={6}>
|
||||||
<CTableHeaderCell scope="row">Address</CTableHeaderCell>
|
<CFormLabel htmlFor="inputEmail4">Email</CFormLabel>
|
||||||
<CTableDataCell>{user.location},{user.city},{user.country}</CTableDataCell>
|
<CFormInput type="email" id="inputEmail4" name='email' value={"habhs"} />
|
||||||
</CTableRow>
|
</CCol>
|
||||||
|
{/* <CCol md={6}>
|
||||||
|
<CFormLabel htmlFor="inputPassword4">Password</CFormLabel>
|
||||||
|
<CFormInput type="password" id="inputPassword4" name='password' value={ownerDetails.password} onChange={handleChange} />
|
||||||
|
</CCol> */}
|
||||||
|
|
||||||
<CTableRow>
|
|
||||||
<CTableHeaderCell scope="row">Item_Name</CTableHeaderCell>
|
|
||||||
<CTableDataCell><img src={user.qr_code} alt="" /></CTableDataCell>
|
|
||||||
</CTableRow>
|
|
||||||
|
|
||||||
</CTableBody>
|
<CCol md={12}>
|
||||||
</CTable>
|
<CFormLabel htmlFor="inputCity">Location</CFormLabel>
|
||||||
</div>
|
<CFormInput id="inputCity" name='location' value={"ajnsj"} />
|
||||||
|
</CCol>
|
||||||
|
<CCol md={12}>
|
||||||
|
<CFormLabel htmlFor="inputCity">image</CFormLabel>
|
||||||
|
<CFormInput
|
||||||
|
type="file"
|
||||||
|
placeholder="image"
|
||||||
|
accept="image/*"
|
||||||
|
required
|
||||||
|
// onChange={handleImage}
|
||||||
|
|
||||||
|
|
||||||
|
/>
|
||||||
|
</CCol>
|
||||||
|
{/* <CCol md={6}>
|
||||||
|
<CFormLabel htmlFor="inputState">Country</CFormLabel>
|
||||||
|
<CFormSelect id="inputState" name='country' >
|
||||||
|
<option>Select a country</option>
|
||||||
|
{countries.map(item => <option value={item.name}>{item.name}</option>)}
|
||||||
|
|
||||||
|
</CFormSelect>
|
||||||
|
</CCol> */}
|
||||||
|
{/* <CCol md={6}>
|
||||||
|
<CFormLabel htmlFor="inputState">City</CFormLabel>
|
||||||
|
<CFormSelect id="inputState" name='city' >
|
||||||
|
<option>Select a city</option>
|
||||||
|
{cities.map(item => <option value={item.name}>{item.name}</option>)}
|
||||||
|
|
||||||
|
</CFormSelect>
|
||||||
|
</CCol> */}
|
||||||
|
|
||||||
|
{/* <CCol xs={12}>
|
||||||
|
<CButton onClick={handleSubmit} color='dark'>Submit</CButton>
|
||||||
|
</CCol> */}
|
||||||
|
</CForm>
|
||||||
|
</CCardBody>
|
||||||
|
</CCard>
|
||||||
|
</div >
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
407
src/views/Temples/AddTemple.js
Normal file
407
src/views/Temples/AddTemple.js
Normal file
@ -0,0 +1,407 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import Button from '@material-ui/core/Button'
|
||||||
|
import { Link, useNavigate } from 'react-router-dom'
|
||||||
|
import swal from 'sweetalert'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { isAutheticated } from 'src/auth'
|
||||||
|
// import { WebsiteURL } from '../WebsiteURL'
|
||||||
|
|
||||||
|
const AddTemple = () => {
|
||||||
|
const [WebsiteURL, setWebsiteURL] = useState('https://reinventuniforms.in/')
|
||||||
|
const token = isAutheticated()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const [data, setData] = useState({
|
||||||
|
image: '',
|
||||||
|
imageURL: '',
|
||||||
|
name: '',
|
||||||
|
address_line_1: '',
|
||||||
|
address_line_2: '',
|
||||||
|
city: '',
|
||||||
|
state_name: '',
|
||||||
|
short_url: '',
|
||||||
|
// pan: '',
|
||||||
|
// business_name: '',
|
||||||
|
// gstin: '',
|
||||||
|
// option: '',
|
||||||
|
})
|
||||||
|
|
||||||
|
const [cities, setCities] = useState([])
|
||||||
|
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const [limiter, setLimiter] = useState({
|
||||||
|
name: 100,
|
||||||
|
nameHas: 100,
|
||||||
|
})
|
||||||
|
|
||||||
|
const getRequired = () => {
|
||||||
|
axios
|
||||||
|
.get(`/api/city`, {
|
||||||
|
headers: {
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
setCities([...res.data.data])
|
||||||
|
})
|
||||||
|
.catch((err) => { })
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getRequired()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const handleChange = (e) => {
|
||||||
|
if (e.target.id === 'name') {
|
||||||
|
if (e.target.value.length === limiter[e.target.id] + 1) return
|
||||||
|
setLimiter((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[e.target.id + 'Has']: prev[e.target.id] - e.target.value.length,
|
||||||
|
}))
|
||||||
|
setData((prev) => ({ ...prev, short_url: e.target.value.toLowerCase().replace(/\s+/g, '-') }))
|
||||||
|
}
|
||||||
|
if (e.target.id === 'city') {
|
||||||
|
const city = cities.filter((m) => e.target.value === m?._id)
|
||||||
|
setData((prev) => ({ ...prev, state_name: city[0]?.state?.state_name || '' }))
|
||||||
|
}
|
||||||
|
if (e.target.id === 'image') {
|
||||||
|
if (
|
||||||
|
e.target.files[0]?.type === 'image/jpeg' ||
|
||||||
|
e.target.files[0]?.type === 'image/png' ||
|
||||||
|
e.target.files[0]?.type === 'image/jpg'
|
||||||
|
) {
|
||||||
|
setData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
imageURL: URL.createObjectURL(e.target.files[0]),
|
||||||
|
image: e.target.files[0],
|
||||||
|
}))
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
swal({
|
||||||
|
title: 'Warning',
|
||||||
|
text: 'Upload jpg, jpeg, png only.',
|
||||||
|
icon: 'error',
|
||||||
|
button: 'Close',
|
||||||
|
dangerMode: true,
|
||||||
|
})
|
||||||
|
setData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
imageURL: '',
|
||||||
|
image: '',
|
||||||
|
}))
|
||||||
|
e.target.value = null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setData((prev) => ({ ...prev, [e.target.id]: e.target.value }))
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
if (
|
||||||
|
data.name.trim() === '' ||
|
||||||
|
// data.pan.trim() === '' ||
|
||||||
|
// data.business_name.trim() === '' ||
|
||||||
|
// data.gstin.trim() === '' ||
|
||||||
|
// data.option.trim() === '' ||
|
||||||
|
data.address_line_1.trim() === '' ||
|
||||||
|
data.address_line_2.trim() === '' ||
|
||||||
|
data.city === '' ||
|
||||||
|
data.short_url === '' ||
|
||||||
|
data.state_name === '' ||
|
||||||
|
data.imageURL.trim() === ''
|
||||||
|
) {
|
||||||
|
swal({
|
||||||
|
title: 'Warning',
|
||||||
|
text: 'Fill all mandatory fields',
|
||||||
|
icon: 'error',
|
||||||
|
button: 'Close',
|
||||||
|
dangerMode: true,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setLoading(true)
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.set('name', data.name)
|
||||||
|
// formData.set('pan', data.pan)
|
||||||
|
// formData.set('business_name', data.business_name)
|
||||||
|
// formData.set('gstin', data.gstin)
|
||||||
|
// formData.set('option', data.option)
|
||||||
|
formData.set('address_line_1', data.address_line_1)
|
||||||
|
formData.set('address_line_2', data.address_line_2)
|
||||||
|
formData.set('city', data.city)
|
||||||
|
formData.set('state_name', data.state_name)
|
||||||
|
formData.set('url', WebsiteURL + data.short_url + '/login')
|
||||||
|
formData.set('short_url', data.short_url)
|
||||||
|
formData.append('image', data.image)
|
||||||
|
axios
|
||||||
|
.post(`/api/temple`, formData, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
'Content-Type': 'multipart/formdata',
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
swal({
|
||||||
|
title: 'Added',
|
||||||
|
text: 'Temple added successfully!',
|
||||||
|
icon: 'success',
|
||||||
|
button: 'Return',
|
||||||
|
})
|
||||||
|
setLoading(false)
|
||||||
|
navigate('/temples', { replace: true })
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
setLoading(false)
|
||||||
|
const message = err.response?.data?.message || 'Something went wrong!'
|
||||||
|
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: '22px' }} className="fw-bold">
|
||||||
|
Add Temple
|
||||||
|
</div>
|
||||||
|
<div style={{ display: 'flex', gap: '1rem' }}>
|
||||||
|
<h4 className="mb-0"></h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="page-title-right">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
style={{
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: '1rem',
|
||||||
|
textTransform: 'capitalize',
|
||||||
|
marginRight: '5px',
|
||||||
|
}}
|
||||||
|
onClick={() => handleSubmit()}
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
{loading ? 'Loading' : 'Save'}
|
||||||
|
</Button>
|
||||||
|
<Link to="/temples">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
style={{
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: '1rem',
|
||||||
|
textTransform: 'capitalize',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-6 my-1">
|
||||||
|
<div className="card h-100">
|
||||||
|
<div className="card-body px-5">
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Temple Name*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="name"
|
||||||
|
value={data.name}
|
||||||
|
maxLength={limiter.name}
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
<p className="pt-1 pl-2 text-secondary">Remaining characters : {limiter.nameHas}</p>
|
||||||
|
</div>
|
||||||
|
{/* <div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
PAN*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="pan"
|
||||||
|
value={data.pan}
|
||||||
|
maxLength="50"
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
</div> */}
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Address Line 1*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="address_line_1"
|
||||||
|
value={data.address_line_1}
|
||||||
|
maxLength="50"
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Address Line 2*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="address_line_2"
|
||||||
|
value={data.address_line_2}
|
||||||
|
maxLength="50"
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/* <div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Business Name*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="business_name"
|
||||||
|
value={data.business_name}
|
||||||
|
maxLength="50"
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
</div> */}
|
||||||
|
{/* <div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
GSTIN*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="gstin"
|
||||||
|
value={data.gstin}
|
||||||
|
maxLength="50"
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
</div> */}
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="pageToLink" className="form-label">
|
||||||
|
City*
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
value={data.city}
|
||||||
|
className="form-control"
|
||||||
|
id="city"
|
||||||
|
>
|
||||||
|
<option value="">---select---</option>
|
||||||
|
{cities[0] ? (
|
||||||
|
cities.map((c, i) => (
|
||||||
|
<option key={i} value={c._id}>
|
||||||
|
{c.city_name + ', ' + c.state?.state_name}
|
||||||
|
</option>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<option value="" disabled>
|
||||||
|
Please add a City
|
||||||
|
</option>
|
||||||
|
)}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
State*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="state_name"
|
||||||
|
value={data.state_name}
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-6 my-1">
|
||||||
|
<div className="card h-100">
|
||||||
|
<div className="card-body px-5">
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
URL*
|
||||||
|
</label>
|
||||||
|
<div className="input-group mb-3">
|
||||||
|
<span className="input-group-text" id="basic-addon3">
|
||||||
|
{WebsiteURL}
|
||||||
|
</span>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="short_url"
|
||||||
|
aria-describedby="basic-addon3"
|
||||||
|
value={data.short_url}
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* <div className="mb-3">
|
||||||
|
<label htmlFor="option" className="form-label">
|
||||||
|
Option*
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
className="form-control"
|
||||||
|
id="option"
|
||||||
|
value={data.option}
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
>
|
||||||
|
<option value="">None</option>
|
||||||
|
<option value="group">Group</option>
|
||||||
|
<option value="bundle">Bundle</option>
|
||||||
|
</select>
|
||||||
|
</div> */}
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="image" className="form-label">
|
||||||
|
Temple Banner*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
className="form-control"
|
||||||
|
id="image"
|
||||||
|
accept="image/*"
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
<p className="pt-1 pl-2 text-secondary">Upload jpg, jpeg and png only*</p>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3" style={{ height: '200px', maxWdth: '100%' }}>
|
||||||
|
<img
|
||||||
|
src={data.imageURL}
|
||||||
|
alt="Uploaded Image will be shown here"
|
||||||
|
style={{ maxHeight: '200px', maxWidth: '100%' }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AddTemple
|
423
src/views/Temples/EditTemple.js
Normal file
423
src/views/Temples/EditTemple.js
Normal file
@ -0,0 +1,423 @@
|
|||||||
|
|
||||||
|
|
||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import Button from '@material-ui/core/Button'
|
||||||
|
import { Link, useNavigate, useParams } from 'react-router-dom'
|
||||||
|
import swal from 'sweetalert'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { isAutheticated } from 'src/auth'
|
||||||
|
|
||||||
|
const EditTemple = () => {
|
||||||
|
|
||||||
|
|
||||||
|
const [WebsiteURL, setWebsiteURL] = useState('https://reinventuniforms.in/')
|
||||||
|
const id = useParams()?.id
|
||||||
|
const token = isAutheticated()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const [data, setData] = useState({
|
||||||
|
image: '',
|
||||||
|
imageURL: '',
|
||||||
|
name: '',
|
||||||
|
address_line_1: '',
|
||||||
|
address_line_2: '',
|
||||||
|
city: '',
|
||||||
|
state_name: '',
|
||||||
|
short_url: '',
|
||||||
|
pan: '',
|
||||||
|
business_name: '',
|
||||||
|
gstin: '',
|
||||||
|
option: '',
|
||||||
|
})
|
||||||
|
const [cities, setCities] = useState([])
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const [limiter, setLimiter] = useState({
|
||||||
|
name: 100,
|
||||||
|
nameHas: 100,
|
||||||
|
})
|
||||||
|
|
||||||
|
const getRequired = async () => {
|
||||||
|
await axios
|
||||||
|
.get(`/api/city`, {
|
||||||
|
headers: {
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
setCities([...res.data.data])
|
||||||
|
})
|
||||||
|
.catch((err) => { })
|
||||||
|
axios
|
||||||
|
.get(`/api/Temple/withoutpopulate/${id}`, {
|
||||||
|
headers: {
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
setData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
...res.data?.data,
|
||||||
|
city: res.data?.data?.city,
|
||||||
|
imageURL: res.data?.data?.banner?.url,
|
||||||
|
}))
|
||||||
|
setLimiter((prev) => ({ ...prev, nameHas: prev.name - res.data?.data?.name?.length || 0 }))
|
||||||
|
})
|
||||||
|
.catch((err) => { })
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getRequired()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const setStateName = () => {
|
||||||
|
const city = cities.filter((m) => data.city === m?._id)
|
||||||
|
setData((prev) => ({ ...prev, state_name: city[0]?.state?.state_name || '' }))
|
||||||
|
}
|
||||||
|
setStateName()
|
||||||
|
}, [data.city])
|
||||||
|
|
||||||
|
const handleChange = (e) => {
|
||||||
|
if (e.target.id === 'name') {
|
||||||
|
if (e.target.value.length === limiter[e.target.id] + 1) return
|
||||||
|
setLimiter((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[e.target.id + 'Has']: prev[e.target.id] - e.target.value.length,
|
||||||
|
}))
|
||||||
|
// setData((prev) => ({ ...prev, short_url: e.target.value.toLowerCase().replace(/\s+/g, '-') }))
|
||||||
|
}
|
||||||
|
if (e.target.id === 'image') {
|
||||||
|
if (
|
||||||
|
e.target.files[0]?.type === 'image/jpeg' ||
|
||||||
|
e.target.files[0]?.type === 'image/png' ||
|
||||||
|
e.target.files[0]?.type === 'image/jpg'
|
||||||
|
) {
|
||||||
|
setData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
imageURL: URL.createObjectURL(e.target.files[0]),
|
||||||
|
image: e.target.files[0],
|
||||||
|
}))
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
swal({
|
||||||
|
title: 'Warning',
|
||||||
|
text: 'Upload jpg, jpeg, png only.',
|
||||||
|
icon: 'error',
|
||||||
|
button: 'Close',
|
||||||
|
dangerMode: true,
|
||||||
|
})
|
||||||
|
setData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
imageURL: '',
|
||||||
|
image: '',
|
||||||
|
}))
|
||||||
|
e.target.value = null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setData((prev) => ({ ...prev, [e.target.id]: e.target.value }))
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
if (
|
||||||
|
data.name.trim() === '' ||
|
||||||
|
data.address_line_1.trim() === '' ||
|
||||||
|
data.address_line_2.trim() === '' ||
|
||||||
|
data.city === '' ||
|
||||||
|
data.short_url === '' ||
|
||||||
|
data.state_name === ''
|
||||||
|
) {
|
||||||
|
swal({
|
||||||
|
title: 'Warning',
|
||||||
|
text: 'Fill all mandatory fields',
|
||||||
|
icon: 'error',
|
||||||
|
button: 'Close',
|
||||||
|
dangerMode: true,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setLoading(true)
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.set('name', data.name)
|
||||||
|
// formData.set('pan', data.pan)
|
||||||
|
// formData.set('business_name', data.business_name)
|
||||||
|
// formData.set('gstin', data.gstin)
|
||||||
|
// formData.set('option', data.option)
|
||||||
|
formData.set('address_line_1', data.address_line_1)
|
||||||
|
formData.set('address_line_2', data.address_line_2)
|
||||||
|
formData.set('city', data.city)
|
||||||
|
formData.set('state_name', data.state_name)
|
||||||
|
formData.set('url', WebsiteURL + data.short_url + '/login')
|
||||||
|
formData.set('short_url', data.short_url)
|
||||||
|
formData.append('image', data.image)
|
||||||
|
axios
|
||||||
|
.patch(`/api/Temple/${id}`, formData, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
'Content-Type': 'multipart/formdata',
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
swal({
|
||||||
|
title: 'Updated',
|
||||||
|
text: 'Temple updated successfully!',
|
||||||
|
icon: 'success',
|
||||||
|
button: 'Return',
|
||||||
|
})
|
||||||
|
setLoading(false)
|
||||||
|
navigate('/temples', { replace: true })
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
setLoading(false)
|
||||||
|
const message = err.response?.data?.message || 'Something went wrong!'
|
||||||
|
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: '22px' }} className="fw-bold">
|
||||||
|
Edit Temple
|
||||||
|
</div>
|
||||||
|
<div style={{ display: 'flex', gap: '1rem' }}>
|
||||||
|
<h4 className="mb-0"></h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="page-title-right">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
style={{
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: '1rem',
|
||||||
|
textTransform: 'capitalize',
|
||||||
|
marginRight: '5px',
|
||||||
|
}}
|
||||||
|
onClick={() => handleSubmit()}
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
{loading ? 'Loading' : 'Update'}
|
||||||
|
</Button>
|
||||||
|
<Link to="/temples">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
style={{
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: '1rem',
|
||||||
|
textTransform: 'capitalize',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-6 my-1">
|
||||||
|
<div className="card h-100">
|
||||||
|
<div className="card-body px-5">
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Temple Name*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="name"
|
||||||
|
value={data.name}
|
||||||
|
maxLength={limiter.name}
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
<p className="pt-1 pl-2 text-secondary">Remaining characters : {limiter.nameHas}</p>
|
||||||
|
</div>
|
||||||
|
{/* <div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
PAN*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="pan"
|
||||||
|
value={data.pan}
|
||||||
|
maxLength="50"
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
</div> */}
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Address Line 1*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="address_line_1"
|
||||||
|
value={data.address_line_1}
|
||||||
|
maxLength="50"
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Address Line 2*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="address_line_2"
|
||||||
|
value={data.address_line_2}
|
||||||
|
maxLength="50"
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/* <div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Business Name*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="business_name"
|
||||||
|
value={data.business_name}
|
||||||
|
maxLength="50"
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
GSTIN*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="gstin"
|
||||||
|
value={data.gstin}
|
||||||
|
maxLength="50"
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
</div> */}
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="pageToLink" className="form-label">
|
||||||
|
City*
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
value={data.city}
|
||||||
|
className="form-control"
|
||||||
|
id="city"
|
||||||
|
>
|
||||||
|
<option value="">---select---</option>
|
||||||
|
{cities[0] ? (
|
||||||
|
cities.map((c, i) => (
|
||||||
|
<option key={i} value={c._id}>
|
||||||
|
{c.city_name + ', ' + c.state?.state_name}
|
||||||
|
</option>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<option value="" disabled>
|
||||||
|
Please add a City
|
||||||
|
</option>
|
||||||
|
)}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
State*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="state_name"
|
||||||
|
value={data.state_name}
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-6 my-1">
|
||||||
|
<div className="card h-100">
|
||||||
|
<div className="card-body px-5">
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
URL*
|
||||||
|
</label>
|
||||||
|
<div className="input-group mb-3">
|
||||||
|
<span className="input-group-text" id="basic-addon3">
|
||||||
|
{WebsiteURL}
|
||||||
|
</span>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="short_url"
|
||||||
|
aria-describedby="basic-addon3"
|
||||||
|
value={data.short_url}
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* <div className="mb-3">
|
||||||
|
<label htmlFor="option" className="form-label">
|
||||||
|
Option*
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
className="form-control"
|
||||||
|
id="option"
|
||||||
|
value={data.option}
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
>
|
||||||
|
<option value="">None</option>
|
||||||
|
<option value="group">Group</option>
|
||||||
|
<option value="bundle">Bundle</option>
|
||||||
|
</select>
|
||||||
|
</div> */}
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="image" className="form-label">
|
||||||
|
Temple Banner*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
className="form-control"
|
||||||
|
id="image"
|
||||||
|
accept="image/*"
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
<p className="pt-1 pl-2 text-secondary">Upload jpg, jpeg and png only*</p>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3" style={{ height: '200px', maxWdth: '100%' }}>
|
||||||
|
<img
|
||||||
|
src={data.imageURL}
|
||||||
|
alt="Uploaded Image will be shown here"
|
||||||
|
style={{ maxHeight: '200px', maxWidth: '100%' }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EditTemple
|
29
src/views/Temples/OverLayButton.js
Normal file
29
src/views/Temples/OverLayButton.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import React, { useState, useRef } from 'react'
|
||||||
|
import Button from 'react-bootstrap/Button'
|
||||||
|
import Overlay from 'react-bootstrap/Overlay'
|
||||||
|
import Tooltip from 'react-bootstrap/Tooltip'
|
||||||
|
|
||||||
|
function OverLayButton(props) {
|
||||||
|
const { url } = props?.data || ''
|
||||||
|
const [show, setShow] = useState(false)
|
||||||
|
const target = useRef(null)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span>
|
||||||
|
<Button ref={target} onClick={() => setShow(!show)} size="sm" variant="outline-info">
|
||||||
|
URL
|
||||||
|
</Button>
|
||||||
|
<Overlay target={target.current} show={show} placement="top">
|
||||||
|
{(props) => (
|
||||||
|
<Tooltip id="overlay-example" {...props}>
|
||||||
|
<a href={url} target="_blank" className="text-white">
|
||||||
|
{url}
|
||||||
|
</a>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
</Overlay>
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default OverLayButton
|
351
src/views/Temples/Temples.js
Normal file
351
src/views/Temples/Temples.js
Normal file
@ -0,0 +1,351 @@
|
|||||||
|
|
||||||
|
import React, { useEffect } from 'react'
|
||||||
|
import Button from '@material-ui/core/Button'
|
||||||
|
import { useState } from 'react'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
import axios from 'axios'
|
||||||
|
import swal from 'sweetalert'
|
||||||
|
import OverLayButton from './OverLayButton.js'
|
||||||
|
import { isAutheticated } from 'src/auth.js'
|
||||||
|
|
||||||
|
const Temples = () => {
|
||||||
|
const token = isAutheticated()
|
||||||
|
const [loading, setLoading] = useState(true)
|
||||||
|
const [success, setSuccess] = useState(true)
|
||||||
|
const [TemplesData, setTemplesData] = useState([])
|
||||||
|
|
||||||
|
const [currentPage, setCurrentPage] = useState(1)
|
||||||
|
const [itemPerPage, setItemPerPage] = useState(10)
|
||||||
|
const [showData, setShowData] = useState(TemplesData)
|
||||||
|
|
||||||
|
const handleShowEntries = (e) => {
|
||||||
|
setCurrentPage(1)
|
||||||
|
setItemPerPage(e.target.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCategories = () => {
|
||||||
|
axios
|
||||||
|
.get(`/api/temple`, {
|
||||||
|
headers: { 'Access-Control-Allow-Origin': '*', Authorization: `Bearer ${token}` },
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
setTemplesData(res.data.data)
|
||||||
|
setLoading(false)
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err)
|
||||||
|
setLoading(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getCategories()
|
||||||
|
}, [success])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const loadData = () => {
|
||||||
|
const indexOfLastPost = currentPage * itemPerPage
|
||||||
|
const indexOfFirstPost = indexOfLastPost - itemPerPage
|
||||||
|
setShowData(TemplesData.slice(indexOfFirstPost, indexOfLastPost))
|
||||||
|
}
|
||||||
|
loadData()
|
||||||
|
}, [currentPage, itemPerPage, TemplesData])
|
||||||
|
|
||||||
|
const handleDelete = (id) => {
|
||||||
|
swal({
|
||||||
|
title: 'Are you sure?',
|
||||||
|
icon: 'error',
|
||||||
|
buttons: { Yes: { text: 'Yes', value: true }, Cancel: { text: 'Cancel', value: 'cancel' } },
|
||||||
|
}).then((value) => {
|
||||||
|
if (value === true) {
|
||||||
|
axios
|
||||||
|
.delete(`/api/temple/${id}`, {
|
||||||
|
headers: {
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
setSuccess((prev) => !prev)
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
swal({
|
||||||
|
title: 'Warning',
|
||||||
|
text: 'Something went wrong!',
|
||||||
|
icon: 'error',
|
||||||
|
button: 'Retry',
|
||||||
|
dangerMode: true,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="main-content">
|
||||||
|
<div className="page-content">
|
||||||
|
<div className="container-fluid">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-12">
|
||||||
|
<div
|
||||||
|
className="
|
||||||
|
page-title-box
|
||||||
|
d-flex
|
||||||
|
align-items-center
|
||||||
|
justify-content-between
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div style={{ fontSize: '22px' }} className="fw-bold">
|
||||||
|
Temples
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="page-title-right">
|
||||||
|
<Link to="/temple/add">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
style={{
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: '1rem',
|
||||||
|
textTransform: 'capitalize',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Add Temple
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="card">
|
||||||
|
<div className="card-body">
|
||||||
|
<div className="row ml-0 mr-0 mb-10">
|
||||||
|
<div className="col-sm-12 col-md-12">
|
||||||
|
<div className="dataTables_length">
|
||||||
|
<label className="w-100">
|
||||||
|
Show
|
||||||
|
<select
|
||||||
|
style={{ width: '10%' }}
|
||||||
|
name=""
|
||||||
|
onChange={(e) => handleShowEntries(e)}
|
||||||
|
className="
|
||||||
|
select-w
|
||||||
|
custom-select custom-select-sm
|
||||||
|
form-control form-control-sm
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<option value="10">10</option>
|
||||||
|
<option value="25">25</option>
|
||||||
|
<option value="50">50</option>
|
||||||
|
<option value="100">100</option>
|
||||||
|
</select>
|
||||||
|
entries
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="table-responsive table-shoot mt-3">
|
||||||
|
<table
|
||||||
|
className="table table-centered table-nowrap"
|
||||||
|
style={{ border: '1px solid' }}
|
||||||
|
>
|
||||||
|
<thead className="thead-info" style={{ background: 'rgb(140, 213, 213)' }}>
|
||||||
|
<tr>
|
||||||
|
<th className="text-start">Temple Name</th>
|
||||||
|
<th className="text-start">Logo</th>
|
||||||
|
<th className="text-start">City </th>
|
||||||
|
<th className="text-start">Created On</th>
|
||||||
|
<th className="text-center">Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{!loading && showData.length === 0 && (
|
||||||
|
<tr className="text-center">
|
||||||
|
<td colSpan="6">
|
||||||
|
<h5>No Data Available</h5>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
{loading ? (
|
||||||
|
<tr>
|
||||||
|
<td className="text-center" colSpan="6">
|
||||||
|
Loading...
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
) : (
|
||||||
|
showData.map((temple, i) => {
|
||||||
|
return (
|
||||||
|
<tr key={i}>
|
||||||
|
<td className="text-start">{temple.name}</td>
|
||||||
|
<td className="text-start">
|
||||||
|
<img src={temple.banner.url} alt="Test Image" height="50" />
|
||||||
|
</td>
|
||||||
|
<td className="text-start">{temple?.city?.city_name}</td>
|
||||||
|
<td className="text-start">
|
||||||
|
{new Date(temple.createdAt).toLocaleString('en-IN', {
|
||||||
|
month: '2-digit',
|
||||||
|
day: 'numeric',
|
||||||
|
year: 'numeric',
|
||||||
|
// hour: 'numeric',
|
||||||
|
// minute: 'numeric',
|
||||||
|
// hour12: true,
|
||||||
|
})}
|
||||||
|
</td>
|
||||||
|
<td className=" text-center">
|
||||||
|
<OverLayButton data={{ url: temple?.url }} />
|
||||||
|
|
||||||
|
<Link to={`/temple/products/${temple._id}`}>
|
||||||
|
<button
|
||||||
|
style={{ color: 'white' }}
|
||||||
|
type="button"
|
||||||
|
className="
|
||||||
|
btn btn-primary btn-sm
|
||||||
|
waves-effect waves-light
|
||||||
|
ms-2
|
||||||
|
"
|
||||||
|
>
|
||||||
|
Products
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<Link to={`/temple/edit/${temple._id}`}>
|
||||||
|
<button
|
||||||
|
style={{ color: 'white' }}
|
||||||
|
type="button"
|
||||||
|
className="
|
||||||
|
btn btn-success btn-sm
|
||||||
|
waves-effect waves-light
|
||||||
|
ms-2
|
||||||
|
"
|
||||||
|
>
|
||||||
|
Edit
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
<button
|
||||||
|
style={{ color: 'white' }}
|
||||||
|
type="button"
|
||||||
|
className="
|
||||||
|
btn btn-danger btn-sm
|
||||||
|
waves-effect waves-light
|
||||||
|
ms-2
|
||||||
|
|
||||||
|
"
|
||||||
|
onClick={() => {
|
||||||
|
handleDelete(temple._id)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
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 {currentPage * itemPerPage - itemPerPage + 1} to{' '}
|
||||||
|
{Math.min(currentPage * itemPerPage, TemplesData.length)} of{' '}
|
||||||
|
{TemplesData.length} entries
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-sm-12 col-md-6">
|
||||||
|
<div className="d-flex">
|
||||||
|
<ul className="pagination ms-auto">
|
||||||
|
<li
|
||||||
|
className={
|
||||||
|
currentPage === 1
|
||||||
|
? 'paginate_button page-item previous disabled'
|
||||||
|
: 'paginate_button page-item previous'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: 'pointer' }}
|
||||||
|
onClick={() => setCurrentPage((prev) => prev - 1)}
|
||||||
|
>
|
||||||
|
Previous
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{!(currentPage - 1 < 1) && (
|
||||||
|
<li className="paginate_button page-item">
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: 'pointer' }}
|
||||||
|
onClick={(e) => setCurrentPage((prev) => prev - 1)}
|
||||||
|
>
|
||||||
|
{currentPage - 1}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<li className="paginate_button page-item active">
|
||||||
|
<span className="page-link" style={{ cursor: 'pointer' }}>
|
||||||
|
{currentPage}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{!(
|
||||||
|
(currentPage + 1) * itemPerPage - itemPerPage >
|
||||||
|
TemplesData.length - 1
|
||||||
|
) && (
|
||||||
|
<li className="paginate_button page-item ">
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: 'pointer' }}
|
||||||
|
onClick={() => {
|
||||||
|
setCurrentPage((prev) => prev + 1)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{currentPage + 1}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<li
|
||||||
|
className={
|
||||||
|
!(
|
||||||
|
(currentPage + 1) * itemPerPage - itemPerPage >
|
||||||
|
TemplesData.length - 1
|
||||||
|
)
|
||||||
|
? 'paginate_button page-item next'
|
||||||
|
: 'paginate_button page-item next disabled'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: 'pointer' }}
|
||||||
|
onClick={() => setCurrentPage((prev) => prev + 1)}
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Temples
|
25
src/views/Users/Pagination.js
Normal file
25
src/views/Users/Pagination.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
const Pagination = ({ userPerPage, totalUsers, paginate }) => {
|
||||||
|
const pageNumbers = [];
|
||||||
|
|
||||||
|
for (let i = 1; i <= Math.ceil(totalUsers / userPerPage); 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="/users" className='page-link'>
|
||||||
|
{number}
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Pagination;
|
131
src/views/Users/ViewUsers.js
Normal file
131
src/views/Users/ViewUsers.js
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
|
||||||
|
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 ViewUsers() {
|
||||||
|
const [user, setUser] = useState([])
|
||||||
|
const { id } = useParams();
|
||||||
|
// console.log(id)
|
||||||
|
const token = isAutheticated();
|
||||||
|
|
||||||
|
const getUserDetails = useCallback(async () => {
|
||||||
|
|
||||||
|
|
||||||
|
let resp = await axios.get(
|
||||||
|
`/api/v1/admin/user/${id}`,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
setUser(resp.data.user)
|
||||||
|
|
||||||
|
|
||||||
|
}, [token]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getUserDetails();
|
||||||
|
}, [getUserDetails]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//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>{user?._id}</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
|
<tr><th>Name</th>
|
||||||
|
<td>{user?.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>
|
||||||
|
|
||||||
|
{/* <th>Description</th> */}
|
||||||
|
<tr><th>Phone No.</th>
|
||||||
|
<td>{user?.phone}</td></tr>
|
||||||
|
<tr><th>Role</th>
|
||||||
|
<td>{user?.role}</td></tr>
|
||||||
|
<tr><th>Register At</th>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
{new Date(`${user?.createdAt}`).toDateString()}<span> , {`${formatAMPM(user?.createdAt)}`}</span>
|
||||||
|
</td></tr>
|
||||||
|
<tr><th>Profile Updated At</th>
|
||||||
|
<td>
|
||||||
|
{new Date(`${user?.updatedAt}`).toDateString()}<span> , {`${formatAMPM(user?.updatedAt)}`}</span>
|
||||||
|
</td></tr>
|
||||||
|
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{/* <!-- end table-responsive --> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* <!-- container-fluid --> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ViewUsers;
|
||||||
|
|
153
src/views/Users/users.js
Normal file
153
src/views/Users/users.js
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
|
||||||
|
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 users() {
|
||||||
|
const [users, setUsers] = useState([])
|
||||||
|
|
||||||
|
|
||||||
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
|
const [userPerPage] = useState(10);
|
||||||
|
const token = isAutheticated();
|
||||||
|
|
||||||
|
const getAllUsers = useCallback(async () => {
|
||||||
|
let res = await axios.get(
|
||||||
|
`/api/v1/admin/users`,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
// console.log(res.data)
|
||||||
|
setUsers(res.data.users)
|
||||||
|
|
||||||
|
|
||||||
|
}, [token]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getAllUsers();
|
||||||
|
}, [getAllUsers]);
|
||||||
|
|
||||||
|
|
||||||
|
// console.log(cmsRes)
|
||||||
|
|
||||||
|
// Get current posts
|
||||||
|
//pagination
|
||||||
|
const indexOfLastUser = currentPage * userPerPage;
|
||||||
|
const indexOfFirstUser = indexOfLastUser - userPerPage;
|
||||||
|
const currentUser = users.slice(indexOfFirstUser, indexOfLastUser);
|
||||||
|
|
||||||
|
// 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 - All 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>email</th>
|
||||||
|
<th>Profile Image</th>
|
||||||
|
<th>Phone No.</th>
|
||||||
|
<th>Register At</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{currentUser && currentUser.map((item, index) =>
|
||||||
|
<tr>
|
||||||
|
|
||||||
|
<td>{item?.name}</td>
|
||||||
|
<td>{item?.email}</td>
|
||||||
|
<td>
|
||||||
|
<img src={`${item.avatar?.url}`} width="50" alt="" />
|
||||||
|
</td>
|
||||||
|
<td>{item?.phone}</td>
|
||||||
|
|
||||||
|
|
||||||
|
<td>
|
||||||
|
|
||||||
|
{new Date(`${item?.createdAt}`).toDateString()}<span> , {`${formatAMPM(item?.createdAt)}`}</span>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<Link to={`/users/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 userPerPage={userPerPage}
|
||||||
|
totalUsers={users.length}
|
||||||
|
paginate={paginate} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default users;
|
293
src/views/configuration/Address.js
Normal file
293
src/views/configuration/Address.js
Normal file
@ -0,0 +1,293 @@
|
|||||||
|
import axios from 'axios'
|
||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
|
||||||
|
import ClipLoader from 'react-spinners/ClipLoader'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
import swal from 'sweetalert'
|
||||||
|
import { isAutheticated } from 'src/auth'
|
||||||
|
|
||||||
|
|
||||||
|
function Address() {
|
||||||
|
const token = isAutheticated()
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const [company, setCompany] = useState('')
|
||||||
|
const [address, setAddress] = useState('')
|
||||||
|
const [city, setCity] = useState('')
|
||||||
|
const [state, setState] = useState('')
|
||||||
|
const [country, setCountry] = useState('')
|
||||||
|
const [pincode, setPincode] = useState('')
|
||||||
|
const [website, setWebsite] = useState('')
|
||||||
|
const [contact, setContact] = useState('')
|
||||||
|
const [email, setEmail] = useState('')
|
||||||
|
const [gstin, setGSTIN] = useState('')
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
async function getConfiguration() {
|
||||||
|
const configDetails = await axios.get(`/api/config`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
configDetails.data.result.map((item) => {
|
||||||
|
item.address.map((el) => {
|
||||||
|
setCompany(el.company)
|
||||||
|
setAddress(el.address)
|
||||||
|
setCity(el.city)
|
||||||
|
setState(el.state)
|
||||||
|
setCountry(el.country)
|
||||||
|
setPincode(el.pincode)
|
||||||
|
setWebsite(el.website)
|
||||||
|
setContact(el.contact)
|
||||||
|
setEmail(el.email)
|
||||||
|
setGSTIN(el?.gstin)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
getConfiguration()
|
||||||
|
}, [])
|
||||||
|
async function handelChange(e) {
|
||||||
|
if (e.target.name.toLowerCase() === 'address') {
|
||||||
|
setAddress(e.target.value)
|
||||||
|
} else if (e.target.name.toLowerCase() === 'company name') {
|
||||||
|
setCompany(e.target.value)
|
||||||
|
} else if (e.target.name.toLowerCase() === 'city') {
|
||||||
|
setCity(e.target.value)
|
||||||
|
} else if (e.target.name.toLowerCase() === 'state') {
|
||||||
|
setState(e.target.value)
|
||||||
|
} else if (e.target.name.toLowerCase() === 'country') {
|
||||||
|
setCountry(e.target.value)
|
||||||
|
} else if (e.target.name.toLowerCase() === 'pincode') {
|
||||||
|
setPincode(e.target.value)
|
||||||
|
} else if (e.target.name.toLowerCase() === 'website') {
|
||||||
|
setWebsite(e.target.value)
|
||||||
|
} else if (e.target.name.toLowerCase() === 'contact number') {
|
||||||
|
setContact(e.target.value)
|
||||||
|
} else if (e.target.name.toLowerCase() === 'email') {
|
||||||
|
setEmail(e.target.value)
|
||||||
|
} else if (e.target.name.toLowerCase() === 'gstin') {
|
||||||
|
setGSTIN(e.target.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function handelSubmit() {
|
||||||
|
if (!/^[0-9A-Za-z]{15}$/.test(gstin)) return swal('Warning!', 'Enter valid GSTIN')
|
||||||
|
setLoading(true)
|
||||||
|
let data = {
|
||||||
|
company,
|
||||||
|
address,
|
||||||
|
city,
|
||||||
|
state,
|
||||||
|
country,
|
||||||
|
pincode,
|
||||||
|
website,
|
||||||
|
contact,
|
||||||
|
email,
|
||||||
|
gstin,
|
||||||
|
}
|
||||||
|
let res = await axios.post(`/api/config/address`, data, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
setLoading(false)
|
||||||
|
console.log(res)
|
||||||
|
swal('Success!', res.data.message, res.data.status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="main-content">
|
||||||
|
<div className="page-content">
|
||||||
|
<div className="container-fluid">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="card">
|
||||||
|
<div className="card-body">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12 col-lg-6 col-xl-6">
|
||||||
|
<h1 className="text-left head-small">Address</h1>
|
||||||
|
|
||||||
|
<form>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="form-group">
|
||||||
|
<>
|
||||||
|
<label
|
||||||
|
htmlFor="basicpill-phoneno-input"
|
||||||
|
className="label-100 mt-3"
|
||||||
|
>
|
||||||
|
Company Name
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="company name"
|
||||||
|
value={company}
|
||||||
|
onChange={(e) => handelChange(e)}
|
||||||
|
className="form-control input-field "
|
||||||
|
id="basicpill-phoneno-input"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
htmlFor="basicpill-phoneno-input"
|
||||||
|
className="label-100 mt-3"
|
||||||
|
>
|
||||||
|
Address
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
value={address}
|
||||||
|
type="text"
|
||||||
|
name="address"
|
||||||
|
onChange={(e) => handelChange(e)}
|
||||||
|
className="form-control input-field "
|
||||||
|
id="basicpill-phoneno-input"
|
||||||
|
/>{' '}
|
||||||
|
<label
|
||||||
|
htmlFor="basicpill-phoneno-input"
|
||||||
|
className="label-100 mt-3"
|
||||||
|
>
|
||||||
|
City
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
value={city}
|
||||||
|
type="text"
|
||||||
|
name="city"
|
||||||
|
onChange={(e) => handelChange(e)}
|
||||||
|
className="form-control input-field "
|
||||||
|
id="basicpill-phoneno-input"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
htmlFor="basicpill-phoneno-input"
|
||||||
|
className="label-100 mt-3"
|
||||||
|
>
|
||||||
|
State
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
value={state}
|
||||||
|
type="text"
|
||||||
|
name="state"
|
||||||
|
onChange={(e) => handelChange(e)}
|
||||||
|
className="form-control input-field "
|
||||||
|
id="basicpill-phoneno-input"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
htmlFor="basicpill-phoneno-input"
|
||||||
|
className="label-100 mt-3"
|
||||||
|
>
|
||||||
|
Country
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
value={country}
|
||||||
|
type="text"
|
||||||
|
name="country"
|
||||||
|
onChange={(e) => handelChange(e)}
|
||||||
|
className="form-control input-field "
|
||||||
|
id="basicpill-phoneno-input"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
htmlFor="basicpill-phoneno-input"
|
||||||
|
className="label-100 mt-3"
|
||||||
|
>
|
||||||
|
Pin Code
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
value={pincode}
|
||||||
|
type="text"
|
||||||
|
name="pincode"
|
||||||
|
onChange={(e) => handelChange(e)}
|
||||||
|
className="form-control input-field "
|
||||||
|
id="basicpill-phoneno-input"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
htmlFor="basicpill-phoneno-input"
|
||||||
|
className="label-100 mt-3"
|
||||||
|
>
|
||||||
|
GSTIN
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
value={gstin}
|
||||||
|
type="text"
|
||||||
|
name="gstin"
|
||||||
|
onChange={(e) => handelChange(e)}
|
||||||
|
className="form-control input-field "
|
||||||
|
id="basicpill-phoneno-input"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
htmlFor="basicpill-phoneno-input"
|
||||||
|
className="label-100 mt-3"
|
||||||
|
>
|
||||||
|
Website
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
value={website}
|
||||||
|
type="text"
|
||||||
|
name="website"
|
||||||
|
onChange={(e) => handelChange(e)}
|
||||||
|
className="form-control input-field "
|
||||||
|
id="basicpill-phoneno-input"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
htmlFor="basicpill-phoneno-input"
|
||||||
|
className="label-100 mt-3"
|
||||||
|
>
|
||||||
|
Contact Number
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
value={contact}
|
||||||
|
type="text"
|
||||||
|
name="contact number"
|
||||||
|
onChange={(e) => handelChange(e)}
|
||||||
|
className="form-control input-field "
|
||||||
|
id="basicpill-phoneno-input"
|
||||||
|
/>{' '}
|
||||||
|
<label
|
||||||
|
htmlFor="basicpill-phoneno-input"
|
||||||
|
className="label-100 mt-3"
|
||||||
|
>
|
||||||
|
Email
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
value={email}
|
||||||
|
type="text"
|
||||||
|
name="email"
|
||||||
|
onChange={(e) => handelChange(e)}
|
||||||
|
className="form-control input-field "
|
||||||
|
id="basicpill-phoneno-input"
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row mt-2">
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="form-group text-left">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={handelSubmit}
|
||||||
|
className="btn btn-success btn-login waves-effect waves-light mr-3 pt-2 pb-2 pr-4 pl-4"
|
||||||
|
>
|
||||||
|
<ClipLoader loading={loading} size={18} />
|
||||||
|
{!loading && 'Save'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* <!-- end table-responsive --> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* <!-- container-fluid --> */}
|
||||||
|
</div>
|
||||||
|
{/* <!-- End Page-content --> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Address
|
222
src/views/configuration/Logo.js
Normal file
222
src/views/configuration/Logo.js
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
|
||||||
|
import swal from 'sweetalert'
|
||||||
|
import ClipLoader from 'react-spinners/ClipLoader'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { isAutheticated } from 'src/auth'
|
||||||
|
|
||||||
|
function Logo() {
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const [Headerlogo, setHeaderlogo] = useState('')
|
||||||
|
const [Footerlogo, setFooterlogo] = useState('')
|
||||||
|
const [Adminlogo, setAdminlogo] = useState('')
|
||||||
|
const [display, setDisplay] = useState(true)
|
||||||
|
const token = isAutheticated()
|
||||||
|
|
||||||
|
// urlcreated images
|
||||||
|
|
||||||
|
const [HeaderlogoUrl, setHeaderlogoUrl] = useState('')
|
||||||
|
const [FooterlogoUrl, setFooterlogoUrl] = useState('')
|
||||||
|
const [AdminlogoUrl, setAdminlogoUrl] = useState('')
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
async function getConfiguration() {
|
||||||
|
const configDetails = await axios.get(`/api/config`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
configDetails.data.result.map((item) => {
|
||||||
|
setHeaderlogo(item?.logo[0]?.Headerlogo)
|
||||||
|
setFooterlogo(item?.logo[0]?.Footerlogo)
|
||||||
|
setAdminlogo(item?.logo[0]?.Adminlogo)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
getConfiguration()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
// async function handelChange(e) {
|
||||||
|
// setDisplay(false);
|
||||||
|
// console.log(e.target.name === "Logo htmlFor Website Header(148 x 48 px)");
|
||||||
|
// if (e.target.name === "Logo htmlFor Website Header(148 x 48 px)") {
|
||||||
|
// console.log(e.target.files[0]);
|
||||||
|
// setHeaderlogo(e.target.files[0]);
|
||||||
|
// } else if (e.target.name === "Logo htmlFor Website Footer(148 x 48 px)") {
|
||||||
|
// setFooterlogo(e.target.files[0]);
|
||||||
|
// } else if (e.target.name === "Logo htmlFor Admin Header(148 x 48 px)") {
|
||||||
|
// setAdminlogo(e.target.files[0]);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
async function handelSubmit() {
|
||||||
|
setLoading(true)
|
||||||
|
|
||||||
|
const formdata = new FormData()
|
||||||
|
formdata.append('Headerlogo', Headerlogo)
|
||||||
|
formdata.append('Footerlogo', Footerlogo)
|
||||||
|
formdata.append('Adminlogo', Adminlogo)
|
||||||
|
|
||||||
|
await axios.post(`/api/config/logo`, formdata, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
'Content-Type': 'multipart/formdata',
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
},
|
||||||
|
}).then((res) => {
|
||||||
|
setLoading(false)
|
||||||
|
swal('Success!', res.data.message, res.data.status)
|
||||||
|
}
|
||||||
|
).catch(error => {
|
||||||
|
console.log(error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="main-content">
|
||||||
|
<div className="page-content">
|
||||||
|
<div className="container-fluid">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="card">
|
||||||
|
<div className="card-body">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12 col-lg-6 col-xl-6">
|
||||||
|
<h1 className="text-left head-small">Logo</h1>
|
||||||
|
|
||||||
|
<form>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="form-group">
|
||||||
|
<>
|
||||||
|
<label
|
||||||
|
htmlFor="basicpill-phoneno-input"
|
||||||
|
className="label-100 mt-3"
|
||||||
|
>
|
||||||
|
{/* Logo htmlFor Website Header(148 x 48 px) */}
|
||||||
|
</label>
|
||||||
|
<div>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
name="Logo htmlFor Website Header(148 x 48 px)"
|
||||||
|
onChange={(e) => {
|
||||||
|
setHeaderlogo(e.target.files[0])
|
||||||
|
if (e.target.files && e.target.files[0]) {
|
||||||
|
setHeaderlogoUrl({
|
||||||
|
image: URL.createObjectURL(e.target.files[0]),
|
||||||
|
})
|
||||||
|
console.log(setHeaderlogoUrl)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
className="form-control input-field mb-3 col-md-6 d-inline-block"
|
||||||
|
id="basicpill-phoneno-input"
|
||||||
|
/>
|
||||||
|
{display ? (
|
||||||
|
<img className='ms-1'
|
||||||
|
style={{ width: '100px' }}
|
||||||
|
src={HeaderlogoUrl.image ? HeaderlogoUrl.image : Headerlogo}
|
||||||
|
alt="header logo"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
''
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<label
|
||||||
|
htmlFor="basicpill-phoneno-input"
|
||||||
|
className="label-100 mt-3"
|
||||||
|
>
|
||||||
|
{/* Logo htmlFor Website Footer(148 x 48 px) */}
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
name="Logo htmlFor Website Footer(148 x 48 px)"
|
||||||
|
onChange={(e) => {
|
||||||
|
setFooterlogo(e.target.files[0])
|
||||||
|
|
||||||
|
if (e.target.files && e.target.files[0]) {
|
||||||
|
setFooterlogoUrl({
|
||||||
|
image: URL.createObjectURL(e.target.files[0]),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
className="form-control input-field mt-1 col-md-6 d-inline-block"
|
||||||
|
id="basicpill-phoneno-input"
|
||||||
|
/>{' '}
|
||||||
|
{display ? (
|
||||||
|
<img
|
||||||
|
style={{ width: '100px' }}
|
||||||
|
src={FooterlogoUrl.image ? FooterlogoUrl.image : Footerlogo}
|
||||||
|
alt="Footer logo"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
''
|
||||||
|
)}
|
||||||
|
<label
|
||||||
|
htmlFor="basicpill-phoneno-input"
|
||||||
|
className="label-100 mt-2 row ms-1"
|
||||||
|
>
|
||||||
|
{/* Logo htmlFor Admin Header(148 x 48 px) */}
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
name="Logo htmlFor Admin Header(148 x 48 px)"
|
||||||
|
onChange={(e) => {
|
||||||
|
setAdminlogo(e.target.files[0])
|
||||||
|
|
||||||
|
if (e.target.files && e.target.files[0]) {
|
||||||
|
setAdminlogoUrl({
|
||||||
|
image: URL.createObjectURL(e.target.files[0]),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
className="form-control input-field col-md-6 d-inline-block"
|
||||||
|
id="basicpill-phoneno-input"
|
||||||
|
/>{' '}
|
||||||
|
{display ? (
|
||||||
|
<img
|
||||||
|
style={{ width: '100px' }}
|
||||||
|
src={AdminlogoUrl.image ? AdminlogoUrl.image : Adminlogo}
|
||||||
|
alt="Admin logo"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
''
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="form-group text-left">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={handelSubmit}
|
||||||
|
className="btn btn-success btn-login waves-effect waves-light mr-3 pt-2 pb-2 pr-4 pl-4"
|
||||||
|
>
|
||||||
|
<ClipLoader loading={loading} size={18} />
|
||||||
|
{!loading && 'Save'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* <!-- end table-responsive --> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* <!-- container-fluid --> */}
|
||||||
|
</div>
|
||||||
|
{/* <!-- End Page-content --> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Logo
|
169
src/views/configuration/Socialmedia.js
Normal file
169
src/views/configuration/Socialmedia.js
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
import ClipLoader from 'react-spinners/ClipLoader'
|
||||||
|
|
||||||
|
import swal from 'sweetalert'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { isAutheticated } from 'src/auth'
|
||||||
|
|
||||||
|
function Socialmedia() {
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const token = isAutheticated()
|
||||||
|
const [facebook, setFacebook] = useState('')
|
||||||
|
const [instagram, setInstagram] = useState('')
|
||||||
|
const [twitter, setTwitter] = useState('')
|
||||||
|
const [linkedin, setLinkedin] = useState('')
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
async function getConfiguration() {
|
||||||
|
const configDetails = await axios.get(`/api/config`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
configDetails.data.result.map((item) => {
|
||||||
|
console.log(item.socialMedia)
|
||||||
|
setFacebook(item?.socialMedia[0]?.facebook)
|
||||||
|
setInstagram(item?.socialMedia[0]?.instagram)
|
||||||
|
setTwitter(item?.socialMedia[0]?.twitter)
|
||||||
|
setLinkedin(item?.socialMedia[0]?.linkedin)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
getConfiguration()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
async function handelChange(e) {
|
||||||
|
if (e.target.name === 'facebook') {
|
||||||
|
setFacebook(e.target.value)
|
||||||
|
} else if (e.target.name === 'twitter') {
|
||||||
|
setTwitter(e.target.value)
|
||||||
|
} else if (e.target.name === 'instagram') {
|
||||||
|
setInstagram(e.target.value)
|
||||||
|
} else if (e.target.name === 'linkedin') {
|
||||||
|
setLinkedin(e.target.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function handelSubmit() {
|
||||||
|
setLoading(true)
|
||||||
|
let data = {
|
||||||
|
facebook,
|
||||||
|
twitter,
|
||||||
|
instagram,
|
||||||
|
linkedin,
|
||||||
|
}
|
||||||
|
let res = await axios.post(`/api/config/social`, data, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
setLoading(false)
|
||||||
|
console.log(res)
|
||||||
|
swal('Success!', res.data.message, res.data.status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{/* <Config
|
||||||
|
heading="Social Media"
|
||||||
|
labels={["Facebook", "Twitter", "Instagram", "LinkedIn"]}
|
||||||
|
postUrl="social"
|
||||||
|
/> */}
|
||||||
|
<div className="main-content">
|
||||||
|
<div className="page-content">
|
||||||
|
<div className="container-fluid">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="card">
|
||||||
|
<div className="card-body">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12 col-lg-6 col-xl-6">
|
||||||
|
<h1 className="text-left head-small">Social Media</h1>
|
||||||
|
|
||||||
|
<form>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="form-group">
|
||||||
|
<>
|
||||||
|
<label for="basicpill-phoneno-input" className="label-100 mt-3">
|
||||||
|
Facebook
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
value={facebook}
|
||||||
|
type="text"
|
||||||
|
name="facebook"
|
||||||
|
onChange={(e) => handelChange(e)}
|
||||||
|
className="form-control input-field "
|
||||||
|
id="basicpill-phoneno-input"
|
||||||
|
/>
|
||||||
|
<label for="basicpill-phoneno-input" className="label-100 mt-3">
|
||||||
|
Twitter
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
value={twitter}
|
||||||
|
type="text"
|
||||||
|
name="twitter"
|
||||||
|
onChange={(e) => handelChange(e)}
|
||||||
|
className="form-control input-field "
|
||||||
|
id="basicpill-phoneno-input"
|
||||||
|
/>{' '}
|
||||||
|
<label for="basicpill-phoneno-input" className="label-100 mt-3">
|
||||||
|
Instagram
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
value={instagram}
|
||||||
|
type="text"
|
||||||
|
name="instagram"
|
||||||
|
onChange={(e) => handelChange(e)}
|
||||||
|
className="form-control input-field "
|
||||||
|
id="basicpill-phoneno-input"
|
||||||
|
/>{' '}
|
||||||
|
<label for="basicpill-phoneno-input" className="label-100 mt-3">
|
||||||
|
Linkedin
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
value={linkedin}
|
||||||
|
type="text"
|
||||||
|
name="linkedin"
|
||||||
|
onChange={(e) => handelChange(e)}
|
||||||
|
className="form-control input-field "
|
||||||
|
id="basicpill-phoneno-input"
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row mt-1">
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="form-group text-left">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={handelSubmit}
|
||||||
|
className="btn btn-success btn-login waves-effect waves-light me-3 pt-2 pb-2 pr-4 pl-4"
|
||||||
|
>
|
||||||
|
<ClipLoader loading={loading} size={18} />
|
||||||
|
{!loading && 'Save'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* <!-- end table-responsive --> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* <!-- container-fluid --> */}
|
||||||
|
</div>
|
||||||
|
{/* <!-- End Page-content --> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Socialmedia
|
211
src/views/configuration/cities/AddCity.js
Normal file
211
src/views/configuration/cities/AddCity.js
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import Button from '@material-ui/core/Button'
|
||||||
|
import { Link, useParams, useNavigate } from 'react-router-dom'
|
||||||
|
|
||||||
|
import swal from 'sweetalert'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { isAutheticated } from 'src/auth'
|
||||||
|
|
||||||
|
|
||||||
|
const AddCity = () => {
|
||||||
|
const token = isAutheticated();
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const [statesData, setStatesData] = useState([])
|
||||||
|
const [data, setData] = useState({
|
||||||
|
city_name: '',
|
||||||
|
state: '',
|
||||||
|
|
||||||
|
})
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const [limiter, setLimiter] = useState({
|
||||||
|
city_name: 30,
|
||||||
|
city_nameHas: 30,
|
||||||
|
})
|
||||||
|
|
||||||
|
const getNewId = () => {
|
||||||
|
axios
|
||||||
|
.get(`/api/city/newid`, {
|
||||||
|
headers: {
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
setData((prev) => ({ ...prev, _id: res.data.data._id }))
|
||||||
|
})
|
||||||
|
.catch((err) => { })
|
||||||
|
axios
|
||||||
|
.get(`/api/state`, {
|
||||||
|
headers: { 'Access-Control-Allow-Origin': '*', Authorization: `Bearer ${token}` },
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
setStatesData(res.data.data)
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getNewId()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const handleChange = (e) => {
|
||||||
|
if (e.target.type === 'text') {
|
||||||
|
if (e.target.value.length === limiter[e.target.id] + 1) return
|
||||||
|
setLimiter((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[e.target.id + 'Has']: prev[e.target.id] - e.target.value.length,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
setData((prev) => ({ ...prev, [e.target.id]: e.target.value }))
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
if (data.city_name.trim() === '' || data.state.trim() === '') {
|
||||||
|
swal({
|
||||||
|
title: 'Warning',
|
||||||
|
text: 'Fill all mandatory fields',
|
||||||
|
icon: 'error',
|
||||||
|
button: 'Close',
|
||||||
|
dangerMode: true,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setLoading(true)
|
||||||
|
axios
|
||||||
|
.post(`/api/city`, data, {
|
||||||
|
headers: {
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
swal({
|
||||||
|
title: 'Added',
|
||||||
|
text: 'City added successfully!',
|
||||||
|
icon: 'success',
|
||||||
|
button: 'Return',
|
||||||
|
})
|
||||||
|
setLoading(false)
|
||||||
|
navigate('/cities', { replace: true })
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
setLoading(false)
|
||||||
|
|
||||||
|
swal({
|
||||||
|
title: 'Warning',
|
||||||
|
text: 'Something went wrong!',
|
||||||
|
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: '22px' }} className="fw-bold">
|
||||||
|
Add City
|
||||||
|
</div>
|
||||||
|
<div style={{ display: 'flex', gap: '1rem' }}>
|
||||||
|
<h4 className="mb-0"></h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="page-title-right">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
style={{
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: '1rem',
|
||||||
|
textTransform: 'capitalize',
|
||||||
|
marginRight: '5px',
|
||||||
|
}}
|
||||||
|
onClick={() => handleSubmit()}
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
{loading ? 'Loading' : 'Save'}
|
||||||
|
</Button>
|
||||||
|
<Link to="/cities">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
style={{
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: '1rem',
|
||||||
|
textTransform: 'capitalize',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-8 mx-auto">
|
||||||
|
<div className="card h-100">
|
||||||
|
<div className="card-body px-5">
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="city_name" className="form-label">
|
||||||
|
City Name*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="city_name"
|
||||||
|
value={data.city_name}
|
||||||
|
maxLength="50"
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
<p className="pt-1 pl-2 text-secondary">
|
||||||
|
Remaining characters : {limiter.city_nameHas}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="city_name" className="form-label">
|
||||||
|
State Name*
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
value={data.state}
|
||||||
|
className="form-control"
|
||||||
|
id="state"
|
||||||
|
>
|
||||||
|
<option value="">---select---</option>
|
||||||
|
{statesData[0] ? (
|
||||||
|
statesData.map((c, i) => (
|
||||||
|
<option key={i} value={c._id}>
|
||||||
|
{c.state_name}
|
||||||
|
</option>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<option value="" disabled>
|
||||||
|
Please add a City
|
||||||
|
</option>
|
||||||
|
)}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AddCity
|
342
src/views/configuration/cities/Cities.js
Normal file
342
src/views/configuration/cities/Cities.js
Normal file
@ -0,0 +1,342 @@
|
|||||||
|
import React, { useEffect } from 'react'
|
||||||
|
import Button from '@material-ui/core/Button'
|
||||||
|
import { useState } from 'react'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
import swal from 'sweetalert'
|
||||||
|
import { isAutheticated } from 'src/auth'
|
||||||
|
|
||||||
|
const Cities = () => {
|
||||||
|
const token = isAutheticated();
|
||||||
|
|
||||||
|
const [loading, setLoading] = useState(true)
|
||||||
|
const [success, setSuccess] = useState(true)
|
||||||
|
const [citiesData, setCitiesData] = useState([])
|
||||||
|
|
||||||
|
const [currentPage, setCurrentPage] = useState(1)
|
||||||
|
const [itemPerPage, setItemPerPage] = useState(10)
|
||||||
|
const [showData, setShowData] = useState(citiesData)
|
||||||
|
|
||||||
|
const handleShowEntries = (e) => {
|
||||||
|
setCurrentPage(1)
|
||||||
|
setItemPerPage(e.target.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCategories = () => {
|
||||||
|
axios
|
||||||
|
.get(`/api/city`, {
|
||||||
|
headers: { 'Access-Control-Allow-Origin': '*', Authorization: `Bearer ${token}` },
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
setCitiesData(res.data.data)
|
||||||
|
setLoading(false)
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err)
|
||||||
|
setLoading(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getCategories()
|
||||||
|
}, [success])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const loadData = () => {
|
||||||
|
const indexOfLastPost = currentPage * itemPerPage
|
||||||
|
const indexOfFirstPost = indexOfLastPost - itemPerPage
|
||||||
|
setShowData(citiesData.slice(indexOfFirstPost, indexOfLastPost))
|
||||||
|
}
|
||||||
|
loadData()
|
||||||
|
}, [currentPage, itemPerPage, citiesData])
|
||||||
|
|
||||||
|
const handleDelete = (id) => {
|
||||||
|
swal({
|
||||||
|
title: 'Are you sure?',
|
||||||
|
icon: 'error',
|
||||||
|
buttons: { Yes: { text: 'Yes', value: true }, Cancel: { text: 'Cancel', value: 'cancel' } },
|
||||||
|
}).then((value) => {
|
||||||
|
if (value === true) {
|
||||||
|
axios
|
||||||
|
.delete(`/api/city/${id}`, {
|
||||||
|
headers: {
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
setSuccess((prev) => !prev)
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
swal({
|
||||||
|
title: 'Warning',
|
||||||
|
text: 'Something went wrong!',
|
||||||
|
icon: 'error',
|
||||||
|
button: 'Retry',
|
||||||
|
dangerMode: true,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="main-content">
|
||||||
|
<div className="page-content">
|
||||||
|
<div className="container-fluid">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-12">
|
||||||
|
<div
|
||||||
|
className="
|
||||||
|
page-title-box
|
||||||
|
d-flex
|
||||||
|
align-items-center
|
||||||
|
justify-content-between
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div style={{ fontSize: '22px' }} className="fw-bold">
|
||||||
|
Cities
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="page-title-right">
|
||||||
|
<Link to="/cities/add">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
style={{
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: '1rem',
|
||||||
|
textTransform: 'capitalize',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Add City
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="card">
|
||||||
|
<div className="card-body">
|
||||||
|
<div className="row ml-0 mr-0 mb-10">
|
||||||
|
<div className="col-sm-12 col-md-12">
|
||||||
|
<div className="dataTables_length">
|
||||||
|
<label className="w-100">
|
||||||
|
Show
|
||||||
|
<select
|
||||||
|
style={{ width: '10%' }}
|
||||||
|
name=""
|
||||||
|
onChange={(e) => handleShowEntries(e)}
|
||||||
|
className="
|
||||||
|
select-w
|
||||||
|
custom-select custom-select-sm
|
||||||
|
form-control form-control-sm
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<option value="10">10</option>
|
||||||
|
<option value="25">25</option>
|
||||||
|
<option value="50">50</option>
|
||||||
|
<option value="100">100</option>
|
||||||
|
</select>
|
||||||
|
entries
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="table-responsive table-shoot mt-3">
|
||||||
|
<table
|
||||||
|
className="table table-centered table-nowrap"
|
||||||
|
style={{ border: '1px solid' }}
|
||||||
|
>
|
||||||
|
<thead className="thead" style={{ background: 'rgb(140, 213, 213)' }}>
|
||||||
|
<tr>
|
||||||
|
<th className="text-start">City Name</th>
|
||||||
|
<th className="text-start">State Name</th>
|
||||||
|
<th className="text-start">Created On</th>
|
||||||
|
<th className="text-start">Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{!loading && showData.length === 0 && (
|
||||||
|
<tr className="text-center">
|
||||||
|
<td colSpan="6">
|
||||||
|
<h5>No Data Available</h5>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
{loading ? (
|
||||||
|
<tr>
|
||||||
|
<td className="text-center" colSpan="6">
|
||||||
|
Loading...
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
) : (
|
||||||
|
showData.map((city, i) => {
|
||||||
|
return (
|
||||||
|
<tr key={i}>
|
||||||
|
<td className="text-start">{city.city_name}</td>
|
||||||
|
<td className="text-start">{city.state?.state_name}</td>
|
||||||
|
<td className="text-start">
|
||||||
|
{new Date(city.createdAt).toLocaleString('en-IN', {
|
||||||
|
weekday: 'short',
|
||||||
|
month: 'short',
|
||||||
|
day: 'numeric',
|
||||||
|
year: 'numeric',
|
||||||
|
hour: 'numeric',
|
||||||
|
minute: 'numeric',
|
||||||
|
hour12: true,
|
||||||
|
})}
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td className="text-start">
|
||||||
|
<Link to={`/cities/edit/${city._id}`}>
|
||||||
|
<button
|
||||||
|
style={{ color: 'white', margin: '0 1rem' }}
|
||||||
|
type="button"
|
||||||
|
className="
|
||||||
|
btn btn-primary btn-sm
|
||||||
|
waves-effect waves-light
|
||||||
|
btn-table
|
||||||
|
ml-2
|
||||||
|
"
|
||||||
|
>
|
||||||
|
Edit
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
to={'#'}
|
||||||
|
style={{
|
||||||
|
margin: '1rem',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
style={{ color: 'white' }}
|
||||||
|
type="button"
|
||||||
|
className="
|
||||||
|
btn btn-danger btn-sm
|
||||||
|
waves-effect waves-light
|
||||||
|
btn-table
|
||||||
|
ml-2
|
||||||
|
|
||||||
|
"
|
||||||
|
onClick={() => {
|
||||||
|
handleDelete(city._id)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Delete
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
</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 {currentPage * itemPerPage - itemPerPage + 1} to{' '}
|
||||||
|
{Math.min(currentPage * itemPerPage, citiesData.length)} of{' '}
|
||||||
|
{citiesData.length} entries
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-sm-12 col-md-6">
|
||||||
|
<div className="d-flex">
|
||||||
|
<ul className="pagination ms-auto">
|
||||||
|
<li
|
||||||
|
className={
|
||||||
|
currentPage === 1
|
||||||
|
? 'paginate_button page-item previous disabled'
|
||||||
|
: 'paginate_button page-item previous'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: 'pointer' }}
|
||||||
|
onClick={() => setCurrentPage((prev) => prev - 1)}
|
||||||
|
>
|
||||||
|
Previous
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{!(currentPage - 1 < 1) && (
|
||||||
|
<li className="paginate_button page-item">
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: 'pointer' }}
|
||||||
|
onClick={(e) => setCurrentPage((prev) => prev - 1)}
|
||||||
|
>
|
||||||
|
{currentPage - 1}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<li className="paginate_button page-item active">
|
||||||
|
<span className="page-link" style={{ cursor: 'pointer' }}>
|
||||||
|
{currentPage}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{!(
|
||||||
|
(currentPage + 1) * itemPerPage - itemPerPage >
|
||||||
|
citiesData.length - 1
|
||||||
|
) && (
|
||||||
|
<li className="paginate_button page-item ">
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: 'pointer' }}
|
||||||
|
onClick={() => {
|
||||||
|
setCurrentPage((prev) => prev + 1)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{currentPage + 1}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<li
|
||||||
|
className={
|
||||||
|
!(
|
||||||
|
(currentPage + 1) * itemPerPage - itemPerPage >
|
||||||
|
citiesData.length - 1
|
||||||
|
)
|
||||||
|
? 'paginate_button page-item next'
|
||||||
|
: 'paginate_button page-item next disabled'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: 'pointer' }}
|
||||||
|
onClick={() => setCurrentPage((prev) => prev + 1)}
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Cities
|
229
src/views/configuration/cities/EditCity.js
Normal file
229
src/views/configuration/cities/EditCity.js
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import Button from '@material-ui/core/Button'
|
||||||
|
import { Link, useNavigate, useParams } from 'react-router-dom'
|
||||||
|
import swal from 'sweetalert'
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
import { isAutheticated } from 'src/auth'
|
||||||
|
|
||||||
|
|
||||||
|
const EditCity = () => {
|
||||||
|
const id = useParams()?.id
|
||||||
|
const token = isAutheticated();
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const [statesData, setStatesData] = useState([])
|
||||||
|
const [data, setData] = useState({
|
||||||
|
city_name: '',
|
||||||
|
state: '',
|
||||||
|
|
||||||
|
})
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const [limiter, setLimiter] = useState({
|
||||||
|
city_name: 30,
|
||||||
|
city_nameHas: 30,
|
||||||
|
})
|
||||||
|
|
||||||
|
const getCategory = () => {
|
||||||
|
axios
|
||||||
|
.get(`$/api/city/${id}`, {
|
||||||
|
headers: {
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
setData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
...res.data?.data,
|
||||||
|
}))
|
||||||
|
setLimiter((prev) => ({
|
||||||
|
...prev,
|
||||||
|
city_nameHas: prev.city_name - res.data?.data?.city_name.length,
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
.catch((err) => { })
|
||||||
|
axios
|
||||||
|
.get(`/api/state`, {
|
||||||
|
headers: { 'Access-Control-Allow-Origin': '*', Authorization: `Bearer ${token}` },
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
setStatesData(res.data.data)
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getCategory()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const handleChange = (e) => {
|
||||||
|
if (e.target.type === 'text') {
|
||||||
|
if (e.target.value.length === limiter[e.target.id] + 1) return
|
||||||
|
setLimiter((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[e.target.id + 'Has']: prev[e.target.id] - e.target.value.length,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
setData((prev) => ({ ...prev, [e.target.id]: e.target.value }))
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
if (data.city_name.trim() === '' || data.state.trim() === '') {
|
||||||
|
swal({
|
||||||
|
title: 'Warning',
|
||||||
|
text: 'Fill all mandatory fields',
|
||||||
|
icon: 'error',
|
||||||
|
button: 'Close',
|
||||||
|
dangerMode: true,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setLoading(true)
|
||||||
|
axios
|
||||||
|
.patch(`/api/city/${id}`, data, {
|
||||||
|
headers: {
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
swal({
|
||||||
|
title: 'Updated',
|
||||||
|
text: 'City updated successfully!',
|
||||||
|
icon: 'success',
|
||||||
|
button: 'Close',
|
||||||
|
})
|
||||||
|
setLoading(false)
|
||||||
|
navigate('/cities', { replace: true })
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
setLoading(false)
|
||||||
|
swal({
|
||||||
|
title: 'Warning',
|
||||||
|
text: 'Something went wrong!',
|
||||||
|
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: '22px' }} className="fw-bold">
|
||||||
|
Edit City
|
||||||
|
</div>
|
||||||
|
<div style={{ display: 'flex', gap: '1rem' }}>
|
||||||
|
<h4 className="mb-0"></h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="page-title-right">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
style={{
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: '1rem',
|
||||||
|
textTransform: 'capitalize',
|
||||||
|
marginRight: '5px',
|
||||||
|
}}
|
||||||
|
onClick={() => handleSubmit()}
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
{loading ? 'Loading' : 'Update'}
|
||||||
|
</Button>
|
||||||
|
<Link to="/cities">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
style={{
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: '1rem',
|
||||||
|
textTransform: 'capitalize',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-8 mx-auto">
|
||||||
|
<div className="card h-100">
|
||||||
|
<div className="card-body px-5">
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="city_name" className="form-label">
|
||||||
|
City Name*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="city_name"
|
||||||
|
value={data.city_name}
|
||||||
|
maxLength={limiter.city_name}
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
<p className="pt-1 pl-2 text-secondary">
|
||||||
|
Remaining characters : {limiter.city_nameHas}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="city_name" className="form-label">
|
||||||
|
State Name*
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
value={data.state}
|
||||||
|
className="form-control"
|
||||||
|
id="state"
|
||||||
|
>
|
||||||
|
<option value="">---select---</option>
|
||||||
|
{statesData[0] ? (
|
||||||
|
statesData.map((c, i) => (
|
||||||
|
<option key={i} value={c._id}>
|
||||||
|
{c.state_name}
|
||||||
|
</option>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<option value="" disabled>
|
||||||
|
Please add a City
|
||||||
|
</option>
|
||||||
|
)}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{/* <div className="mb-3">
|
||||||
|
<label>Unique ID</label>
|
||||||
|
<input type="text" value={data._id} className="form-control" disabled />
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label>TimeStamp</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={new Date(data.createdAt)}
|
||||||
|
className="form-control"
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</div> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EditCity
|
172
src/views/configuration/states/AddState.js
Normal file
172
src/views/configuration/states/AddState.js
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import Button from '@material-ui/core/Button'
|
||||||
|
import { Link, useNavigate } from 'react-router-dom'
|
||||||
|
import swal from 'sweetalert'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { isAutheticated } from 'src/auth'
|
||||||
|
|
||||||
|
|
||||||
|
const AddState = () => {
|
||||||
|
const token = isAutheticated()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const [data, setData] = useState({
|
||||||
|
state_code: '',
|
||||||
|
state_name: '',
|
||||||
|
})
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const [limiter, setLimiter] = useState({
|
||||||
|
state_code: 10,
|
||||||
|
state_name: 50,
|
||||||
|
state_codeHas: 10,
|
||||||
|
state_nameHas: 50,
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleChange = (e) => {
|
||||||
|
if (e.target.id === 'state_code' && /^\D+$/.test(e.target.value)) return
|
||||||
|
if (e.target.type === 'text') {
|
||||||
|
if (e.target.value.length === limiter[e.target.id] + 1) return
|
||||||
|
setLimiter((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[e.target.id + 'Has']: prev[e.target.id] - e.target.value.length,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
setData((prev) => ({ ...prev, [e.target.id]: e.target.value }))
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
if (data.state_name.trim() === '') {
|
||||||
|
swal({
|
||||||
|
title: 'Warning',
|
||||||
|
text: 'Fill all mandatory fields',
|
||||||
|
icon: 'error',
|
||||||
|
button: 'Close',
|
||||||
|
dangerMode: true,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setLoading(true)
|
||||||
|
axios
|
||||||
|
.post(`/api/state`, data, {
|
||||||
|
headers: {
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
swal({
|
||||||
|
title: 'Added',
|
||||||
|
text: 'State added successfully!',
|
||||||
|
icon: 'success',
|
||||||
|
button: 'Return',
|
||||||
|
})
|
||||||
|
setLoading(false)
|
||||||
|
navigate('/states', { replace: true })
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
setLoading(false)
|
||||||
|
swal({
|
||||||
|
title: 'Warning',
|
||||||
|
text: 'Something went wrong!',
|
||||||
|
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: '22px' }} className="fw-bold">
|
||||||
|
Add State
|
||||||
|
</div>
|
||||||
|
<div style={{ display: 'flex', gap: '1rem' }}>
|
||||||
|
<h4 className="mb-0"></h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="page-title-right">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
style={{
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: '1rem',
|
||||||
|
textTransform: 'capitalize',
|
||||||
|
marginRight: '5px',
|
||||||
|
}}
|
||||||
|
onClick={() => handleSubmit()}
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
{loading ? 'Loading' : 'Save'}
|
||||||
|
</Button>
|
||||||
|
<Link to="/states">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
style={{
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: '1rem',
|
||||||
|
textTransform: 'capitalize',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-8 mx-auto">
|
||||||
|
<div className="card h-100">
|
||||||
|
<div className="card-body px-5">
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="city_name" className="form-label">
|
||||||
|
State Name*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="state_name"
|
||||||
|
value={data.state_name}
|
||||||
|
maxLength={limiter.state_name}
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
<p className="pt-1 pl-2 text-secondary">
|
||||||
|
Remaining characters : {limiter.state_nameHas}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{/* <div className="mb-3">
|
||||||
|
<label htmlFor="city_name" className="form-label">
|
||||||
|
State Code (GST)*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="state_code"
|
||||||
|
value={data.state_code}
|
||||||
|
maxLength={limiter.state_code}
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
<p className="pt-1 pl-2 text-secondary">
|
||||||
|
Remaining characters : {limiter.state_codeHas}
|
||||||
|
</p>
|
||||||
|
</div> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AddState
|
199
src/views/configuration/states/EditStates.js
Normal file
199
src/views/configuration/states/EditStates.js
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import Button from '@material-ui/core/Button'
|
||||||
|
import { Link, useNavigate, useParams } from 'react-router-dom'
|
||||||
|
import swal from 'sweetalert'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { isAutheticated } from 'src/auth'
|
||||||
|
|
||||||
|
|
||||||
|
const EditState = () => {
|
||||||
|
const id = useParams()?.id
|
||||||
|
const token = isAutheticated()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const [data, setData] = useState({
|
||||||
|
state_code: '',
|
||||||
|
state_name: '',
|
||||||
|
})
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const [limiter, setLimiter] = useState({
|
||||||
|
state_code: 10,
|
||||||
|
state_name: 50,
|
||||||
|
state_codeHas: 10,
|
||||||
|
state_nameHas: 50,
|
||||||
|
})
|
||||||
|
|
||||||
|
const getCategory = () => {
|
||||||
|
axios
|
||||||
|
.get(`/api/state/${id}`, {
|
||||||
|
headers: {
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
setData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
...res.data?.data,
|
||||||
|
}))
|
||||||
|
setLimiter((prev) => ({
|
||||||
|
...prev,
|
||||||
|
state_nameHas: prev.state_name - res.data?.data?.state_name.length,
|
||||||
|
state_codeHas: prev.state_code - res.data?.data?.state_code?.toString()?.length,
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
.catch((err) => { })
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getCategory()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const handleChange = (e) => {
|
||||||
|
if (e.target.id === 'state_code' && /^\D+$/.test(e.target.value)) return
|
||||||
|
if (e.target.type === 'text') {
|
||||||
|
if (e.target.value.length === limiter[e.target.id] + 1) return
|
||||||
|
setLimiter((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[e.target.id + 'Has']: prev[e.target.id] - e.target.value.length,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
setData((prev) => ({ ...prev, [e.target.id]: e.target.value }))
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
if (data.state_name.trim() === '') {
|
||||||
|
swal({
|
||||||
|
title: 'Warning',
|
||||||
|
text: 'Fill all mandatory fields',
|
||||||
|
icon: 'error',
|
||||||
|
button: 'Close',
|
||||||
|
dangerMode: true,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setLoading(true)
|
||||||
|
axios
|
||||||
|
.patch(`/api/state/${id}`, data, {
|
||||||
|
headers: {
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
swal({
|
||||||
|
title: 'Updated',
|
||||||
|
text: 'State updated successfully!',
|
||||||
|
icon: 'success',
|
||||||
|
button: 'Close',
|
||||||
|
})
|
||||||
|
setLoading(false)
|
||||||
|
navigate('/states', { replace: true })
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
setLoading(false)
|
||||||
|
swal({
|
||||||
|
title: 'Warning',
|
||||||
|
text: 'Something went wrong!',
|
||||||
|
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: '22px' }} className="fw-bold">
|
||||||
|
Edit State
|
||||||
|
</div>
|
||||||
|
<div style={{ display: 'flex', gap: '1rem' }}>
|
||||||
|
<h4 className="mb-0"></h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="page-title-right">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
style={{
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: '1rem',
|
||||||
|
textTransform: 'capitalize',
|
||||||
|
marginRight: '5px',
|
||||||
|
}}
|
||||||
|
onClick={() => handleSubmit()}
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
{loading ? 'Loading' : 'Update'}
|
||||||
|
</Button>
|
||||||
|
<Link to="/states">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
style={{
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: '1rem',
|
||||||
|
textTransform: 'capitalize',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-8 mx-auto">
|
||||||
|
<div className="card h-100">
|
||||||
|
<div className="card-body px-5">
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="city_name" className="form-label">
|
||||||
|
State Name*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="state_name"
|
||||||
|
value={data.state_name}
|
||||||
|
maxLength={limiter.state_name}
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
<p className="pt-1 pl-2 text-secondary">
|
||||||
|
Remaining characters : {limiter.state_nameHas}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{/* <div className="mb-3">
|
||||||
|
<label htmlFor="city_name" className="form-label">
|
||||||
|
State Code (GST)*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="state_code"
|
||||||
|
value={data.state_code}
|
||||||
|
maxLength={limiter.state_code}
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
/>
|
||||||
|
<p className="pt-1 pl-2 text-secondary">
|
||||||
|
Remaining characters : {limiter.state_codeHas}
|
||||||
|
</p>
|
||||||
|
</div> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EditState
|
342
src/views/configuration/states/States.js
Normal file
342
src/views/configuration/states/States.js
Normal file
@ -0,0 +1,342 @@
|
|||||||
|
import React, { useEffect } from 'react'
|
||||||
|
import Button from '@material-ui/core/Button'
|
||||||
|
import { useState } from 'react'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
import swal from 'sweetalert'
|
||||||
|
import { isAutheticated } from 'src/auth'
|
||||||
|
|
||||||
|
const States = () => {
|
||||||
|
const token = isAutheticated()
|
||||||
|
const [loading, setLoading] = useState(true)
|
||||||
|
const [success, setSuccess] = useState(true)
|
||||||
|
const [statesData, setStatesData] = useState([])
|
||||||
|
|
||||||
|
const [currentPage, setCurrentPage] = useState(1)
|
||||||
|
const [itemPerPage, setItemPerPage] = useState(10)
|
||||||
|
const [showData, setShowData] = useState(statesData)
|
||||||
|
|
||||||
|
const handleShowEntries = (e) => {
|
||||||
|
setCurrentPage(1)
|
||||||
|
setItemPerPage(e.target.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCategories = () => {
|
||||||
|
axios
|
||||||
|
.get(`/api/state`, {
|
||||||
|
headers: { 'Access-Control-Allow-Origin': '*', Authorization: `Bearer ${token}` },
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
setStatesData(res.data.data)
|
||||||
|
setLoading(false)
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err)
|
||||||
|
setLoading(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getCategories()
|
||||||
|
}, [success])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const loadData = () => {
|
||||||
|
const indexOfLastPost = currentPage * itemPerPage
|
||||||
|
const indexOfFirstPost = indexOfLastPost - itemPerPage
|
||||||
|
setShowData(statesData.slice(indexOfFirstPost, indexOfLastPost))
|
||||||
|
}
|
||||||
|
loadData()
|
||||||
|
}, [currentPage, itemPerPage, statesData])
|
||||||
|
|
||||||
|
const handleDelete = (id) => {
|
||||||
|
swal({
|
||||||
|
title: 'Are you sure?',
|
||||||
|
icon: 'error',
|
||||||
|
buttons: { Yes: { text: 'Yes', value: true }, Cancel: { text: 'Cancel', value: 'cancel' } },
|
||||||
|
}).then((value) => {
|
||||||
|
if (value === true) {
|
||||||
|
axios
|
||||||
|
.delete(`/api/state/${id}`, {
|
||||||
|
headers: {
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
setSuccess((prev) => !prev)
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
swal({
|
||||||
|
title: 'Warning',
|
||||||
|
text: 'Something went wrong!',
|
||||||
|
icon: 'error',
|
||||||
|
button: 'Retry',
|
||||||
|
dangerMode: true,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="main-content">
|
||||||
|
<div className="page-content">
|
||||||
|
<div className="container-fluid">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-12">
|
||||||
|
<div
|
||||||
|
className="
|
||||||
|
page-title-box
|
||||||
|
d-flex
|
||||||
|
align-items-center
|
||||||
|
justify-content-between
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div style={{ fontSize: '22px' }} className="fw-bold">
|
||||||
|
States
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="page-title-right">
|
||||||
|
<Link to="/states/add">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
style={{
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: '1rem',
|
||||||
|
textTransform: 'capitalize',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Add State
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="card">
|
||||||
|
<div className="card-body">
|
||||||
|
<div className="row ml-0 mr-0 mb-10">
|
||||||
|
<div className="col-sm-12 col-md-12">
|
||||||
|
<div className="dataTables_length">
|
||||||
|
<label className="w-100">
|
||||||
|
Show
|
||||||
|
<select
|
||||||
|
style={{ width: '10%' }}
|
||||||
|
name=""
|
||||||
|
onChange={(e) => handleShowEntries(e)}
|
||||||
|
className="
|
||||||
|
select-w
|
||||||
|
custom-select custom-select-sm
|
||||||
|
form-control form-control-sm
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<option value="10">10</option>
|
||||||
|
<option value="25">25</option>
|
||||||
|
<option value="50">50</option>
|
||||||
|
<option value="100">100</option>
|
||||||
|
</select>
|
||||||
|
entries
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="table-responsive table-shoot mt-3">
|
||||||
|
<table
|
||||||
|
className="table table-centered table-nowrap"
|
||||||
|
style={{ border: '1px solid' }}
|
||||||
|
>
|
||||||
|
<thead className="thead-info" style={{ background: 'rgb(140, 213, 213)' }}>
|
||||||
|
<tr>
|
||||||
|
<th className="text-start">State Name</th>
|
||||||
|
{/* <th className="text-start">State Code (GST)</th> */}
|
||||||
|
<th className="text-start">Created On</th>
|
||||||
|
<th className="text-start">Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{!loading && showData.length === 0 && (
|
||||||
|
<tr className="text-center">
|
||||||
|
<td colSpan="6">
|
||||||
|
<h5>No Data Available</h5>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
{loading ? (
|
||||||
|
<tr>
|
||||||
|
<td className="text-center" colSpan="6">
|
||||||
|
Loading...
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
) : (
|
||||||
|
showData.map((city, i) => {
|
||||||
|
return (
|
||||||
|
<tr key={i}>
|
||||||
|
<td className="text-start">{city.state_name}</td>
|
||||||
|
{/* <td className="text-start">{city.state_code}</td> */}
|
||||||
|
<td className="text-start">
|
||||||
|
{new Date(city.createdAt).toLocaleString('en-IN', {
|
||||||
|
weekday: 'short',
|
||||||
|
month: 'short',
|
||||||
|
day: 'numeric',
|
||||||
|
year: 'numeric',
|
||||||
|
hour: 'numeric',
|
||||||
|
minute: 'numeric',
|
||||||
|
hour12: true,
|
||||||
|
})}
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td className="text-start">
|
||||||
|
<Link to={`/states/edit/${city._id}`}>
|
||||||
|
<button
|
||||||
|
style={{ color: 'white', margin: '0 1rem' }}
|
||||||
|
type="button"
|
||||||
|
className="
|
||||||
|
btn btn-primary btn-sm
|
||||||
|
waves-effect waves-light
|
||||||
|
btn-table
|
||||||
|
ml-2
|
||||||
|
"
|
||||||
|
>
|
||||||
|
Edit
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
to={'#'}
|
||||||
|
style={{
|
||||||
|
margin: '1rem',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
style={{ color: 'white' }}
|
||||||
|
type="button"
|
||||||
|
className="
|
||||||
|
btn btn-danger btn-sm
|
||||||
|
waves-effect waves-light
|
||||||
|
btn-table
|
||||||
|
ml-2
|
||||||
|
|
||||||
|
"
|
||||||
|
onClick={() => {
|
||||||
|
handleDelete(city._id)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Delete
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
</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 {currentPage * itemPerPage - itemPerPage + 1} to{' '}
|
||||||
|
{Math.min(currentPage * itemPerPage, statesData.length)} of{' '}
|
||||||
|
{statesData.length} entries
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-sm-12 col-md-6">
|
||||||
|
<div className="d-flex">
|
||||||
|
<ul className="pagination ms-auto">
|
||||||
|
<li
|
||||||
|
className={
|
||||||
|
currentPage === 1
|
||||||
|
? 'paginate_button page-item previous disabled'
|
||||||
|
: 'paginate_button page-item previous'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: 'pointer' }}
|
||||||
|
onClick={() => setCurrentPage((prev) => prev - 1)}
|
||||||
|
>
|
||||||
|
Previous
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{!(currentPage - 1 < 1) && (
|
||||||
|
<li className="paginate_button page-item">
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: 'pointer' }}
|
||||||
|
onClick={(e) => setCurrentPage((prev) => prev - 1)}
|
||||||
|
>
|
||||||
|
{currentPage - 1}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<li className="paginate_button page-item active">
|
||||||
|
<span className="page-link" style={{ cursor: 'pointer' }}>
|
||||||
|
{currentPage}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{!(
|
||||||
|
(currentPage + 1) * itemPerPage - itemPerPage >
|
||||||
|
statesData.length - 1
|
||||||
|
) && (
|
||||||
|
<li className="paginate_button page-item ">
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: 'pointer' }}
|
||||||
|
onClick={() => {
|
||||||
|
setCurrentPage((prev) => prev + 1)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{currentPage + 1}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<li
|
||||||
|
className={
|
||||||
|
!(
|
||||||
|
(currentPage + 1) * itemPerPage - itemPerPage >
|
||||||
|
statesData.length - 1
|
||||||
|
)
|
||||||
|
? 'paginate_button page-item next'
|
||||||
|
: 'paginate_button page-item next disabled'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: 'pointer' }}
|
||||||
|
onClick={() => setCurrentPage((prev) => prev + 1)}
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default States
|
@ -1,20 +1,122 @@
|
|||||||
import React, { lazy } from 'react'
|
import React, { lazy } from 'react'
|
||||||
|
import axios from "axios";
|
||||||
|
import { useEffect, useState, useCallback, useMemo } from "react";
|
||||||
|
import { isAutheticated } from "../../auth.js";
|
||||||
|
|
||||||
const WidgetsDropdown = lazy(() => import('../widgets/WidgetsDropdown.js'))
|
const WidgetsDropdown = lazy(() => import('../widgets/WidgetsDropdown.js'))
|
||||||
const WidgetsBrand = lazy(() => import('../widgets/WidgetsBrand.js'))
|
|
||||||
|
|
||||||
const Dashboard = () => {
|
const Dashboard = () => {
|
||||||
const random = (min, max) => {
|
//1 st
|
||||||
return Math.floor(Math.random() * (max - min + 1) + min)
|
const [users, setUsers] = useState([])
|
||||||
}
|
const token = isAutheticated();
|
||||||
|
|
||||||
|
const getAllUsers = useCallback(async () => {
|
||||||
|
let res = await axios.get(
|
||||||
|
`/api/v1/admin/users`,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
// console.log(res.data)
|
||||||
|
setUsers(res.data.users)
|
||||||
|
|
||||||
|
|
||||||
|
}, [token]);
|
||||||
|
// //2nd
|
||||||
|
// const [category, setCategory] = useState([])
|
||||||
|
// const getAllCategory = useCallback(async () => {
|
||||||
|
// let res = await axios.get(
|
||||||
|
// `/api/category/getAll`,
|
||||||
|
// {
|
||||||
|
// headers: {
|
||||||
|
// Authorization: `Bearer ${token}`,
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
// // console.log(res.data.category[0].image.url)
|
||||||
|
// setCategory(res.data.category)
|
||||||
|
// }, [token]);
|
||||||
|
|
||||||
|
// //3 requiment
|
||||||
|
// const [requirement, setRequirement] = useState([])
|
||||||
|
// // console.log(token)
|
||||||
|
// const getRequirement = useCallback(async () => {
|
||||||
|
// let res = await axios.get(
|
||||||
|
// `/api/requirement/getAll`,
|
||||||
|
// {
|
||||||
|
// headers: {
|
||||||
|
// Authorization: `Bearer ${token}`,
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
|
||||||
|
// setRequirement(res.data.Requirement)
|
||||||
|
|
||||||
|
// }, [token]);
|
||||||
|
// //4 news
|
||||||
|
// const [news, setNews] = useState([])
|
||||||
|
|
||||||
|
// const getNews = useCallback(async () => {
|
||||||
|
// let res = await axios.get(
|
||||||
|
// `/api/news/getAll`,
|
||||||
|
// {
|
||||||
|
// headers: {
|
||||||
|
// Authorization: `Bearer ${token}`,
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
|
||||||
|
// setNews(res.data.news)
|
||||||
|
|
||||||
|
|
||||||
|
// }, [token]);
|
||||||
|
// //5 offers
|
||||||
|
// const [offer, setOffer] = useState([])
|
||||||
|
|
||||||
|
// 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]);
|
||||||
|
// //6 event
|
||||||
|
// const [event, setEvent] = useState([])
|
||||||
|
// 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(() => {
|
||||||
|
// getAllUsers();
|
||||||
|
// getAllCategory()
|
||||||
|
// getRequirement()
|
||||||
|
// getNews()
|
||||||
|
// getOffer()
|
||||||
|
// getEvent()
|
||||||
|
// }, [getAllUsers, getAllCategory, getRequirement, getNews, getOffer, getEvent]);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<WidgetsDropdown />
|
<WidgetsDropdown users={users} />
|
||||||
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React from 'react'
|
import React, { useEffect } from 'react'
|
||||||
import { Link } from 'react-router-dom'
|
import { Link, useNavigate } from 'react-router-dom'
|
||||||
import {
|
import {
|
||||||
CButton,
|
CButton,
|
||||||
CCard,
|
CCard,
|
||||||
@ -15,42 +15,127 @@ import {
|
|||||||
} from '@coreui/react'
|
} from '@coreui/react'
|
||||||
import CIcon from '@coreui/icons-react'
|
import CIcon from '@coreui/icons-react'
|
||||||
import { cilLockLocked, cilUser } from '@coreui/icons'
|
import { cilLockLocked, cilUser } from '@coreui/icons'
|
||||||
|
import ClipLoader from "react-spinners/ClipLoader";
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { useHistory } from 'react-router-dom'
|
import { useHistory } from 'react-router-dom'
|
||||||
|
|
||||||
const Login = () => {
|
const Login = () => {
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [validForm, setValidForm] = useState(false)
|
||||||
const [auth, setAuth] = useState({
|
const [auth, setAuth] = useState({
|
||||||
email: "",
|
email: "",
|
||||||
password: ""
|
password: ""
|
||||||
});
|
});
|
||||||
const history = useHistory();
|
const [errors, setErrors] = useState({
|
||||||
|
emailError: '',
|
||||||
|
passwordError: '',
|
||||||
|
|
||||||
const handleChange = (e) => (event) => {
|
})
|
||||||
setAuth({ ...auth, [e]: event.target.value });
|
const validEmailRegex = RegExp(
|
||||||
};
|
/^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i,
|
||||||
|
)
|
||||||
|
const validPasswordRegex = RegExp(/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[^\w\s]).{7,}$/)
|
||||||
|
const history = useNavigate();
|
||||||
|
// const handleChange = (e) => (event) => {
|
||||||
|
|
||||||
|
// setAuth({ ...auth, [e]: event.target.value });
|
||||||
|
// };
|
||||||
|
const validateForm = () => {
|
||||||
|
let valid = true
|
||||||
|
Object.values(errors).forEach((val) => {
|
||||||
|
if (val.length > 0) {
|
||||||
|
valid = false
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Object.values(auth).forEach((val) => {
|
||||||
|
if (val.length <= 0) {
|
||||||
|
valid = false
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return valid
|
||||||
|
}
|
||||||
|
|
||||||
|
//cheking email and password
|
||||||
|
useEffect(() => {
|
||||||
|
if (validateForm()) {
|
||||||
|
setValidForm(true)
|
||||||
|
} else {
|
||||||
|
setValidForm(false)
|
||||||
|
}
|
||||||
|
}, [errors])
|
||||||
|
const handleChange = (e) => {
|
||||||
|
const { name, value } = e.target
|
||||||
|
|
||||||
|
switch (name) {
|
||||||
|
case 'email':
|
||||||
|
setErrors({
|
||||||
|
...errors,
|
||||||
|
emailError: validEmailRegex.test(value) ? '' : 'Email is not valid!',
|
||||||
|
})
|
||||||
|
|
||||||
|
break
|
||||||
|
case 'password':
|
||||||
|
setErrors((errors) => ({
|
||||||
|
...errors,
|
||||||
|
passwordError: validPasswordRegex.test(value)
|
||||||
|
? ''
|
||||||
|
: 'Password Shoud Be 8 Characters Long, Atleast One Uppercase, Atleast One Lowercase,Atleast One Digit, Atleast One Special Character',
|
||||||
|
}))
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
setAuth({ ...auth, [name]: value })
|
||||||
|
}
|
||||||
|
|
||||||
const Login = async () => {
|
const Login = async () => {
|
||||||
const res = await axios.post("/api/user/login/", auth);
|
if (!(auth.email && auth.password)) {
|
||||||
if (res.data.success == true) {
|
|
||||||
localStorage.setItem("authToken", res.data.token)
|
|
||||||
console.log(res.data)
|
|
||||||
localStorage.setItem("auth", JSON.stringify({
|
|
||||||
user: res.data.user,
|
|
||||||
token: res.data.token,
|
|
||||||
|
|
||||||
|
|
||||||
}));
|
|
||||||
history.push('/dashboard')
|
|
||||||
|
|
||||||
|
return swal('Error!', 'All fields are required', 'error')
|
||||||
}
|
}
|
||||||
else {
|
setLoading({ loading: true })
|
||||||
if (res.data.status === "blocked")
|
try {
|
||||||
alert(res.data.message)
|
const res = await axios.post("/api/v1/user/login/", auth);
|
||||||
else
|
if (res.data.success == true) {
|
||||||
alert("Invalid Credentials");
|
localStorage.setItem("authToken", res.data.token)
|
||||||
|
let response = await axios.get(`/api/v1/user/details`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${res.data.token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
// console.log(response.data)
|
||||||
|
const data = response.data
|
||||||
|
if (data.user.role === 'admin') {
|
||||||
|
history('/dashboard')
|
||||||
|
setLoading(false);
|
||||||
|
window.location.reload()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
swal('Error!', 'please try with admin credential!!', 'error')
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setLoading(false);
|
||||||
|
|
||||||
|
swal('Error!', 'Invalid Credentials', 'error')
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
setLoading(false);
|
||||||
|
|
||||||
|
swal('Error!', 'Invalid Credentials', 'error')
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-light min-vh-100 d-flex flex-row align-items-center">
|
<div className="bg-light min-vh-100 d-flex flex-row align-items-center">
|
||||||
<CContainer>
|
<CContainer>
|
||||||
@ -61,28 +146,37 @@ const Login = () => {
|
|||||||
<CCardBody>
|
<CCardBody>
|
||||||
<CForm>
|
<CForm>
|
||||||
<h1>Login</h1>
|
<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">
|
<CInputGroup className="mb-3">
|
||||||
<CInputGroupText>
|
<CInputGroupText>
|
||||||
<CIcon icon={cilUser} />
|
<CIcon icon={cilUser} />
|
||||||
</CInputGroupText>
|
</CInputGroupText>
|
||||||
<CFormInput placeholder="Email" onChange={handleChange("email")} autoComplete="email" />
|
<CFormInput type="email" placeholder="Email" onChange={handleChange} value={auth.email} name="email" autoComplete="email" />
|
||||||
</CInputGroup>
|
</CInputGroup>
|
||||||
|
{errors.emailError && (
|
||||||
|
<p className="text-center py-2 text-danger">{errors.emailError}</p>
|
||||||
|
)}
|
||||||
<CInputGroup className="mb-4">
|
<CInputGroup className="mb-4">
|
||||||
<CInputGroupText>
|
<CInputGroupText>
|
||||||
<CIcon icon={cilLockLocked} />
|
<CIcon icon={cilLockLocked} />
|
||||||
</CInputGroupText>
|
</CInputGroupText>
|
||||||
<CFormInput
|
<CFormInput
|
||||||
type="password"
|
type="password"
|
||||||
onChange={handleChange("password")}
|
name="password"
|
||||||
|
value={auth.password}
|
||||||
|
onChange={handleChange}
|
||||||
placeholder="Password"
|
placeholder="Password"
|
||||||
autoComplete="current-password"
|
autoComplete="current-password"
|
||||||
/>
|
/>
|
||||||
</CInputGroup>
|
</CInputGroup>
|
||||||
|
|
||||||
|
{errors.passwordError && (
|
||||||
|
<p className="text-center py-2 text-danger">{errors.passwordError}</p>
|
||||||
|
)}
|
||||||
|
<CButton color="primary" className="px-4" disabled={!validForm} onClick={Login}>
|
||||||
|
<ClipLoader loading={loading} size={18} />
|
||||||
|
{!loading && "Login"}
|
||||||
|
|
||||||
<CButton color="primary" className="px-4" onClick={Login}>
|
|
||||||
Login
|
|
||||||
</CButton>
|
</CButton>
|
||||||
|
|
||||||
|
|
||||||
@ -93,11 +187,11 @@ const Login = () => {
|
|||||||
</Link>
|
</Link>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
{/* <CButton color="link" className="px-0">
|
<CButton color="link" className="px-0">
|
||||||
<Link to="/forgot">
|
<Link to="/password/forgot">
|
||||||
Forgot password?
|
Forgot password.?
|
||||||
</Link>
|
</Link>
|
||||||
</CButton> */}
|
</CButton>
|
||||||
|
|
||||||
|
|
||||||
</CForm>
|
</CForm>
|
||||||
@ -118,3 +212,8 @@ const Login = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default Login
|
export default Login
|
||||||
|
|
||||||
|
// < Route path = "/" name = "Home" render = {(props) => (
|
||||||
|
// userdata && userdata.role === 'admin' ? <DefaultLayout {...props} /> :
|
||||||
|
// <><Login {...props} /></>
|
||||||
|
// )} />
|
@ -13,35 +13,92 @@ import {
|
|||||||
} from '@coreui/react'
|
} from '@coreui/react'
|
||||||
import CIcon from '@coreui/icons-react'
|
import CIcon from '@coreui/icons-react'
|
||||||
import { cilLockLocked, cilUser } from '@coreui/icons'
|
import { cilLockLocked, cilUser } from '@coreui/icons'
|
||||||
|
import ClipLoader from "react-spinners/ClipLoader";
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { isAutheticated } from 'src/auth'
|
import { isAutheticated } from 'src/auth'
|
||||||
import Swal from 'sweetalert2'
|
import Swal from 'sweetalert2'
|
||||||
import { useHistory } from 'react-router-dom'
|
import { useNavigate } from 'react-router-dom'
|
||||||
|
|
||||||
const Register = () => {
|
const Register = () => {
|
||||||
const [oldPassword, setOldPassword] = useState();
|
|
||||||
const [newPassword, setNewPassword] = useState();
|
|
||||||
const [confirmPassword, setConfirmPassword] = useState();
|
|
||||||
const history = useHistory();
|
|
||||||
|
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const history = useNavigate();
|
||||||
|
const [user, setUser] = useState({
|
||||||
|
oldPassword: '',
|
||||||
|
newPassword: '',
|
||||||
|
confirmPassword: '',
|
||||||
|
})
|
||||||
|
const [errors, setErrors] = useState({
|
||||||
|
confirmPasswordError: '',
|
||||||
|
newPasswordError: '',
|
||||||
|
oldPasswordError: '',
|
||||||
|
|
||||||
|
})
|
||||||
|
const validEmailRegex = RegExp(
|
||||||
|
/^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i,
|
||||||
|
)
|
||||||
|
const validPasswordRegex = RegExp(/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[^\w\s]).{7,}$/)
|
||||||
|
const handleChange = (e) => {
|
||||||
|
const { name, value } = e.target
|
||||||
|
|
||||||
|
switch (name) {
|
||||||
|
case 'oldPassword':
|
||||||
|
setErrors({
|
||||||
|
...errors,
|
||||||
|
oldPasswordError: validPasswordRegex.test(value)
|
||||||
|
? ''
|
||||||
|
: 'Password Shoud Be 8 Characters Long, Atleast One Uppercase, Atleast One Lowercase,Atleast One Digit, Atleast One Special Character',
|
||||||
|
})
|
||||||
|
|
||||||
|
break
|
||||||
|
case 'newPassword':
|
||||||
|
setErrors({
|
||||||
|
...errors,
|
||||||
|
newPasswordError: validPasswordRegex.test(value)
|
||||||
|
? ''
|
||||||
|
: 'Password Shoud Be 8 Characters Long, Atleast One Uppercase, Atleast One Lowercase,Atleast One Digit, Atleast One Special Character',
|
||||||
|
})
|
||||||
|
|
||||||
|
break
|
||||||
|
case 'confirmPassword':
|
||||||
|
setErrors((errors) => ({
|
||||||
|
...errors,
|
||||||
|
confirmPasswordError: validPasswordRegex.test(value)
|
||||||
|
? ''
|
||||||
|
: 'Password Shoud Be 8 Characters Long, Atleast One Uppercase, Atleast One Lowercase,Atleast One Digit, Atleast One Special Character',
|
||||||
|
}))
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
setUser({ ...user, [name]: value })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
|
if (!(user.oldPassword && user.newPassword && user.confirmPassword)) {
|
||||||
|
|
||||||
|
return swal('Error!', 'All fields are required', 'error')
|
||||||
|
}
|
||||||
|
if (!(user.newPassword.length >= 8)) {
|
||||||
|
|
||||||
|
return swal('Error!', 'All fields are required', 'error');
|
||||||
|
}
|
||||||
const token = localStorage.getItem("authToken")
|
const token = localStorage.getItem("authToken")
|
||||||
//console.log(token)
|
setLoading({ loading: true })
|
||||||
if (newPassword == confirmPassword) {
|
if (user.newPassword == user.confirmPassword) {
|
||||||
let res = await axios.put('/api/user/update/password',
|
let res = await axios.put('/api/v1/user/password/update',
|
||||||
{
|
{
|
||||||
oldPassword
|
...user
|
||||||
, newPassword,
|
|
||||||
confirmPassword
|
|
||||||
}, {
|
}, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
console.log(res)
|
|
||||||
if (res) {
|
// console.log(res.data.success)
|
||||||
|
if (res.data.success == true) {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: 'Done',
|
title: 'Done',
|
||||||
text: 'Password Changed',
|
text: 'Password Changed',
|
||||||
@ -50,12 +107,14 @@ const Register = () => {
|
|||||||
confirmButtonColor: '#303c54',
|
confirmButtonColor: '#303c54',
|
||||||
iconColor: '#303c54'
|
iconColor: '#303c54'
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
history.push('/dashboard')
|
history('/dashboard')
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
setLoading(false);
|
||||||
} else {
|
} else {
|
||||||
alert('new password and confirm password are not matched')
|
swal('Error!', 'New Password And Confirm Password is Not Match !', 'error')
|
||||||
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -74,31 +133,56 @@ const Register = () => {
|
|||||||
<CInputGroupText>
|
<CInputGroupText>
|
||||||
<CIcon icon={cilLockLocked} />
|
<CIcon icon={cilLockLocked} />
|
||||||
</CInputGroupText>
|
</CInputGroupText>
|
||||||
<CFormInput placeholder="Old Password" autoComplete="email" onChange={(e) => setOldPassword(e.target.value)} />
|
<CFormInput placeholder="Old Password" type="password" value={user.oldPassword}
|
||||||
|
onChange={handleChange}
|
||||||
|
autoComplete="current-password"
|
||||||
|
name="oldPassword" />
|
||||||
</CInputGroup>
|
</CInputGroup>
|
||||||
|
{errors.oldPasswordError && (
|
||||||
|
<p className="text-center py-2 text-danger">{errors.oldPasswordError}</p>
|
||||||
|
)}
|
||||||
|
|
||||||
<CInputGroup className="mb-3">
|
<CInputGroup className="mb-3">
|
||||||
<CInputGroupText>
|
<CInputGroupText>
|
||||||
<CIcon icon={cilLockLocked} />
|
<CIcon icon={cilLockLocked} />
|
||||||
</CInputGroupText>
|
</CInputGroupText>
|
||||||
<CFormInput
|
<CFormInput
|
||||||
type="password"
|
type="password"
|
||||||
placeholder="Password"
|
placeholder=" New Password"
|
||||||
|
|
||||||
|
value={user.newPassword}
|
||||||
|
onChange={handleChange}
|
||||||
|
name="newPassword"
|
||||||
|
|
||||||
onChange={(e) => setNewPassword(e.target.value)}
|
|
||||||
/>
|
/>
|
||||||
</CInputGroup>
|
</CInputGroup>
|
||||||
|
{errors.newPasswordError && (
|
||||||
|
<p className="text-center py-2 text-danger">{errors.newPasswordError}</p>
|
||||||
|
)}
|
||||||
<CInputGroup className="mb-4">
|
<CInputGroup className="mb-4">
|
||||||
<CInputGroupText>
|
<CInputGroupText>
|
||||||
<CIcon icon={cilLockLocked} />
|
<CIcon icon={cilLockLocked} />
|
||||||
</CInputGroupText>
|
</CInputGroupText>
|
||||||
|
{errors.passwordError && (
|
||||||
|
<p className="text-center py-2 text-danger">{errors.passwordError}</p>
|
||||||
|
)}
|
||||||
<CFormInput
|
<CFormInput
|
||||||
type="password"
|
type="password"
|
||||||
placeholder="Confirm password"
|
|
||||||
onChange={(e) => setConfirmPassword(e.target.value)}
|
placeholder="Confirm password "
|
||||||
|
value={user.confirmPassword}
|
||||||
|
onChange={handleChange}
|
||||||
|
name="confirmPassword"
|
||||||
/>
|
/>
|
||||||
</CInputGroup>
|
</CInputGroup>
|
||||||
|
{errors.confirmPasswordError && (
|
||||||
|
<p className="text-center py-2 text-danger">{errors.confirmPasswordError}</p>
|
||||||
|
)}
|
||||||
<div className="d-grid">
|
<div className="d-grid">
|
||||||
<CButton color="success" onClick={handleSubmit}>Submit</CButton>
|
<CButton color="success" onClick={handleSubmit}>
|
||||||
|
<ClipLoader loading={loading} size={18} />
|
||||||
|
{!loading && "Submit"}
|
||||||
|
</CButton>
|
||||||
</div>
|
</div>
|
||||||
</CForm>
|
</CForm>
|
||||||
</CCardBody>
|
</CCardBody>
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
import React from 'react';
|
import React, { useState } from 'react'
|
||||||
|
import axios from 'axios';
|
||||||
|
import ClipLoader from "react-spinners/ClipLoader";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
|
||||||
CButton,
|
CButton,
|
||||||
CCard,
|
CCard,
|
||||||
CCardBody,
|
CCardBody,
|
||||||
@ -13,9 +17,41 @@ import {
|
|||||||
} from '@coreui/react'
|
} from '@coreui/react'
|
||||||
import CIcon from '@coreui/icons-react'
|
import CIcon from '@coreui/icons-react'
|
||||||
import { cilEnvelopeLetter, cilEnvelopeOpen, cilLockLocked, cilUser } from '@coreui/icons'
|
import { cilEnvelopeLetter, cilEnvelopeOpen, cilLockLocked, cilUser } from '@coreui/icons'
|
||||||
import { Link } from 'react-router-dom';
|
import { Link, useNavigate } from 'react-router-dom';
|
||||||
|
import swal from 'sweetalert';
|
||||||
|
|
||||||
const ForgotPassword = () => {
|
const ForgotPassword = () => {
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [email, setEmail] = useState()
|
||||||
|
// console.log(email)
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
if (email) {
|
||||||
|
try {
|
||||||
|
setLoading(true)
|
||||||
|
|
||||||
|
const res = await axios.post(`/api/v1/user/password/forgot`, { email: email })
|
||||||
|
// console.log(res);
|
||||||
|
if (res.data.success === true) {
|
||||||
|
setLoading(false)
|
||||||
|
// alert("Email Send Successfully! please check your mail for reset password")
|
||||||
|
swal("success!", "Email Send Successfully! please check your Email for new password", "success");
|
||||||
|
navigate("/");
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
swal('Error!', 'Wrong Email ID. Enter valid email to get the password', 'error')
|
||||||
|
setLoading(false)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alert("please fill Email field..")
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
return <div className="bg-light min-vh-100 d-flex flex-row align-items-center">
|
return <div className="bg-light min-vh-100 d-flex flex-row align-items-center">
|
||||||
<CContainer>
|
<CContainer>
|
||||||
<CRow className="justify-content-center">
|
<CRow className="justify-content-center">
|
||||||
@ -24,7 +60,7 @@ const ForgotPassword = () => {
|
|||||||
<CCardBody className="p-4">
|
<CCardBody className="p-4">
|
||||||
<CForm>
|
<CForm>
|
||||||
<h1>Forgot Password?</h1>
|
<h1>Forgot Password?</h1>
|
||||||
<p className="text-medium-emphasis"> Enter your email Below we will send you a link to reset your password</p>
|
<p className="text-medium-emphasis"> Enter your email Below, we will send you password in your Email</p>
|
||||||
{/* <CInputGroup className="mb-3">
|
{/* <CInputGroup className="mb-3">
|
||||||
<CInputGroupText>
|
<CInputGroupText>
|
||||||
<CIcon icon={cilUser} />
|
<CIcon icon={cilUser} />
|
||||||
@ -37,15 +73,20 @@ const ForgotPassword = () => {
|
|||||||
<CIcon icon={cilEnvelopeOpen} />
|
<CIcon icon={cilEnvelopeOpen} />
|
||||||
</CInputGroupText>
|
</CInputGroupText>
|
||||||
<CFormInput
|
<CFormInput
|
||||||
type="password"
|
type="email"
|
||||||
placeholder="Email"
|
placeholder="Email"
|
||||||
autoComplete="email"
|
autoComplete="email"
|
||||||
|
// value={email}
|
||||||
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
/>
|
/>
|
||||||
</CInputGroup>
|
</CInputGroup>
|
||||||
|
|
||||||
<CButton color="dark">Send</CButton>
|
<CButton color="primary" disabled={!email} onClick={() => handleSubmit()}>
|
||||||
|
<ClipLoader loading={loading} size={18} />
|
||||||
|
{!loading && "Send"}
|
||||||
|
</CButton>
|
||||||
<Link to='/'>
|
<Link to='/'>
|
||||||
<CButton color="dark" className='ms-2'>Back to Login</CButton>
|
<CButton color="secondary" className='ms-2'>Back to Login</CButton>
|
||||||
</Link>
|
</Link>
|
||||||
</CForm>
|
</CForm>
|
||||||
</CCardBody>
|
</CCardBody>
|
||||||
|
@ -3,7 +3,7 @@ import { CForm, CCol, CFormLabel, CContainer, CRow, CCardGroup, CCard, CCardBody
|
|||||||
import { Country, City } from 'country-state-city'
|
import { Country, City } from 'country-state-city'
|
||||||
import { useState, useEffect } from 'react'
|
import { useState, useEffect } from 'react'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { useHistory } from 'react-router-dom'
|
import { useNavigate } from 'react-router-dom'
|
||||||
const NewRegister = () => {
|
const NewRegister = () => {
|
||||||
const [cities, setCities] = useState([])
|
const [cities, setCities] = useState([])
|
||||||
const [ownerDetails, setOwnerDetails] = useState({
|
const [ownerDetails, setOwnerDetails] = useState({
|
||||||
@ -14,7 +14,7 @@ const NewRegister = () => {
|
|||||||
country: 'India',
|
country: 'India',
|
||||||
city: ''
|
city: ''
|
||||||
})
|
})
|
||||||
const history = useHistory()
|
const history = useNavigate()
|
||||||
const [processing, setProcessing] = useState(false)
|
const [processing, setProcessing] = useState(false)
|
||||||
const countries = Country.getAllCountries()
|
const countries = Country.getAllCountries()
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -48,7 +48,7 @@ const NewRegister = () => {
|
|||||||
|
|
||||||
// token: res.data.token,
|
// token: res.data.token,
|
||||||
// }));
|
// }));
|
||||||
history.push('/')
|
history('/')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,8 +12,10 @@ import { getStyle } from '@coreui/utils'
|
|||||||
import { CChartBar, CChartLine } from '@coreui/react-chartjs'
|
import { CChartBar, CChartLine } from '@coreui/react-chartjs'
|
||||||
import CIcon from '@coreui/icons-react'
|
import CIcon from '@coreui/icons-react'
|
||||||
import { cilArrowBottom, cilArrowTop, cilOptions } from '@coreui/icons'
|
import { cilArrowBottom, cilArrowTop, cilOptions } from '@coreui/icons'
|
||||||
|
import { BeatLoader } from 'react-spinners'
|
||||||
|
{/* <BeatLoader color="#36d7b7" /> */ }
|
||||||
|
|
||||||
const WidgetsDropdown = () => {
|
const WidgetsDropdown = ({ users }) => {
|
||||||
return (
|
return (
|
||||||
<CRow>
|
<CRow>
|
||||||
<CCol sm={6} lg={3}>
|
<CCol sm={6} lg={3}>
|
||||||
@ -22,244 +24,39 @@ const WidgetsDropdown = () => {
|
|||||||
color="primary"
|
color="primary"
|
||||||
value={
|
value={
|
||||||
<>
|
<>
|
||||||
26K{' '}
|
|
||||||
{/* <span className="fs-6 fw-normal">
|
{users.length}
|
||||||
(-12.4% <CIcon icon={cilArrowBottom} />)
|
|
||||||
</span> */}
|
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
title="Users"
|
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}>
|
|
||||||
<CWidgetStatsA
|
|
||||||
className="mb-4"
|
|
||||||
color="info"
|
|
||||||
value={
|
|
||||||
<>
|
|
||||||
$6.200{' '}
|
|
||||||
{/* <span className="fs-6 fw-normal">
|
|
||||||
(40.9% <CIcon icon={cilArrowTop} />)
|
|
||||||
</span> */}
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
title="Income"
|
|
||||||
// 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-info'),
|
|
||||||
data: [1, 18, 9, 17, 34, 22, 11],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}}
|
|
||||||
options={{
|
|
||||||
plugins: {
|
|
||||||
legend: {
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
maintainAspectRatio: false,
|
|
||||||
scales: {
|
|
||||||
x: {
|
|
||||||
grid: {
|
|
||||||
display: false,
|
|
||||||
drawBorder: false,
|
|
||||||
},
|
|
||||||
ticks: {
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
y: {
|
|
||||||
min: -9,
|
|
||||||
max: 39,
|
|
||||||
display: false,
|
|
||||||
grid: {
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
ticks: {
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
elements: {
|
|
||||||
line: {
|
|
||||||
borderWidth: 1,
|
|
||||||
},
|
|
||||||
point: {
|
|
||||||
radius: 4,
|
|
||||||
hitRadius: 10,
|
|
||||||
hoverRadius: 4,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
</CCol>
|
</CCol>
|
||||||
{/* <CCol sm={6} lg={3}>
|
{/* <CCol sm={6} lg={3}>
|
||||||
|
<CWidgetStatsA
|
||||||
|
className="mb-4"
|
||||||
|
color="info"
|
||||||
|
value={
|
||||||
|
<>
|
||||||
|
{category.length}
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
title="Total Categories"
|
||||||
|
|
||||||
|
/>
|
||||||
|
</CCol>
|
||||||
|
<CCol sm={6} lg={3}>
|
||||||
<CWidgetStatsA
|
<CWidgetStatsA
|
||||||
className="mb-4"
|
className="mb-4"
|
||||||
color="warning"
|
color="warning"
|
||||||
value={
|
value={
|
||||||
<>
|
<>
|
||||||
2.49{' '}
|
{requirement.length}
|
||||||
<span className="fs-6 fw-normal">
|
|
||||||
(84.7% <CIcon icon={cilArrowTop} />)
|
|
||||||
</span>
|
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
title="Conversion Rate"
|
title="Requirements"
|
||||||
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"
|
|
||||||
style={{ height: '70px' }}
|
|
||||||
data={{
|
|
||||||
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
label: 'My First dataset',
|
|
||||||
backgroundColor: 'rgba(255,255,255,.2)',
|
|
||||||
borderColor: 'rgba(255,255,255,.55)',
|
|
||||||
data: [78, 81, 80, 45, 34, 12, 40],
|
|
||||||
fill: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}}
|
|
||||||
options={{
|
|
||||||
plugins: {
|
|
||||||
legend: {
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
maintainAspectRatio: false,
|
|
||||||
scales: {
|
|
||||||
x: {
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
y: {
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
elements: {
|
|
||||||
line: {
|
|
||||||
borderWidth: 2,
|
|
||||||
tension: 0.4,
|
|
||||||
},
|
|
||||||
point: {
|
|
||||||
radius: 0,
|
|
||||||
hitRadius: 10,
|
|
||||||
hoverRadius: 4,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
</CCol>
|
</CCol>
|
||||||
<CCol sm={6} lg={3}>
|
<CCol sm={6} lg={3}>
|
||||||
@ -268,92 +65,42 @@ const WidgetsDropdown = () => {
|
|||||||
color="danger"
|
color="danger"
|
||||||
value={
|
value={
|
||||||
<>
|
<>
|
||||||
44K{' '}
|
{news.length}
|
||||||
<span className="fs-6 fw-normal">
|
|
||||||
(-23.6% <CIcon icon={cilArrowBottom} />)
|
|
||||||
</span>
|
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
title="Sessions"
|
title="Total News"
|
||||||
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={
|
|
||||||
<CChartBar
|
|
||||||
className="mt-3 mx-3"
|
|
||||||
style={{ height: '70px' }}
|
|
||||||
data={{
|
|
||||||
labels: [
|
|
||||||
'January',
|
|
||||||
'February',
|
|
||||||
'March',
|
|
||||||
'April',
|
|
||||||
'May',
|
|
||||||
'June',
|
|
||||||
'July',
|
|
||||||
'August',
|
|
||||||
'September',
|
|
||||||
'October',
|
|
||||||
'November',
|
|
||||||
'December',
|
|
||||||
'January',
|
|
||||||
'February',
|
|
||||||
'March',
|
|
||||||
'April',
|
|
||||||
],
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
label: 'My First dataset',
|
|
||||||
backgroundColor: 'rgba(255,255,255,.2)',
|
|
||||||
borderColor: 'rgba(255,255,255,.55)',
|
|
||||||
data: [78, 81, 80, 45, 34, 12, 40, 85, 65, 23, 12, 98, 34, 84, 67, 82],
|
|
||||||
barPercentage: 0.6,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}}
|
|
||||||
options={{
|
|
||||||
maintainAspectRatio: false,
|
|
||||||
plugins: {
|
|
||||||
legend: {
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
scales: {
|
|
||||||
x: {
|
|
||||||
grid: {
|
|
||||||
display: false,
|
|
||||||
drawTicks: false,
|
|
||||||
},
|
|
||||||
ticks: {
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
y: {
|
|
||||||
grid: {
|
|
||||||
display: false,
|
|
||||||
drawBorder: false,
|
|
||||||
drawTicks: false,
|
|
||||||
},
|
|
||||||
ticks: {
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
</CCol> */}
|
</CCol>
|
||||||
|
<CCol sm={6} lg={3}>
|
||||||
|
<CWidgetStatsA
|
||||||
|
className="mb-4"
|
||||||
|
color="success"
|
||||||
|
value={
|
||||||
|
<>
|
||||||
|
{offer.length}
|
||||||
|
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
title="Total Offers"
|
||||||
|
|
||||||
|
/>
|
||||||
|
</CCol>
|
||||||
|
<CCol sm={6} lg={3}>
|
||||||
|
<CWidgetStatsA
|
||||||
|
className="mb-4"
|
||||||
|
color="dark"
|
||||||
|
value={
|
||||||
|
<>
|
||||||
|
{event.length}
|
||||||
|
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
title="Total Events"
|
||||||
|
|
||||||
|
/> */}
|
||||||
|
{/* </CCol> */}
|
||||||
</CRow>
|
</CRow>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user