Compare commits
147 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cb4f9fbb42 | |||
| ad4a92ceed | |||
| d71fe9cc01 | |||
| aeb9f0512c | |||
| 62c3a8be82 | |||
| c7c1da919d | |||
| 669a249499 | |||
| 2cc57f0b0a | |||
| 2be1f2ebd1 | |||
| 54be47e1c8 | |||
| 8eefbbede8 | |||
| fa6b53ede0 | |||
| a5ac576176 | |||
| b840f28667 | |||
| 66d1ae1609 | |||
| 9cfb4651af | |||
| 2d141b529c | |||
| b418ca7d58 | |||
| 9eea804f71 | |||
| f3ebb0a925 | |||
| 6421eb5b3e | |||
| 971624a358 | |||
| 21463ed501 | |||
| f450d0e868 | |||
| c880cccb5a | |||
| c776419dcf | |||
| 80d5c8ea12 | |||
| df6d2b570c | |||
| a802c1ca39 | |||
| 1a054a9fbc | |||
| 33eacecacf | |||
| a71017fae6 | |||
| 8969234fe5 | |||
| a0da97e14d | |||
| 4d1de18713 | |||
| 4fe66fd161 | |||
| 6028e4c617 | |||
| 398392062c | |||
| b84eac1299 | |||
| 52e3553aaa | |||
| 220e4952d5 | |||
| 59c90ea175 | |||
| 9838fc948e | |||
| cb4c741a90 | |||
| bba38affae | |||
| 9468793d91 | |||
| 44224e23ff | |||
| 5b926300ae | |||
| 9125730d2b | |||
| 00baa0b9bf | |||
| f5018bc6b7 | |||
| 59d9eb3df9 | |||
| 8f78011800 | |||
| 3c3f70fd3f | |||
| 4f62410e6d | |||
| b8c65ee091 | |||
| 5e1e97a2dd | |||
| f794e6d31c | |||
| a4e1376c27 | |||
| 16db88808b | |||
| 2e97ec9857 | |||
| 6ec537bebf | |||
| d84c266653 | |||
| bb5a886e47 | |||
| b5a37c4cc5 | |||
| ddde4bd0d5 | |||
| bf9c6c8b32 | |||
| 14e588b0a9 | |||
| dde01ab79a | |||
| a5f1c4b5bb | |||
| a16dd7af24 | |||
| 54d44e39d3 | |||
| 578a0e4c8f | |||
| d0ac2515a3 | |||
| b26f8b4e0d | |||
| ab6518e2ee | |||
| 563abe6c35 | |||
| 894ed6ea35 | |||
| 71859d9712 | |||
| 6d9a0e5624 | |||
| 0bd0b3ca64 | |||
| 0bef976bca | |||
| 0d6dc40633 | |||
| f50590850b | |||
| 1dcae6b163 | |||
| c06dc93e9a | |||
| 67d67e773a | |||
| 0493ee4f03 | |||
| 866c127135 | |||
| f7d27a3778 | |||
| c7fac54e12 | |||
| f994c7f45e | |||
| b0821981e7 | |||
| a220f2faa4 | |||
| 2e46a56146 | |||
| b7aaff7adc | |||
| d606b5682c | |||
| 25d4751935 | |||
| a8d78c4c3f | |||
| 9c672d4bf2 | |||
| c744eccd15 | |||
| 302a3aa3bb | |||
| 23a295866a | |||
| 487494fbff | |||
| 919594d7b2 | |||
| 7eedae8fc2 | |||
| 51a3c60590 | |||
| ab597039ba | |||
| 6fd2dcdb3d | |||
| 614910e29c | |||
| 2c832699c2 | |||
| c8fe2eadf6 | |||
| 1e174b7432 | |||
| dda8fa7d30 | |||
| d0f1d5ee34 | |||
| a2843d97e2 | |||
| a0e417fc68 | |||
| 10e65fa6ff | |||
| f503422c42 | |||
| bd470ea8bc | |||
| 6c14b2587c | |||
| 085756b8bc | |||
| eb4d5315de | |||
| 8ac742e5d6 | |||
| c2db47cbb8 | |||
| ee787c0740 | |||
| 6136d762a3 | |||
| 2f73e84a84 | |||
| 8c57e94bb6 | |||
| fa7660de29 | |||
| bde30f781a | |||
| 9f9dcc5e37 | |||
| ec11a7b5b3 | |||
| 38c5717667 | |||
| 77eaf15c6a | |||
| 60488524ed | |||
| 3584447c65 | |||
| 58cd232f91 | |||
| 9684e7fcfa | |||
| d4eda11477 | |||
| 1d31507984 | |||
| a3dbc8cab1 | |||
| 29878e3ddf | |||
| 80a40da9df | |||
| 9f7f1b706b | |||
| d878d1d098 | |||
| 3a60d4e12c |
@@ -1,15 +1,16 @@
|
||||
SKIP_PREFLIGHT_CHECK=true
|
||||
REACT_APP_NODE_ENV="development"
|
||||
REACT_APP_SOCKET_URL="https://dev-socket.mermsemr.com"
|
||||
NODE_ENV="development"
|
||||
REACT_APP_SOCKET_URL="https://devsocket.mermsemr.com"
|
||||
REACT_APP_MAIN_API="https://devapi.mermsemr.com"
|
||||
REACT_APP_MEDIA_SERVER="https://dev-media.mermsemr.com"
|
||||
REACT_APP_MAIN_SOCKET="https://dev-socket.mermsemr.com"
|
||||
REACT_APP_MEDIA_SERVER="https://qa-media.mermsemr.com"
|
||||
REACT_APP_MAIN_SOCKET="https://devsocket.mermsemr.com"
|
||||
|
||||
# login footer links
|
||||
REACT_APP_HOME_LINK='https://dev-www.mermsemr.com/'
|
||||
REACT_APP_ABOUT_LINK='https://dev-www.mermsemr.com/about'
|
||||
REACT_APP_CONTACTS_LINK='https://dev-www.mermsemr.com/contacts'
|
||||
REACT_APP_TERMS_LINK='https://dev-www.mermsemr.com/terms'
|
||||
REACT_APP_HOME_LINK='https://qa-www.mermsemr.com/'
|
||||
REACT_APP_ABOUT_LINK='https://qa-www.mermsemr.com/about'
|
||||
REACT_APP_CONTACTS_LINK='https://qa-www.mermsemr.com/contacts'
|
||||
REACT_APP_TERMS_LINK='https://qa-www.mermsemr.com/terms'
|
||||
|
||||
# Inactivity timeout/logout AT 10MINS
|
||||
REACT_APP_TIMEOUT=600000
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
SKIP_PREFLIGHT_CHECK=true
|
||||
REACT_APP_NODE_ENV="development"
|
||||
REACT_APP_SOCKET_URL="https://dev-socket.mermsemr.com"
|
||||
REACT_APP_SOCKET_URL="https://devsocket.mermsemr.com"
|
||||
REACT_APP_MAIN_API="https://devapi.mermsemr.com"
|
||||
REACT_APP_MEDIA_SERVER="https://dev-media.mermsemr.com"
|
||||
REACT_APP_MAIN_SOCKET="https://dev-socket.mermsemr.com"
|
||||
REACT_APP_MEDIA_SERVER="https://qa-media.mermsemr.com"
|
||||
REACT_APP_MAIN_SOCKET="https://devsocket.mermsemr.com"
|
||||
|
||||
# login footer links
|
||||
REACT_APP_HOME_LINK='https://dev-www.mermsemr.com/'
|
||||
REACT_APP_ABOUT_LINK='https://dev-www.mermsemr.com/about'
|
||||
REACT_APP_CONTACTS_LINK='https://dev-www.mermsemr.com/contacts'
|
||||
REACT_APP_TERMS_LINK='https://dev-www.mermsemr.com/terms'
|
||||
REACT_APP_HOME_LINK='https://qa-www.mermsemr.com/'
|
||||
REACT_APP_ABOUT_LINK='https://qa-www.mermsemr.com/about'
|
||||
REACT_APP_CONTACTS_LINK='https://qa-www.mermsemr.com/contacts'
|
||||
REACT_APP_TERMS_LINK='https://qa-www.mermsemr.com/terms'
|
||||
|
||||
# Inactivity timeout/logout AT 10MINS
|
||||
REACT_APP_TIMEOUT=600000
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
SKIP_PREFLIGHT_CHECK=true
|
||||
REACT_APP_NODE_ENV="production"
|
||||
NODE_ENV="production"
|
||||
REACT_APP_SOCKET_URL="https://socket.mermsemr.com"
|
||||
REACT_APP_MAIN_API="https://devapi.mermsemr.com"
|
||||
REACT_APP_MAIN_API="https://api.mermsemr.com"
|
||||
REACT_APP_MEDIA_SERVER="https://media.mermsemr.com"
|
||||
REACT_APP_MAIN_SOCKET="https://socket.mermsemr.com"
|
||||
|
||||
# login footer links
|
||||
REACT_APP_HOME_LINK='https://www.mermsemr.com/'
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
SKIP_PREFLIGHT_CHECK=true
|
||||
REACT_APP_NODE_ENV="development"
|
||||
NODE_ENV="development"
|
||||
REACT_APP_SOCKET_URL="https://devsocket.mermsemr.com"
|
||||
REACT_APP_MAIN_API="https://devapi.mermsemr.com"
|
||||
REACT_APP_MEDIA_SERVER="https://qa-media.mermsemr.com"
|
||||
REACT_APP_MAIN_SOCKET="https://devsocket.mermsemr.com"
|
||||
|
||||
# login footer links
|
||||
REACT_APP_HOME_LINK='https://qa-www.mermsemr.com/'
|
||||
REACT_APP_ABOUT_LINK='https://qa-www.mermsemr.com/about'
|
||||
REACT_APP_CONTACTS_LINK='https://qa-www.mermsemr.com/contacts'
|
||||
REACT_APP_TERMS_LINK='https://qa-www.mermsemr.com/terms'
|
||||
|
||||
# Inactivity timeout/logout AT 10MINS
|
||||
REACT_APP_TIMEOUT=600000
|
||||
@@ -20,7 +20,7 @@ services:
|
||||
extra_hosts:
|
||||
- api.mermsemr.com:10.10.33.15
|
||||
- devapi.mermsemr.com:10.10.33.15
|
||||
- dev-socket.mermsemr.com:10.10.33.15
|
||||
- devsocket.mermsemr.com:10.10.33.15
|
||||
- socket.mermsemr.com:10.10.33.15
|
||||
- dev-media.mermsemr.com:10.10.33.15
|
||||
- media.mermsemr.com:10.10.33.15
|
||||
|
||||
@@ -33,8 +33,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start -e .env.development",
|
||||
"build": "react-scripts start -e .env.development",
|
||||
"build_real": "GENERATE_SOURCEMAP=false react-scripts build -e .env.production",
|
||||
"build": "GENERATE_SOURCEMAP=false react-scripts build -e .env.production",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
|
||||
|
After Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 18 KiB |
@@ -4,12 +4,17 @@ set -x
|
||||
|
||||
export NODE_ENV="${NODE_ENV:-development}"
|
||||
|
||||
if [ $NODE_ENV == "development" ]; then
|
||||
if [ $NODE_ENV = "development" ]; then
|
||||
# this runs webpack-dev-server with hot reloading
|
||||
echo "Development build"
|
||||
npm install --legacy-peer-deps
|
||||
npm start
|
||||
# npm run build
|
||||
elif [ $NODE_ENV = "qa" -o $NODE_ENV = "test" ]; then
|
||||
echo "QA build"
|
||||
export NODE_ENV="test"
|
||||
npm install --legacy-peer-deps
|
||||
npm start
|
||||
else
|
||||
# build the app and serve it via nginx
|
||||
echo "Production build"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.custom-bg {
|
||||
background-image: url('./assets/bg/bg_1.jpg') !important;
|
||||
background-image: url('./assets/bg/bg_2.jpg') !important;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
@@ -22,10 +22,9 @@
|
||||
}
|
||||
|
||||
.login-links a {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
font-size: 14px;
|
||||
padding: 0px 20px;
|
||||
border-right: 2px solid;
|
||||
border-right: 2px solid #6c757d;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -35,4 +34,17 @@
|
||||
|
||||
.login-links a:last-child{
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
button{
|
||||
font-size: 1rem!important;
|
||||
font-weight: 700!important;
|
||||
}
|
||||
|
||||
.font-600 {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.accordion-button, .accordion-button:not(.collapsed) {
|
||||
background-color: transparent!important;
|
||||
}
|
||||
@@ -1,23 +1,28 @@
|
||||
import { QueryClientProvider, QueryClient } from '@tanstack/react-query'
|
||||
import { Provider } from 'react-redux';
|
||||
import store from './store/store'
|
||||
import AppRouters from './AppRouters';
|
||||
|
||||
import './App.css';
|
||||
|
||||
|
||||
function App() {
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
refetchOnWindowFocus: false,
|
||||
retry: 3,
|
||||
// refetchOnMount: false,
|
||||
staleTime: Infinity // can also be a number in millisecond
|
||||
},
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
refetchOnWindowFocus: false,
|
||||
retry: 3,
|
||||
// refetchOnMount: false,
|
||||
staleTime: 10*60*1000 // can also be a number in millisecond
|
||||
},
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<AppRouters />
|
||||
<Provider store={store}>
|
||||
<AppRouters />
|
||||
</Provider>
|
||||
</QueryClientProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,12 @@ import SettingsPage from './views/SettingsPage'
|
||||
import ProductPage from './views/ProductPage'
|
||||
import SocketIOContextProvider from './component/context/SocketIOContext';
|
||||
import CSignupPage from './views/CSignupPage';
|
||||
import HelpPage from './views/HelpPage';
|
||||
import SubscriptionPage from './views/SubscriptionPage';
|
||||
import OnboardPage from "./views/OnboardPage";
|
||||
import AccPWDResetPage from './views/AccPWDResetPage';
|
||||
import ProfileCompletePage from './views/ProfileCompletePage';
|
||||
import SubscribePage from './views/Subscribe'
|
||||
|
||||
function AppRouters() {
|
||||
return (
|
||||
@@ -31,6 +37,7 @@ function AppRouters() {
|
||||
<Route path={siteLinks.signup} element={<SignupPage />} />
|
||||
<Route path={siteLinks.forgetpwd} element={<ForgetpwdPage />} />
|
||||
<Route path={siteLinks.csignup} element={<CSignupPage />} />
|
||||
<Route path={siteLinks.accreset} element={<AccPWDResetPage />} />
|
||||
<Route path={siteLinks.error} element={<LoginPage />} />
|
||||
</Route>
|
||||
|
||||
@@ -38,13 +45,18 @@ function AppRouters() {
|
||||
<Route element={<SocketIOContextProvider />}>
|
||||
<Route element={<UserExist />}>
|
||||
<Route path={siteLinks.dash} element={<HomePage />} />
|
||||
<Route path={siteLinks.profile_complete} element={<ProfileCompletePage />} />
|
||||
<Route path={siteLinks.product} element={<ProductPage />} />
|
||||
<Route path={siteLinks.reports} element={<ReportsPage />} />
|
||||
<Route path={siteLinks.comments} element={<CommentsPage />} />
|
||||
<Route path={siteLinks.contacts} element={<ContactsPage />} />
|
||||
<Route path={siteLinks.user} element={<UserPage />} />
|
||||
<Route path={siteLinks.subscription} element={<SubscriptionPage />} />
|
||||
<Route path={siteLinks.onboard} element={<OnboardPage />} />
|
||||
<Route path={siteLinks.calendar} element={<CalendarPage />} />
|
||||
<Route path={siteLinks.settings} element={<SettingsPage />} />
|
||||
<Route path={siteLinks.subscribe} element={<SubscribePage />} />
|
||||
<Route path={siteLinks.help} element={<HelpPage />} />
|
||||
</Route>
|
||||
</Route>
|
||||
</Route>
|
||||
|
||||
|
After Width: | Height: | Size: 390 KiB |
|
After Width: | Height: | Size: 995 B |
|
After Width: | Height: | Size: 99 KiB |
|
After Width: | Height: | Size: 113 KiB |
|
After Width: | Height: | Size: 101 KiB |
|
After Width: | Height: | Size: 104 KiB |
|
After Width: | Height: | Size: 132 KiB |
|
After Width: | Height: | Size: 9.2 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 18 KiB |
@@ -0,0 +1,220 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { Form, Formik } from "formik";
|
||||
import * as Yup from "yup";
|
||||
import { useDispatch } from 'react-redux'
|
||||
|
||||
import { Link, useNavigate, useParams } from 'react-router-dom'
|
||||
import siteLinks from '../../links/siteLinks'
|
||||
import { useMutation } from '@tanstack/react-query';
|
||||
import { completePWDReset, verifyResetToken } from '../../services/services';
|
||||
import { updateUserDetails } from '../../store/UserDetails'
|
||||
|
||||
import { IoMdArrowDropdown } from "react-icons/io";
|
||||
import getImage from '../../utils/getImage';
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
password: Yup.string().required("Password is required"),
|
||||
confirmpassword: Yup.string().required("Confirm Password is required").oneOf([Yup.ref('password')], 'Passwords must match')
|
||||
})
|
||||
|
||||
const initialValues = {
|
||||
password: '',
|
||||
confirmpassword: '',
|
||||
};
|
||||
|
||||
export default function AccPWDReset() {
|
||||
|
||||
const {token} = useParams()
|
||||
|
||||
const dispatch = useDispatch()
|
||||
|
||||
const navigate = useNavigate()
|
||||
|
||||
const [user, setUser] = useState(null)
|
||||
|
||||
// API to verify email link
|
||||
const verifyLink = useMutation({
|
||||
mutationFn: (fields) => {
|
||||
return verifyResetToken(fields)
|
||||
},
|
||||
onSuccess: (res) => {
|
||||
// console.log('res', res.data)
|
||||
if(res.data.resultCode != '0' || !res?.data?.pending_uid){
|
||||
throw({message: res?.data?.resultDescription})
|
||||
}
|
||||
// setUser({user:'testaccount', ...res.data})
|
||||
setUser(res.data)
|
||||
},
|
||||
// onError: (err) => {
|
||||
// console.log('err', err)
|
||||
// }
|
||||
})
|
||||
|
||||
const resetPWD = useMutation({
|
||||
mutationFn: (fields) => {
|
||||
return completePWDReset(fields)
|
||||
},
|
||||
onSuccess: (res) => {
|
||||
if(res?.data?.resultCode != '0'){
|
||||
throw({message: res?.data?.resultDescription})
|
||||
}
|
||||
// const {token, room, uid} = res?.data
|
||||
// if(!token || !room){
|
||||
// throw({message: 'something went wrong, try again!'})
|
||||
// }
|
||||
// localStorage.setItem('token', token)
|
||||
// localStorage.setItem('room', room)
|
||||
// localStorage.setItem('uid', uid)
|
||||
// dispatch(updateUserDetails({ ...res?.data }));
|
||||
// navigate('/dash') // later add redux to dispatch state
|
||||
},
|
||||
// onError: (err) => {
|
||||
// console.log('err', err)
|
||||
// }
|
||||
})
|
||||
|
||||
const handleCompletePWDReset = (values) => {
|
||||
let reqData = {
|
||||
reset_token: token,
|
||||
reset_uid: user?.pending_uid,
|
||||
new_password: values.password,
|
||||
}
|
||||
resetPWD.mutate(reqData)
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
if(!token){
|
||||
return navigate(siteLinks.login, {replace: true})
|
||||
}
|
||||
verifyLink.mutate({reset_token: token})
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="app">
|
||||
<div className="app-wrap">
|
||||
<div className="app-contant">
|
||||
<div className="vh-100 bg-white custom-bg">
|
||||
<div className="container-fluid p-0">
|
||||
<div className="row no-gutters justify-content-center">
|
||||
<div className="col-11 col-sm-6 col-lg-5 col-xxl-4 align-self-center order-2 order-sm-1" style={{maxWidth: '520px'}}>
|
||||
<div className="mt-5 d-flex">
|
||||
<div className="bg-white register p-5">
|
||||
<h1 className="mb-2">MERMS Panel</h1>
|
||||
{(verifyLink.isSuccess && !resetPWD.isSuccess) && <p>Complete your password reset</p>}
|
||||
<div
|
||||
>
|
||||
<div className='mt-2'>
|
||||
<div className="row">
|
||||
{resetPWD.isSuccess ?
|
||||
<>
|
||||
<div className='col-12'>
|
||||
<div className="rounded-2 d-flex flex-column justify-content-between align-items-center" style={{backgroundColor: '#F2FAF7'}}>
|
||||
<h4 className='p-4 text-black'>Your password reset is completed</h4>
|
||||
<img className='' style={{width: '150px'}} src={getImage('reset-password.png')} alt='reset-icon' />
|
||||
<Link to={siteLinks.login} className='p-2 text-primary' style={{color: '#6FCAEF'}}>Home</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col-12 mt-3">
|
||||
<p>Go <Link to={siteLinks.home}> Back</Link></p>
|
||||
</div>
|
||||
</>
|
||||
:
|
||||
<>
|
||||
{verifyLink.isPending ?
|
||||
<div className='col-12'>
|
||||
<div className="rounded-2 d-flex flex-column justify-content-center align-items-center" style={{height: '200px', backgroundColor: '#F2FAF7'}}>
|
||||
<div className="col-12 d-flex flex-column justify-content-center align-items-center">
|
||||
<p className='text-black'>loading...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
: verifyLink.isSuccess ?
|
||||
<div className='col-12'>
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
validationSchema={validationSchema}
|
||||
onSubmit={handleCompletePWDReset}
|
||||
>
|
||||
{(props) => {
|
||||
return (
|
||||
<Form className='mt-2'>
|
||||
<div className="row">
|
||||
<>
|
||||
<div className="col-12">
|
||||
<div className="form-group">
|
||||
<label className={`text-black fw-bold control-label`}>Username: {user?.user}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-12">
|
||||
<div className="form-group">
|
||||
<label className={`text-black fw-bold control-label ${(props.errors.password && props.touched.password) && 'text-danger'}`}>Password*</label>
|
||||
<input type="password" name='password' className="form-control" placeholder="password" value={props.values.password} onChange={props.handleChange} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-12">
|
||||
<div className="form-group">
|
||||
<label className={`text-black fw-bold control-label`}>Confirm Password* <span className={`${(props.errors.confirmpassword && props.touched.confirmpassword) && 'text-danger'}`}>{(props.errors.confirmpassword && props.touched.confirmpassword) && props.errors.confirmpassword}</span></label>
|
||||
<input type="password" name='confirmpassword' className="form-control" placeholder="confirmpassword" value={props.values.confirmpassword} onChange={props.handleChange} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{resetPWD.error &&
|
||||
<>
|
||||
<div className="col-12">
|
||||
<p className='text-danger'>{resetPWD.error.message}</p>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
|
||||
<div className="col-12 mt-3 text-end">
|
||||
<button type='submit' className="btn btn-primary text-uppercase">{resetPWD.isPending ? 'loading...' : 'reset password'}</button>
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
</Form>
|
||||
);
|
||||
}}
|
||||
</Formik>
|
||||
</div>
|
||||
: verifyLink.error ?
|
||||
<>
|
||||
<div className='col-12'>
|
||||
<div className="rounded-2 d-flex flex-column justify-content-between align-items-center" style={{backgroundColor: '#E9D0DD'}}>
|
||||
<h4 className='p-4 text-black'>Unable to continue password reset. Please start again</h4>
|
||||
<img className='' style={{width: '150px'}} src={getImage('reset-password.png')} alt='reset-icon' />
|
||||
<Link to={siteLinks.login} className='p-2 text-primary' style={{color: '#6FCAEF'}}>Home</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col-12 mt-3">
|
||||
<p>Go <Link to={siteLinks.home}> Back</Link></p>
|
||||
</div>
|
||||
</>
|
||||
:
|
||||
null
|
||||
}
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <div className="custom-bg col-sm-6 col-xxl-9 col-lg-7 b-gradient o-hidden order-1 order-sm-2">
|
||||
<div className="row align-items-center h-100">
|
||||
<div className="col-7 mx-auto ">
|
||||
<img className="img-fluid" src={LoginImg} alt="" />
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { Form, Formik } from "formik";
|
||||
import * as Yup from "yup";
|
||||
import { useDispatch } from 'react-redux'
|
||||
|
||||
import { Link, useNavigate, useParams } from 'react-router-dom'
|
||||
import siteLinks from '../../links/siteLinks'
|
||||
import { useMutation } from '@tanstack/react-query';
|
||||
import { completeRegistration, verifyEmail } from '../../services/services';
|
||||
import { updateUserDetails } from '../../store/UserDetails'
|
||||
|
||||
import { IoMdArrowDropdown } from "react-icons/io";
|
||||
|
||||
@@ -28,6 +30,8 @@ const validationSchema = Yup.object().shape({
|
||||
export default function CSignup() {
|
||||
|
||||
const {jwt} = useParams()
|
||||
|
||||
const dispatch = useDispatch()
|
||||
|
||||
const navigate = useNavigate()
|
||||
|
||||
@@ -51,15 +55,19 @@ export default function CSignup() {
|
||||
return completeRegistration(fields)
|
||||
},
|
||||
onSuccess: (res) => {
|
||||
const {token, room} = res?.data?.data
|
||||
if(token){
|
||||
localStorage.setItem('token', token)
|
||||
localStorage.setItem('room', room)
|
||||
// const data = {token}
|
||||
// dispatch(updateUserDetails({ ...data }));
|
||||
navigate('/dash') // later add redux to dispatch state
|
||||
if(res?.data?.resultCode != '0'){
|
||||
throw({message: res?.data?.resultDescription})
|
||||
}
|
||||
}
|
||||
const {token, room, uid} = res?.data
|
||||
if(!token || !room){
|
||||
throw({message: 'something went wrong, try again!'})
|
||||
}
|
||||
localStorage.setItem('token', token)
|
||||
localStorage.setItem('room', room)
|
||||
localStorage.setItem('uid', uid)
|
||||
dispatch(updateUserDetails({ ...res?.data }));
|
||||
navigate('/dash') // later add redux to dispatch state
|
||||
},
|
||||
// onError: (err) => {
|
||||
// console.log('err', err)
|
||||
// }
|
||||
@@ -70,7 +78,7 @@ export default function CSignup() {
|
||||
country : values.country,
|
||||
username: values.username,
|
||||
password: values.password,
|
||||
verify_link: user.verify_link
|
||||
verify_link: jwt
|
||||
}
|
||||
cSignup.mutate(reqData)
|
||||
}
|
||||
@@ -89,7 +97,7 @@ export default function CSignup() {
|
||||
<div className="vh-100 bg-white custom-bg">
|
||||
<div className="container-fluid p-0">
|
||||
<div className="row no-gutters justify-content-center">
|
||||
<div className="col-11 col-sm-6 col-lg-5 col-xxl-3 align-self-center order-2 order-sm-1">
|
||||
<div className="col-11 col-sm-6 col-lg-5 col-xxl-4 align-self-center order-2 order-sm-1" style={{maxWidth: '520px'}}>
|
||||
<div className="mt-5 d-flex">
|
||||
<div className="bg-white register p-5">
|
||||
<h1 className="mb-2">MERMS Panel</h1>
|
||||
@@ -196,7 +204,7 @@ export default function CSignup() {
|
||||
}
|
||||
|
||||
<div className="col-12 mt-3 text-center">
|
||||
<Link to={siteLinks.login} className='text-primary' style={{color: '#6FCAEF'}}>Need help with logging in or signing up?</Link>
|
||||
<Link to={siteLinks.signup} className='text-primary' style={{color: '#6FCAEF'}}>Need help with logging in or signing up?</Link>
|
||||
</div>
|
||||
|
||||
<div className="col-12 mt-3 text-center">
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import React from "react";
|
||||
|
||||
export default function ExtFooter() {
|
||||
return <div className="login-links">
|
||||
<a href={process.env.REACT_APP_HOME_LINK}>Home</a>
|
||||
<a href={process.env.REACT_APP_ABOUT_LINK}>About</a>
|
||||
<a href={process.env.REACT_APP_CONTACTS_LINK}>Contact</a>
|
||||
<a href={process.env.REACT_APP_TERMS_LINK}>Terms</a>
|
||||
</div>
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import { Link } from 'react-router-dom'
|
||||
import siteLinks from '../../links/siteLinks'
|
||||
import { useMutation } from '@tanstack/react-query'
|
||||
import { recoverPWD } from '../../services/services';
|
||||
import getImage from '../../utils/getImage';
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
username: Yup.string()
|
||||
@@ -46,11 +47,11 @@ export default function Forgetpwd2() {
|
||||
<div className="vh-100 bg-white custom-bg">
|
||||
<div className="container-fluid p-0">
|
||||
<div className="row no-gutters justify-content-center">
|
||||
<div className="col-11 col-sm-6 col-lg-5 col-xxl-3 align-self-center order-2 order-sm-1h">
|
||||
<div className="col-11 col-sm-6 col-lg-5 col-xxl-4 align-self-center order-2 order-sm-1h" style={{maxWidth: '520px'}}>
|
||||
<div className="mt-5 d-flex">
|
||||
<div className="bg-white register p-5">
|
||||
<h1 className="mb-2">MERMS Panel</h1>
|
||||
<p>Please enter your username.</p>
|
||||
{!mutation.isSuccess && <p>Please enter your username.</p>}
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
validationSchema={validationSchema}
|
||||
@@ -81,8 +82,9 @@ export default function Forgetpwd2() {
|
||||
</>
|
||||
:
|
||||
<div className='col-12'>
|
||||
<div className="rounded-2 d-flex flex-column justify-content-between align-items-center" style={{height: '200px', backgroundColor: '#F2FAF7'}}>
|
||||
<div className="rounded-2 d-flex flex-column justify-content-between align-items-center" style={{backgroundColor: '#F2FAF7'}}>
|
||||
<h4 className='p-4 text-black'>Check your email to continue password reset.</h4>
|
||||
<img className='' style={{width: '150px'}} src={getImage('reset-password.png')} alt='reset-icon' />
|
||||
<Link to={siteLinks.login} className='p-2 text-primary' style={{color: '#6FCAEF'}}>Home</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -83,7 +83,7 @@ export default function Login() {
|
||||
<div className="vh-100 custom-bg">
|
||||
<div className="container-fluid p-0">
|
||||
<div className="row no-gutters justify-content-center">
|
||||
<div className="col-11 col-sm-6 col-lg-5 col-xxl-3 align-self-center order-2 order-sm-1">
|
||||
<div className="col-11 col-sm-6 col-lg-5 col-xxl-4 align-self-center order-2 order-sm-1" style={{maxWidth: '520px'}}>
|
||||
<div className="mt-5 d-flex">
|
||||
<div className="bg-white register px-5 pt-5 pb-3">
|
||||
<h1 className="mb-2">MERMS Panel</h1>
|
||||
@@ -124,7 +124,7 @@ export default function Login() {
|
||||
<button type='button' onClick={()=>{login.mutate(fields)}} className="btn btn-primary text-uppercase">{login.isPending ? 'loading...' : 'Sign In'}</button>
|
||||
</div>
|
||||
<div className="col-12 mt-3">
|
||||
<p>Don't have an account ?<Link to={siteLinks.signup}> Sign Up</Link></p>
|
||||
<p>Don't have an account ?<Link to={siteLinks.signup}><span style={{fontWeight: 'bolder'}}>Sign Up</span></Link></p>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@@ -133,7 +133,7 @@ export default function Login() {
|
||||
<div className="app-store-icons-wrap text-center">
|
||||
<a className="icon google"
|
||||
href='#' >
|
||||
<img src={IOSDownload} className='w-100 h-auto' alt='IOS Download' />
|
||||
<img src={IOSDownload} className='w-80 h-auto' alt='IOS Download' />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -141,7 +141,7 @@ export default function Login() {
|
||||
<div className="col-6">
|
||||
<div className="app-store-icons-wrap text-center">
|
||||
<a className="icon apple" href='#'>
|
||||
<img src={GoogleDownload} className='w-100 h-auto' alt='IOS Download' />
|
||||
<img src={GoogleDownload} className='w-80 h-auto' alt='IOS Download' />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -153,6 +153,7 @@ export default function Login() {
|
||||
<a href={process.env.REACT_APP_CONTACTS_LINK}>Contact</a>
|
||||
<a href={process.env.REACT_APP_TERMS_LINK}>Terms</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8,6 +8,7 @@ import { Link } from 'react-router-dom'
|
||||
import siteLinks from '../../links/siteLinks'
|
||||
import { useMutation } from '@tanstack/react-query';
|
||||
import { signUpUser } from '../../services/services';
|
||||
import getImage from '../../utils/getImage';
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
email: Yup.string()
|
||||
@@ -49,6 +50,7 @@ export default function Signup2() {
|
||||
const signUp = (values) => {
|
||||
// helpers.resetForm()
|
||||
// console.log('values', values, helpers)
|
||||
delete values.isChecked
|
||||
mutation.mutate(values)
|
||||
}
|
||||
|
||||
@@ -59,7 +61,7 @@ export default function Signup2() {
|
||||
<div className="vh-100 bg-white custom-bg">
|
||||
<div className="container-fluid p-0">
|
||||
<div className="row no-gutters justify-content-center">
|
||||
<div className="col-11 col-sm-6 col-lg-5 col-xxl-3 align-self-center order-2 order-sm-1">
|
||||
<div className="col-11 col-sm-6 col-lg-5 col-xxl-4 align-self-center order-2 order-sm-1" style={{maxWidth: '520px'}}>
|
||||
<div className="mt-5 d-flex">
|
||||
<div className="bg-white register p-5">
|
||||
<h1 className="mb-2">MERMS Panel</h1>
|
||||
@@ -129,8 +131,9 @@ export default function Signup2() {
|
||||
</>
|
||||
:
|
||||
<div className='col-12'>
|
||||
<div className="rounded-2 d-flex flex-column justify-content-between align-items-center" style={{height: '200px', backgroundColor: '#F2FAF7'}}>
|
||||
<h4 className='p-4 text-black'>Check your email to continue.</h4>
|
||||
<div className="rounded-2 d-flex flex-column justify-content-between align-items-center" style={{backgroundColor: '#F2FAF7'}}>
|
||||
<h4 className='p-4 text-black' style={{marginBottom: '-30px'}}>Check your email to continue.</h4>
|
||||
<img className='' style={{width: '200px'}} src={getImage('check-mail.png')} alt='mail-alert' />
|
||||
<Link to={siteLinks.login} className='p-2 text-primary' style={{color: '#6FCAEF'}}>Home</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -11,7 +11,8 @@ export default function BearerToken() {
|
||||
return userToken(fields)
|
||||
},
|
||||
onError: (error) => {
|
||||
location.reload();
|
||||
console.log(error)
|
||||
// window.location.reload(true)
|
||||
},
|
||||
onSuccess: (res) => {
|
||||
if(res?.data?.resultCode != '0'){
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { useMutation, useQuery } from '@tanstack/react-query'
|
||||
|
||||
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
|
||||
import EventCalendar from "./EventCalendar";
|
||||
@@ -16,12 +16,42 @@ export default function Calendar(){
|
||||
// setDraggedEvent(event)
|
||||
// }
|
||||
|
||||
// const {data, isFetching, isError, error} = useQuery({
|
||||
// queryKey: queryKeys.calendar_events,
|
||||
// queryFn: () => getCalendarEvents()
|
||||
// })
|
||||
|
||||
// const calendarEvents = useMutation({
|
||||
// mutationFn: (reqData) => {
|
||||
// return getCalendarEvents(reqData)
|
||||
// },
|
||||
// onError: (error) => {
|
||||
// console.log(error)
|
||||
// },
|
||||
// onSuccess: (res) => {
|
||||
// if(res?.data?.resultCode != '0'){
|
||||
// throw({message: 'Something went wrong'})
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
|
||||
// useEffect(()=>{
|
||||
// let reqData = {
|
||||
// token: localStorage.getItem('token'), // USER TOKEN
|
||||
// uid: localStorage.getItem('uid') // USER UID
|
||||
// }
|
||||
// calendarEvents.mutate(reqData)
|
||||
// },[])
|
||||
let reqData = {
|
||||
token: localStorage.getItem('token'), // USER TOKEN
|
||||
uid: localStorage.getItem('uid') // USER UID
|
||||
}
|
||||
const {data, isFetching, isError, error} = useQuery({
|
||||
queryKey: queryKeys.calendar_events,
|
||||
queryFn: () => getCalendarEvents()
|
||||
queryFn: () => getCalendarEvents(reqData)
|
||||
})
|
||||
|
||||
const receievedEvents = data?.data?.bar_data
|
||||
const receievedEvents = data?.data
|
||||
const category = receievedEvents?.category //EVENT CATEGORIES FROM API
|
||||
const eventList = receievedEvents?.list //EVENT LIST FROM API
|
||||
|
||||
@@ -57,7 +87,7 @@ export default function Calendar(){
|
||||
<div className="card card-statistics">
|
||||
<div className="card-header">
|
||||
<div className="card-heading">
|
||||
<h4 className="card-title">Event Calendar</h4>
|
||||
<h4 className="card-title">Events</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div className="card-body">
|
||||
@@ -70,7 +100,7 @@ export default function Calendar(){
|
||||
</>
|
||||
: isError ?
|
||||
<div className="col-12">
|
||||
<p className='text-danger'>{error.message}</p>
|
||||
<p className='text-danger'>{error?.message}</p>
|
||||
</div>
|
||||
:
|
||||
<>
|
||||
@@ -83,7 +113,7 @@ export default function Calendar(){
|
||||
Drag and drop your event or click in the calendar.
|
||||
</p> */}
|
||||
|
||||
{category.map((item, index) => {
|
||||
{category?.map((item, index) => {
|
||||
let color = item?.cid == '1' ? 'fc-event-success' : item?.cid == '2' ? 'fc-event-danger' : item?.cid == '3' ? 'fc-event-warning' : 'fc-event-primary'
|
||||
let circleColor = item?.cid == '1' ? 'text-success' : item?.cid == '2' ? 'text-danger' : item?.cid == '3' ? 'text-warning' : 'text-primary'
|
||||
return (
|
||||
|
||||
@@ -81,7 +81,7 @@ export default function EventCalendar({removeAfterDrop, eventList, activeCategor
|
||||
useEffect(()=>{
|
||||
// let newEventList = eventList?.map(item => ({...item, start: new Date(item?.start)}))
|
||||
let newEventList = eventList?.filter(item => (Number(item.category) == Number(activeCategory)))?.map(item => ({...item, start: new Date(item?.start)}))
|
||||
console.log('newEventList', newEventList)
|
||||
// console.log('newEventList', newEventList)
|
||||
setCurrentEvents(newEventList)
|
||||
},[activeCategory])
|
||||
|
||||
|
||||
@@ -2,27 +2,40 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
|
||||
import getImage from "../../utils/getImage";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||
import { contactData } from "../../services/services";
|
||||
import queryKeys from "../../services/queryKeys";
|
||||
import getCustomTime from "../../utils/getCustomTime";
|
||||
|
||||
export default function Contacts(){
|
||||
|
||||
const {data:contacts, isFetching, isError, error} = useQuery({
|
||||
queryKey: queryKeys.contacts,
|
||||
queryFn: () => contactData()
|
||||
})
|
||||
|
||||
const contactsData = contacts?.data?.calendar_data?.contacts // LIST OF CONTACTS
|
||||
const contactsCategory = contacts?.data?.calendar_data?.category // LIST OF CATEGORY
|
||||
// const {data:contacts, isFetching, isError, error} = useQuery({
|
||||
// queryKey: queryKeys.contacts,
|
||||
// queryFn: () => contactData()
|
||||
// })
|
||||
|
||||
const [activeCategoryUID, setActiveCategoryUID] = useState('0') // HOLDS VALUE OF THE ACTIVE CATEGORY
|
||||
|
||||
const [activeContactUID, setActiveContactUID] = useState(null)
|
||||
const [activeDetail, setActiveDetail] = useState(null)
|
||||
const [activeContactUID, setActiveContactUID] = useState('')
|
||||
const [activeDetail, setActiveDetail] = useState([])
|
||||
|
||||
const [filteredContactData, setFiltererdContactData] = useState(null)
|
||||
const [filteredContactData, setFiltererdContactData] = useState([])
|
||||
|
||||
|
||||
const getContactData = useMutation({
|
||||
mutationFn: (reqData) => {
|
||||
return contactData(reqData)
|
||||
},
|
||||
onError: (error) => {
|
||||
console.log(error)
|
||||
},
|
||||
onSuccess: (res) => {
|
||||
if(res?.data?.resultCode != '0'){
|
||||
throw({message: 'Something went wrong'})
|
||||
}
|
||||
setFiltererdContactData(res?.data?.contacts)
|
||||
}
|
||||
})
|
||||
|
||||
const changeActiveUID = (uid) => {
|
||||
setActiveContactUID(uid)
|
||||
@@ -42,10 +55,21 @@ export default function Contacts(){
|
||||
changeActiveUID(filteredConData[0]?.uid)
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
let reqData = {
|
||||
token: localStorage.getItem('token'), // USER TOKEN
|
||||
uid: localStorage.getItem('uid') // USER UID
|
||||
}
|
||||
getContactData.mutate(reqData)
|
||||
},[])
|
||||
|
||||
const contactsData = getContactData?.data?.data?.contacts // LIST OF CONTACTS
|
||||
const contactsCategory = getContactData?.data?.data?.category // LIST OF CATEGORY
|
||||
|
||||
return(
|
||||
<>
|
||||
<BreadcrumbComBS title='Contacts' paths={['Dashboard', 'Contacts']} />
|
||||
{isFetching ?
|
||||
{getContactData?.isPending ?
|
||||
<>
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
@@ -53,10 +77,10 @@ export default function Contacts(){
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
: isError ?
|
||||
: getContactData?.error ?
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<p className='text-danger'>{error.message}</p>
|
||||
<p className='text-danger'>{getContactData?.error?.message}</p>
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
@@ -121,14 +145,14 @@ export default function Contacts(){
|
||||
</div>
|
||||
</li>
|
||||
{contactsCategory && contactsCategory.map(item => (
|
||||
<li key={item?.product_id} className="py-2" onClick={()=>changeActiveCategoryUID(item?.product_id)} style={{cursor: 'pointer'}}>
|
||||
<li key={item?.cid} className="py-2" onClick={()=>changeActiveCategoryUID(`A00000${item?.cid}`)} style={{cursor: 'pointer'}}>
|
||||
<div>
|
||||
<span className="nav align-items-center">
|
||||
<span>
|
||||
<i className={`fa fa-circle-o pr-4 ${activeCategoryUID == item?.product_id ? 'text-primary' : 'text-warning'}`}></i>
|
||||
<i className={`fa fa-circle-o pr-4 ${activeCategoryUID == `A00000${item?.cid}` ? 'text-primary' : 'text-warning'}`}></i>
|
||||
</span>
|
||||
<span>
|
||||
<span>{item?.title}</span>
|
||||
<span>{item?.description}</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
@@ -177,10 +201,10 @@ export default function Contacts(){
|
||||
</div>
|
||||
</div>
|
||||
<div className="mail-msg scrollbar scroll_dark">
|
||||
{contactsData && (filteredContactData || contactsData).map((contact, index)=> {
|
||||
const isActive = (contact.uid == activeContactUID) || (!activeContactUID && index == 0)
|
||||
{contactsData && filteredContactData?.map((contact, index)=> {
|
||||
const isActive = (contact?.uid == activeContactUID) || (!activeContactUID && index == 0)
|
||||
return (
|
||||
<div key={contact.uid} onClick={()=>changeActiveUID(contact.uid)} className={`mail-msg-item ${isActive && 'bg-light'}`}>
|
||||
<div key={contact?.uid} onClick={()=>changeActiveUID(contact?.uid)} className={`mail-msg-item ${isActive && 'bg-light'}`}>
|
||||
<a href="#">
|
||||
<div className="media align-items-center">
|
||||
<div className="mr-3">
|
||||
@@ -190,15 +214,15 @@ export default function Contacts(){
|
||||
</div>
|
||||
<div className="w-100">
|
||||
<div className="mail-msg-item-titel justify-content-between">
|
||||
<p>{contact.sender}</p>
|
||||
<p>{contact?.sender}</p>
|
||||
{/* <p className="d-none d-xl-block">06:59 <span> PM </span></p> */}
|
||||
<p className="d-none d-xl-block"><span>{new Date(contact.added).toDateString()}</span></p>
|
||||
<p className="d-none d-xl-block"><span>{new Date(contact?.added).toDateString()}</span></p>
|
||||
</div>
|
||||
<h5 className="mb-0 my-2">{contact.title}</h5>
|
||||
<p>{contact.message.length < 100 ? contact.message : contact.message.substring(0,101) + ' ...' }</p>
|
||||
<h5 className="mb-0 my-2">{contact?.title}</h5>
|
||||
<p>{contact?.message?.length < 100 ? contact?.message : contact?.message.substring(0,101) + ' ...' }</p>
|
||||
<p className="d-xl-none">
|
||||
<span>
|
||||
{new Date(contact.added).toDateString()}
|
||||
{new Date(contact?.added).toDateString()}
|
||||
{/* {getCustomTime(contact.added)} */}
|
||||
</span>
|
||||
</p>
|
||||
@@ -219,13 +243,13 @@ export default function Contacts(){
|
||||
<img src={getImage("avtar/03.jpg")} className="img-fluid" alt="user" />
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="mb-0">{activeContactUID ? activeDetail[0].sender : contactsData[0].sender}</h4>
|
||||
<p>{activeContactUID ? new Date(activeDetail[0].added).toDateString() : new Date(contactsData[0].added).toDateString()}</p>
|
||||
<h4 className="mb-0">{activeContactUID ? activeDetail[0]?.sender : filteredContactData[0]?.sender}</h4>
|
||||
<p>{activeContactUID ? new Date(activeDetail[0]?.added).toDateString() : new Date(filteredContactData[0]?.added).toDateString()}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 d-flex justify-content-between">
|
||||
<div>
|
||||
<h3>{activeContactUID ? activeDetail[0].title : contactsData[0].title}</h3>
|
||||
<h3>{activeContactUID ? activeDetail[0]?.title : filteredContactData[0]?.title}</h3>
|
||||
</div>
|
||||
<div className="d-flex">
|
||||
{/*<a href="javascript:void(0)"><i className="fa fa-reply font-22 pr-3"></i></a>*/}
|
||||
@@ -233,7 +257,7 @@ export default function Contacts(){
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p>{activeContactUID ? activeDetail[0].message : contactsData[0].message}</p>
|
||||
<p>{activeContactUID ? activeDetail[0]?.message : filteredContactData[0]?.message}</p>
|
||||
{/* <p className="my-4">hey adminjon...</p>
|
||||
<p className="mb-2">I truly believe Augustine’s words are true and if you look at history you know it is true. There are many people in the world with amazing talents who realize only a small percentage of their potential. We all know people who live this truth.</p>
|
||||
<p>We also know those epic stories, those modern-day legends surrounding the early failures of such supremely successful folks as Michael Jordan and Bill Gates. We can look a bit further back in time to Albert Einstein or even further back to Abraham Lincoln. What made each of these people so successful? Motivation.</p>
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import React from "react";
|
||||
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
|
||||
|
||||
|
||||
export default function HelpCom(){
|
||||
|
||||
return(
|
||||
<>
|
||||
<BreadcrumbComBS title='Frequesntly Asked Questions' paths={['Dashboard', 'Help']} />
|
||||
{/*<div className="row">*/}
|
||||
{/* <div className="vh-100 col-12 flex align-items-center">Coming Soon</div>*/}
|
||||
{/*</div>*/}
|
||||
|
||||
|
||||
<div className="row account-contant">
|
||||
<div className="col-12">
|
||||
<div className="card card-statistics">
|
||||
<div className="card-body p-lg-15" style={{backgroundColor:"#f9f9fb"}}>
|
||||
|
||||
<p className="mb-4">First, a disclaimer – the entire process of writing a blog post often takes more than a couple of hours, even if you can type eighty words as per minute and your writing skills are sharp.</p>
|
||||
<div className="row">
|
||||
<div className="accordion" id="accordionExample">
|
||||
{['a', 'b', 'c', 'd'].map((item, index)=>{
|
||||
return (
|
||||
<div className="accordion-item">
|
||||
<h2 className="accordion-header">
|
||||
<button className="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target={`#${item}`} aria-expanded="true" aria-controls="collapseOne">
|
||||
{`Accordion Item ${item} 1`}
|
||||
</button>
|
||||
</h2>
|
||||
<div id={item} className={`accordion-collapse collapse ${index == 0 && 'show'}`} data-bs-parent="#accordionExample">
|
||||
<div className="accordion-body">
|
||||
<strong>This is the first item’s accordion body.</strong> It is shown by default, until the collapse plugin adds the appropriate classes that we use to style each element. These classes control the overall appearance, as well as the showing and hiding via CSS transitions. You can modify any of this with custom CSS or overriding our default variables. It’s also worth noting that just about any HTML can go within the accordion-body, though the transition does limit overflow.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1,29 +1,22 @@
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import React from 'react'
|
||||
import { productData } from '../../services/services'
|
||||
import queryKeys from '../../services/queryKeys'
|
||||
import { productsData } from '../../services/services'
|
||||
import productPath from "../../utils/productpath";
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import queryKeys from '../../services/queryKeys'
|
||||
|
||||
|
||||
export default function Products() {
|
||||
|
||||
let reqData = {
|
||||
token: localStorage.getItem('token'), // USER TOKEN
|
||||
uid: localStorage.getItem('uid') // USER UID
|
||||
}
|
||||
const {data, isFetching, isError, error} = useQuery({
|
||||
queryKey: queryKeys.product,
|
||||
queryFn: () => productData()
|
||||
queryKey: queryKeys.products,
|
||||
queryFn: () => productsData(reqData)
|
||||
})
|
||||
/*
|
||||
{
|
||||
"banner": "p1.jpg",
|
||||
"description": "Your personal professional web presence",
|
||||
"id": 1,
|
||||
"name": "Personal Website",
|
||||
"product_id": "A000001",
|
||||
"product_uid": "e92282b4-3ee1-4026-92ac-12cfd214b43a",
|
||||
"status": 5,
|
||||
"status_text": "Activate Now"
|
||||
},
|
||||
*/
|
||||
//const products = data?.data?.products_list?.products
|
||||
const products = data?.data?.products_list
|
||||
const products = data?.data?.products_data // PRODUCTS DATA
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -43,17 +36,17 @@ export default function Products() {
|
||||
: isError ?
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<p className='text-danger'>{error.message}</p>
|
||||
<p className='text-danger'>{error?.message}</p>
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
<div className="row m-b-20">
|
||||
{products && products.map((product, index) => (
|
||||
<div key={product.uid+index} className="col-xxs-6 col-xl-4 col-xxl-6 mb-2 mb-xxl-0 ">
|
||||
<div key={product.uid+index} className={`col-xxs-6 col-xl-4 col-xxl-6 mb-2 mb-xxl-0`}>
|
||||
<Link to={productPath(product?.product_id)} >
|
||||
<div className="d-flex align-items-center extraProductCard">
|
||||
<div className={`d-flex align-items-center extraProductCard ${product?.icon_style}`} >
|
||||
<div className="icon-container img-icon m-r-20 bg-light-gray rounded">
|
||||
<i className="fa fa-cart-plus text-primary"></i>
|
||||
<i className={`fa ${product?.product_icon} text-primary`}></i>
|
||||
</div>
|
||||
<div className="report-details">
|
||||
<p>{product?.status_text}</p>
|
||||
|
||||
@@ -2,15 +2,22 @@ import React from 'react'
|
||||
import { productsURL } from '../../services/services'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import queryKeys from '../../services/queryKeys'
|
||||
import getImage from '../../utils/getImage'
|
||||
|
||||
export default function ProductsURL() {
|
||||
|
||||
const {data:data, isFetching, isError, error} = useQuery({
|
||||
let reqData = {
|
||||
token: localStorage.getItem('token'), // USER TOKEN
|
||||
uid: localStorage.getItem('uid') // USER UID
|
||||
}
|
||||
|
||||
const {data, isFetching, isError, error} = useQuery({
|
||||
queryKey: queryKeys.product_url,
|
||||
queryFn: () => productsURL()
|
||||
queryFn: () => productsURL(reqData)
|
||||
})
|
||||
|
||||
const urlData = data?.data?.url_data?.url
|
||||
const urlData = data?.data?.products_data
|
||||
// console.log('data', urlData)
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -53,29 +60,28 @@ export default function ProductsURL() {
|
||||
</thead>
|
||||
<tbody>
|
||||
{urlData && urlData.map((item, index) => {
|
||||
let statusColor = item?.status === 'Preparing' ? 'badge-success-inverse' : item?.status === 'Active' ? 'badge-success-inverse' : item?.status == 'Refreshing' ? 'badge-danger-inverse' : 'badge-info-inverse'
|
||||
let statusColor = item?.status === '1' ? 'badge-success-inverse' : item?.status === '6' ? 'badge-success-inverse' : item?.status == '7' ? 'badge-danger-inverse' : 'badge-info-inverse'
|
||||
let statusText = item?.status === '1' ? 'Preparing' : item?.status === '6' ? 'Provisioning' : item?.status == '7' ? 'Ready' : 'Started'
|
||||
let productUrl = '/product/'+ item?.product_id
|
||||
let externalUrl= item?.url_protocol +"://"+ item?.internal_url;
|
||||
return (
|
||||
<tr key={index}>
|
||||
<td>{Number(item?.no) + Number(index)}</td>
|
||||
<td>{item?.description} - <a href={productUrl} target='_blank'>{item?.url}</a></td>
|
||||
<td>{Number(item?.id).toString().padStart(6,'0')}</td>
|
||||
<td>
|
||||
<a className="mr-3" href={externalUrl} target='_blank'><b>{externalUrl}</b></a> - {item?.description}
|
||||
</td>
|
||||
|
||||
<td><span className={`badge ${statusColor}`}>{item?.status}</span></td>
|
||||
<td><a className="mr-3" href=""><i className="fe fe-edit"></i></a></td>
|
||||
<td><span className={`badge ${statusColor}`}>{statusText}</span></td>
|
||||
{/* <td><a className="mr-3" href={productUrl}><i className="fe fe-edit"></i></a></td> */}
|
||||
<td>
|
||||
<a className="mr-3" href={productUrl}>
|
||||
<img src={getImage('arrow-next.png')} alt='next' />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Name</th>
|
||||
<th>Price</th>
|
||||
<th>In stock</th>
|
||||
<th>Status</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,7 @@ export default function RecentActions() {
|
||||
queryFn: () => recentActions()
|
||||
})
|
||||
|
||||
const actionData = dataAction?.data?.action_data
|
||||
const actionData = dataAction?.data?.recent_actions
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -43,7 +43,7 @@ export default function RecentActions() {
|
||||
<div className="d-xxs-flex align-items-center">
|
||||
<div className="total-sales">
|
||||
<p>Last Update</p>
|
||||
<h3>{dataAction?.data?.action_data?.last_update}</h3>
|
||||
<h3>{dataAction?.data?.last_update}</h3>
|
||||
</div>
|
||||
<div className="mb-3 mb-sm-0 ml-auto">
|
||||
{/*<button className="btn btn-primary btn-xs">View All Invoices</button>*/}
|
||||
@@ -62,19 +62,19 @@ export default function RecentActions() {
|
||||
<div className="row no-gutters">
|
||||
<div className="col-6 col-xxs-3 ">
|
||||
<p>Initial</p>
|
||||
<h4>{actionData?.initial}</h4>
|
||||
<h4>{dataAction?.data?.initial}</h4>
|
||||
</div>
|
||||
<div className="col-6 col-xxs-3 ">
|
||||
<p>Processing</p>
|
||||
<h4>{actionData?.processing}</h4>
|
||||
<h4>{dataAction?.data?.processing}</h4>
|
||||
</div>
|
||||
<div className="col-6 col-xxs-3 ">
|
||||
<p>Verifying</p>
|
||||
<h4>{actionData?.verifying}</h4>
|
||||
<h4>{dataAction?.data?.verifying}</h4>
|
||||
</div>
|
||||
<div className="col-6 col-xxs-3 ">
|
||||
<p>Completed</p>
|
||||
<h4>{actionData?.completed}</h4>
|
||||
<h4>{dataAction?.data?.completed}</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div className="table-responsive m-t-20">
|
||||
@@ -89,16 +89,16 @@ export default function RecentActions() {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="text-muted">
|
||||
{actionData && actionData?.actions.map((action, index) => {
|
||||
{actionData && actionData?.map((action, index) => {
|
||||
let bgColor = action?.status == '5' ? 'badge-success-inverse' : action?.status == '3' ? 'badge-info-inverse' : action?.status == '0' ? 'badge-warning-inverse' : 'badge-primary-inverse'
|
||||
let text = action?.status == '5' ? 'completed' : action?.status == '3' ? 'verifying' : action?.status == '0' ? 'processing' : 'processing'
|
||||
return (
|
||||
<tr key={index}>
|
||||
<td>{action?.no}</td>
|
||||
<td>{action?.description}</td>
|
||||
<td>{new Date(action?.date).toDateString()}</td>
|
||||
<td>{action?.id}</td>
|
||||
<td>{action?.action_label}</td>
|
||||
<td>{new Date(action?.added).toDateString()}</td>
|
||||
<td>
|
||||
<label className={`badge mb-0 ${bgColor}`}>{text}</label>
|
||||
<label className={`badge mb-0 ${bgColor}`}>{action?.status_description}</label>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
|
||||
@@ -1,37 +1,44 @@
|
||||
import React, {useEffect} from 'react'
|
||||
import { useMutation } from '@tanstack/react-query'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { topBar } from '../../services/services'
|
||||
import queryKeys from '../../services/queryKeys'
|
||||
|
||||
export default function TopBar() {
|
||||
|
||||
const topBarData = useMutation({
|
||||
mutationFn: (reqData) => {
|
||||
return topBar(reqData)
|
||||
},
|
||||
onError: (error) => {
|
||||
console.log(error)
|
||||
location.reload();
|
||||
},
|
||||
onSuccess: (res) => {
|
||||
if(res?.data?.resultCode != '0'){
|
||||
throw({message: 'Something went wrong'})
|
||||
}
|
||||
}
|
||||
})
|
||||
// const topBarData = useMutation({
|
||||
// mutationFn: (reqData) => {
|
||||
// return topBar(reqData)
|
||||
// },
|
||||
// onError: (error) => {
|
||||
// console.log(error)
|
||||
// },
|
||||
// onSuccess: (res) => {
|
||||
// if(res?.data?.resultCode != '0'){
|
||||
// throw({message: 'Something went wrong'})
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
|
||||
useEffect(()=>{
|
||||
let reqData = {
|
||||
// useEffect(()=>{
|
||||
// let reqData = {
|
||||
// token: localStorage.getItem('token'), // USER TOKEN
|
||||
// uid: localStorage.getItem('uid') // USER UID
|
||||
// }
|
||||
// topBarData.mutate(reqData)
|
||||
// },[])
|
||||
|
||||
let reqData = {
|
||||
token: localStorage.getItem('token'), // USER TOKEN
|
||||
uid: localStorage.getItem('uid') // USER UID
|
||||
}
|
||||
topBarData.mutate(reqData)
|
||||
},[])
|
||||
|
||||
const data = topBarData?.data?.data?.top_bar // top bar data
|
||||
}
|
||||
const {data:topBarData, isFetching, isError, error} = useQuery({
|
||||
queryKey: queryKeys.topBar,
|
||||
queryFn: () => topBar(reqData)
|
||||
})
|
||||
const data = topBarData?.data?.top_bar // top bar data
|
||||
|
||||
return (
|
||||
<>
|
||||
{topBarData.isPending ?
|
||||
{isFetching ?
|
||||
<>
|
||||
<div className="col-12">
|
||||
<div className="card p-4">
|
||||
@@ -39,10 +46,10 @@ export default function TopBar() {
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
: topBarData.error ?
|
||||
: isError?
|
||||
<div className="col-12">
|
||||
<div className="card p-4">
|
||||
<p className='text-danger'>{topBarData.error.message}</p>
|
||||
<p className='text-danger'>{error.message}</p>
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
@@ -51,7 +58,7 @@ export default function TopBar() {
|
||||
let textColor = item?.description == 'Contacts' ? 'text-danger' : item?.description == 'Site Traffic' ? 'text-primary' : item?.description == 'Appointments' ? 'text-orange' : 'text-success'
|
||||
return (
|
||||
<div key={item.id + index} className="col-sm-6 col-xxl-3">
|
||||
<div className="card card-statistics ecommerce-contant overflow-h">
|
||||
<div className={`card card-statistics ecommerce-contant overflow-h ${item?.extra_style} `}>
|
||||
<div className="card-body p-0">
|
||||
<div className="d-flex m-b-0 ecommerce-contant-text h-100">
|
||||
<div className="w-100">
|
||||
@@ -61,9 +68,7 @@ export default function TopBar() {
|
||||
<small className="d-block">{item?.data_span}</small>
|
||||
</div>
|
||||
<div className="col text-right">
|
||||
<h5 className="text-muted mb-0">{item?.description}</h5>
|
||||
<strong className={`${textColor} m-t-5`}><i
|
||||
className="zmdi zmdi-long-arrow-up font-weight-bold"></i> N/A</strong>
|
||||
<h5 className="text-muted mb-0"><a href={item?.link}>{item?.description}</a></h5>
|
||||
</div>
|
||||
</div>
|
||||
<div className="apexchart-wrapper">
|
||||
|
||||
@@ -1,16 +1,22 @@
|
||||
import React from 'react'
|
||||
import { Outlet, useLocation } from 'react-router-dom';
|
||||
import UserMenu from "./layoutcom/UserMenu";
|
||||
import UserHeader from "./layoutcom/UserHeader";
|
||||
import UserFooter from "./layoutcom/UserFooter";
|
||||
import { Outlet } from 'react-router-dom';
|
||||
import siteLinks from '../../links/siteLinks';
|
||||
|
||||
|
||||
export default function Layout() {
|
||||
|
||||
const {pathname} = useLocation()
|
||||
// const isProfileComplete = pathname == siteLinks.profile_complete
|
||||
|
||||
return (
|
||||
<div className="app">
|
||||
<div className="app-wrap">
|
||||
<UserHeader />
|
||||
<div className="app-container">
|
||||
|
||||
<aside className="app-navbar">
|
||||
<UserMenu />
|
||||
</aside>
|
||||
|
||||
@@ -2,11 +2,13 @@ import React from "react";
|
||||
|
||||
export default function UserFooter(){
|
||||
|
||||
const year = new Date().getFullYear()
|
||||
|
||||
return <>
|
||||
<footer className="footer">
|
||||
<footer className={`footer`}>
|
||||
<div className="row">
|
||||
<div className="col-12 col-sm-6 text-center text-sm-left">
|
||||
<p>© Copyright 2024. All rights reserved.</p>
|
||||
<p>© Copyright {year}. All rights reserved.</p>
|
||||
</div>
|
||||
<div className="col col-sm-6 ml-sm-auto text-center text-sm-right">
|
||||
<p>A division of <i className="fa fa-key text-danger mx-1"></i> autoMedSys A.I.</p>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from "react";
|
||||
import React, { useRef } from "react";
|
||||
import getImage from "../../../utils/getImage";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { useSelector } from "react-redux";
|
||||
@@ -9,6 +9,8 @@ export default function UserHeader(){
|
||||
|
||||
const { userDetails } = useSelector((state) => state?.userDetails); // CHECKS IF USER Details are avaliable, to determine if user is active
|
||||
|
||||
const nav_menu = useRef(null)
|
||||
|
||||
const toggleSidebar = (e) => {
|
||||
e.preventDefault()
|
||||
document.body.classList.toggle('sidebar-toggled')
|
||||
@@ -32,14 +34,19 @@ export default function UserHeader(){
|
||||
window.location.reload()
|
||||
}
|
||||
|
||||
const toggleMenu = (e) => {
|
||||
// e.preventDefault()
|
||||
nav_menu.current.classList.toggle('show')
|
||||
}
|
||||
|
||||
return (
|
||||
<header className="app-header top-bar">
|
||||
<nav className="navbar navbar-expand-md">
|
||||
<div className="navbar-header d-flex align-items-center">
|
||||
<a href="#" onClick={toggleSidebar} className="mobile-toggle"><i className="ti ti-align-right"></i></a>
|
||||
<a className="navbar-brand" href="/dash">
|
||||
<img src={getImage('logo-light.png')} className="img-fluid logo-desktop" alt="logo"/>
|
||||
<img src={getImage('logo-icon.png')} className="img-fluid logo-mobile" alt="logo"/>
|
||||
<img src={getImage('logo-pink.png')} className="img-fluid logo-desktop" alt="logo"/>
|
||||
<img src={getImage('logo-pink.png')} className="img-fluid logo-mobile" alt="logo"/>
|
||||
</a>
|
||||
</div>
|
||||
<button onClick={removeSidebar} className="navbar-toggler" type="button" data-bs-toggle="collapse"
|
||||
@@ -66,16 +73,16 @@ export default function UserHeader(){
|
||||
|
||||
<ul className="navbar-nav nav-right ml-auto">
|
||||
<li className="nav-item user-profile">
|
||||
<a href="#" className="nav-link dropdown-toggle" role="button" data-bs-toggle="dropdown">
|
||||
<img src={getImage('avtar/02.jpg')} alt="avtar-img" />
|
||||
<a onClick={toggleMenu} className="nav-link dropdown-toggle" role="button" data-bs-toggle="dropdow">
|
||||
<img src={getImage('profile-pic-circle.png')} alt="avtar-img" />
|
||||
<span className="bg-success user-status"></span>
|
||||
</a>
|
||||
<div className="dropdown-menu animated fadeIn">
|
||||
<div ref={nav_menu} onClick={toggleMenu} className="dropdown-menu animated fadeIn">
|
||||
<div className="bg-gradient px-4 py-3">
|
||||
<div className="d-flex align-items-center justify-content-between">
|
||||
<div className="mr-1">
|
||||
<h5 className="text-white mb-0">{userDetails?.firstname} {userDetails?.lastname}</h5>
|
||||
<small className="text-white">{userDetails.email}</small>
|
||||
{/* <h4 className="text-white mb-0 font-600">{userDetails?.username}</h4> */}
|
||||
<p className="text-white font-600">{userDetails.username}</p>
|
||||
</div>
|
||||
<a href="#" onClick={logout} className="text-white font-20 tooltip-wrapper" data-toggle="tooltip"
|
||||
data-placement="top" title="" data-original-title="Logout"> <i
|
||||
@@ -83,8 +90,8 @@ export default function UserHeader(){
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-4">
|
||||
<Link className="dropdown-item d-flex nav-link" to={siteLinks.user}>
|
||||
<i className="fa fa-user pr-2 text-success"></i> Users</Link>
|
||||
<Link className="dropdown-item d-flex nav-link" to={siteLinks.subscription}>
|
||||
<i className="fa fa-user pr-2 text-success"></i> Subscription</Link>
|
||||
<Link className="dropdown-item d-flex nav-link" to={siteLinks.contacts}>
|
||||
<i className="fa fa-envelope pr-2 text-primary"></i> Contacts
|
||||
<span className="badge badge-primary ml-auto">6</span>
|
||||
@@ -92,8 +99,10 @@ export default function UserHeader(){
|
||||
<Link className="dropdown-item d-flex nav-link" to={siteLinks.settings}>
|
||||
<i className=" ti ti-settings pr-2 text-info"></i> Settings
|
||||
</Link>
|
||||
<a className="dropdown-item d-flex nav-link" href="#">
|
||||
<i className="fa fa-compass pr-2 text-warning"></i> Need help?</a>
|
||||
<Link className="dropdown-item d-flex nav-link" to={siteLinks.help}>
|
||||
<i className="fa fa-compass pr-2 text-warning"></i>
|
||||
Need help?
|
||||
</Link>
|
||||
|
||||
{/*<div className="row mt-2">*/}
|
||||
{/* <div className="col">*/}
|
||||
|
||||
@@ -20,7 +20,7 @@ export default function UserMenu() {
|
||||
<li className="nav-static-title">Panel</li>
|
||||
<li className={`${pathname == siteLinks.dash ? 'active' : ''}`}>
|
||||
<Link className="has-arrow" to='#' data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
|
||||
<i className="nav-icon ti ti-rocket"></i>
|
||||
<i className="nav-icon ti ti-home"></i>
|
||||
<div className='d-flex gap-2 justify-content-between align-items-center'>
|
||||
<span className="nav-title">Dashboard</span>
|
||||
<IoIosArrowDown />
|
||||
@@ -48,7 +48,7 @@ export default function UserMenu() {
|
||||
</div>
|
||||
</Link>
|
||||
<ul id="collapseTwo" className="collapse" aria-labelledby="headingTwo" data-bs-parent="#sidebarNav">
|
||||
<li className={`${pathname == siteLinks.user ? 'active' : ''}`}><Link to={siteLinks.user}>Users</Link></li>
|
||||
<li className={`${pathname == siteLinks.subscription ? 'active' : ''}`}><Link to={siteLinks.subscription}>Subscription</Link></li>
|
||||
<li className={`${pathname == siteLinks.settings ? 'active' : ''}`}><Link to={siteLinks.settings}>Settings</Link></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
import React from 'react'
|
||||
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
|
||||
import getImage from "../../utils/getImage";
|
||||
|
||||
export default function Onboard() {
|
||||
|
||||
const pricingFields ={
|
||||
starter: { name: 'Starter', price: 5.99, active: true },
|
||||
basic: { name: 'Basic', price: 12.99, active: true },
|
||||
premium: { name: 'Premium', price: 20.00, active: true },
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<BreadcrumbComBS title='Subscription' paths={['Dashboard', 'Subscription']} />
|
||||
|
||||
|
||||
|
||||
<div className="row">
|
||||
<div className="col-xl-3 col-md-6">
|
||||
<div className="card card-statistics text-center py-3">
|
||||
<div className="card-body pricing-content">
|
||||
<div className="pricing-content-card">
|
||||
<h5>Current Subscription(s)</h5>
|
||||
<h2 className="text-primary pt-3">Basic</h2>
|
||||
{/*<p className="text-primary pb-3">/ Monthly</p>*/}
|
||||
{/*<ul className="py-2">*/}
|
||||
{/* <li>post jobs</li>*/}
|
||||
{/* <li>advanced instructors search</li>*/}
|
||||
{/* <li>invite candidates</li>*/}
|
||||
{/* <li>post events</li>*/}
|
||||
{/* <li>cancel any time</li>*/}
|
||||
{/*</ul>*/}
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<>
|
||||
{Object.entries(pricingFields)?.map(([key, value]) => (
|
||||
|
||||
<div key={key} className="col-xl-3 col-md-6">
|
||||
<div className="card card-statistics text-center py-3">
|
||||
<div className="card-body pricing-content">
|
||||
<div className="pricing-content-card">
|
||||
<h5>{value.name}</h5>
|
||||
<h2 className="text-primary pt-3">${value.price}</h2>
|
||||
<p className="text-primary pb-3">/ Monthly</p>
|
||||
<ul className="py-2">
|
||||
<li>post jobs</li>
|
||||
<li>advanced instructors search</li>
|
||||
<li>invite candidates</li>
|
||||
<li>post events</li>
|
||||
<li>cancel any time</li>
|
||||
</ul>
|
||||
<div className="pt-2"><a href="javascript:void(0)" className="btn btn-inverse-secondary btn-round btn-sm">go {value.name}</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
))}
|
||||
</>
|
||||
|
||||
</div>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1,140 +1,81 @@
|
||||
import React from "react";
|
||||
import React, { useMemo, useRef, useState } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import getImage from "../../utils/getImage";
|
||||
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
|
||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||
import { productRefreshSite, getSettingsData } from "../../services/services";
|
||||
import Settings from "./settingsTab/Settings";
|
||||
import queryKeys from "../../services/queryKeys";
|
||||
|
||||
|
||||
export default function ProductActive(){
|
||||
export default function ProductActive({productData}){
|
||||
|
||||
const iframe = useRef()
|
||||
|
||||
const refresh = useMutation({
|
||||
mutationFn: (fields) => {
|
||||
return productRefreshSite(fields)
|
||||
},
|
||||
onSuccess: (res) => {
|
||||
iframe.current.src += ''
|
||||
}
|
||||
})
|
||||
|
||||
const handleRefresh = () => {
|
||||
const reqData = {
|
||||
token: localStorage.getItem('token'), // USER TOKEN
|
||||
uid: localStorage.getItem('uid'), // USER UID
|
||||
product_id: productData.product_id,
|
||||
subscription_uid: productData.subscription_uid
|
||||
}
|
||||
refresh.mutate(reqData)
|
||||
}
|
||||
let externalUrl= 'https://'+productData?.internal_url
|
||||
|
||||
return(
|
||||
<>
|
||||
<BreadcrumbComBS title='Active Product Name' paths={['Dashboard', 'Product']} />
|
||||
{/*<BreadcrumbComBS title='Active Product Name' paths={['Dashboard', 'Product']} />*/}
|
||||
{/*<div className="row">*/}
|
||||
{/* <div className="vh-100 col-12 flex align-items-center">Coming Soon</div>*/}
|
||||
{/*</div>*/}
|
||||
|
||||
|
||||
<div className="row account-contant">
|
||||
<div className="col-12">
|
||||
<div className="card card-statistics">
|
||||
<div className="card-body p-0">
|
||||
<div className="row no-gutters">
|
||||
<div className="col-xl-3 pb-xl-0 pb-5 border-right">
|
||||
<div className="page-account-profil pt-5">
|
||||
<div className="profile-img text-center rounded-circle">
|
||||
<div className="pt-5">
|
||||
<div className="bg-img m-auto">
|
||||
<img src={getImage('widget/01.jpg')} className="img-fluid"
|
||||
alt="users-avatar" />
|
||||
</div>
|
||||
<div className="profile pt-4">
|
||||
<h4 className="mb-1">Product Short Name</h4>
|
||||
<p>last Update : 00:00:0000</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<>
|
||||
<div className="row tabs-contant">
|
||||
<div className="col-xxl-6">
|
||||
<div className="card card-statistics">
|
||||
<div className="card-header">
|
||||
<div className="card-heading d-flex justify-content-between">
|
||||
<h4 className="card-title">{externalUrl}</h4>
|
||||
<button type="button" onClick={()=>iframe.current.src += ''} className="btn">
|
||||
<img src={getImage('refresh.png')} style={{width: '30px', height: 'auto'}} alt='refresh page' />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-xl-5 col-md-6 col-12 border-t border-right">
|
||||
<div className="page-account-form">
|
||||
<div className="form-titel border-bottom p-3">
|
||||
<h5 className="mb-0 py-2">Edit Your Product Settings</h5>
|
||||
</div>
|
||||
<div className="p-4">
|
||||
<form>
|
||||
<div className="form-row">
|
||||
<div className="form-group col-md-12">
|
||||
<label htmlFor="name1">Full Name</label>
|
||||
<input type="text" className="form-control" id="name1"
|
||||
value="Alice Williams" />
|
||||
</div>
|
||||
<div className="form-group col-md-12">
|
||||
<label htmlFor="title1">Title</label>
|
||||
<input type="text" className="form-control" id="title1"
|
||||
value="Marketing expert" />
|
||||
</div>
|
||||
<div className="form-group col-md-12">
|
||||
<label htmlFor="phone1">Phone Number</label>
|
||||
<input type="text" className="form-control" id="phone1"
|
||||
value="(01) 97 563 15613" />
|
||||
</div>
|
||||
<div className="form-group col-md-12">
|
||||
<label htmlFor="email1">Email</label>
|
||||
<input type="email" className="form-control" id="email1"
|
||||
value="alicewilliams@gmail.com" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="add1">Address</label>
|
||||
<input type="text" className="form-control" id="add1"
|
||||
value="17504 Carlton Cuevas Rd, Gulfport, MS, 39503" />
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="add2">Address 2</label>
|
||||
<input type="text" className="form-control" id="add2"
|
||||
value="1234 North Avenue Luke Lane, South Bend, IN 360001" />
|
||||
</div>
|
||||
|
||||
|
||||
<button type="submit" className="btn btn-primary">Update Information
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<div className="card-body">
|
||||
<iframe ref={iframe} style={{borderWidth: '0px'}} src={externalUrl} width="100%" height="600" title={externalUrl}></iframe>
|
||||
</div>
|
||||
<div className="p-4 ml-auto">
|
||||
<button type="button" onClick={handleRefresh} className="btn btn-primary">{refresh.isPending ? 'Loading...' : 'Refresh Site'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-xxl-6">
|
||||
<div className="card card-statistics">
|
||||
<div className="card-header">
|
||||
<div className="card-heading">
|
||||
<h4 className="card-title"> Site Settings </h4>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-xl-4 col-md-6 border-t col-12">
|
||||
<div className="page-account-form">
|
||||
<div className="form-titel border-bottom p-3">
|
||||
<h5 className="mb-0 py-2">Your External Link</h5>
|
||||
</div>
|
||||
<div className="p-4">
|
||||
<form>
|
||||
<div className="form-group">
|
||||
<label htmlFor="fb">Facebook URL:</label>
|
||||
<input type="text" className="form-control" id="fb"
|
||||
value="https://www.facebook.com/" />
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="tr">Twitter URL:</label>
|
||||
<input type="text" className="form-control" id="tr"
|
||||
value="https://twitter.com/" />
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="br">Blogger URL:</label>
|
||||
<input type="text" className="form-control" id="br"
|
||||
value="https://www.blogger.com" />
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="go">Google+ URL:</label>
|
||||
<input type="text" className="form-control" id="go"
|
||||
value="https://plus.google.com/discover" />
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="li">LinkedIn URL:</label>
|
||||
<input type="text" className="form-control" id="li"
|
||||
value="https://in.linkedin.com/" />
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="we">Website URL:</label>
|
||||
<input type="text" className="form-control" id="we"
|
||||
value="https://yourwebsite.com" />
|
||||
</div>
|
||||
<button type="submit" className="btn btn-primary">Save & Update</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div className="card-body">
|
||||
<Settings productData={productData} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1,39 +1,34 @@
|
||||
import React, {useState} from "react";
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
|
||||
// import getImage from "../../utils/getImage";
|
||||
import ProductStart from "./ProductStart";
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import {MyProductData, productData} from "../../services/services";
|
||||
import queryKeys from "../../services/queryKeys";
|
||||
import {MyProductData} from "../../services/services";
|
||||
import ProductActive from "./ProductActive";
|
||||
import ProductProvision from "./ProductProvision";
|
||||
import {productConst} from "../../constants/products";
|
||||
import queryKeys from "../../services/queryKeys";
|
||||
|
||||
export default function ProductFactory(){
|
||||
const location = useLocation();
|
||||
const pathname = location.pathname;
|
||||
const [productStatus, setProductStatus] = useState(0);
|
||||
|
||||
//productConst.PRODUCT_ACTIVE
|
||||
|
||||
|
||||
// Split the pathname by '/' and get the last element
|
||||
const lastPart = pathname.split('/').pop();
|
||||
// console.log(lastPart)
|
||||
const productID = pathname.split('/').pop();
|
||||
|
||||
let reqData = {
|
||||
product_id : productID,
|
||||
token: localStorage.getItem('token'), // USER TOKEN
|
||||
uid: localStorage.getItem('uid') // USER UID
|
||||
}
|
||||
const {data, isFetching, isError, error} = useQuery({
|
||||
queryKey: queryKeys.product,
|
||||
queryFn: () => MyProductData(lastPart)
|
||||
queryKey: queryKeys.product_page,
|
||||
queryFn: () => MyProductData(reqData),
|
||||
staleTime: 0
|
||||
})
|
||||
|
||||
|
||||
|
||||
const myproduct_data = data?.data?.myproduct_data
|
||||
//setProductStatus(myproduct_data?.status)
|
||||
|
||||
const myproduct_data = data?.data?.myproduct?.myproudct // PRODUCT DETAILS
|
||||
const product_name = myproduct_data?.product_name;
|
||||
|
||||
const product_status = myproduct_data?.status;
|
||||
|
||||
return(
|
||||
@@ -51,24 +46,23 @@ export default function ProductFactory(){
|
||||
: isError ?
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<p className='text-danger'>{error.message}</p>
|
||||
<p className='text-danger'>{error?.message}</p>
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
<div>
|
||||
{(product_status <= productConst.PRODUCT_AVAILABLE)?
|
||||
<ProductStart productData={myproduct_data} />
|
||||
:<></> }
|
||||
:
|
||||
<div>
|
||||
{(product_status <= productConst.PRODUCT_AVAILABLE)?
|
||||
<ProductStart productData={myproduct_data} />
|
||||
:<></> }
|
||||
|
||||
{(product_status === productConst.PRODUCT_PROVISIONING)?
|
||||
<ProductProvision productData={myproduct_data} />
|
||||
:<></> }
|
||||
{(product_status === productConst.PRODUCT_PROVISIONING)?
|
||||
<ProductProvision productData={myproduct_data} />
|
||||
:<></> }
|
||||
|
||||
{(product_status === productConst.PRODUCT_ACTIVE)?
|
||||
<ProductActive productData={myproduct_data} />
|
||||
:<></> }
|
||||
|
||||
</div>
|
||||
{(product_status === productConst.PRODUCT_ACTIVE)?
|
||||
<ProductActive productData={myproduct_data} />
|
||||
:<></> }
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -25,7 +25,7 @@ export default function ProductProvision(props){
|
||||
queryFn: () => productProvision(reqData)
|
||||
})
|
||||
|
||||
const provisionData = provision?.data?.provision
|
||||
const provisionData = provision?.data
|
||||
|
||||
useEffect(()=>{
|
||||
joinRoom(productSubUID); // provision subscription room
|
||||
@@ -60,7 +60,7 @@ export default function ProductProvision(props){
|
||||
<div className="card-body">
|
||||
<div className="progress">
|
||||
<div className="progress-bar progress-bar-striped progress-bar-animated" role="progressbar"
|
||||
aria-valuenow={`${provisionData.percent_completed}%`} aria-valuemin="0" aria-valuemax="100" style={{width:`${provisionData.percent_completed}%`}} ></div>
|
||||
aria-valuenow={`${provisionData?.percent_completed}%`} aria-valuemin="0" aria-valuemax="100" style={{width:`${provisionData?.percent_completed}%`}} ></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -110,11 +110,9 @@ export default function ProductProvision(props){
|
||||
<div className="card card-statistics ">
|
||||
<h4 className="card-title" style={{padding:'10px'}}>Started creating your selection</h4>
|
||||
<img className="card-img-top" src={getImage('widget/working.jpg')} alt="Card image cap" />
|
||||
<div className="card-body">
|
||||
<p>
|
||||
{productDescription}
|
||||
</p>
|
||||
</div>
|
||||
{/* <div className="card-body">
|
||||
<div className="" dangerouslySetInnerHTML={{__html: productDescription}}/>
|
||||
</div> */}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useRef, useState } from "react";
|
||||
import {useNavigate} from 'react-router-dom'
|
||||
import getImage from "../../utils/getImage";
|
||||
// import { Modal } from "bootstrap";
|
||||
import { Modal } from "bootstrap";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { subscribe } from '../../services/services'
|
||||
import queryKeys from "../../services/queryKeys";
|
||||
@@ -8,24 +9,28 @@ import queryKeys from "../../services/queryKeys";
|
||||
export default function ProductStart(props){
|
||||
|
||||
const queryClient = useQueryClient()
|
||||
const navigate = useNavigate()
|
||||
|
||||
const [requestStatus, setRequestStatus] = useState({status:false, message: ''})
|
||||
|
||||
const product_uid = props?.productData?.product_uid;
|
||||
const product_id = props?.productData?.product_id;
|
||||
const productBanner = "product/"+props.productData?.banner;
|
||||
const productTitle = props.productData?.title;
|
||||
const productDescription = props.productData?.description;
|
||||
const promotion_text = props.productData?.promotion_text;
|
||||
const product_status = props.productData?.status;
|
||||
const modalRef = useRef()
|
||||
const productBanner = `product/${props.productData?.banner}`;
|
||||
const productTitle = props?.productData?.title;
|
||||
const productDescription = props?.productData?.description;
|
||||
const promotion_text = props?.productData?.promotion_text;
|
||||
const product_status = props?.productData?.status;
|
||||
const saleText = props?.productData?.sale_text;
|
||||
|
||||
const refetch = () => {
|
||||
queryClient.refetchQueries({
|
||||
queryKey: [...queryKeys.product],
|
||||
// type: 'active',
|
||||
// exact: true,
|
||||
})
|
||||
const modalRef = useRef(null)
|
||||
|
||||
const invalidate = () => {
|
||||
// queryClient.refetchQueries({
|
||||
// queryKey: [...queryKeys.product],
|
||||
// // type: 'active',
|
||||
// // exact: true,
|
||||
// })
|
||||
queryClient.invalidateQueries({ queryKey: [...queryKeys.product_url] })
|
||||
queryClient.invalidateQueries({ queryKey: [...queryKeys.product_page] })
|
||||
}
|
||||
|
||||
const mutation = useMutation({
|
||||
@@ -38,9 +43,12 @@ export default function ProductStart(props){
|
||||
},
|
||||
onSuccess: (res) => {
|
||||
setRequestStatus({status:true, message:'successful'})
|
||||
navigate(`/product/${product_id}`, {replace: true}) //'/product/'+ product_id
|
||||
dismissModal()
|
||||
console.log(res)
|
||||
},
|
||||
onSettled: () => {
|
||||
invalidate() // Invalidates selected queries
|
||||
setTimeout(()=>{
|
||||
setRequestStatus({status:false, message:''})
|
||||
},4000)
|
||||
@@ -51,6 +59,22 @@ export default function ProductStart(props){
|
||||
mutation.mutate({product_id: product_id})
|
||||
}
|
||||
|
||||
const dismissModal = () => {
|
||||
const body = document.querySelector('body')
|
||||
body.removeAttribute('style')
|
||||
// body.classList.toggle('modal-open')
|
||||
|
||||
const modalBackdrop = document.querySelectorAll('.modal-backdrop')
|
||||
modalBackdrop.forEach(item => {
|
||||
if (item) {
|
||||
item.remove();
|
||||
}
|
||||
})
|
||||
|
||||
const modal = Modal.getInstance(modalRef.current);
|
||||
modal && modal.hide();
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="row">
|
||||
@@ -59,7 +83,8 @@ export default function ProductStart(props){
|
||||
<img className="card-img-top" src={getImage(productBanner)} alt="Card image cap" />
|
||||
<div className="card-body">
|
||||
<h4 className="card-title">{productTitle}</h4>
|
||||
<p className="card-text">{productDescription}</p>
|
||||
<div className="card-text" dangerouslySetInnerHTML={{__html: productDescription}}/>
|
||||
{/* <p className="card-text">{productDescription}</p> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -110,21 +135,12 @@ export default function ProductStart(props){
|
||||
<div className="modal-content">
|
||||
<div className="modal-header">
|
||||
<h5 className="modal-title" id="verticalCenterTitle">{productTitle}</h5>
|
||||
<button onClick={refetch} type="button" className="close" data-bs-dismiss="modal" aria-label="Close">
|
||||
<button type="button" className="close" data-bs-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div className="modal-body">
|
||||
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis
|
||||
in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at
|
||||
eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus
|
||||
</p>
|
||||
<p>
|
||||
sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean lacinia
|
||||
bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque
|
||||
nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor
|
||||
fringilla. Cras mattis consectetur purus sit amet fermentum. Cras justo odio,
|
||||
</p>
|
||||
<div className="" dangerouslySetInnerHTML={{__html: saleText}}/>
|
||||
{/* {mutation.error &&
|
||||
<>
|
||||
<div className="col-12">
|
||||
@@ -146,7 +162,7 @@ export default function ProductStart(props){
|
||||
)}
|
||||
</div>
|
||||
<div className="modal-footer">
|
||||
<button onClick={refetch} type="button" className="btn btn-danger" data-bs-dismiss="modal">Close</button>
|
||||
<button type="button" className="btn btn-danger" data-bs-dismiss="modal">Close</button>
|
||||
<button type="button" className="btn btn-success" disabled={mutation.isSuccess} onClick={handleSubscribe}>{mutation.isPending ? 'loading...' : 'Start'}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,278 @@
|
||||
import React from "react";
|
||||
import getImage from "../../utils/getImage";
|
||||
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
|
||||
|
||||
|
||||
export default function ProductActive(){
|
||||
|
||||
return(
|
||||
<>
|
||||
{/*<BreadcrumbComBS title='Active Product Name' paths={['Dashboard', 'Product']} />*/}
|
||||
{/*<div className="row">*/}
|
||||
{/* <div className="vh-100 col-12 flex align-items-center">Coming Soon</div>*/}
|
||||
{/*</div>*/}
|
||||
|
||||
|
||||
<div className="row account-contant">
|
||||
<>
|
||||
|
||||
|
||||
<div className="row tabs-contant">
|
||||
<div className="col-xxl-6">
|
||||
<div className="card card-statistics">
|
||||
<div className="card-header">
|
||||
<div className="card-heading">
|
||||
<h4 className="card-title">https://25681.devprov.mermsemr.com/</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div className="card-body">
|
||||
<iframe style={{borderWidth: '0px;'}} src="https://25681.devprov.mermsemr.com/" width="100%" height="600" title="https://25681.devprov.mermsemr.com"></iframe>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-xxl-6">
|
||||
<div className="card card-statistics">
|
||||
<div className="card-header">
|
||||
<div className="card-heading">
|
||||
<h4 className="card-title"> Site Settings </h4>
|
||||
</div>
|
||||
</div>
|
||||
<div className="card-body">
|
||||
<div className="tab tab-vertical">
|
||||
<ul className="nav nav-tabs" role="tablist">
|
||||
<li className="nav-item">
|
||||
<a className="nav-link active show" id="home-09-tab" data-toggle="tab" href="#home-09" role="tab" aria-controls="home-09" aria-selected="true">General</a>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<a className="nav-link" id="home-09-tab" data-toggle="tab" href="#home-09" role="tab" aria-controls="home-09" aria-selected="true">Home Page</a>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<a className="nav-link" id="profile-09-tab" data-toggle="tab" href="#profile-09" role="tab" aria-controls="profile-09" aria-selected="false"> Footer </a>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<a className="nav-link" id="portfolio-09-tab" data-toggle="tab" href="#portfolio-09" role="tab" aria-controls="portfolio-09" aria-selected="false">About Page </a>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<a className="nav-link" id="contact-09-tab" data-toggle="tab" href="#contact-09" role="tab" aria-controls="contact-09" aria-selected="false"> Contact Page</a>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<a className="nav-link" id="home-09-tab" data-toggle="tab" href="#home-09" role="tab" aria-controls="home-09" aria-selected="true">Socials</a>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<a className="nav-link" id="home-09-tab" data-toggle="tab" href="#home-09" role="tab" aria-controls="home-09" aria-selected="true">Template</a>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<a className="nav-link" id="home-09-tab" data-toggle="tab" href="#home-09" role="tab" aria-controls="home-09" aria-selected="true"> Color Scheme</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div className="tab-content">
|
||||
<div className="tab-pane fade active show" id="home-09" role="tabpanel" aria-labelledby="home-09-tab">
|
||||
|
||||
<div className="page-account-form">
|
||||
<div className="p-4">
|
||||
<form>
|
||||
<div className="form-row">
|
||||
<div className="form-group col-md-12">
|
||||
<label htmlFor="name1">Full Name</label>
|
||||
<input type="text" className="form-control" id="name1"
|
||||
value="Alice Williams" />
|
||||
</div>
|
||||
<div className="form-group col-md-12">
|
||||
<label htmlFor="title1">Title</label>
|
||||
<input type="text" className="form-control" id="title1"
|
||||
value="Marketing expert" />
|
||||
</div>
|
||||
<div className="form-group col-md-12">
|
||||
<label htmlFor="phone1">Phone Number</label>
|
||||
<input type="text" className="form-control" id="phone1"
|
||||
value="(01) 97 563 15613" />
|
||||
</div>
|
||||
<div className="form-group col-md-12">
|
||||
<label htmlFor="email1">Email</label>
|
||||
<input type="email" className="form-control" id="email1"
|
||||
value="alicewilliams@gmail.com" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="add1">Address</label>
|
||||
<input type="text" className="form-control" id="add1"
|
||||
value="17504 Carlton Cuevas Rd, Gulfport, MS, 39503" />
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="add2">Address 2</label>
|
||||
<input type="text" className="form-control" id="add2"
|
||||
value="1234 North Avenue Luke Lane, South Bend, IN 360001" />
|
||||
</div>
|
||||
|
||||
|
||||
<button type="submit" className="btn btn-primary">Update Information
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div className="tab-pane fade" id="profile-09" role="tabpanel" aria-labelledby="profile-09-tab">
|
||||
<div className="page-account-form">
|
||||
|
||||
<div className="p-4">
|
||||
<form>
|
||||
<div className="form-row">
|
||||
<div className="form-group col-md-12">
|
||||
<label htmlFor="name1">Full Name</label>
|
||||
<input type="text" className="form-control" id="name1"
|
||||
value="Alice Williams" />
|
||||
</div>
|
||||
<div className="form-group col-md-12">
|
||||
<label htmlFor="title1">Title</label>
|
||||
<input type="text" className="form-control" id="title1"
|
||||
value="Marketing expert" />
|
||||
</div>
|
||||
<div className="form-group col-md-12">
|
||||
<label htmlFor="phone1">Phone Number</label>
|
||||
<input type="text" className="form-control" id="phone1"
|
||||
value="(01) 97 563 15613" />
|
||||
</div>
|
||||
<div className="form-group col-md-12">
|
||||
<label htmlFor="email1">Email</label>
|
||||
<input type="email" className="form-control" id="email1"
|
||||
value="alicewilliams@gmail.com" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="add1">Address</label>
|
||||
<input type="text" className="form-control" id="add1"
|
||||
value="17504 Carlton Cuevas Rd, Gulfport, MS, 39503" />
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="add2">Address 2</label>
|
||||
<input type="text" className="form-control" id="add2"
|
||||
value="1234 North Avenue Luke Lane, South Bend, IN 360001" />
|
||||
</div>
|
||||
|
||||
|
||||
<button type="submit" className="btn btn-primary">Update Information
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="tab-pane fade" id="portfolio-09" role="tabpanel" aria-labelledby="portfolio-09-tab">
|
||||
<p>
|
||||
<div className="page-account-form">
|
||||
<div className="form-titel border-bottom p-3">
|
||||
<h5 className="mb-0 py-2">Edit Your Product Settings</h5>
|
||||
</div>
|
||||
<div className="p-4">
|
||||
<form>
|
||||
<div className="form-row">
|
||||
<div className="form-group col-md-12">
|
||||
<label htmlFor="name1">Full Name</label>
|
||||
<input type="text" className="form-control" id="name1"
|
||||
value="Alice Williams" />
|
||||
</div>
|
||||
<div className="form-group col-md-12">
|
||||
<label htmlFor="title1">Title</label>
|
||||
<input type="text" className="form-control" id="title1"
|
||||
value="Marketing expert" />
|
||||
</div>
|
||||
<div className="form-group col-md-12">
|
||||
<label htmlFor="phone1">Phone Number</label>
|
||||
<input type="text" className="form-control" id="phone1"
|
||||
value="(01) 97 563 15613" />
|
||||
</div>
|
||||
<div className="form-group col-md-12">
|
||||
<label htmlFor="email1">Email</label>
|
||||
<input type="email" className="form-control" id="email1"
|
||||
value="alicewilliams@gmail.com" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="add1">Address</label>
|
||||
<input type="text" className="form-control" id="add1"
|
||||
value="17504 Carlton Cuevas Rd, Gulfport, MS, 39503" />
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="add2">Address 2</label>
|
||||
<input type="text" className="form-control" id="add2"
|
||||
value="1234 North Avenue Luke Lane, South Bend, IN 360001" />
|
||||
</div>
|
||||
|
||||
|
||||
<button type="submit" className="btn btn-primary">Update Information
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</p> </div>
|
||||
<div className="tab-pane fade" id="contact-09" role="tabpanel" aria-labelledby="contact-09-tab">
|
||||
<p>
|
||||
<div className="page-account-form">
|
||||
<div className="form-titel border-bottom p-3">
|
||||
<h5 className="mb-0 py-2">Edit Your Product Settings</h5>
|
||||
</div>
|
||||
<div className="p-4">
|
||||
<form>
|
||||
<div className="form-row">
|
||||
<div className="form-group col-md-12">
|
||||
<label htmlFor="name1">Full Name</label>
|
||||
<input type="text" className="form-control" id="name1"
|
||||
value="Alice Williams" />
|
||||
</div>
|
||||
<div className="form-group col-md-12">
|
||||
<label htmlFor="title1">Title</label>
|
||||
<input type="text" className="form-control" id="title1"
|
||||
value="Marketing expert" />
|
||||
</div>
|
||||
<div className="form-group col-md-12">
|
||||
<label htmlFor="phone1">Phone Number</label>
|
||||
<input type="text" className="form-control" id="phone1"
|
||||
value="(01) 97 563 15613" />
|
||||
</div>
|
||||
<div className="form-group col-md-12">
|
||||
<label htmlFor="email1">Email</label>
|
||||
<input type="email" className="form-control" id="email1"
|
||||
value="alicewilliams@gmail.com" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="add1">Address</label>
|
||||
<input type="text" className="form-control" id="add1"
|
||||
value="17504 Carlton Cuevas Rd, Gulfport, MS, 39503" />
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="add2">Address 2</label>
|
||||
<input type="text" className="form-control" id="add2"
|
||||
value="1234 North Avenue Luke Lane, South Bend, IN 360001" />
|
||||
</div>
|
||||
|
||||
|
||||
<button type="submit" className="btn btn-primary">Update Information
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
import React, {memo, useState} from 'react'
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { pageSettings } from "../../../services/services";
|
||||
import SiteTemplateSelector from './SiteTemplateSelector';
|
||||
import NoYesBooleanDropdown from './NoYesBooleanDropdown';
|
||||
import { IoMdArrowDropdown } from 'react-icons/io';
|
||||
import queryKeys from '../../../services/queryKeys';
|
||||
|
||||
const GeneralTab = memo(({name='Full Name', data, isCustom, productData, backendValues, setFieldsChanged}) =>{
|
||||
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
const [reqStatus, setReqStatus] = useState({error: null, message: ''})
|
||||
|
||||
const fieldData = {}
|
||||
Object.entries(data)?.forEach(([key, value]) => { // LOOP TO POPULATE FIELDDATA PROPERTIES WITH DATA OF EACH TAB
|
||||
fieldData[value?.name?.toLowerCase().replaceAll(" ", "_")] = ''
|
||||
})
|
||||
backendValues.forEach(item => { //LOOPING THROUGH USER ALREADY ADDED DATA FROM BACKEND IF ANY AND UPDATING THE FIELDDATA OBJECT
|
||||
fieldData[item?.setting_key?.toLowerCase().replaceAll(" ", "_")] = item?.setting_value
|
||||
})
|
||||
|
||||
console.log('fieldData', fieldData)
|
||||
|
||||
const [fields, setFields] = useState(fieldData)
|
||||
|
||||
const handleChange = ({target:{name, value}}) => {
|
||||
setFields(prev => ({...prev, [name]:value}))
|
||||
setFieldsChanged(true)
|
||||
}
|
||||
|
||||
const submitSettings = useMutation({
|
||||
mutationFn: (fields) => {
|
||||
return pageSettings(fields)
|
||||
},
|
||||
onSuccess: (res) => {
|
||||
if(res?.data?.resultCode != '0'){
|
||||
return setReqStatus({error: true, message: 'Unable to complete, try again later'})
|
||||
}
|
||||
setFieldsChanged(false)
|
||||
setReqStatus({error: false, message: 'Completed successfully'})
|
||||
},
|
||||
onError: (err) => {
|
||||
setReqStatus({error: true, message: 'Unable to complete, try again later'})
|
||||
},
|
||||
onSettled: () => {
|
||||
queryClient.refetchQueries({ // refetches productProvision API call
|
||||
queryKey: [...queryKeys.settingsData],
|
||||
})
|
||||
setTimeout(()=>{
|
||||
setReqStatus({error: null, message: ''})
|
||||
},3000)
|
||||
},
|
||||
})
|
||||
|
||||
const handleSubmit = () => {
|
||||
const reqData = {
|
||||
token: localStorage.getItem('token'), // USER TOKEN
|
||||
uid: localStorage.getItem('uid'), // USER UID
|
||||
product_id: productData?.product_id,
|
||||
settings : {
|
||||
...fields
|
||||
}
|
||||
}
|
||||
// console.log('formInfo', reqData)
|
||||
submitSettings.mutate(reqData)
|
||||
}
|
||||
|
||||
if (isCustom === true){
|
||||
return <SiteTemplateSelector name={name} data={data} isCustom={isCustom} productData={productData} />
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div className="page-account-form">
|
||||
<div className="p-0" style={{ minHeight: '500px'}}>
|
||||
|
||||
<form id='tab_form'>
|
||||
<div className="form-row">
|
||||
<>
|
||||
{Object.entries(data)?.map(([key, value]) => {
|
||||
let fieldName = value.name.toLowerCase().replaceAll(" ", "_")
|
||||
let fieldValue = fields[value.name.toLowerCase().replaceAll(" ", "_")]
|
||||
return (
|
||||
<div key={key} className="form-group col-md-12">
|
||||
<label htmlFor="name1">{value.name}</label>
|
||||
{value.controls == 'TEXT' ?
|
||||
<input name={fieldName} type="text" className="form-control" id={key} value={fieldValue} onChange={handleChange} />
|
||||
:value.controls == 'TEXTAREA' ?
|
||||
<textarea name={fieldName} rows={5} style={{resize: 'none'}} type="text" className="form-control" id={key} value={fieldValue} onChange={handleChange} />
|
||||
: value.controls == 'SELECT_NO_YES' ?
|
||||
// <NoYesBooleanDropdown name={fieldName} value={fieldValue} onChange={handleChange} />
|
||||
<div className='position-relative'>
|
||||
<select onChange={handleChange} name={fieldName} value={fieldValue} className="form-control">
|
||||
<option value=''>Select</option>
|
||||
<option value='0'>No</option>
|
||||
<option value='1'>Yes</option>
|
||||
</select>
|
||||
<IoMdArrowDropdown className='position-absolute w-auto' style={{top: '50%', right: '2px', transform: 'translateY(-50%)'}} />
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
)}
|
||||
</>
|
||||
{reqStatus.message &&
|
||||
<>
|
||||
<div className="col-12">
|
||||
<p className={reqStatus.error ? 'text-danger' : 'text-success'}>{reqStatus.message}</p>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
<div className="form-group col-md-12" style={{textAlign:'right'}}>
|
||||
<button onClick={handleSubmit} type="button" className="btn btn-primary" disabled={submitSettings.isPending}>{submitSettings.isPending ? 'Loading...' : 'Update'}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
export default GeneralTab
|
||||
@@ -0,0 +1,11 @@
|
||||
import React, {memo} from 'react'
|
||||
|
||||
export default function NoYesBooleanDropdown(name, value, onChange) {
|
||||
return (
|
||||
<select onChange={onChange} name={name} value={value} className="form-control">
|
||||
<option value=''>Select</option>
|
||||
<option value='0'>No</option>
|
||||
<option value='1'>Yes</option>
|
||||
</select>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
import React, { memo, useMemo, useState } from 'react'
|
||||
import GeneralTab from './GeneralTab'
|
||||
import { getSettingsData } from '../../../services/services';
|
||||
import queryKeys from '../../../services/queryKeys';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
const Settings = memo(({productData}) => {
|
||||
|
||||
const { userDetails: { uid }} = useSelector((state) => state?.userDetails); // GETS USER UID
|
||||
|
||||
const dataFields ={
|
||||
site_title: { name: 'Title', controls: 'TEXT', active: true },
|
||||
site_description: { name: 'Description', controls: 'TEXTAREA', active: true },
|
||||
site_logo_text: { name: 'Logo Text', controls: 'TEXT', active: true },
|
||||
site_contact_email: { name: 'Email', controls: 'TEXT', active: true },
|
||||
site_contact_phone: { name: 'Phone', controls: 'TEXT', active: true },
|
||||
}
|
||||
|
||||
const socialFields ={
|
||||
facebook: { name: 'Facebook', controls: 'TEXT', active: true },
|
||||
twitter: { name: 'Twitter', controls: 'TEXT', active: true },
|
||||
youtube: { name: 'Youtube', controls: 'TEXT', active: true },
|
||||
}
|
||||
|
||||
const homeFields ={
|
||||
banner_text: { name: 'Banner Text', controls: 'TEXT', active: true },
|
||||
banner_description: { name: 'Banner Description', controls: 'TEXTAREA', active: true },
|
||||
}
|
||||
|
||||
const footerFields ={
|
||||
footer_description: { name: 'Footer Description', controls: 'TEXTAREA', active: true },
|
||||
boolean_footer_show_email: { name: 'Show email in footer', controls: 'SELECT_NO_YES', active: true },
|
||||
}
|
||||
|
||||
const aboutFields ={
|
||||
about_title: { name: 'About Title', controls: 'TEXT', active: true },
|
||||
about_description: { name: 'About Details', controls: 'TEXTAREA', active: true },
|
||||
about_extra_1: { name: 'Extra About us', controls: 'TEXTAREA', active: true },
|
||||
about_extra_2: { name: 'More About us', controls: 'TEXTAREA', active: true },
|
||||
}
|
||||
|
||||
const templateData = {
|
||||
template_16 : { title: 'Template Name-16', template_id: '02af24fd-2b1a-46ed-af21-87018e726408', banner: 'file-icon/svg.png', active: '' },
|
||||
template_22 : { title: 'Template Name-22', template_id: '8b296894-42e4-4f2e-abd1-7c2a38d6e07b', banner: 'file-icon/svg.png', active: '' },
|
||||
template_47 : { title: 'Template Name-47', template_id: 'ef2ffa1c-9272-42cd-9d33-0e614047b4f8', banner: 'file-icon/svg.png', active: '' },
|
||||
template_25 : { title: 'Template Name-25', template_id: 'b3a7ba31-dc47-4a40-a5cc-fd1ff27d6b78', banner: 'file-icon/svg.png', active: '' },
|
||||
template_49 : { title: 'Template Name-49', template_id: '60959c69-6672-4f69-a006-eeb7d210e605', banner: 'file-icon/svg.png', active: '' },
|
||||
template_27 : { title: 'Template Name-27', template_id: 'e4acb98a-c584-45f2-bece-af677dcf0a1f', banner: 'file-icon/svg.png', active: '' },
|
||||
template_51 : { title: 'Template Name-51', template_id: '975ee42e-3169-4978-92d7-d28e7e2ac014', banner: 'file-icon/svg.png', active: '' },
|
||||
template_9 : { title: 'Template Name-9', template_id: 'fc8f0738-6500-4775-9895-2047cd275302', banner: 'file-icon/svg.png', active: '' },
|
||||
}
|
||||
|
||||
const contactFields ={
|
||||
contact_title : { name: 'Contact Title', controls: 'TEXT', active: true },
|
||||
contact_introduction: { name: 'Extra Introduction', controls: 'TEXTAREA', active: true },
|
||||
}
|
||||
|
||||
const settingsObject = useMemo(()=>{
|
||||
return {
|
||||
settings: { title: 'Settings', controls: 'settings', active: 'active show' , custom: false, data: dataFields},
|
||||
home_tab: { title: 'Home Page', controls: 'home', active: '', custom: false, data: homeFields},
|
||||
footer_tab: { title: 'Footer', controls: 'footer', active: '', custom: false, data: footerFields },
|
||||
about_tab: { title: 'About Page', controls: 'about', active: '', custom: false, data: aboutFields },
|
||||
contact_tab: { title: 'Contact Page', controls: 'contact', active: '', custom: false, data: contactFields },
|
||||
social_tab: { title: 'Socials', controls: 'social', active: '', custom: false, data: socialFields },
|
||||
template_tab: { title: 'Template', controls: 'template', active: '', custom: true, data: templateData },
|
||||
color_scheme_tab: { title: 'Color Scheme', controls: 'color-scheme', active: '', custom: true, data: {} },
|
||||
};
|
||||
},[])
|
||||
|
||||
|
||||
const [fieldsChanged, setFieldsChanged] = useState(false)
|
||||
|
||||
const [activeTab, setActiveTab] = useState(Object.entries(settingsObject)[0][1]?.controls)
|
||||
|
||||
const handleChangeTab = (value) => {
|
||||
// if(fieldsChanged){
|
||||
// const proceed = confirm('Continue without saving changes')
|
||||
// if(proceed){
|
||||
// setActiveTab(value)
|
||||
// setFieldsChanged(false)
|
||||
// }
|
||||
// }else{
|
||||
// setActiveTab(value)
|
||||
// }
|
||||
setActiveTab(value)
|
||||
}
|
||||
|
||||
|
||||
const {data, isFetching, isError, error} = useQuery({
|
||||
queryKey: queryKeys.settingsData,
|
||||
queryFn: () => {
|
||||
let reqData = {
|
||||
token: localStorage.getItem('token'), // USER TOKEN
|
||||
uid: localStorage.getItem('uid'), // USER UID
|
||||
product_id: productData?.product_id
|
||||
}
|
||||
return getSettingsData(reqData)
|
||||
}
|
||||
})
|
||||
|
||||
const settingsData = data?.data?.settings
|
||||
// console.log('data', settingsData)
|
||||
|
||||
return (
|
||||
<>
|
||||
{isFetching ?
|
||||
<>
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<p className='text-mute'>Loading...</p>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
: isError ?
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<p className='text-danger'>{error.message}</p>
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
<div className="tab tab-vertical">
|
||||
<ul className="nav nav-tabs" role="tablist">
|
||||
<>
|
||||
{Object.entries(settingsObject).map(([key, value]) => (
|
||||
<li key={key} className="nav-item">
|
||||
<a className={`nav-link ${activeTab == value.controls && 'active show'}`}
|
||||
id={key}
|
||||
// data-bs-toggle="pill"
|
||||
// data-bs-target={`#${value.controls}`}
|
||||
type="button"
|
||||
// role="tab"
|
||||
// aria-controls={value.controls}
|
||||
// aria-selected="true"
|
||||
onClick={()=>handleChangeTab(value.controls)}
|
||||
>
|
||||
{value.title}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</>
|
||||
</ul>
|
||||
<div className="tab-content">
|
||||
<>
|
||||
{Object.entries(settingsObject).map(([key, value]) => (
|
||||
<div key={key} className={`tab-pane fade ${activeTab == value.controls && 'active show'}`}
|
||||
// id={value.controls} role="tabpanel"
|
||||
// aria-labelledby={key}
|
||||
>
|
||||
<GeneralTab name={value.title} data={value.data} isCustom={value.custom} productData={productData} backendValues={settingsData} setFieldsChanged={setFieldsChanged} />
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
export default Settings
|
||||
@@ -0,0 +1,33 @@
|
||||
import React, {memo} from 'react'
|
||||
import getImage from "../../../utils/getImage";
|
||||
|
||||
const SiteTemplateSelector = memo(({name='Full Name', data}) =>{
|
||||
console.log("Page data == ", data)
|
||||
return (
|
||||
<div className="page-account-form">
|
||||
<div className="p-0">
|
||||
<div className="row">
|
||||
<>
|
||||
{Object.entries(data)?.map(([key, value]) => (
|
||||
<div key={key} className="col-xl-6 col-sm-6">
|
||||
<div className="card card-statistics">
|
||||
<div className="card-body">
|
||||
<div className="text-center p-2">
|
||||
<div className="mb-2">
|
||||
<img src={getImage(value.banner)} alt={value.title} />
|
||||
</div>
|
||||
<h4 className="mb-0">{value.title}</h4>
|
||||
<a href="javascript:void(0)" className="btn btn-light">Activate</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
)
|
||||
export default SiteTemplateSelector
|
||||
@@ -0,0 +1,217 @@
|
||||
import React, { useEffect, useMemo, useState } from "react";
|
||||
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
|
||||
// import { useLocation } from "react-router-dom";
|
||||
// import { Form, Formik } from "formik";
|
||||
import * as Yup from "yup";
|
||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||
import getImage from "../../utils/getImage";
|
||||
import { IoMdArrowDropdown } from "react-icons/io";
|
||||
import { completeProfile, getCommonPractice } from '../../services/services';
|
||||
import siteLinks from "../../links/siteLinks";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import { updateUserDetails } from "../../store/UserDetails";
|
||||
import { useDispatch } from "react-redux";
|
||||
|
||||
|
||||
// const validationSchema = Yup.object().shape({
|
||||
// practice: Yup.string().required("Required"),
|
||||
// specialization: Yup.string().required("Required"),
|
||||
// introduction: Yup.string().min(1, "Minimum 10 characters").max(50, "Maximum 50 characters").required("Required"),
|
||||
// })
|
||||
|
||||
// const initialValues = {
|
||||
// practice: '',
|
||||
// specialization: '',
|
||||
// introduction: '',
|
||||
// };
|
||||
|
||||
|
||||
export default function ProfileCompleteCom(){
|
||||
|
||||
const dispatch = useDispatch()
|
||||
|
||||
const navigate = useNavigate()
|
||||
|
||||
const {state:{redirectLink}} = useLocation()
|
||||
|
||||
const [practices, setPractices] = useState([])
|
||||
|
||||
const [initialValues, setInitialValues] = useState({
|
||||
practice: '',
|
||||
specialization: '',
|
||||
introduction: '',
|
||||
})
|
||||
|
||||
const specialties = useMemo(()=>{ // FUNCTION TO UPDATE SPECIALITY ARRAY EACH TIME PRACTICE CHANGES
|
||||
setInitialValues(prev => ({...prev, specialization: ''}))
|
||||
if(!initialValues.practice){
|
||||
return []
|
||||
}
|
||||
const specialtiesArr = practices.filter(item => item.practice == initialValues.practice)[0]?.specialties
|
||||
return specialtiesArr
|
||||
},[initialValues.practice])
|
||||
|
||||
|
||||
const mutation = useMutation({
|
||||
mutationFn: (fields) => {
|
||||
const {practice, specialization} = fields
|
||||
if(!practice || !specialization){
|
||||
throw new Error('Please select both practice and specialization fields')
|
||||
}
|
||||
return completeProfile(fields)
|
||||
},
|
||||
onError: () => {
|
||||
setTimeout(()=>{mutation.reset()}, 4000)
|
||||
},
|
||||
onSuccess: (res) => {
|
||||
if(res.data.resultCode != '0'){
|
||||
throw({message: res?.data?.resultDescription})
|
||||
}
|
||||
dispatch(updateUserDetails({profile_completed: res?.data?.profile_completed }));
|
||||
setTimeout(()=>{
|
||||
navigate(redirectLink)
|
||||
},2000)
|
||||
// console.log('res', res)
|
||||
}
|
||||
})
|
||||
|
||||
const commonPractices = useMutation({ // FUNCTION TO GET COMMON PRACTICES
|
||||
mutationFn: (fields) => {
|
||||
return getCommonPractice(fields)
|
||||
},
|
||||
onError: ()=> {
|
||||
setPractices([])
|
||||
},
|
||||
onSuccess: (res) => {
|
||||
if(!res?.data){
|
||||
return setPractices([])
|
||||
}
|
||||
let returnPractices = Object.entries(res?.data).filter(([key, value]) => typeof value == 'object')?.map(item => item[1])
|
||||
setPractices(returnPractices)
|
||||
}
|
||||
})
|
||||
|
||||
const handlePracticeChange = ({target:{name, value}}) => {
|
||||
setInitialValues(prev => ({...prev, [name]:value}))
|
||||
}
|
||||
|
||||
const handleCompleteProfile = () => { // FUNCTION TO COMPLETE PROFILE
|
||||
let reqData = {
|
||||
token: localStorage.getItem('token'), // USER TOKEN
|
||||
uid: localStorage.getItem('uid'), // USER UID
|
||||
...initialValues
|
||||
}
|
||||
mutation.mutate(reqData)
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
let reqData = {
|
||||
token: localStorage.getItem('token'), // USER TOKEN
|
||||
uid: localStorage.getItem('uid') // USER UID
|
||||
}
|
||||
commonPractices.mutate(reqData)
|
||||
},[])
|
||||
|
||||
return <>
|
||||
|
||||
<BreadcrumbComBS title='Tell us more about your practice.' paths={['Dashboard', 'Profile']} />
|
||||
|
||||
{commonPractices?.isFetching ?
|
||||
<>
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<p className='text-mute'>Loading...</p>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
: commonPractices?.isError ?
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<p className='text-danger'>{commonPractices?.error?.message}</p>
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
<div className="row pt-1">
|
||||
<div className="col-md-6 m-b-30">
|
||||
<div className="card card-statistics h-100 mb-0">
|
||||
{/* <div className="card-header d-flex align-items-center justify-content-between">
|
||||
<div className="card-heading">
|
||||
<h4 className="card-title">My Product URLs</h4>
|
||||
</div>
|
||||
</div> */}
|
||||
{/* <div style={{minHeight: '400px'}}></div> */}
|
||||
<div className="card-body">
|
||||
<div className='h-100 row flex-column'>
|
||||
{/* <div className="row"> */}
|
||||
<>
|
||||
<div className="">
|
||||
<div className="form-group position-relative">
|
||||
<label className={`text-black fw-bold control-label`}>Practice :</label>
|
||||
<div className="position-relative">
|
||||
{/* <select onChange={props.handleChange} name='practice' value={props.values.practice} className="form-control">
|
||||
<option value=''>Select</option>
|
||||
{practices.map((practice, index)=>(
|
||||
<option key={index} value={practice.practice}>{practice.practice}</option>
|
||||
))}
|
||||
</select> */}
|
||||
<select onChange={handlePracticeChange} name='practice' value={initialValues.practice} className="form-control">
|
||||
<option value=''>Select</option>
|
||||
{practices.map((practice, index)=>(
|
||||
<option key={index} value={practice.practice}>{practice.practice}</option>
|
||||
))}
|
||||
</select>
|
||||
<IoMdArrowDropdown className='position-absolute w-auto' style={{top: '50%', right: '2px', transform: 'translateY(-50%)'}} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="">
|
||||
<div className="form-group">
|
||||
<label className={`text-black fw-bold control-label`}>Specialization :</label>
|
||||
<div className="position-relative">
|
||||
<select onChange={handlePracticeChange} name='specialization' value={initialValues.specialization} className="form-control">
|
||||
<option value=''>Select</option>
|
||||
{specialties.map((specialty, index)=>(
|
||||
<option key={index} value={specialty}>{specialty}</option>
|
||||
))}
|
||||
</select>
|
||||
<IoMdArrowDropdown className='position-absolute w-auto' style={{top: '50%', right: '2px', transform: 'translateY(-50%)'}} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="">
|
||||
<div className="form-group position-relative">
|
||||
<label className={`text-black fw-bold control-label`}>General Information :</label>
|
||||
<textarea name='introduction' rows={10} style={{resize: 'none'}} className="form-control" value={initialValues.introduction} onChange={handlePracticeChange} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{(mutation.isError || mutation.isSuccess) &&
|
||||
<>
|
||||
<div className="">
|
||||
<p className={`${mutation.isSuccess ? 'text-success' : 'text-danger'}`}>{mutation.isSuccess ? 'Completed successfully, redirecting...' : mutation.error.message}</p>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
|
||||
<div className="mt-auto text-end">
|
||||
<button type='button' onClick={handleCompleteProfile} className="btn btn-primary text-uppercase">{mutation.isPending ? 'loading...' : 'Continue'}</button>
|
||||
</div>
|
||||
</>
|
||||
{/* </div> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-md-6 m-b-30">
|
||||
<div className="text-center img-block left-column wow fadeInRight">
|
||||
<img className="img-fluid" src={getImage('img-07.png')} alt="content-image" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</>;
|
||||
|
||||
}
|
||||
@@ -15,7 +15,7 @@ export default function Settings(){
|
||||
<div className="row account-contant">
|
||||
<div className="col-12">
|
||||
<div className="card card-statistics">
|
||||
<div className="card-body p-0">
|
||||
<div className="card-body p-0" style={{backgroundColor:"#f9f9fb"}}>
|
||||
<div className="row no-gutters">
|
||||
<div className="col-xl-3 pb-xl-0 pb-5 border-right">
|
||||
<div className="page-account-profil pt-5">
|
||||
@@ -62,9 +62,9 @@ export default function Settings(){
|
||||
<button className="btn btn-light text-primary mb-2">Upload New Avatar
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button className="btn btn-danger">Delete</button>
|
||||
</div>
|
||||
{/*<div>*/}
|
||||
{/* <button className="btn btn-danger">Delete</button>*/}
|
||||
{/*</div>*/}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -77,15 +77,25 @@ export default function Settings(){
|
||||
<form>
|
||||
<div className="form-row">
|
||||
<div className="form-group col-md-12">
|
||||
<label htmlFor="name1">Full Name</label>
|
||||
<label htmlFor="name1">First Name</label>
|
||||
<input type="text" className="form-control" id="name1"
|
||||
value="Alice Williams" />
|
||||
value="Alice" />
|
||||
</div>
|
||||
<div className="form-group col-md-12">
|
||||
<label htmlFor="title1">Title</label>
|
||||
<input type="text" className="form-control" id="title1"
|
||||
value="Marketing expert" />
|
||||
<label htmlFor="name1">Last Name</label>
|
||||
<input type="text" className="form-control" id="name1"
|
||||
value="Williams" />
|
||||
</div>
|
||||
<div className="form-group col-md-12">
|
||||
<label htmlFor="name1">Account Name</label>
|
||||
<input type="text" className="form-control" id="name1"
|
||||
value="This is the best hospital name" />
|
||||
</div>
|
||||
{/*<div className="form-group col-md-12">*/}
|
||||
{/* <label htmlFor="title1">Email</label>*/}
|
||||
{/* <input type="text" className="form-control" id="title1"*/}
|
||||
{/* value="email@email.com" />*/}
|
||||
{/*</div>*/}
|
||||
<div className="form-group col-md-12">
|
||||
<label htmlFor="phone1">Phone Number</label>
|
||||
<input type="text" className="form-control" id="phone1"
|
||||
@@ -108,135 +118,47 @@ export default function Settings(){
|
||||
value="1234 North Avenue Luke Lane, South Bend, IN 360001" />
|
||||
</div>
|
||||
|
||||
<div className="form-row">
|
||||
<div className="col-12">
|
||||
<label className="mb-1">Birthday</label>
|
||||
</div>
|
||||
<div className="form-group col-md-4">
|
||||
<select id="inputState" className="form-control">
|
||||
<option>Date</option>
|
||||
<option>01</option>
|
||||
<option>02</option>
|
||||
<option>03</option>
|
||||
<option>04</option>
|
||||
<option>05</option>
|
||||
<option>06</option>
|
||||
<option>07</option>
|
||||
<option>08</option>
|
||||
<option>09</option>
|
||||
<option>10</option>
|
||||
<option selected="">11</option>
|
||||
<option>12</option>
|
||||
<option>13</option>
|
||||
<option>14</option>
|
||||
<option>15</option>
|
||||
<option>16</option>
|
||||
<option>17</option>
|
||||
<option>18</option>
|
||||
<option>19</option>
|
||||
<option>20</option>
|
||||
<option>21</option>
|
||||
<option>22</option>
|
||||
<option>23</option>
|
||||
<option>24</option>
|
||||
<option>25</option>
|
||||
<option>26</option>
|
||||
<option>27</option>
|
||||
<option>28</option>
|
||||
<option>29</option>
|
||||
<option>30</option>
|
||||
<option>31</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-group col-md-4">
|
||||
<select id="inputState1" className="form-control">
|
||||
<option>Month</option>
|
||||
<option>January</option>
|
||||
<option>February</option>
|
||||
<option>March</option>
|
||||
<option>April</option>
|
||||
<option selected="">May</option>
|
||||
<option>June</option>
|
||||
<option>July</option>
|
||||
<option>August</option>
|
||||
<option>September</option>
|
||||
<option>October</option>
|
||||
<option>November</option>
|
||||
<option>December</option>
|
||||
</select>
|
||||
</div>
|
||||
{/*<div className="form-row">*/}
|
||||
{/* <div className="form-group col-md-4">*/}
|
||||
{/* <label htmlFor="inputState3">City</label>*/}
|
||||
{/* <select id="inputState3" className="form-control">*/}
|
||||
{/* <option>Choose...</option>*/}
|
||||
{/* <option selected="">London</option>*/}
|
||||
{/* <option>Montreal</option>*/}
|
||||
{/* <option>Delhi</option>*/}
|
||||
{/* <option>Tokyo</option>*/}
|
||||
{/* </select>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="form-group col-md-4">*/}
|
||||
{/* <label htmlFor="inputState4">State</label>*/}
|
||||
{/* <select id="inputState4" className="form-control">*/}
|
||||
{/* <option>Choose...</option>*/}
|
||||
{/* <option selected="">England</option>*/}
|
||||
{/* <option>California</option>*/}
|
||||
{/* <option>Texas</option>*/}
|
||||
{/* <option>Scotland</option>*/}
|
||||
{/* </select>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="form-group col-md-4">*/}
|
||||
{/* <label htmlFor="inputZip">Zip</label>*/}
|
||||
{/* <input type="text" className="form-control" id="inputZip"*/}
|
||||
{/* value="EC1A 1BB" />*/}
|
||||
{/* </div>*/}
|
||||
{/*</div>*/}
|
||||
{/*<div className="form-group">*/}
|
||||
{/* <div className="form-check">*/}
|
||||
{/* <input className="form-check-input" type="checkbox"*/}
|
||||
{/* id="gridCheck" />*/}
|
||||
{/* <label className="form-check-label" htmlFor="gridCheck">*/}
|
||||
{/* I agree to receive email notification.*/}
|
||||
{/* </label>*/}
|
||||
{/* </div>*/}
|
||||
{/*</div>*/}
|
||||
<div style={{textAlign:"right"}}>
|
||||
<button type="submit" className="btn btn-primary">Update Profile
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="form-group col-md-4">
|
||||
<select id="inputState2" className="form-control">
|
||||
<option>Year</option>
|
||||
<option>1984</option>
|
||||
<option>1985</option>
|
||||
<option>1986</option>
|
||||
<option>1987</option>
|
||||
<option>1988</option>
|
||||
<option>1989</option>
|
||||
<option>1990</option>
|
||||
<option>1991</option>
|
||||
<option>1992</option>
|
||||
<option>1993</option>
|
||||
<option selected="">1994</option>
|
||||
<option>1995</option>
|
||||
<option>1996</option>
|
||||
<option>1997</option>
|
||||
<option>1998</option>
|
||||
<option>1999</option>
|
||||
<option>2000</option>
|
||||
<option>2001</option>
|
||||
<option>2002</option>
|
||||
<option>2003</option>
|
||||
<option>2004</option>
|
||||
<option>2005</option>
|
||||
<option>2006</option>
|
||||
<option>2007</option>
|
||||
<option>2008</option>
|
||||
<option>2009</option>
|
||||
<option>2010</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-row">
|
||||
<div className="form-group col-md-4">
|
||||
<label htmlFor="inputState3">City</label>
|
||||
<select id="inputState3" className="form-control">
|
||||
<option>Choose...</option>
|
||||
<option selected="">London</option>
|
||||
<option>Montreal</option>
|
||||
<option>Delhi</option>
|
||||
<option>Tokyo</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-group col-md-4">
|
||||
<label htmlFor="inputState4">State</label>
|
||||
<select id="inputState4" className="form-control">
|
||||
<option>Choose...</option>
|
||||
<option selected="">England</option>
|
||||
<option>California</option>
|
||||
<option>Texas</option>
|
||||
<option>Scotland</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-group col-md-4">
|
||||
<label htmlFor="inputZip">Zip</label>
|
||||
<input type="text" className="form-control" id="inputZip"
|
||||
value="EC1A 1BB" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<div className="form-check">
|
||||
<input className="form-check-input" type="checkbox"
|
||||
id="gridCheck" />
|
||||
<label className="form-check-label" htmlFor="gridCheck">
|
||||
I agree to receive email notification.
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" className="btn btn-primary">Update Information
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -282,7 +204,10 @@ export default function Settings(){
|
||||
<input type="text" className="form-control" id="we"
|
||||
value="https://yourwebsite.com" />
|
||||
</div>
|
||||
<button type="submit" className="btn btn-primary">Save & Update</button>
|
||||
<div style={{textAlign:"right"}}>
|
||||
<button type="submit" className="btn btn-primary">Update Links</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import React from 'react'
|
||||
|
||||
export default function SubcribePaymentOptions(){
|
||||
|
||||
return <>
|
||||
|
||||
|
||||
<div className="card-header">
|
||||
<div className="card-heading">
|
||||
<h4 className="card-title">Select Payment Option</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div className="card-body">
|
||||
|
||||
<div className="form-check form-check-inline">
|
||||
<input className="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio1"
|
||||
value="option1" />
|
||||
<label className="form-check-label" htmlFor="inlineRadio1">Previous Cards</label>
|
||||
</div>
|
||||
<div className="form-check form-check-inline">
|
||||
<input className="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio2"
|
||||
value="option2" />
|
||||
<label className="form-check-label" htmlFor="inlineRadio2">Add New card</label>
|
||||
</div>
|
||||
</div>
|
||||
{/*<div className="card card-statistics"> </div>*/}
|
||||
|
||||
</>
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import React from 'react'
|
||||
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
|
||||
import getImage from "../../utils/getImage";
|
||||
import { getSubscriptions } from '../../services/services';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import queryKeys from '../../services/queryKeys';
|
||||
import siteLinks from "../../links/siteLinks";
|
||||
import { Link, useLocation } from 'react-router-dom'
|
||||
import SubscribeNewCard from "./SubscribeNewCard";
|
||||
import SubscribePreviousCard from "./SubscribePreviousCard";
|
||||
import SubcribePaymentOptions from "./SubcribePaymentOptions";
|
||||
|
||||
export default function Subscribe() {
|
||||
|
||||
const {state:{selectedSubscription}} = useLocation()
|
||||
|
||||
// console.log('selectedSubscription', selectedSubscription)
|
||||
|
||||
return (
|
||||
<>
|
||||
<BreadcrumbComBS title='Activate or Update your Subscription' paths={['Dashboard', 'subscribe']} />
|
||||
|
||||
<div className="row">
|
||||
<div className="col-12 col-lg-6 col-xl-6">
|
||||
<div className="card card-statistics text-center py-3">
|
||||
<div className="card-body pricing-content">
|
||||
<div className="pricing-content-card">
|
||||
<h5>Current Subscription(s)</h5>
|
||||
{/*<h2 className="text-primary pt-3">{currentSubscription?.display_name}</h2>*/}
|
||||
<SubcribePaymentOptions />
|
||||
|
||||
<SubscribeNewCard />
|
||||
<SubscribePreviousCard />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<>
|
||||
<div key="basic" className="col-12 col-lg-6 col-xl-6">
|
||||
<div className="card card-statistics text-center py-3">
|
||||
<div className="card-body pricing-content">
|
||||
<div className="pricing-content-card">
|
||||
<h5>{selectedSubscription.display_name}</h5>
|
||||
<h2 className="text-primary pt-3">${selectedSubscription.monthly}</h2>
|
||||
<p className="text-primary pb-3">/ Monthly</p>
|
||||
<ul className="py-2">
|
||||
{selectedSubscription?.items?.map(item =>(
|
||||
<li key={item}>{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
{/*<div className="pt-2">*/}
|
||||
{/* <button className="btn btn-inverse-secondary btn-round btn-sm">Go {subscriptionSelection.display_name}</button>*/}
|
||||
{/*</div>*/}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import React from 'react'
|
||||
export default function SubscribeNewCard(){
|
||||
|
||||
return <>Previous Card</>
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import React from 'react'
|
||||
export default function SubscribePreviousCard(){
|
||||
|
||||
return <>Previous Card</>
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
import React from 'react'
|
||||
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
|
||||
import getImage from "../../utils/getImage";
|
||||
import { getSubscriptions } from '../../services/services';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import queryKeys from '../../services/queryKeys';
|
||||
import siteLinks from "../../links/siteLinks";
|
||||
import { Link, useNavigate } from 'react-router-dom'
|
||||
|
||||
export default function Subscription() {
|
||||
const navigate = useNavigate()
|
||||
const pricingFields ={
|
||||
starter: { name: 'Starter', price: 5.99, active: true },
|
||||
basic: { name: 'Basic', price: 12.99, active: true },
|
||||
premium: { name: 'Premium', price: 20.00, active: true },
|
||||
}
|
||||
|
||||
const {data, isFetching, isError, error} = useQuery({
|
||||
queryKey: queryKeys.subscriptions,
|
||||
queryFn: () => {
|
||||
let reqData = {
|
||||
token: localStorage.getItem('token'), // USER TOKEN
|
||||
uid: localStorage.getItem('uid') // USER UID
|
||||
}
|
||||
return getSubscriptions(reqData)
|
||||
}
|
||||
})
|
||||
|
||||
const currentSubscription = data?.data?.current_product
|
||||
const otherSubscriptions = data?.data?.options
|
||||
// console.log('urlData', data?.data)
|
||||
|
||||
return (
|
||||
<>
|
||||
<BreadcrumbComBS title='Subscription' paths={['Dashboard', 'Subscription']} />
|
||||
|
||||
{isFetching ?
|
||||
<>
|
||||
<div className="col-12">
|
||||
<p className='text-mute'>Loading...</p>
|
||||
</div>
|
||||
</>
|
||||
: isError ?
|
||||
<div className="col-12">
|
||||
<p className='text-danger'>{error.message}</p>
|
||||
</div>
|
||||
:
|
||||
<div className="row">
|
||||
<div className="col-12 col-lg-6 col-xl-3">
|
||||
<div className="card card-statistics text-center py-3">
|
||||
<div className="card-body pricing-content">
|
||||
<div className="pricing-content-card">
|
||||
<h5>Current Subscription(s)</h5>
|
||||
<h2 className="text-primary pt-3">{currentSubscription?.display_name}</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<>
|
||||
{Object.entries(otherSubscriptions)?.map(([key, value]) => (
|
||||
|
||||
<div key={key} className="col-12 col-lg-6 col-xl-3">
|
||||
<div className="card card-statistics text-center py-3">
|
||||
<div className="card-body pricing-content">
|
||||
<div className="pricing-content-card">
|
||||
<h5>{value.display_name}</h5>
|
||||
<h2 className="text-primary pt-3">${value.monthly}</h2>
|
||||
<p className="text-primary pb-3">/ Monthly</p>
|
||||
<ul className="py-2">
|
||||
{value?.items?.map(item =>(
|
||||
<li key={item}>{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
<div className="pt-2">
|
||||
<button onClick={()=>{navigate(siteLinks.subscribe, {state:{selectedSubscription: value}})}} className="btn btn-inverse-secondary btn-round btn-sm">Go {value.display_name}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
))}
|
||||
</>
|
||||
|
||||
</div>
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -53,172 +53,172 @@ export default function Users(){
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-xxl-3 col-xl-4 col-sm-6">
|
||||
<div className="card card-statistics contact-contant">
|
||||
<div className="card-body py-4">
|
||||
<div className="d-flex align-items-center">
|
||||
<div className="bg-img">
|
||||
<img src="assets/img/avtar/02.jpg" alt="" className="img-fluid" />
|
||||
</div>
|
||||
<div className="ml-3">
|
||||
<h4 className="mb-0">Samuel Woods</h4>
|
||||
<p><span className="badge badge-success-inverse px-2 py-1 mt-1">Friends</span></p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<ul className="nav">
|
||||
<li className="nav-item">
|
||||
<div className="img-icon">
|
||||
<div className="img-icon"><i className="fa fa-mobile"></i></div>
|
||||
</div>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<p>026-123-8546</p>
|
||||
</li>
|
||||
</ul>
|
||||
<ul className="nav">
|
||||
<li className="nav-item">
|
||||
<div className="img-icon"><i className="fa fa-phone"></i></div>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<p>80-1230-8546</p>
|
||||
</li>
|
||||
</ul>
|
||||
<ul className="nav">
|
||||
<li className="nav-item">
|
||||
<div className="img-icon"><i className="fa fa-envelope-o"></i></div>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<p>Samuel.Woods@gmail.com</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-xxl-3 col-xl-4 col-sm-6">
|
||||
<div className="card card-statistics contact-contant">
|
||||
<div className="card-body py-4">
|
||||
<div className="d-flex align-items-center">
|
||||
<div className="bg-img">
|
||||
<img src="assets/img/avtar/03.jpg" alt="" className="img-fluid" />
|
||||
</div>
|
||||
<div className="ml-3">
|
||||
<h4 className="mb-0">Garettdon</h4>
|
||||
<p><span className="badge badge-primary-inverse px-2 py-1 mt-1">Office</span></p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<ul className="nav">
|
||||
<li className="nav-item">
|
||||
<div className="img-icon"><i className="fa fa-mobile"></i></div>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<p>026-123-8546</p>
|
||||
</li>
|
||||
</ul>
|
||||
<ul className="nav">
|
||||
<li className="nav-item">
|
||||
<div className="img-icon"><i className="fa fa-phone"></i></div>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<p>80-1230-8546</p>
|
||||
</li>
|
||||
</ul>
|
||||
<ul className="nav">
|
||||
<li className="nav-item">
|
||||
<div className="img-icon"><i className="fa fa-envelope-o"></i></div>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<p>Garettdon@gmail.com</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-xxl-3 col-xl-4 col-sm-6">
|
||||
<div className="card card-statistics contact-contant">
|
||||
<div className="card-body py-4">
|
||||
<div className="d-flex align-items-center">
|
||||
<div className="bg-img">
|
||||
<img src="assets/img/avtar/04.jpg" alt="" className="img-fluid" />
|
||||
</div>
|
||||
<div className="ml-3">
|
||||
<h4 className="mb-0">Garynice</h4>
|
||||
<p><span className="badge badge-warning-inverse px-2 py-1 mt-1">Home</span></p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<ul className="nav">
|
||||
<li className="nav-item">
|
||||
<div className="img-icon"><i className="fa fa-mobile"></i></div>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<p>026-123-8546</p>
|
||||
</li>
|
||||
</ul>
|
||||
<ul className="nav">
|
||||
<li className="nav-item">
|
||||
<div className="img-icon"><i className="fa fa-phone"></i></div>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<p>80-1230-8546</p>
|
||||
</li>
|
||||
</ul>
|
||||
<ul className="nav">
|
||||
<li className="nav-item">
|
||||
<div className="img-icon"><i className="fa fa-envelope-o"></i></div>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<p>Garynice@gmail.com</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-xxl-3 col-xl-4 col-sm-6">
|
||||
<div className="card card-statistics contact-contant">
|
||||
<div className="card-body py-4">
|
||||
<div className="d-flex align-items-center">
|
||||
<div className="bg-img">
|
||||
<img src="assets/img/avtar/05.jpg" alt="" className="img-fluid" />
|
||||
</div>
|
||||
<div className="ml-3">
|
||||
<h4 className="mb-0">Andrew nico</h4>
|
||||
<p><span className="badge badge-success-inverse px-2 py-1 mt-1">Friends</span></p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<ul className="nav">
|
||||
<li className="nav-item">
|
||||
<div className="img-icon"><i className="fa fa-mobile"></i></div>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<p>026-123-8546</p>
|
||||
</li>
|
||||
</ul>
|
||||
<ul className="nav">
|
||||
<li className="nav-item">
|
||||
<div className="img-icon"><i className="fa fa-phone"></i></div>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<p>80-1230-8546</p>
|
||||
</li>
|
||||
</ul>
|
||||
<ul className="nav">
|
||||
<li className="nav-item">
|
||||
<div className="img-icon"><i className="fa fa-envelope-o"></i></div>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<p>Andrew.nico@gmail.com</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/*<div className="col-xxl-3 col-xl-4 col-sm-6">*/}
|
||||
{/* <div className="card card-statistics contact-contant">*/}
|
||||
{/* <div className="card-body py-4">*/}
|
||||
{/* <div className="d-flex align-items-center">*/}
|
||||
{/* <div className="bg-img">*/}
|
||||
{/* <img src="assets/img/avtar/02.jpg" alt="" className="img-fluid" />*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="ml-3">*/}
|
||||
{/* <h4 className="mb-0">Samuel Woods</h4>*/}
|
||||
{/* <p><span className="badge badge-success-inverse px-2 py-1 mt-1">Friends</span></p>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div>*/}
|
||||
{/* <ul className="nav">*/}
|
||||
{/* <li className="nav-item">*/}
|
||||
{/* <div className="img-icon">*/}
|
||||
{/* <div className="img-icon"><i className="fa fa-mobile"></i></div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </li>*/}
|
||||
{/* <li className="nav-item">*/}
|
||||
{/* <p>026-123-8546</p>*/}
|
||||
{/* </li>*/}
|
||||
{/* </ul>*/}
|
||||
{/* <ul className="nav">*/}
|
||||
{/* <li className="nav-item">*/}
|
||||
{/* <div className="img-icon"><i className="fa fa-phone"></i></div>*/}
|
||||
{/* </li>*/}
|
||||
{/* <li className="nav-item">*/}
|
||||
{/* <p>80-1230-8546</p>*/}
|
||||
{/* </li>*/}
|
||||
{/* </ul>*/}
|
||||
{/* <ul className="nav">*/}
|
||||
{/* <li className="nav-item">*/}
|
||||
{/* <div className="img-icon"><i className="fa fa-envelope-o"></i></div>*/}
|
||||
{/* </li>*/}
|
||||
{/* <li className="nav-item">*/}
|
||||
{/* <p>Samuel.Woods@gmail.com</p>*/}
|
||||
{/* </li>*/}
|
||||
{/* </ul>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/*</div>*/}
|
||||
{/*<div className="col-xxl-3 col-xl-4 col-sm-6">*/}
|
||||
{/* <div className="card card-statistics contact-contant">*/}
|
||||
{/* <div className="card-body py-4">*/}
|
||||
{/* <div className="d-flex align-items-center">*/}
|
||||
{/* <div className="bg-img">*/}
|
||||
{/* <img src="assets/img/avtar/03.jpg" alt="" className="img-fluid" />*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="ml-3">*/}
|
||||
{/* <h4 className="mb-0">Garettdon</h4>*/}
|
||||
{/* <p><span className="badge badge-primary-inverse px-2 py-1 mt-1">Office</span></p>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div>*/}
|
||||
{/* <ul className="nav">*/}
|
||||
{/* <li className="nav-item">*/}
|
||||
{/* <div className="img-icon"><i className="fa fa-mobile"></i></div>*/}
|
||||
{/* </li>*/}
|
||||
{/* <li className="nav-item">*/}
|
||||
{/* <p>026-123-8546</p>*/}
|
||||
{/* </li>*/}
|
||||
{/* </ul>*/}
|
||||
{/* <ul className="nav">*/}
|
||||
{/* <li className="nav-item">*/}
|
||||
{/* <div className="img-icon"><i className="fa fa-phone"></i></div>*/}
|
||||
{/* </li>*/}
|
||||
{/* <li className="nav-item">*/}
|
||||
{/* <p>80-1230-8546</p>*/}
|
||||
{/* </li>*/}
|
||||
{/* </ul>*/}
|
||||
{/* <ul className="nav">*/}
|
||||
{/* <li className="nav-item">*/}
|
||||
{/* <div className="img-icon"><i className="fa fa-envelope-o"></i></div>*/}
|
||||
{/* </li>*/}
|
||||
{/* <li className="nav-item">*/}
|
||||
{/* <p>Garettdon@gmail.com</p>*/}
|
||||
{/* </li>*/}
|
||||
{/* </ul>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/*</div>*/}
|
||||
{/*<div className="col-xxl-3 col-xl-4 col-sm-6">*/}
|
||||
{/* <div className="card card-statistics contact-contant">*/}
|
||||
{/* <div className="card-body py-4">*/}
|
||||
{/* <div className="d-flex align-items-center">*/}
|
||||
{/* <div className="bg-img">*/}
|
||||
{/* <img src="assets/img/avtar/04.jpg" alt="" className="img-fluid" />*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="ml-3">*/}
|
||||
{/* <h4 className="mb-0">Garynice</h4>*/}
|
||||
{/* <p><span className="badge badge-warning-inverse px-2 py-1 mt-1">Home</span></p>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div>*/}
|
||||
{/* <ul className="nav">*/}
|
||||
{/* <li className="nav-item">*/}
|
||||
{/* <div className="img-icon"><i className="fa fa-mobile"></i></div>*/}
|
||||
{/* </li>*/}
|
||||
{/* <li className="nav-item">*/}
|
||||
{/* <p>026-123-8546</p>*/}
|
||||
{/* </li>*/}
|
||||
{/* </ul>*/}
|
||||
{/* <ul className="nav">*/}
|
||||
{/* <li className="nav-item">*/}
|
||||
{/* <div className="img-icon"><i className="fa fa-phone"></i></div>*/}
|
||||
{/* </li>*/}
|
||||
{/* <li className="nav-item">*/}
|
||||
{/* <p>80-1230-8546</p>*/}
|
||||
{/* </li>*/}
|
||||
{/* </ul>*/}
|
||||
{/* <ul className="nav">*/}
|
||||
{/* <li className="nav-item">*/}
|
||||
{/* <div className="img-icon"><i className="fa fa-envelope-o"></i></div>*/}
|
||||
{/* </li>*/}
|
||||
{/* <li className="nav-item">*/}
|
||||
{/* <p>Garynice@gmail.com</p>*/}
|
||||
{/* </li>*/}
|
||||
{/* </ul>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/*</div>*/}
|
||||
{/*<div className="col-xxl-3 col-xl-4 col-sm-6">*/}
|
||||
{/* <div className="card card-statistics contact-contant">*/}
|
||||
{/* <div className="card-body py-4">*/}
|
||||
{/* <div className="d-flex align-items-center">*/}
|
||||
{/* <div className="bg-img">*/}
|
||||
{/* <img src="assets/img/avtar/05.jpg" alt="" className="img-fluid" />*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="ml-3">*/}
|
||||
{/* <h4 className="mb-0">Andrew nico</h4>*/}
|
||||
{/* <p><span className="badge badge-success-inverse px-2 py-1 mt-1">Friends</span></p>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div>*/}
|
||||
{/* <ul className="nav">*/}
|
||||
{/* <li className="nav-item">*/}
|
||||
{/* <div className="img-icon"><i className="fa fa-mobile"></i></div>*/}
|
||||
{/* </li>*/}
|
||||
{/* <li className="nav-item">*/}
|
||||
{/* <p>026-123-8546</p>*/}
|
||||
{/* </li>*/}
|
||||
{/* </ul>*/}
|
||||
{/* <ul className="nav">*/}
|
||||
{/* <li className="nav-item">*/}
|
||||
{/* <div className="img-icon"><i className="fa fa-phone"></i></div>*/}
|
||||
{/* </li>*/}
|
||||
{/* <li className="nav-item">*/}
|
||||
{/* <p>80-1230-8546</p>*/}
|
||||
{/* </li>*/}
|
||||
{/* </ul>*/}
|
||||
{/* <ul className="nav">*/}
|
||||
{/* <li className="nav-item">*/}
|
||||
{/* <div className="img-icon"><i className="fa fa-envelope-o"></i></div>*/}
|
||||
{/* </li>*/}
|
||||
{/* <li className="nav-item">*/}
|
||||
{/* <p>Andrew.nico@gmail.com</p>*/}
|
||||
{/* </li>*/}
|
||||
{/* </ul>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/*</div>*/}
|
||||
<div className="col-xxl-3 col-xl-4 col-sm-6">
|
||||
<div className="card card-statistics contact-contant">
|
||||
<div className="card-body py-4">
|
||||
|
||||
@@ -85,7 +85,13 @@
|
||||
}
|
||||
|
||||
.mail-contant .mail-f{
|
||||
position: absolute;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
@include desktop {
|
||||
position: absolute;
|
||||
}
|
||||
@include desktop-lg {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -588,11 +588,16 @@
|
||||
left: 0px;
|
||||
}
|
||||
}
|
||||
.show + .dropdown-menu{
|
||||
margin-top: 0;
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
.show{
|
||||
margin-top: 0!important;
|
||||
visibility: visible!important;
|
||||
opacity: 1!important;
|
||||
}
|
||||
// .show + .dropdown-menu{
|
||||
// margin-top: 0;
|
||||
// visibility: visible;
|
||||
// opacity: 1;
|
||||
// }
|
||||
// .show {
|
||||
// .dropdown-menu{
|
||||
// margin-top: 0;
|
||||
|
||||
@@ -10,6 +10,7 @@ body {
|
||||
outline:0;
|
||||
background:$body;
|
||||
color:$muted;
|
||||
font-weight: $font-regular;
|
||||
&.sidebar-mini {
|
||||
.app-main {
|
||||
padding-left:$sidebar-mini;
|
||||
|
||||
@@ -39,8 +39,7 @@ h6 {
|
||||
|
||||
p {
|
||||
color: $muted;
|
||||
font-weight: $font-regular;
|
||||
font-size: $font-base;
|
||||
font-size: $font-18;
|
||||
line-height: $line-md;
|
||||
}
|
||||
a {
|
||||
|
||||
@@ -35,13 +35,13 @@ $container-max-widths: (
|
||||
|
||||
// Colors
|
||||
$body : #f9f9fb;
|
||||
$primary : #8E54E9;
|
||||
$primary : #148399; //#8E54E9;
|
||||
$primary2 : #4776E6;
|
||||
$secondary : #a1a1a1;
|
||||
$light-gray : #eceef3;
|
||||
$dark-gray : #2c2e3e;
|
||||
$darker-gray : #333333;
|
||||
$muted : #a6a9b7;
|
||||
$muted : #6c757d; //#a6a9b7;
|
||||
$info : #45aaf2;
|
||||
$danger : #e3324c;
|
||||
$cyan : #2bcbba;
|
||||
@@ -75,7 +75,7 @@ $behance : #053eff;
|
||||
$whatsapp : #4FCE5D;
|
||||
|
||||
// Font family
|
||||
$font-primary : 'Roboto', sans-serif;
|
||||
$font-primary : 'Plus Jakarta Sans', sans-serif;
|
||||
|
||||
//Font size
|
||||
|
||||
|
||||
@@ -90,7 +90,18 @@ $today-highlight-bg: #fcf8e3;
|
||||
$btn-bg: #8e54e9;
|
||||
$btn-border: #8e54e9;
|
||||
$event-padding: 10px;
|
||||
|
||||
.manage{
|
||||
background-color:lightgreen !important;
|
||||
border-radius: 5px !important;
|
||||
}
|
||||
.creating{
|
||||
background-color: lightyellow !important;
|
||||
border-radius: 5px !important;
|
||||
}
|
||||
.billing{
|
||||
background-color: darkgoldenrod;
|
||||
color: white;
|
||||
}
|
||||
.extraProductCard{
|
||||
background-color: aliceblue;
|
||||
border-radius: 5px;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
// import './index.css';
|
||||
import { Provider } from 'react-redux';
|
||||
// import { Provider } from 'react-redux';
|
||||
// import store from './store/store'
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import store from './store/store'
|
||||
|
||||
import App from './App';
|
||||
//import reportWebVitals from './reportWebVitals';
|
||||
@@ -17,9 +17,7 @@ const root = ReactDOM.createRoot(document.getElementById('root'));
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<BrowserRouter>
|
||||
<Provider store={store}>
|
||||
<App />
|
||||
</Provider>
|
||||
<App />
|
||||
</BrowserRouter>
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
||||
@@ -1,18 +1,24 @@
|
||||
const siteLinks = {
|
||||
error: '*',
|
||||
help: '/help',
|
||||
home: '/',
|
||||
dash: '/dash',
|
||||
profile_complete: '/profile-complete',
|
||||
product: '/product/*',
|
||||
contacts: '/contacts',
|
||||
comments: '/comments',
|
||||
reports: '/reports',
|
||||
subscription: '/subscription',
|
||||
subscribe: '/subscribe',
|
||||
onboard: '/subscription',
|
||||
user: '/user',
|
||||
calendar: '/calendar',
|
||||
settings: '/settings',
|
||||
login: '/auth/login',
|
||||
signup: '/auth/signup',
|
||||
forgetpwd: '/auth/forgetpwd',
|
||||
csignup: '/csignup/:jwt'
|
||||
csignup: '/csignup/:jwt',
|
||||
accreset: '/accreset/:token'
|
||||
}
|
||||
|
||||
export default siteLinks
|
||||
@@ -1,12 +1,15 @@
|
||||
const queryKeys = {
|
||||
user_details: ['user_details'],
|
||||
product_url: ['product_url'],
|
||||
products: ['product-data'],
|
||||
myproduct_provision: ['myproduct_provision'],
|
||||
product_page: ['product_page'],
|
||||
recentAction: ['recent-action'],
|
||||
settingsData: ['settings_data'],
|
||||
subscriptions: ['subscriptions'],
|
||||
|
||||
dashboard: ['dashboard'],
|
||||
topBar: ['top-bar'],
|
||||
recentAction: ['recent-action'],
|
||||
product: ['product-data'],
|
||||
product_url: ['product_url'],
|
||||
myproduct_provision: ['myproduct_provision'],
|
||||
calendar_events: ['calendar_events'],
|
||||
contacts: ['contacts']
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ axios.interceptors.request.use(
|
||||
// "Access-Control-Expose-Headers": "Access-Control-Allow-Origin",
|
||||
// "Access-Control-Allow-Headers": "Origin, X-API-KEY, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method, Access-Control-Allow-Headers, Authorization, observe, enctype, Content-Length, X-Csrf-Token",
|
||||
// "Content-Type": "application/json;charset=UTF-8",
|
||||
'Authorization': (localStorage && localStorage.getItem('access_token')) ? `Bearer ${localStorage.getItem('access_token')}` : ''
|
||||
'Authorization': (localStorage && localStorage.getItem('access_token')) ? `Bearer ${localStorage.getItem('access_token')}` : '',
|
||||
// 'uuid': 'dummy'
|
||||
};
|
||||
// config.headers['Authorization'] = `Bearer ${localStorage.getItem('token')}`;
|
||||
// config.baseURL = process.env.REACT_APP_MAIN_API
|
||||
@@ -42,7 +43,7 @@ const getAuxEnd = (path, reqData= null) => {
|
||||
})
|
||||
}
|
||||
|
||||
// FUNCTION TO LOGIN USER IN
|
||||
// FUNCTION TO AUTHORIZE USER IN
|
||||
export const userToken = (reqData) => {
|
||||
let postData = {
|
||||
...reqData
|
||||
@@ -63,9 +64,133 @@ export const userInfo = (reqData) => {
|
||||
let postData = {
|
||||
...reqData
|
||||
}
|
||||
return postAuxEnd('/panel/Account', postData, false)
|
||||
return postAuxEnd('/panel/account', postData, false)
|
||||
}
|
||||
|
||||
// FUNCTION TO GET DASHBOARD TOP BAR SECTION
|
||||
export const topBar = (reqData) => {
|
||||
let postData = {
|
||||
...reqData,
|
||||
}
|
||||
return postAuxEnd(`/panel/account/bar`, postData, false)
|
||||
}
|
||||
|
||||
// FUNCTION TO GET PRODUCT BY ID
|
||||
export const MyProductData = (reqData) => {
|
||||
let postData = {
|
||||
...reqData,
|
||||
}
|
||||
return postAuxEnd(`/panel/myproduct/dash`, postData, false)
|
||||
}
|
||||
|
||||
// FUNCTION TO GET CALENDAR EVENTS
|
||||
export const getCalendarEvents = (reqData) => {
|
||||
let postData = {
|
||||
...reqData,
|
||||
}
|
||||
return postAuxEnd(`/panel/account/calendar`, postData, false)
|
||||
}
|
||||
|
||||
// FUNCTION TO GET DASHBOARD PRODUCT DATA SECTION
|
||||
export const contactData = (reqData) => {
|
||||
let postData = {
|
||||
...reqData,
|
||||
}
|
||||
return postAuxEnd(`/panel/contacts`, postData, false)
|
||||
}
|
||||
|
||||
// FUNCTION TO GET DASHBOARD PRODUCT URL DATA SECTION
|
||||
export const productsURL = (reqData) => {
|
||||
let postData = {
|
||||
...reqData,
|
||||
}
|
||||
return postAuxEnd(`/panel/account/products/url`, postData, false)
|
||||
}
|
||||
|
||||
// FUNCTION TO GET DASHBOARD PRODUCT DATA SECTION
|
||||
export const productsData = (reqData) => {
|
||||
let postData = {
|
||||
...reqData,
|
||||
}
|
||||
return postAuxEnd(`/panel/account/products`, postData, false)
|
||||
}
|
||||
|
||||
// FUNCTION TO REFRESH SITE
|
||||
export const productRefreshSite = (reqData) => {
|
||||
let postData = {
|
||||
...reqData,
|
||||
}
|
||||
return postAuxEnd(`/panel/account/products/refresh`, postData, false)
|
||||
}
|
||||
|
||||
// FUNCTION TO GET DASHBOARD RECENT ACTIONS SECTION
|
||||
export const recentActions = (reqData) => {
|
||||
let postData = {
|
||||
...reqData,
|
||||
token: localStorage.getItem('token'), // USER TOKEN
|
||||
uid: localStorage.getItem('uid') // USER UID
|
||||
}
|
||||
//return getAuxEnd(`/panel/account/actions`)
|
||||
return postAuxEnd(`/panel/account/actions`, postData, false)
|
||||
}
|
||||
|
||||
// FUNCTION TO VERIFY RESET TOKEN
|
||||
export const verifyResetToken = (reqData) => {
|
||||
let postData = {
|
||||
...reqData
|
||||
}
|
||||
return postAuxEnd('/panel/auth/resetverify', postData, false)
|
||||
}
|
||||
|
||||
// FUNCTION TO COMPLETE PASSWORD RESET
|
||||
export const completePWDReset = (reqData) => {
|
||||
let postData = {
|
||||
...reqData
|
||||
}
|
||||
return postAuxEnd('/panel/auth/resetcomplete', postData, false)
|
||||
}
|
||||
|
||||
// FUNCTION TO SUBMIT PAGE TAB SETTINGS
|
||||
export const pageSettings = (reqData) => {
|
||||
let postData = {
|
||||
...reqData,
|
||||
}
|
||||
return postAuxEnd(`/panel/myproduct/settings`, postData, false)
|
||||
}
|
||||
|
||||
// FUNCTION TO GET SETTINGS DATA
|
||||
export const getSettingsData = (reqData) => {
|
||||
let postData = {
|
||||
...reqData,
|
||||
}
|
||||
return postAuxEnd(`/panel/myproduct/settings/values`, postData, false)
|
||||
}
|
||||
|
||||
// FUNCTION TO GET PRODUCT SUBSCRIPTIONS
|
||||
export const completeProfile = (reqData) => {
|
||||
let postData = {
|
||||
...reqData,
|
||||
}
|
||||
return postAuxEnd(`/panel/account/startprofile`, postData, false)
|
||||
}
|
||||
|
||||
// FUNCTION TO COMPLETE PROFILE
|
||||
export const getSubscriptions = (reqData) => {
|
||||
let postData = {
|
||||
...reqData,
|
||||
}
|
||||
return postAuxEnd(`/panel/subscription/products`, postData, false)
|
||||
}
|
||||
|
||||
// FUNCTION TO GET COMMON PRACTICE
|
||||
export const getCommonPractice = (reqData) => {
|
||||
let postData = {
|
||||
...reqData,
|
||||
}
|
||||
return postAuxEnd(`/panel/common/practice`, postData, false)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -75,7 +200,7 @@ export const signUpUser = (reqData) => {
|
||||
let postData = {
|
||||
...reqData
|
||||
}
|
||||
return postAuxEnd('/panel/auth/register', postData, false)
|
||||
return postAuxEnd('/panel/Register', postData, false)
|
||||
}
|
||||
|
||||
// FUNCTION TO VERIFY EMAIL
|
||||
@@ -83,7 +208,7 @@ export const verifyEmail = (reqData) => {
|
||||
let postData = {
|
||||
...reqData
|
||||
}
|
||||
return postAuxEnd('/panel/auth/register/verify', postData, false)
|
||||
return postAuxEnd('/panel/Register/verify', postData, false)
|
||||
}
|
||||
|
||||
// FUNCTION TO COMPLETE REGISTRATION
|
||||
@@ -91,15 +216,17 @@ export const completeRegistration = (reqData) => {
|
||||
let postData = {
|
||||
...reqData
|
||||
}
|
||||
return postAuxEnd('/panel/auth/register/complete', postData, false)
|
||||
return postAuxEnd('/panel/Register/complete', postData, false)
|
||||
}
|
||||
|
||||
// FUNCTION TO SUBSCRIBE
|
||||
export const subscribe = (reqData) => {
|
||||
let postData = {
|
||||
...reqData
|
||||
...reqData,
|
||||
token: localStorage.getItem('token'), // USER TOKEN
|
||||
uid: localStorage.getItem('uid') // USER UID
|
||||
}
|
||||
return postAuxEnd('/panel/myproduct/subscription', postData, false)
|
||||
return postAuxEnd(`/panel/myproduct/subscription`, postData, false)
|
||||
}
|
||||
|
||||
|
||||
@@ -111,57 +238,14 @@ export const recoverPWD = (reqData) => {
|
||||
return postAuxEnd('/panel/auth/reset', postData, false)
|
||||
}
|
||||
|
||||
// FUNCTION TO GET DASHBOARD TOP BAR SECTION
|
||||
export const topBar = (reqData) => {
|
||||
let postData = {
|
||||
...reqData,
|
||||
// "token":"there-will-be-token",
|
||||
// "uid": "there-will-be-uid"
|
||||
}
|
||||
return postAuxEnd(`/panel/account-bar`, postData, false)
|
||||
}
|
||||
|
||||
// FUNCTION TO GET CALENDAR EVENTS
|
||||
export const getCalendarEvents = () => {
|
||||
// return getAuxEnd(`/panel/account/calendar`)
|
||||
let postData = {
|
||||
"a":"b"
|
||||
}
|
||||
return postAuxEnd(`/panel/account/calendar`, postData, false)
|
||||
}
|
||||
|
||||
// FUNCTION TO GET DASHBOARD RECENT ACTIONS SECTION
|
||||
export const recentActions = () => {
|
||||
//return getAuxEnd(`/panel/account/actions`)
|
||||
let postData = {
|
||||
"a":"b"
|
||||
}
|
||||
return postAuxEnd(`/panel/account/actions`, postData, false)
|
||||
}
|
||||
|
||||
// FUNCTION TO GET MY PRODUCT PROVISION DATA
|
||||
export const productProvision = (reqData) => {
|
||||
const postData = { ...reqData }
|
||||
return getAuxEnd(`/panel/myproduct/provision`, postData)
|
||||
let postData = {
|
||||
...reqData,
|
||||
token: localStorage.getItem('token'), // USER TOKEN
|
||||
uid: localStorage.getItem('uid') // USER UID
|
||||
}
|
||||
return postAuxEnd(`/panel/myproduct/provision`, postData, false)
|
||||
// return getAuxEnd(`/panel/myproduct/provision`, postData)
|
||||
}
|
||||
|
||||
// FUNCTION TO GET DASHBOARD PRODUCT DATA SECTION
|
||||
export const productData = () => {
|
||||
return getAuxEnd(`/panel/account/products`)
|
||||
}
|
||||
|
||||
// FUNCTION TO GET DASHBOARD PRODUCT DATA SECTION
|
||||
export const contactData = () => {
|
||||
return getAuxEnd(`/panel/contacts`)
|
||||
}
|
||||
|
||||
// FUNCTION TO GET DASHBOARD PRODUCT URL DATA SECTION
|
||||
export const productsURL = () => {
|
||||
return getAuxEnd(`/panel/account/products/url`)
|
||||
}
|
||||
|
||||
export const MyProductData = (productID) => {
|
||||
const reqData = { product_id : productID}
|
||||
//console.log(reqData)
|
||||
return getAuxEnd(`/panel/myproduct/dash`,reqData)
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
let getImage = (location) => {
|
||||
if (!location) {
|
||||
return require(`../assets/img/logo.png`);
|
||||
return require(`../assets/img/logo-pink.png`);
|
||||
} else {
|
||||
return require(`../assets/img/${location}`);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import AccPWDReset from '../component/auth/AccPWDReset'
|
||||
|
||||
export default function AccPWDResetPage() {
|
||||
return (
|
||||
<AccPWDReset />
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import HelpCom from '../component/help/HelpCom'
|
||||
|
||||
export default function HelpPage() {
|
||||
return (
|
||||
<HelpCom />
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
import Onboard from '../component/onboard/Onboard';
|
||||
|
||||
|
||||
export default function OnboardPage(){
|
||||
return <Onboard />
|
||||
}
|
||||
@@ -1,6 +1,23 @@
|
||||
import React from 'react'
|
||||
import React, { useEffect } from 'react'
|
||||
import ProductFactory from '../component/product/ProductFactory'
|
||||
import { useSelector } from 'react-redux';
|
||||
import siteLinks from '../links/siteLinks';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
|
||||
|
||||
export default function ProductPage() {
|
||||
|
||||
const navigate = useNavigate()
|
||||
let {pathname} = useLocation()
|
||||
|
||||
const { userDetails: { profile_completed }} = useSelector((state) => state?.userDetails); // CHECKS IF USER Details are avaliable, to determine if user is active
|
||||
|
||||
useEffect(()=>{
|
||||
if(!profile_completed){
|
||||
navigate(siteLinks.profile_complete, {replace: true, state:{redirectLink: pathname}})
|
||||
}
|
||||
},[])
|
||||
|
||||
return (
|
||||
<ProductFactory />
|
||||
)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import ProfileCompleteCom from '../component/profile_complete/ProfileCompleteCom';
|
||||
|
||||
export default function ProfileCompletePage(){
|
||||
return <ProfileCompleteCom />
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import React from 'react'
|
||||
//import Signup2 from '../component/auth/Signup2'
|
||||
import Subscribe from '../component/subscribe/Subscribe'
|
||||
|
||||
export default function SubscribePage() {
|
||||
return (
|
||||
<Subscribe />
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
import Subscription from '../component/subscription/Subscription';
|
||||
|
||||
|
||||
export default function SubscriptionPage(){
|
||||
return <Subscription />
|
||||
}
|
||||