Compare commits
85 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b39a7ab58c | |||
| ad90def3c9 | |||
| 737430bf04 | |||
| d371ada805 | |||
| b77f1d6213 | |||
| 64085c6be5 | |||
| 3f8b45b6d6 | |||
| 4b6c927efc | |||
| 8a8adcbbc7 | |||
| 706baadb33 | |||
| 58128fdd96 | |||
| 14e8b1b01d | |||
| 504bfbcae4 | |||
| ec47aa5f9c | |||
| 9267ded0f1 | |||
| 0b24ca650d | |||
| b535a656a0 | |||
| e69cc9130e | |||
| daafb66cbb | |||
| 3852468afe | |||
| d32204e08f | |||
| 8372209923 | |||
| 6c3f96d9a3 | |||
| c25acecb1a | |||
| 3f5ae4685e | |||
| a80298c824 | |||
| e9bc1c1318 | |||
| 2543a91b19 | |||
| 4c38b0a31f | |||
| 6ed396a34c | |||
| 465a480f02 | |||
| 4409ed45f3 | |||
| 470c94ae5e | |||
| 52fd4275e9 | |||
| 0dadaf00b0 | |||
| 0fbe0f4c3f | |||
| 464182e583 | |||
| 517886df7e | |||
| 3db5d56410 | |||
| 6c107c8000 | |||
| 225a3d36e4 | |||
| f66f92c58d | |||
| 599e8a7715 | |||
| 97b75e0d9b | |||
| 4bc985892e | |||
| c951f925d8 | |||
| 1681ca1437 | |||
| d2cb38f141 | |||
| 67d26f6ab0 | |||
| 72dc343d01 | |||
| 4969ad1ae4 | |||
| 9e33578ef2 | |||
| be6dab1ec9 | |||
| aae69ffd3b | |||
| 6294d7cafd | |||
| be483c9451 | |||
| 6559d00052 | |||
| 6f3ed362b7 | |||
| fe88a6d7f2 | |||
| 6adb6aed1f | |||
| 373c5427c2 | |||
| a9473debdb | |||
| e4eb445059 | |||
| 44b2e08006 | |||
| 17239f9ea8 | |||
| 519b6e5585 | |||
| 56fb97eda1 | |||
| 1abc998120 | |||
| 858dd39936 | |||
| 292c8409d6 | |||
| 45c457e210 | |||
| 1e7014172d | |||
| 98bf50fcde | |||
| 4385d8bec0 | |||
| d1c86ec9b2 | |||
| dae4862db2 | |||
| d80bb55205 | |||
| 3205d5627e | |||
| bfea6b956b | |||
| 4ec74ff895 | |||
| 84b4523154 | |||
| c19cfdd524 | |||
| 2476c491be | |||
| ece281ef8a | |||
| 8ae0de1004 |
@@ -1,4 +1,5 @@
|
|||||||
SKIP_PREFLIGHT_CHECK=true
|
REACT_APP_PANEL_NAME="MERMS Panel DEV"
|
||||||
|
SKIP_PREFLIGHT_CHECK=true
|
||||||
REACT_APP_NODE_ENV="development"
|
REACT_APP_NODE_ENV="development"
|
||||||
NODE_ENV="development"
|
NODE_ENV="development"
|
||||||
REACT_APP_SOCKET_URL="https://devsocket.mermsemr.com"
|
REACT_APP_SOCKET_URL="https://devsocket.mermsemr.com"
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
SKIP_PREFLIGHT_CHECK=true
|
REACT_APP_PANEL_NAME="MERMS Panel DEV"
|
||||||
|
SKIP_PREFLIGHT_CHECK=true
|
||||||
REACT_APP_NODE_ENV="development"
|
REACT_APP_NODE_ENV="development"
|
||||||
|
NODE_ENV="development"
|
||||||
REACT_APP_SOCKET_URL="https://devsocket.mermsemr.com"
|
REACT_APP_SOCKET_URL="https://devsocket.mermsemr.com"
|
||||||
REACT_APP_MAIN_API="https://devapi.mermsemr.com"
|
REACT_APP_MAIN_API="https://devapi.mermsemr.com"
|
||||||
|
REACT_APP_MAIN_API_LL="http://localhost:14700"
|
||||||
REACT_APP_MEDIA_SERVER="https://qa-media.mermsemr.com"
|
REACT_APP_MEDIA_SERVER="https://qa-media.mermsemr.com"
|
||||||
REACT_APP_MAIN_SOCKET="https://devsocket.mermsemr.com"
|
REACT_APP_MAIN_SOCKET="https://devsocket.mermsemr.com"
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
SKIP_PREFLIGHT_CHECK=true
|
REACT_APP_PANEL_NAME="MERMS Panel"
|
||||||
|
SKIP_PREFLIGHT_CHECK=true
|
||||||
REACT_APP_NODE_ENV="production"
|
REACT_APP_NODE_ENV="production"
|
||||||
NODE_ENV="production"
|
NODE_ENV="production"
|
||||||
REACT_APP_SOCKET_URL="https://socket.mermsemr.com"
|
REACT_APP_SOCKET_URL="https://socket.mermsemr.com"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
REACT_APP_PANEL_NAME="MERMS Panel QA"
|
||||||
SKIP_PREFLIGHT_CHECK=true
|
SKIP_PREFLIGHT_CHECK=true
|
||||||
REACT_APP_NODE_ENV="development"
|
REACT_APP_NODE_ENV="development"
|
||||||
NODE_ENV="development"
|
NODE_ENV="development"
|
||||||
|
|||||||
@@ -126,10 +126,10 @@ RUN apk add --no-cache --virtual .build-deps-yarn curl gnupg tar \
|
|||||||
# add app
|
# add app
|
||||||
COPY . ./
|
COPY . ./
|
||||||
|
|
||||||
# start app
|
# start appdpvle
|
||||||
# CMD ["npm","run", "start"]
|
#CMD ["npm","run", "start"]
|
||||||
|
|
||||||
# CMD ["yarn", "start"]
|
# CMD ["yarn", "start"]
|
||||||
|
|
||||||
# start app
|
# start app
|
||||||
CMD /bin/sh ./run.sh
|
CMD /bin/sh ./run.sh
|
||||||
|
|||||||
@@ -1,31 +1,35 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8"/>
|
||||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
<link rel="icon" href="%PUBLIC_URL%/favicon.ico"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||||
<meta name="theme-color" content="#000000" />
|
<meta name="theme-color" content="#000000"/>
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
content="Web site created using create-react-app"
|
content="Empowering Healthcare Decision-Making with Artificial Intelligence"
|
||||||
/>
|
/>
|
||||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png"/>
|
||||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
<link rel="manifest" href="%PUBLIC_URL%/manifest.json"/>
|
||||||
<title>MERMS-Panel</title>
|
<title>MERMS-Panel</title>
|
||||||
</head>
|
</head>
|
||||||
<!-- Google tag (gtag.js) -->
|
<!-- Google tag (gtag.js) -->
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Y9QSQFV003"></script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Y9QSQFV003"></script>
|
||||||
<script>
|
<script>
|
||||||
window.dataLayer = window.dataLayer || [];
|
window.dataLayer = window.dataLayer || [];
|
||||||
function gtag(){dataLayer.push(arguments);}
|
|
||||||
|
function gtag() {
|
||||||
|
dataLayer.push(arguments);
|
||||||
|
}
|
||||||
|
|
||||||
gtag('js', new Date());
|
gtag('js', new Date());
|
||||||
|
|
||||||
gtag('config', 'G-Y9QSQFV003');
|
gtag('config', 'G-Y9QSQFV003');
|
||||||
</script>
|
</script>
|
||||||
<body class="light-sidebar">
|
<body class="light-sidebar">
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
</body>
|
</body>
|
||||||
<!-- <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
|
<!-- <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script> -->
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script> -->
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -14,6 +14,10 @@
|
|||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.border-radius-10 {
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.login-links{
|
.login-links{
|
||||||
margin-top: 50px;
|
margin-top: 50px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Routes, Route } from 'react-router-dom';
|
import {Routes, Route} from 'react-router-dom';
|
||||||
|
|
||||||
import UserExist from './component/authorization/UserExist';
|
import UserExist from './component/authorization/UserExist';
|
||||||
import AuthLayout from './component/auth/AuthLayout';
|
import AuthLayout from './component/auth/AuthLayout';
|
||||||
@@ -23,47 +23,51 @@ import SubscriptionPage from './views/SubscriptionPage';
|
|||||||
import OnboardPage from "./views/OnboardPage";
|
import OnboardPage from "./views/OnboardPage";
|
||||||
import AccPWDResetPage from './views/AccPWDResetPage';
|
import AccPWDResetPage from './views/AccPWDResetPage';
|
||||||
import ProfileCompletePage from './views/ProfileCompletePage';
|
import ProfileCompletePage from './views/ProfileCompletePage';
|
||||||
import SubscribePage from './views/Subscribe'
|
import SubscribePage from './views/Subscribe'
|
||||||
|
import StartPage from "./views/StartPage";
|
||||||
|
import TrafficPage from "./views/TrafficPage";
|
||||||
|
|
||||||
function AppRouters() {
|
function AppRouters() {
|
||||||
return (
|
return (
|
||||||
<div className="">
|
<div className="">
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route element={<BearerToken />}>
|
<Route element={<BearerToken/>}>
|
||||||
{/* auth routes wrapper */}
|
{/* auth routes wrapper */}
|
||||||
<Route element={<AuthLayout />}>
|
<Route element={<AuthLayout/>}>
|
||||||
<Route path={siteLinks.home} element={<LoginPage />} />
|
<Route path={siteLinks.home} element={<LoginPage/>}/>
|
||||||
<Route path={siteLinks.login} element={<LoginPage />} />
|
<Route path={siteLinks.login} element={<LoginPage/>}/>
|
||||||
<Route path={siteLinks.signup} element={<SignupPage />} />
|
<Route path={siteLinks.signup} element={<SignupPage/>}/>
|
||||||
<Route path={siteLinks.forgetpwd} element={<ForgetpwdPage />} />
|
<Route path={siteLinks.forgetpwd} element={<ForgetpwdPage/>}/>
|
||||||
<Route path={siteLinks.csignup} element={<CSignupPage />} />
|
<Route path={siteLinks.csignup} element={<CSignupPage/>}/>
|
||||||
<Route path={siteLinks.accreset} element={<AccPWDResetPage />} />
|
<Route path={siteLinks.accreset} element={<AccPWDResetPage/>}/>
|
||||||
<Route path={siteLinks.error} element={<LoginPage />} />
|
<Route path={siteLinks.error} element={<LoginPage/>}/>
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
{/* protected routes */}
|
{/* protected routes */}
|
||||||
<Route element={<SocketIOContextProvider />}>
|
<Route element={<SocketIOContextProvider/>}>
|
||||||
<Route element={<UserExist />}>
|
<Route element={<UserExist/>}>
|
||||||
<Route path={siteLinks.dash} element={<HomePage />} />
|
<Route path={siteLinks.start} element={<StartPage/>}/>
|
||||||
<Route path={siteLinks.profile_complete} element={<ProfileCompletePage />} />
|
<Route path={siteLinks.dash} element={<HomePage/>}/>
|
||||||
<Route path={siteLinks.product} element={<ProductPage />} />
|
<Route path={siteLinks.traffic} element={<TrafficPage/>}/>
|
||||||
<Route path={siteLinks.reports} element={<ReportsPage />} />
|
<Route path={siteLinks.profile_complete} element={<ProfileCompletePage/>}/>
|
||||||
<Route path={siteLinks.comments} element={<CommentsPage />} />
|
<Route path={siteLinks.product} element={<ProductPage/>}/>
|
||||||
<Route path={siteLinks.contacts} element={<ContactsPage />} />
|
<Route path={siteLinks.reports} element={<ReportsPage/>}/>
|
||||||
<Route path={siteLinks.user} element={<UserPage />} />
|
<Route path={siteLinks.comments} element={<CommentsPage/>}/>
|
||||||
<Route path={siteLinks.subscription} element={<SubscriptionPage />} />
|
<Route path={siteLinks.contacts} element={<ContactsPage/>}/>
|
||||||
<Route path={siteLinks.subscription_success} element={<SubscriptionPage />} />
|
<Route path={siteLinks.user} element={<UserPage/>}/>
|
||||||
<Route path={siteLinks.onboard} element={<OnboardPage />} />
|
<Route path={siteLinks.subscription} element={<SubscriptionPage/>}/>
|
||||||
<Route path={siteLinks.calendar} element={<CalendarPage />} />
|
<Route path={siteLinks.subscription_success} element={<SubscriptionPage/>}/>
|
||||||
<Route path={siteLinks.settings} element={<SettingsPage />} />
|
<Route path={siteLinks.onboard} element={<OnboardPage/>}/>
|
||||||
<Route path={siteLinks.subscribe} element={<SubscribePage />} />
|
<Route path={siteLinks.calendar} element={<CalendarPage/>}/>
|
||||||
<Route path={siteLinks.help} element={<HelpPage />} />
|
<Route path={siteLinks.settings} element={<SettingsPage/>}/>
|
||||||
</Route>
|
<Route path={siteLinks.subscribe} element={<SubscribePage/>}/>
|
||||||
</Route>
|
<Route path={siteLinks.help} element={<HelpPage/>}/>
|
||||||
</Route>
|
</Route>
|
||||||
</Routes>
|
</Route>
|
||||||
</div>
|
</Route>
|
||||||
);
|
</Routes>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default AppRouters;
|
export default AppRouters;
|
||||||
|
|||||||
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 417 KiB |
@@ -66,7 +66,7 @@ export default function CSignup() {
|
|||||||
localStorage.setItem('room', room)
|
localStorage.setItem('room', room)
|
||||||
localStorage.setItem('uid', uid)
|
localStorage.setItem('uid', uid)
|
||||||
dispatch(updateUserDetails({ ...res?.data }));
|
dispatch(updateUserDetails({ ...res?.data }));
|
||||||
navigate('/dash') // later add redux to dispatch state
|
navigate(siteLinks.start, {replace: true}) // later add redux to dispatch state
|
||||||
},
|
},
|
||||||
// onError: (err) => {
|
// onError: (err) => {
|
||||||
// console.log('err', err)
|
// console.log('err', err)
|
||||||
@@ -100,7 +100,7 @@ export default function CSignup() {
|
|||||||
<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="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="mt-5 d-flex">
|
||||||
<div className="bg-white register p-5">
|
<div className="bg-white register p-5">
|
||||||
<h1 className="mb-2">MERMS Panel</h1>
|
<h1 className="mb-2">{process.env.REACT_APP_PANEL_NAME}</h1>
|
||||||
{/* <p>Welcome, Enter your password.</p> */}
|
{/* <p>Welcome, Enter your password.</p> */}
|
||||||
<div
|
<div
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export default function Forgetpwd2() {
|
|||||||
<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="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="mt-5 d-flex">
|
||||||
<div className="bg-white register p-5">
|
<div className="bg-white register p-5">
|
||||||
<h1 className="mb-2">MERMS Panel</h1>
|
<h1 className="mb-2">{process.env.REACT_APP_PANEL_NAME}</h1>
|
||||||
{!mutation.isSuccess && <p>Please enter your username.</p>}
|
{!mutation.isSuccess && <p>Please enter your username.</p>}
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export default function Login() {
|
|||||||
<div className="col-span-1 lg:col-span-2 xl:col-span-2 place-content-center order-2 sm:order-1">
|
<div className="col-span-1 lg:col-span-2 xl:col-span-2 place-content-center order-2 sm:order-1">
|
||||||
<div className="w-full p-4 px-8 md:p-10 flex flex-col gap-6 items-start justify-start">
|
<div className="w-full p-4 px-8 md:p-10 flex flex-col gap-6 items-start justify-start">
|
||||||
<div className='w-full text-left'>
|
<div className='w-full text-left'>
|
||||||
<h1 className="mb-2 text-black text-4xl font-semibold">MERMS Panel</h1>
|
<h1 className="mb-2 text-black text-4xl font-semibold">{process.env.REACT_APP_PANEL_NAME}</h1>
|
||||||
<p className='text-black-gray text-base'>Welcome back, please login to your account.</p>
|
<p className='text-black-gray text-base'>Welcome back, please login to your account.</p>
|
||||||
</div>
|
</div>
|
||||||
<form className="w-full text-14 text-left text-black-gray">
|
<form className="w-full text-14 text-left text-black-gray">
|
||||||
|
|||||||
@@ -86,20 +86,20 @@ export default function Login() {
|
|||||||
<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="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="mt-5 d-flex">
|
||||||
<div className="bg-white register px-5 pt-5 pb-3">
|
<div className="bg-white register px-5 pt-5 pb-3">
|
||||||
<h1 className="mb-2">MERMS Panel</h1>
|
<h1 className="mb-2">{process.env.REACT_APP_PANEL_NAME}</h1>
|
||||||
<p>Welcome back, please login to your account.</p>
|
<p>Welcome back, please login to your account.</p>
|
||||||
<form className="mt-3 mt-sm-5">
|
<form className="mt-3 mt-sm-5">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className="control-label text-black fw-bold">User Name*</label>
|
<label className="control-label text-black fw-bold">User Name*</label>
|
||||||
<input maxLength={55} name='username' value={fields.username} onChange={handleChange} type="text" className="form-control" placeholder="Username" />
|
<input maxLength={25} name='username' value={fields.username} onChange={handleChange} type="text" className="form-control" placeholder="Username" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className="control-label text-black fw-bold">Password*</label>
|
<label className="control-label text-black fw-bold">Password*</label>
|
||||||
<input maxLength={55} name='password' value={fields.password} onChange={handleChange} type="password" className="form-control" placeholder="Password" />
|
<input maxLength={25} name='password' value={fields.password} onChange={handleChange} type="password" className="form-control" placeholder="Password" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
@@ -124,10 +124,18 @@ export default function Login() {
|
|||||||
<button type='button' onClick={()=>{login.mutate(fields)}} className="btn btn-primary text-uppercase">{login.isPending ? 'loading...' : 'Sign In'}</button>
|
<button type='button' onClick={()=>{login.mutate(fields)}} className="btn btn-primary text-uppercase">{login.isPending ? 'loading...' : 'Sign In'}</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-12 mt-3">
|
<div className="col-12 mt-3">
|
||||||
<p>Don't have an account ?<Link to={siteLinks.signup}><span style={{fontWeight: 'bolder'}}>Sign Up</span></Link></p>
|
<p> <Link to={siteLinks.signup}>
|
||||||
|
{/*<span style={{fontWeight: 'bolder'}}>Sign Up</span>*/}
|
||||||
|
<button className="btn btn-warning text-uppercase">
|
||||||
|
Sign Up
|
||||||
|
</button>
|
||||||
|
</Link><span style={{paddingLeft: '5px' , fontWeight: 'bolder'}}> if you don't have an account yet.</span></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
<div className="row" style={{margin: '5px'}}>
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
<div className="row" style={{marginTop: '20px'}}>
|
<div className="row" style={{marginTop: '20px'}}>
|
||||||
<div className="col-6">
|
<div className="col-6">
|
||||||
<div className="app-store-icons-wrap text-center">
|
<div className="app-store-icons-wrap text-center">
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React, { useEffect, useState } from 'react'
|
import React, {useEffect, useState} from 'react'
|
||||||
import LoginImg from '../../assets/bg/login.svg'
|
import LoginImg from '../../assets/bg/login.svg'
|
||||||
import MainLoader from '../loaders/MainLoader'
|
import MainLoader from '../loaders/MainLoader'
|
||||||
import { Link, useNavigate } from 'react-router-dom'
|
import {Link, useNavigate} from 'react-router-dom'
|
||||||
import siteLinks from '../../links/siteLinks'
|
import siteLinks from '../../links/siteLinks'
|
||||||
import Label from '../Label'
|
import Label from '../Label'
|
||||||
import TextInput from '../inputs/TextInput'
|
import TextInput from '../inputs/TextInput'
|
||||||
@@ -9,89 +9,102 @@ import TextInput from '../inputs/TextInput'
|
|||||||
|
|
||||||
export default function Signup() {
|
export default function Signup() {
|
||||||
|
|
||||||
const [loading, setLoading] = useState(true)
|
const [loading, setLoading] = useState(true)
|
||||||
|
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(() => {
|
||||||
const timer = setTimeout(()=>{
|
const timer = setTimeout(() => {
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
},1000)
|
}, 1000)
|
||||||
|
|
||||||
return () => clearTimeout(timer)
|
return () => clearTimeout(timer)
|
||||||
},[])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-screen bg-white w-full flex justify-center items-center">
|
<div className="h-screen bg-white w-full flex justify-center items-center">
|
||||||
<div className="h-full w-full bg-white grid sm:grid-cols-2 lg:grid-cols-5 xl:grid-cols-8">
|
<div className="h-full w-full bg-white grid sm:grid-cols-2 lg:grid-cols-5 xl:grid-cols-8">
|
||||||
<div className="col-span-1 lg:col-span-2 xl:col-span-2 place-content-center order-2 sm:order-1">
|
<div className="col-span-1 lg:col-span-2 xl:col-span-2 place-content-center order-2 sm:order-1">
|
||||||
<div className="w-full p-4 px-8 md:p-10 flex flex-col gap-6 items-start justify-start">
|
<div className="w-full p-4 px-8 md:p-10 flex flex-col gap-6 items-start justify-start">
|
||||||
<div className='w-full text-left'>
|
<div className='w-full text-left'>
|
||||||
<h1 className="mb-2 text-black text-4xl font-semibold">MERMS Panel</h1>
|
<h1 className="mb-2 text-black text-4xl font-semibold">{process.env.REACT_APP_PANEL_NAME}</h1>
|
||||||
<p className='text-black-gray text-base'>Welcome, Please create your account.</p>
|
<p className='text-black-gray text-base'>Welcome, Please create your account.</p>
|
||||||
</div>
|
|
||||||
<form className="w-full text-14 text-left text-black-gray">
|
|
||||||
<div className="w-full flex flex-col gap-4 justify-start items-start">
|
|
||||||
<div className='w-full grid grid-cols-2 gap-8'>
|
|
||||||
<div className="w-full">
|
|
||||||
<div className="w-full flex flex-col gap-2">
|
|
||||||
<Label desc='First Name*' />
|
|
||||||
<TextInput type='text' placeholder='Firstname' />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="w-full">
|
|
||||||
<div className="w-full flex flex-col gap-2">
|
|
||||||
<Label desc='Last Name*' />
|
|
||||||
<TextInput type='text' placeholder='Lastname' />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="w-full">
|
|
||||||
<div className="w-full flex flex-col gap-2">
|
|
||||||
<Label desc='Email*' />
|
|
||||||
<TextInput type='text' placeholder='Email' />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="w-full">
|
|
||||||
<div className="w-full flex flex-col gap-2">
|
|
||||||
<Label desc='User Name*' />
|
|
||||||
<TextInput type='text' placeholder='Username' />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="w-full">
|
|
||||||
<div className="w-full flex flex-col gap-2">
|
|
||||||
<Label desc='Password*' />
|
|
||||||
<TextInput type='password' placeholder='Password' />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="w-full text-left">
|
|
||||||
<div className="flex justify-between items-center">
|
|
||||||
<div className="flex gap-2">
|
|
||||||
<input className="form-check-input" type="checkbox" id="gridCheck" />
|
|
||||||
<label className="font-semibold form-check-label" htmlFor="gridCheck">
|
|
||||||
I accept terms & policy
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="w-full mt-3">
|
|
||||||
<button onClick={()=>{navigate(siteLinks.home)}} className="bg-primary rounded-sm px-4 py-2 text-white font-medium uppercase">Sign Up</button>
|
|
||||||
</div>
|
|
||||||
<div className="mt-3">
|
|
||||||
<p className='font-medium'>Already have an account ?<Link to={siteLinks.login} className=' hover:text-primary'> Sign In</Link></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
<form className="w-full text-14 text-left text-black-gray">
|
||||||
|
<div className="w-full flex flex-col gap-4 justify-start items-start">
|
||||||
|
<div className='w-full grid grid-cols-2 gap-8'>
|
||||||
|
<div className="w-full">
|
||||||
|
<div className="w-full flex flex-col gap-2">
|
||||||
|
<Label desc='First Name*'/>
|
||||||
|
<TextInput type='text' placeholder='Firstname'/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="w-full">
|
||||||
|
<div className="w-full flex flex-col gap-2">
|
||||||
|
<Label desc='Last Name*'/>
|
||||||
|
<TextInput type='text' placeholder='Lastname'/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="w-full">
|
||||||
|
<div className="w-full flex flex-col gap-2">
|
||||||
|
<Label desc='Email*'/>
|
||||||
|
<TextInput type='text' placeholder='Email'/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="w-full">
|
||||||
|
<div className="w-full flex flex-col gap-2">
|
||||||
|
<Label desc='User Name*'/>
|
||||||
|
<TextInput type='text' placeholder='Username'/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="w-full">
|
||||||
|
<div className="w-full flex flex-col gap-2">
|
||||||
|
<Label desc='Password*'/>
|
||||||
|
<TextInput type='password' placeholder='Password'/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="w-full text-left">
|
||||||
|
<div className="flex justify-between items-center">
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<input className="form-check-input" type="checkbox" id="gridCheck"/>
|
||||||
|
<label className="font-semibold form-check-label" htmlFor="gridCheck">
|
||||||
|
I accept terms & policy of use.
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="w-full mt-3">
|
||||||
|
<button onClick={() => {
|
||||||
|
navigate(siteLinks.home)
|
||||||
|
}} className="bg-primary rounded-sm px-4 py-2 text-white font-medium uppercase">Sign
|
||||||
|
Up
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="mt-3">
|
||||||
|
<hr />
|
||||||
|
<p className='font-medium'>Already have an account ?
|
||||||
|
<Link to={siteLinks.login}
|
||||||
|
className='bg-secondary; hover:text-primary font-bold' style={{paddingRight: '10px'}}>
|
||||||
|
<button className="btn btn-warning text-uppercase">
|
||||||
|
Sign In
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div
|
||||||
<div className="bg-login_gradient h-full col-span-1 lg:col-span-3 xl:col-span-6 place-content-center order-1 sm:order-2">
|
className="bg-login_gradient h-full col-span-1 lg:col-span-3 xl:col-span-6 place-content-center order-1 sm:order-2">
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="w-2/3 mx-auto">
|
<div className="w-2/3 mx-auto">
|
||||||
<img className="w-[80%]" src={LoginImg} alt="" />
|
<img className="w-[80%]" src={LoginImg} alt=""/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,101 +1,119 @@
|
|||||||
import React, { useState } from 'react'
|
import React, {useState} from 'react'
|
||||||
import { Form, Formik } from "formik";
|
import {Form, Formik} from "formik";
|
||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
|
|
||||||
// import LoginImg from '../../assets/bg/login.svg'
|
// import LoginImg from '../../assets/bg/login.svg'
|
||||||
|
|
||||||
import { Link } from 'react-router-dom'
|
import {Link} from 'react-router-dom'
|
||||||
import siteLinks from '../../links/siteLinks'
|
import siteLinks from '../../links/siteLinks'
|
||||||
import { useMutation } from '@tanstack/react-query';
|
import {useMutation} from '@tanstack/react-query';
|
||||||
import { signUpUser } from '../../services/services';
|
import {signUpUser} from '../../services/services';
|
||||||
import getImage from '../../utils/getImage';
|
import getImage from '../../utils/getImage';
|
||||||
|
|
||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
email: Yup.string()
|
email: Yup.string()
|
||||||
.email("Wrong email format")
|
.email("Wrong email format")
|
||||||
// .matches(
|
// .matches(
|
||||||
// /^[^0-9][a-zA-Z0-9._%+-]+@[a-zA-Z]+(\.[a-zA-Z]+)+$/,
|
// /^[^0-9][a-zA-Z0-9._%+-]+@[a-zA-Z]+(\.[a-zA-Z]+)+$/,
|
||||||
// "Invalid email format"
|
// "Invalid email format"
|
||||||
// )
|
// )
|
||||||
.min(3, "Minimum 3 characters")
|
.min(3, "Minimum 3 characters")
|
||||||
.max(50, "Maximum 50 characters")
|
.max(50, "Maximum 50 characters")
|
||||||
.required("Email is required"),
|
.required("Email is required"),
|
||||||
firstname: Yup.string().required("Firstname is required"),
|
firstname: Yup.string().required("Firstname is required"),
|
||||||
lastname: Yup.string().required("Lastname is required"),
|
lastname: Yup.string().required("Lastname is required"),
|
||||||
isChecked: Yup.bool().oneOf([true], "Please accept the terms & policy"), // use bool instead of boolean
|
isChecked: Yup.bool().oneOf([true], "Please accept the terms & policy"), // use bool instead of boolean
|
||||||
// username: Yup.string().min(3, "Minimum 3 characters").max(50, "Maximum 50 characters").required("Email is required"),
|
// username: Yup.string().min(3, "Minimum 3 characters").max(50, "Maximum 50 characters").required("Email is required"),
|
||||||
// password: Yup.string().min(3, "Minimum 3 characters").max(50, "Maximum 50 characters").required("Email is required"),
|
// password: Yup.string().min(3, "Minimum 3 characters").max(50, "Maximum 50 characters").required("Email is required"),
|
||||||
})
|
})
|
||||||
|
|
||||||
const initialValues = {
|
const initialValues = {
|
||||||
email: '',
|
email: '',
|
||||||
firstname: '',
|
firstname: '',
|
||||||
lastname: '',
|
lastname: '',
|
||||||
isChecked: false,
|
isChecked: false,
|
||||||
// username: '',
|
// username: '',
|
||||||
// password: ''
|
// password: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Signup2() {
|
export default function Signup2() {
|
||||||
|
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationFn: (fields) => {
|
mutationFn: (fields) => {
|
||||||
return signUpUser(fields)
|
return signUpUser(fields)
|
||||||
},
|
},
|
||||||
onSuccess: (res) => {
|
onSuccess: (res) => {
|
||||||
console.log('res', res)
|
console.log('res', res)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const signUp = (values) => {
|
||||||
|
// helpers.resetForm()
|
||||||
|
// console.log('values', values, helpers)
|
||||||
|
delete values.isChecked
|
||||||
|
mutation.mutate(values)
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
const signUp = (values) => {
|
return (
|
||||||
// helpers.resetForm()
|
<div className="app">
|
||||||
// console.log('values', values, helpers)
|
<div className="app-wrap">
|
||||||
delete values.isChecked
|
<div className="app-contant">
|
||||||
mutation.mutate(values)
|
<div className="vh-100 bg-white custom-bg">
|
||||||
}
|
<div className="container-fluid p-0">
|
||||||
|
<div className="row no-gutters justify-content-center">
|
||||||
return (
|
<div className="col-11 col-sm-6 col-lg-5 col-xxl-4 align-self-center order-2 order-sm-1"
|
||||||
<div className="app">
|
style={{maxWidth: '520px'}}>
|
||||||
<div className="app-wrap">
|
<div className="mt-5 d-flex">
|
||||||
<div className="app-contant">
|
<div className="bg-white register p-5">
|
||||||
<div className="vh-100 bg-white custom-bg">
|
<h1 className="mb-2">{process.env.REACT_APP_PANEL_NAME}</h1>
|
||||||
<div className="container-fluid p-0">
|
<p>Welcome, Please create your account.</p>
|
||||||
<div className="row no-gutters justify-content-center">
|
<Formik
|
||||||
<div className="col-11 col-sm-6 col-lg-5 col-xxl-4 align-self-center order-2 order-sm-1" style={{maxWidth: '520px'}}>
|
initialValues={initialValues}
|
||||||
<div className="mt-5 d-flex">
|
validationSchema={validationSchema}
|
||||||
<div className="bg-white register p-5">
|
onSubmit={signUp}
|
||||||
<h1 className="mb-2">MERMS Panel</h1>
|
>
|
||||||
<p>Welcome, Please create your account.</p>
|
{(props) => {
|
||||||
<Formik
|
return (
|
||||||
initialValues={initialValues}
|
<Form className='mt-2 mt-sm-5'>
|
||||||
validationSchema={validationSchema}
|
<div className="row">
|
||||||
onSubmit={signUp}
|
{!mutation.isSuccess ?
|
||||||
>
|
<>
|
||||||
{(props) => {
|
<div className="col-12 col-md-6">
|
||||||
return (
|
<div className="form-group">
|
||||||
<Form className='mt-2 mt-sm-5'>
|
<label
|
||||||
<div className="row">
|
className={`text-black fw-bold control-label ${(props.errors.firstname && props.touched.firstname) && 'text-danger'}`}>First
|
||||||
{!mutation.isSuccess ?
|
Name*</label>
|
||||||
<>
|
<input type="text" name='firstname'
|
||||||
<div className="col-12 col-md-6">
|
className="form-control"
|
||||||
<div className="form-group">
|
placeholder="First Name"
|
||||||
<label className={`text-black fw-bold control-label ${(props.errors.firstname && props.touched.firstname) && 'text-danger'}`}>First Name*</label>
|
value={props.values.firstname}
|
||||||
<input type="text" name='firstname' className="form-control" placeholder="First Name" value={props.values.firstname} onChange={props.handleChange} />
|
onChange={props.handleChange}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-12 col-md-6">
|
<div className="col-12 col-md-6">
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className={`text-black fw-bold control-label ${(props.errors.lastname && props.touched.lastname) && 'text-danger'}`}>Last Name*</label>
|
<label
|
||||||
<input type="text" name='lastname' className="form-control" placeholder="Last Name" value={props.values.lastname} onChange={props.handleChange} />
|
className={`text-black fw-bold control-label ${(props.errors.lastname && props.touched.lastname) && 'text-danger'}`}>Last
|
||||||
</div>
|
Name*</label>
|
||||||
</div>
|
<input type="text" name='lastname'
|
||||||
<div className="col-12">
|
className="form-control"
|
||||||
<div className="form-group">
|
placeholder="Last Name"
|
||||||
<label className={`text-black fw-bold control-label ${(props.errors.email && props.touched.email) && 'text-danger'}`}>Email*</label>
|
value={props.values.lastname}
|
||||||
<input type="email" name='email' className="form-control" placeholder="Email" value={props.values.email} onChange={props.handleChange} />
|
onChange={props.handleChange}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* <div className="col-12">
|
<div className="col-12">
|
||||||
|
<div className="form-group">
|
||||||
|
<label
|
||||||
|
className={`text-black fw-bold control-label ${(props.errors.email && props.touched.email) && 'text-danger'}`}>Email*</label>
|
||||||
|
<input type="email" name='email'
|
||||||
|
className="form-control"
|
||||||
|
placeholder="Email"
|
||||||
|
value={props.values.email}
|
||||||
|
onChange={props.handleChange}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* <div className="col-12">
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className={`text-black fw-bold control-label ${(props.errors.username && props.touched.username) && 'text-danger'}`}>Username*</label>
|
<label className={`text-black fw-bold control-label ${(props.errors.username && props.touched.username) && 'text-danger'}`}>Username*</label>
|
||||||
<input type="text" name='username' className="form-control" placeholder="Username" value={props.values.username} onChange={props.handleChange} />
|
<input type="text" name='username' className="form-control" placeholder="Username" value={props.values.username} onChange={props.handleChange} />
|
||||||
@@ -107,62 +125,83 @@ export default function Signup2() {
|
|||||||
<input type="password" name='password' className="form-control" placeholder="Password" value={props.values.password} onChange={props.handleChange} />
|
<input type="password" name='password' className="form-control" placeholder="Password" value={props.values.password} onChange={props.handleChange} />
|
||||||
</div>
|
</div>
|
||||||
</div> */}
|
</div> */}
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
<div className="form-check">
|
<div className="form-check">
|
||||||
<input name='isChecked' className="form-check-input" type="checkbox" id="gridCheck" value={props.values.isChecked} onChange={props.handleChange} />
|
<input name='isChecked'
|
||||||
<label className="form-check-label" htmlFor="gridCheck">
|
className="form-check-input"
|
||||||
I accept terms & policy
|
type="checkbox" id="gridCheck"
|
||||||
</label>
|
value={props.values.isChecked}
|
||||||
</div>
|
onChange={props.handleChange}/>
|
||||||
<span className={`${(props.errors.isChecked && props.touched.isChecked) && 'text-danger'}`}>{props.errors.isChecked}</span>
|
<label className="form-check-label"
|
||||||
</div>
|
htmlFor="gridCheck">
|
||||||
|
I accept terms & policy
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
className={`${(props.errors.isChecked && props.touched.isChecked) && 'text-danger'}`}>{props.errors.isChecked}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
{mutation.error &&
|
{mutation.error &&
|
||||||
<>
|
<>
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
<p className='text-danger'>{mutation.error.message}</p>
|
<p className='text-danger'>{mutation.error.message}</p>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
|
||||||
|
<div className="col-12 mt-3 text-end">
|
||||||
|
<button type='submit'
|
||||||
|
className="btn btn-primary text-uppercase">{mutation.isPending ? 'loading...' : 'Sign up'}</button>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
|
:
|
||||||
|
<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'
|
||||||
|
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>
|
||||||
}
|
}
|
||||||
|
|
||||||
<div className="col-12 mt-3 text-end">
|
<div className="col-12 mt-3">
|
||||||
<button type='submit' className="btn btn-primary text-uppercase">{mutation.isPending ? 'loading...' : 'Sign up'}</button>
|
<p>Already have an account ?<Link
|
||||||
</div>
|
to={siteLinks.login}>
|
||||||
</>
|
<button
|
||||||
:
|
className="btn btn-warning text-uppercase">
|
||||||
<div className='col-12'>
|
Sign In
|
||||||
<div className="rounded-2 d-flex flex-column justify-content-between align-items-center" style={{backgroundColor: '#F2FAF7'}}>
|
</button>
|
||||||
<h4 className='p-4 text-black' style={{marginBottom: '-30px'}}>Check your email to continue.</h4>
|
</Link></p>
|
||||||
<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>
|
||||||
</div>
|
</div>
|
||||||
}
|
</Form>
|
||||||
|
);
|
||||||
<div className="col-12 mt-3">
|
}}
|
||||||
<p>Already have an account ?<Link to={siteLinks.login}> Sign In</Link></p>
|
</Formik>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</Form>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</Formik>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{/* <div className="signup-bg col-sm-6 col-xxl-9 col-lg-7 b-gradient o-hidden order-1 order-sm-2">
|
||||||
{/* <div className="signup-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="row align-items-center h-100">
|
||||||
<div className="col-7 mx-auto ">
|
<div className="col-7 mx-auto ">
|
||||||
<img className="img-fluid" src={LoginImg} alt="" />
|
<img className="img-fluid" src={LoginImg} alt="" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div> */}
|
</div> */}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,372 +1,349 @@
|
|||||||
import React from "react";
|
"use client";
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
|
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
|
||||||
import getImage from "../../utils/getImage";
|
import getImage from "../../utils/getImage";
|
||||||
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
import { commentsData } from "../../services/services";
|
||||||
|
import queryKeys from "../../services/queryKeys";
|
||||||
|
import getCustomTime from "../../utils/getCustomTime";
|
||||||
|
|
||||||
export default function Comments(){
|
export default function Comments() {
|
||||||
|
// const {data:contacts, isFetching, isError, error} = useQuery({
|
||||||
|
// queryKey: queryKeys.contacts,
|
||||||
|
// queryFn: () => contactData()
|
||||||
|
// })
|
||||||
|
|
||||||
return(
|
const [activeCategoryUID, setActiveCategoryUID] = useState("0"); // HOLDS VALUE OF THE ACTIVE CATEGORY
|
||||||
<>
|
|
||||||
<BreadcrumbComBS title='Comments' paths={['Dashboard', 'Comments']} />
|
const [activeContactUID, setActiveContactUID] = useState("");
|
||||||
<div className="row">
|
const [activeDetail, setActiveDetail] = useState([]);
|
||||||
{/*<div className="vh-100 col-12 flex align-items-center">Coming Soon</div>*/}
|
|
||||||
|
const [filteredContactData, setFiltererdContactData] = useState([]);
|
||||||
|
|
||||||
|
const getContactData = useMutation({
|
||||||
|
mutationFn: (reqData) => {
|
||||||
|
return commentsData(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);
|
||||||
|
let detail = contactsData.filter((item) => item.uid == uid);
|
||||||
|
setActiveDetail(detail);
|
||||||
|
};
|
||||||
|
|
||||||
|
const changeActiveCategoryUID = (id) => {
|
||||||
|
let filteredConData = [];
|
||||||
|
setActiveCategoryUID(id);
|
||||||
|
if (id == "0") {
|
||||||
|
filteredConData = contactsData;
|
||||||
|
} else {
|
||||||
|
filteredConData = contactsData.filter((item) => item.category == id);
|
||||||
|
}
|
||||||
|
setFiltererdContactData(filteredConData);
|
||||||
|
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="Comments" paths={["Dashboard", "Comments"]} />
|
||||||
|
{getContactData?.isPending ? (
|
||||||
|
<>
|
||||||
|
<div className="row">
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
<div className="card card-statistics mail-contant">
|
<p className="text-mute">Loading...</p>
|
||||||
<div className="card-body p-0">
|
|
||||||
<div className="row no-gutters">
|
|
||||||
<div className="col-md-4 col-xxl-2 col-md-4">
|
|
||||||
<div className="mail-sidebar">
|
|
||||||
<div className="row justify-content-center">
|
|
||||||
<div className="col-12">
|
|
||||||
<div className="text-center mail-sidebar-title px-4">
|
|
||||||
<a href="javascript:void(0)" className="btn btn-primary btn-block py-3 font-weight-bold font-18"><i className="fa fa-plus pl-2"></i></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="col-12">
|
|
||||||
<div className="px-4 py-4">
|
|
||||||
<ul className="pl-0">
|
|
||||||
<li className="py-2">
|
|
||||||
<a href="javascript:void(0)">
|
|
||||||
<span className="nav align-items-center">
|
|
||||||
<span>
|
|
||||||
<i className="fa fa-envelope-o text-primary pr-4"></i>
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
<span>Inbox</span>
|
|
||||||
</span>
|
|
||||||
<span className="nav-item ml-auto text-right">
|
|
||||||
<span className="badge badge-pill badge-primary float-right">0+</span>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li className="py-2">
|
|
||||||
<a href="javascript:void(0)">
|
|
||||||
<span className="nav align-items-center">
|
|
||||||
<span>
|
|
||||||
<i className="fa fa-paper-plane-o pr-4"></i>
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
<span>Sent Mail</span>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
<ul className="pl-0 mt-5">
|
|
||||||
<li className="py-2">
|
|
||||||
<a href="javascript:void(0)">
|
|
||||||
<span className="nav align-items-center">
|
|
||||||
<span>
|
|
||||||
<i className="fa fa-circle-o text-danger pr-4"></i>
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
<span>Personal</span>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li className="py-2">
|
|
||||||
<a href="javascript:void(0)">
|
|
||||||
<span className="nav align-items-center">
|
|
||||||
<span>
|
|
||||||
<i className="fa fa-circle-o pr-4 text-warning"></i>
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
<span>Work</span>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li className="py-2">
|
|
||||||
<a href="javascript:void(0)">
|
|
||||||
<span className="nav align-items-center">
|
|
||||||
<span>
|
|
||||||
<i className="fa fa-plus pr-4"></i>
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
<span>Add Category</span>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="col-md-8 col-xxl-4 border-md-t">
|
|
||||||
<div className="mail-content border-right border-n h-100">
|
|
||||||
<div className="mail-search border-bottom">
|
|
||||||
<div className="row align-items-center mx-0">
|
|
||||||
<div className="col-12">
|
|
||||||
<div className="form-group pt-3">
|
|
||||||
<input type="text" className="form-control" id="search" placeholder="Search.." />
|
|
||||||
<i className="fa fa-search"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="mail-msg scrollbar scroll_dark">
|
|
||||||
<div className="mail-msg-item">
|
|
||||||
<a href="javascript:void(0)">
|
|
||||||
<div className="media align-items-center">
|
|
||||||
<div className="mr-3">
|
|
||||||
<div className="bg-img">
|
|
||||||
<img src={getImage("avtar/01.jpg")} className="img-fluid" alt="user" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="w-100">
|
|
||||||
<div className="mail-msg-item-titel justify-content-between">
|
|
||||||
<p>Martin smith</p>
|
|
||||||
<p className="d-none d-xl-block">06:59 <span> PM </span></p>
|
|
||||||
</div>
|
|
||||||
<h5 className="mb-0 my-2">Saas Designer</h5>
|
|
||||||
<p>Since there is not an "all the above" category, I'll take the opportunity to enthusiastically congratulate you on the very high quality.</p>
|
|
||||||
<p className="d-xl-none">06:59 <span> PM </span></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div className="mail-msg-item">
|
|
||||||
<a href="javascript:void(0)">
|
|
||||||
<div className="media align-items-center">
|
|
||||||
<div className="mr-3">
|
|
||||||
<div className="bg-img">
|
|
||||||
<img src={getImage("avtar/02.jpg")} className="img-fluid" alt="user" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="w-100">
|
|
||||||
<div className="mail-msg-item-titel justify-content-between">
|
|
||||||
<p>DutcaPatrick</p>
|
|
||||||
<p className="d-none d-xl-block">06:59 <span> PM </span></p>
|
|
||||||
</div>
|
|
||||||
<h5 className="mb-0 my-2">Mobile app Designer </h5>
|
|
||||||
<p>Very nice template, lots of pages and good documentation.</p>
|
|
||||||
<p className="d-xl-none">06:59 <span> PM </span></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div className="mail-msg-item">
|
|
||||||
<a href="javascript:void(0)">
|
|
||||||
<div className="media align-items-center">
|
|
||||||
<div className="mr-3">
|
|
||||||
<div className="bg-img">
|
|
||||||
<img src={getImage("avtar/03.jpg")} className="img-fluid" alt="user" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="w-100">
|
|
||||||
<div className="mail-msg-item-titel justify-content-between">
|
|
||||||
<p>m_morsch</p>
|
|
||||||
<p className="d-none d-xl-block">06:59 <span> PM </span></p>
|
|
||||||
</div>
|
|
||||||
<h5 className="mb-0 my-2">Landing page Designer</h5>
|
|
||||||
<p>Excellent and at a great price... thank you very much!</p>
|
|
||||||
<p className="d-xl-none">06:59 <span> PM </span></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div className="mail-msg-item">
|
|
||||||
<a href="javascript:void(0)">
|
|
||||||
<div className="media align-items-center">
|
|
||||||
<div className="mr-3">
|
|
||||||
<div className="bg-img">
|
|
||||||
<img src={getImage("avtar/04.jpg")} className="img-fluid" alt="user" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="w-100">
|
|
||||||
<div className="mail-msg-item-titel justify-content-between">
|
|
||||||
<p>AnnaHorno</p>
|
|
||||||
<p className="d-none d-xl-block">06:59 <span> PM </span></p>
|
|
||||||
</div>
|
|
||||||
<h5 className="mb-0 my-2">Re-Design ios app</h5>
|
|
||||||
<p>Solved my theme problem in 10 minutes. We thank you.</p>
|
|
||||||
<p className="d-xl-none">06:59 <span> PM </span></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div className="mail-msg-item">
|
|
||||||
<a href="javascript:void(0)">
|
|
||||||
<div className="media align-items-center">
|
|
||||||
<div className="mr-3">
|
|
||||||
<div className="bg-img">
|
|
||||||
<img src={getImage("avtar/05.jpg")} className="img-fluid" alt="user" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="w-100">
|
|
||||||
<div className="mail-msg-item-titel justify-content-between">
|
|
||||||
<p>Wdcorbitt</p>
|
|
||||||
<p className="d-none d-xl-block">06:59 <span> PM </span></p>
|
|
||||||
</div>
|
|
||||||
<h5 className="mb-0 my-2">Mobil UX/UI Designer</h5>
|
|
||||||
<p>Asked for information and received it EXTREMELY quickly. Great layout - good code - great price! </p>
|
|
||||||
<p className="d-xl-none">06:59 <span> PM </span></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div className="mail-msg-item">
|
|
||||||
<a href="javascript:void(0)">
|
|
||||||
<div className="media align-items-center">
|
|
||||||
<div className="mr-3">
|
|
||||||
<div className="bg-img">
|
|
||||||
<img src={getImage("avtar/06.jpg")} className="img-fluid" alt="user" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="w-100">
|
|
||||||
<div className="mail-msg-item-titel justify-content-between">
|
|
||||||
<p>Anne Smith</p>
|
|
||||||
<p className="d-none d-xl-block">06:59 <span> PM </span></p>
|
|
||||||
</div>
|
|
||||||
<h5 className="mb-0 my-2">Jobly Opportunity</h5>
|
|
||||||
<p>Mentor has so many features and layouts. Its a great choice.</p>
|
|
||||||
<p className="d-xl-none">06:59 <span> PM </span></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div className="mail-msg-item">
|
|
||||||
<a href="javascript:void(0)">
|
|
||||||
<div className="media align-items-center">
|
|
||||||
<div className="mr-3">
|
|
||||||
<div className="bg-img">
|
|
||||||
<img src={getImage("avtar/07.jpg")} className="img-fluid" alt="user" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="w-100">
|
|
||||||
<div className="mail-msg-item-titel justify-content-between">
|
|
||||||
<p>Paul Flavius</p>
|
|
||||||
<p className="d-none d-xl-block">06:59 <span> PM </span></p>
|
|
||||||
</div>
|
|
||||||
<h5 className="mb-0 my-2">Saas Designer</h5>
|
|
||||||
<p>There are many people in the world with amazing talents who realize only a small percentage of their potential. </p>
|
|
||||||
<p className="d-xl-none">06:59 <span> PM </span></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div className="mail-msg-item">
|
|
||||||
<a href="javascript:void(0)">
|
|
||||||
<div className="media align-items-center">
|
|
||||||
<div className="mr-3">
|
|
||||||
<div className="bg-img">
|
|
||||||
<img src={getImage("avtar/08.jpg")} className="img-fluid" alt="user" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="w-100">
|
|
||||||
<div className="mail-msg-item-titel justify-content-between">
|
|
||||||
<p>Sara Lisbon</p>
|
|
||||||
<p className="d-none d-xl-block">06:59 <span> PM </span></p>
|
|
||||||
</div>
|
|
||||||
<h5 className="mb-0 my-2">UI Designer</h5>
|
|
||||||
<p>We can look a bit further back in time to Albert Einstein or even further back to Abraham Lincoln.</p>
|
|
||||||
<p className="d-xl-none">06:59 <span> PM </span></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div className="mail-msg-item">
|
|
||||||
<a href="javascript:void(0)">
|
|
||||||
<div className="media align-items-center">
|
|
||||||
<div className="mr-3">
|
|
||||||
<div className="bg-img">
|
|
||||||
<img src={getImage("avtar/09.jpg")} className="img-fluid" alt="user" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="w-100">
|
|
||||||
<div className="mail-msg-item-titel justify-content-between">
|
|
||||||
<p>Annahorno</p>
|
|
||||||
<p className="d-none d-xl-block">06:59 <span> PM </span></p>
|
|
||||||
</div>
|
|
||||||
<h5 className="mb-0 my-2">Saas Designer</h5>
|
|
||||||
<p>One of the most difficult aspects of achieving success is staying motivated over the long haul.</p>
|
|
||||||
<p className="d-xl-none">06:59 <span> PM </span></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="col-xxl-6 border-t border-xxl-t">
|
|
||||||
<div className="mail-chat py-5 px-5">
|
|
||||||
<div className="media align-items-center">
|
|
||||||
<div className="bg-img mr-3">
|
|
||||||
<img src={getImage("avtar/03.jpg")} className="img-fluid" alt="user" />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h4 className="mb-0">Dutca Patrick</h4>
|
|
||||||
<p>30 Min ago</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="mt-4 d-flex justify-content-between">
|
|
||||||
<div>
|
|
||||||
<h3>Landing page Designer...</h3>
|
|
||||||
</div>
|
|
||||||
<div className="d-flex">
|
|
||||||
{/*<a href="javascript:void(0)"><i className="fa fa-reply font-22 pr-3"></i></a>*/}
|
|
||||||
{/*<a href="javascript:void(0)"><i className="fa fa-print font-22"></i></a>*/}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<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>
|
|
||||||
<p>We know this in our gut, but what can we do about it? How can we motivate ourselves? One of the most difficult aspects of achieving success is staying motivated over the long haul.</p>
|
|
||||||
<div className="my-5">
|
|
||||||
<p>Have lovely Day,</p>
|
|
||||||
<p>adminjon</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/*<div className="d-md-flex px-5 py-4">*/}
|
|
||||||
{/* <div className="flex-fill align-items-center">*/}
|
|
||||||
{/* <div className="d-flex">*/}
|
|
||||||
{/* <i className="ti ti-clip pr-3 font-22"></i>*/}
|
|
||||||
{/* <p className="pr-3 font-weight-bold">Wireframe</p>*/}
|
|
||||||
{/* <p>(220.MB)</p>*/}
|
|
||||||
{/* </div>*/}
|
|
||||||
{/* </div>*/}
|
|
||||||
{/* <div className="flex-fill text-left text-md-right"><a href="javascript:void(0)" className="text-primary"><i className="ti ti-download pr-2"></i><span>Download</span></a></div>*/}
|
|
||||||
{/*</div>*/}
|
|
||||||
<div className="bg-light mail-f px-4 py-3">
|
|
||||||
<div className="py-2 bg-white px-4 py-3 d-flex justify-content-between">
|
|
||||||
<p>Click here to <a href="#editer" data-toggle="collapse" className="text-primary px-1">Reply</a>or<a href="#forward" data-toggle="collapse" className="text-primary px-1">Forward</a></p>
|
|
||||||
<a href="javascript:void(0)" className="text-primary"><i className="fa fa-microphone"></i></a>
|
|
||||||
</div>
|
|
||||||
<div className="collapse" id="editer">
|
|
||||||
<div className="form-group">
|
|
||||||
<textarea className="form-control mt-3" id="exampleFormControlTextarea1" rows="3" placeholder="Type here..."></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="collapse" id="forward">
|
|
||||||
<div className="form-group">
|
|
||||||
<input className="form-control mt-3" id="exampleFormControl" placeholder="Email Address" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="d-flex align-items-center justify-content-between py-2">
|
|
||||||
<div>
|
|
||||||
<ul className="nav">
|
|
||||||
<li className="nav-item pr-3"><a href="javascript:void(0)"><i className="ti ti-clip font-20"></i></a></li>
|
|
||||||
<li className="nav-item pr-3"><a href="javascript:void(0)"><i className="ti ti-face-smile font-20"></i></a></li>
|
|
||||||
<li className="nav-item"><a href="javascript:void(0)"><i className="ti ti-gallery font-20"></i></a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<a href="javascript:void(0)" className="btn btn-primary"><span>Send</span> <i className="fa fa-paper-plane"></i></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
) : getContactData?.error ? (
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-12">
|
||||||
|
<p className="text-danger">{getContactData?.error?.message}</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
) : (
|
||||||
)
|
<div className="row">
|
||||||
}
|
{/*<div className="vh-100 col-12 flex align-items-center">Coming Soon</div>*/}
|
||||||
|
<div className="col-12">
|
||||||
|
<div
|
||||||
|
className="card card-statistics mail-contant"
|
||||||
|
style={{ minHeight: "200px", borderRadius: "10px" }}
|
||||||
|
>
|
||||||
|
<div className="card-body p-0">
|
||||||
|
<div className="row no-gutters">
|
||||||
|
<div className="col-md-4 col-xxl-2 col-md-4">
|
||||||
|
<div className="mail-sidebar">
|
||||||
|
<div className="row justify-content-center">
|
||||||
|
<div className="d-none col-12">
|
||||||
|
<div className="text-center mail-sidebar-title px-4">
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
className="btn btn-primary btn-block py-3 font-weight-bold font-18"
|
||||||
|
>
|
||||||
|
<i className="fa fa-plus pl-2"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-12">
|
||||||
|
<div className="px-4 py-4">
|
||||||
|
<ul className="pl-0">
|
||||||
|
<li className="py-2">
|
||||||
|
<a href="#">
|
||||||
|
<span className="nav align-items-center">
|
||||||
|
<span>
|
||||||
|
<i className="fa fa-envelope-o text-primary pr-4"></i>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<span>Inbox</span>
|
||||||
|
</span>
|
||||||
|
<span className="nav-item ml-auto text-right">
|
||||||
|
<span className="badge badge-pill badge-primary float-right">
|
||||||
|
{contactsData?.length}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{/*<li className="py-2">*/}
|
||||||
|
{/* <a href="#">*/}
|
||||||
|
{/* <span*/}
|
||||||
|
{/* className="nav align-items-center">*/}
|
||||||
|
{/* <span>*/}
|
||||||
|
{/* <i className="fa fa-paper-plane-o pr-4"></i>*/}
|
||||||
|
{/* </span>*/}
|
||||||
|
{/* <span>*/}
|
||||||
|
{/* <span>Replied Mail</span>*/}
|
||||||
|
{/* </span>*/}
|
||||||
|
{/* </span>*/}
|
||||||
|
{/* </a>*/}
|
||||||
|
{/*</li>*/}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul className="pl-0 mt-5">
|
||||||
|
<li
|
||||||
|
className="py-2"
|
||||||
|
onClick={() => changeActiveCategoryUID("0")}
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<span className="nav align-items-center">
|
||||||
|
<span>
|
||||||
|
<i
|
||||||
|
className={`fa fa-circle-o pr-4 ${
|
||||||
|
activeCategoryUID == "0"
|
||||||
|
? "text-primary"
|
||||||
|
: "text-warning"
|
||||||
|
}`}
|
||||||
|
></i>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<span>All</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{contactsCategory &&
|
||||||
|
contactsCategory.map((item) => (
|
||||||
|
<li
|
||||||
|
key={item?.cid}
|
||||||
|
className="py-2"
|
||||||
|
onClick={() =>
|
||||||
|
changeActiveCategoryUID(`${item?.cid}`)
|
||||||
|
}
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<span className="nav align-items-center">
|
||||||
|
<span>
|
||||||
|
<i
|
||||||
|
className={`fa fa-circle-o pr-4 ${
|
||||||
|
activeCategoryUID ==
|
||||||
|
`${item?.cid}`
|
||||||
|
? "text-primary"
|
||||||
|
: "text-warning"
|
||||||
|
}`}
|
||||||
|
></i>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<span>{item?.description}</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={`${filteredContactData.length > 0 ? 'col-md-8 col-xxl-4' : 'col-md-8 col-xxl-10'} border-md-t`}>
|
||||||
|
<div className="mail-content border-right border-n h-100" style={{placeContent: 'center'}}>
|
||||||
|
{/* <div className="mail-search border-bottom">
|
||||||
|
<div className="row align-items-center mx-0">
|
||||||
|
<div className="col-12">
|
||||||
|
<div className="form-group pt-3">
|
||||||
|
<input type="text" className="form-control" id="search" placeholder="Search.." />
|
||||||
|
<i className="fa fa-search"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div> */}
|
||||||
|
<div className="mail-msg scrollbar scroll_dark">
|
||||||
|
{ filteredContactData.length ?
|
||||||
|
filteredContactData?.map((contact, index) => {
|
||||||
|
const isActive =
|
||||||
|
contact?.uid == activeContactUID ||
|
||||||
|
(!activeContactUID && index == 0);
|
||||||
|
const avtarImage =
|
||||||
|
contact?.category === undefined
|
||||||
|
? "avtar/01.jpg"
|
||||||
|
: "avtar/" + contact.category + ".png";
|
||||||
|
return (
|
||||||
|
<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">
|
||||||
|
<div className="bg-img">
|
||||||
|
<img
|
||||||
|
src={getImage(avtarImage)}
|
||||||
|
className="img-fluid"
|
||||||
|
alt="user"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="w-100">
|
||||||
|
<div className="mail-msg-item-titel justify-content-between">
|
||||||
|
<p>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
fontSize: "14px",
|
||||||
|
color: "#148399",
|
||||||
|
fontWeight: "bolder",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{contact?.sender}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
{/* <p className="d-none d-xl-block">06:59 <span> PM </span></p> */}
|
||||||
|
<p className="d-none d-xl-block">
|
||||||
|
<span style={{ fontSize: "14px" }}>
|
||||||
|
{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>
|
||||||
|
<p className="d-xl-none">
|
||||||
|
<span>
|
||||||
|
{new Date(
|
||||||
|
contact?.added
|
||||||
|
).toDateString()}
|
||||||
|
{/* {getCustomTime(contact.added)} */}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
:
|
||||||
|
<p className="text-center">Messages will appear here as soon as they are available for selection</p>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{filteredContactData.length > 0 &&
|
||||||
|
<div className="col-xxl-6 border-t border-xxl-t">
|
||||||
|
<div className="mail-chat py-5 px-5">
|
||||||
|
<div className="media align-items-center">
|
||||||
|
<div className="bg-img mr-3">
|
||||||
|
<img
|
||||||
|
src={activeContactUID ? getImage("avtar/" + activeDetail[0].category + ".png") : getImage(filteredContactData[0] == undefined ? "avtar/01.jpg": "avtar/" + filteredContactData[0].category + ".png")}
|
||||||
|
className="img-fluid"
|
||||||
|
alt="user"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4 className="mb-0" style={{ color: "#148399" }}>
|
||||||
|
{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
|
||||||
|
: 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>*/}
|
||||||
|
{/*<a href="javascript:void(0)"><i className="fa fa-print font-22"></i></a>*/}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{activeContactUID
|
||||||
|
? activeDetail[0]?.message
|
||||||
|
: filteredContactData[0]?.message}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
"use client"
|
"use client";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
|
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
|
||||||
import getImage from "../../utils/getImage";
|
import getImage from "../../utils/getImage";
|
||||||
@@ -7,303 +7,343 @@ import { contactData } from "../../services/services";
|
|||||||
import queryKeys from "../../services/queryKeys";
|
import queryKeys from "../../services/queryKeys";
|
||||||
import getCustomTime from "../../utils/getCustomTime";
|
import getCustomTime from "../../utils/getCustomTime";
|
||||||
|
|
||||||
export default function Contacts(){
|
export default function Contacts() {
|
||||||
|
// const {data:contacts, isFetching, isError, error} = useQuery({
|
||||||
|
// queryKey: queryKeys.contacts,
|
||||||
|
// queryFn: () => contactData()
|
||||||
|
// })
|
||||||
|
|
||||||
// const {data:contacts, isFetching, isError, error} = useQuery({
|
const [activeCategoryUID, setActiveCategoryUID] = useState("0"); // HOLDS VALUE OF THE ACTIVE CATEGORY
|
||||||
// queryKey: queryKeys.contacts,
|
|
||||||
// queryFn: () => contactData()
|
|
||||||
// })
|
|
||||||
|
|
||||||
const [activeCategoryUID, setActiveCategoryUID] = useState('0') // HOLDS VALUE OF THE ACTIVE CATEGORY
|
const [activeContactUID, setActiveContactUID] = useState("");
|
||||||
|
const [activeDetail, setActiveDetail] = useState([]);
|
||||||
|
|
||||||
const [activeContactUID, setActiveContactUID] = useState('')
|
const [filteredContactData, setFiltererdContactData] = useState([]);
|
||||||
const [activeDetail, setActiveDetail] = useState([])
|
|
||||||
|
|
||||||
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) => {
|
||||||
const getContactData = useMutation({
|
setActiveContactUID(uid);
|
||||||
mutationFn: (reqData) => {
|
let detail = contactsData.filter((item) => item.uid == uid);
|
||||||
return contactData(reqData)
|
setActiveDetail(detail);
|
||||||
},
|
};
|
||||||
onError: (error) => {
|
|
||||||
console.log(error)
|
|
||||||
},
|
|
||||||
onSuccess: (res) => {
|
|
||||||
if(res?.data?.resultCode != '0'){
|
|
||||||
throw({message: 'Something went wrong'})
|
|
||||||
}
|
|
||||||
setFiltererdContactData(res?.data?.contacts)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const changeActiveUID = (uid) => {
|
const changeActiveCategoryUID = (id) => {
|
||||||
setActiveContactUID(uid)
|
let filteredConData = [];
|
||||||
let detail = contactsData.filter(item => item.uid == uid)
|
setActiveCategoryUID(id);
|
||||||
setActiveDetail(detail)
|
if (id == "0") {
|
||||||
|
filteredConData = contactsData;
|
||||||
|
} else {
|
||||||
|
filteredConData = contactsData.filter((item) => item.category == id);
|
||||||
}
|
}
|
||||||
|
setFiltererdContactData(filteredConData);
|
||||||
|
changeActiveUID(filteredConData[0]?.uid);
|
||||||
|
};
|
||||||
|
|
||||||
const changeActiveCategoryUID = (id) => {
|
useEffect(() => {
|
||||||
let filteredConData = []
|
|
||||||
setActiveCategoryUID(id)
|
|
||||||
if(id == '0'){
|
|
||||||
filteredConData = contactsData
|
|
||||||
}else{
|
|
||||||
filteredConData = contactsData.filter(item => item.category == id)
|
|
||||||
}
|
|
||||||
setFiltererdContactData(filteredConData)
|
|
||||||
changeActiveUID(filteredConData[0]?.uid)
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(()=>{
|
|
||||||
let reqData = {
|
let reqData = {
|
||||||
token: localStorage.getItem('token'), // USER TOKEN
|
token: localStorage.getItem("token"), // USER TOKEN
|
||||||
uid: localStorage.getItem('uid') // USER UID
|
uid: localStorage.getItem("uid"), // USER UID
|
||||||
}
|
};
|
||||||
getContactData.mutate(reqData)
|
getContactData.mutate(reqData);
|
||||||
},[])
|
}, []);
|
||||||
|
|
||||||
const contactsData = getContactData?.data?.data?.contacts // LIST OF CONTACTS
|
const contactsData = getContactData?.data?.data?.contacts; // LIST OF CONTACTS
|
||||||
const contactsCategory = getContactData?.data?.data?.category // LIST OF CATEGORY
|
const contactsCategory = getContactData?.data?.data?.category; // LIST OF CATEGORY
|
||||||
|
|
||||||
return(
|
return (
|
||||||
|
<>
|
||||||
|
<BreadcrumbComBS title="Contacts" paths={["Dashboard", "Contacts"]} />
|
||||||
|
{getContactData?.isPending ? (
|
||||||
<>
|
<>
|
||||||
<BreadcrumbComBS title='Contacts' paths={['Dashboard', 'Contacts']} />
|
<div className="row">
|
||||||
{getContactData?.isPending ?
|
<div className="col-12">
|
||||||
<>
|
<p className="text-mute">Loading...</p>
|
||||||
<div className="row">
|
</div>
|
||||||
<div className="col-12">
|
</div>
|
||||||
<p className='text-mute'>Loading...</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
: getContactData?.error ?
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-12">
|
|
||||||
<p className='text-danger'>{getContactData?.error?.message}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
:
|
|
||||||
<div className="row">
|
|
||||||
{/*<div className="vh-100 col-12 flex align-items-center">Coming Soon</div>*/}
|
|
||||||
<div className="col-12">
|
|
||||||
<div className="card card-statistics mail-contant">
|
|
||||||
<div className="card-body p-0">
|
|
||||||
<div className="row no-gutters">
|
|
||||||
<div className="col-md-4 col-xxl-2 col-md-4">
|
|
||||||
<div className="mail-sidebar">
|
|
||||||
<div className="row justify-content-center">
|
|
||||||
<div className="d-none col-12">
|
|
||||||
<div className="text-center mail-sidebar-title px-4">
|
|
||||||
<a href="#" className="btn btn-primary btn-block py-3 font-weight-bold font-18"><i className="fa fa-plus pl-2"></i></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="col-12">
|
|
||||||
<div className="px-4 py-4">
|
|
||||||
<ul className="pl-0">
|
|
||||||
<li className="py-2">
|
|
||||||
<a href="#">
|
|
||||||
<span className="nav align-items-center">
|
|
||||||
<span>
|
|
||||||
<i className="fa fa-envelope-o text-primary pr-4"></i>
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
<span>Inbox</span>
|
|
||||||
</span>
|
|
||||||
<span className="nav-item ml-auto text-right">
|
|
||||||
<span className="badge badge-pill badge-primary float-right">{contactsData?.length}</span>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li className="py-2">
|
|
||||||
<a href="#">
|
|
||||||
<span className="nav align-items-center">
|
|
||||||
<span>
|
|
||||||
<i className="fa fa-paper-plane-o pr-4"></i>
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
<span>Replied Mail</span>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<ul className="pl-0 mt-5">
|
|
||||||
<li className="py-2" onClick={()=>changeActiveCategoryUID('0')} style={{cursor: 'pointer'}}>
|
|
||||||
<div>
|
|
||||||
<span className="nav align-items-center">
|
|
||||||
<span>
|
|
||||||
<i className={`fa fa-circle-o pr-4 ${activeCategoryUID == '0' ? 'text-primary' : 'text-warning'}`}></i>
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
<span>All</span>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
{contactsCategory && contactsCategory.map(item => (
|
|
||||||
<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 == `A00000${item?.cid}` ? 'text-primary' : 'text-warning'}`}></i>
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
<span>{item?.description}</span>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
{/* <li className="py-2">
|
|
||||||
<a href="#">
|
|
||||||
<span className="nav align-items-center">
|
|
||||||
<span>
|
|
||||||
<i className="fa fa-circle-o pr-4 text-warning"></i>
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
<span>Work</span>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li className="py-2">
|
|
||||||
<a href="#">
|
|
||||||
<span className="nav align-items-center">
|
|
||||||
<span>
|
|
||||||
<i className="fa fa-plus pr-4"></i>
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
<span>Add Category</span>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</li> */}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="col-md-8 col-xxl-4 border-md-t">
|
|
||||||
<div className="mail-content border-right border-n h-100">
|
|
||||||
<div className="mail-search border-bottom">
|
|
||||||
<div className="row align-items-center mx-0">
|
|
||||||
<div className="col-12">
|
|
||||||
{/*<div className="form-group pt-3">*/}
|
|
||||||
{/* <input type="text" className="form-control" id="search" placeholder="Search.." />*/}
|
|
||||||
{/* <i className="fa fa-search"></i>*/}
|
|
||||||
{/*</div>*/}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="mail-msg scrollbar scroll_dark">
|
|
||||||
{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'}`}>
|
|
||||||
<a href="#">
|
|
||||||
<div className="media align-items-center">
|
|
||||||
<div className="mr-3">
|
|
||||||
<div className="bg-img">
|
|
||||||
<img src={getImage("avtar/01.jpg")} className="img-fluid" alt="user" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="w-100">
|
|
||||||
<div className="mail-msg-item-titel justify-content-between">
|
|
||||||
<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>
|
|
||||||
</div>
|
|
||||||
<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()}
|
|
||||||
{/* {getCustomTime(contact.added)} */}
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="col-xxl-6 border-t border-xxl-t">
|
|
||||||
|
|
||||||
<div className="mail-chat py-5 px-5">
|
|
||||||
<div className="media align-items-center">
|
|
||||||
<div className="bg-img mr-3">
|
|
||||||
<img src={getImage("avtar/03.jpg")} className="img-fluid" alt="user" />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<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 : 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>*/}
|
|
||||||
{/*<a href="javascript:void(0)"><i className="fa fa-print font-22"></i></a>*/}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<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>
|
|
||||||
<p>We know this in our gut, but what can we do about it? How can we motivate ourselves? One of the most difficult aspects of achieving success is staying motivated over the long haul.</p> */}
|
|
||||||
{/*<div className="my-5">*/}
|
|
||||||
{/* <p>Have lovely Day,</p>*/}
|
|
||||||
{/* <p>adminjon</p>*/}
|
|
||||||
{/*</div>*/}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="bg-light mail-f px-4 py-3">
|
|
||||||
<div className="py-2 bg-white px-4 py-3 d-flex justify-content-between">
|
|
||||||
<p>Click here to <a href="#editer" data-toggle="collapse" className="text-primary px-1">Reply</a>or<a href="#forward" data-toggle="collapse" className="text-primary px-1">Forward</a></p>
|
|
||||||
<a href="#" className="text-primary"><i className="fa fa-microphone"></i></a>
|
|
||||||
</div>
|
|
||||||
<div className="collapse" id="editer">
|
|
||||||
<div className="form-group">
|
|
||||||
<textarea className="form-control mt-3" id="exampleFormControlTextarea1" rows="3" placeholder="Type here..."></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="collapse" id="forward">
|
|
||||||
<div className="form-group">
|
|
||||||
<input className="form-control mt-3" id="exampleFormControl" placeholder="Email Address" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="d-flex align-items-center justify-content-between py-2">
|
|
||||||
<div>
|
|
||||||
{/*<ul className="nav">*/}
|
|
||||||
{/* <li className="nav-item pr-3"><a href="javascript:void(0)"><i className="ti ti-clip font-20"></i></a></li>*/}
|
|
||||||
{/* <li className="nav-item pr-3"><a href="javascript:void(0)"><i className="ti ti-face-smile font-20"></i></a></li>*/}
|
|
||||||
{/* <li className="nav-item"><a href="javascript:void(0)"><i className="ti ti-gallery font-20"></i></a></li>*/}
|
|
||||||
{/*</ul>*/}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
{/*<a href="javascript:void(0)" className="btn btn-primary"><span>Send</span> <i className="fa fa-paper-plane"></i></a>*/}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</>
|
</>
|
||||||
)
|
) : getContactData?.error ? (
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-12">
|
||||||
|
<p className="text-danger">{getContactData?.error?.message}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="row">
|
||||||
|
{/*<div className="vh-100 col-12 flex align-items-center">Coming Soon</div>*/}
|
||||||
|
<div className="col-12">
|
||||||
|
<div
|
||||||
|
className="card card-statistics mail-contant"
|
||||||
|
style={{ minHeight: "200px", borderRadius: "10px" }}
|
||||||
|
>
|
||||||
|
<div className="card-body p-0">
|
||||||
|
<div className="row no-gutters">
|
||||||
|
<div className="col-md-4 col-xxl-2 col-md-4">
|
||||||
|
<div className="mail-sidebar">
|
||||||
|
<div className="row justify-content-center">
|
||||||
|
<div className="d-none col-12">
|
||||||
|
<div className="text-center mail-sidebar-title px-4">
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
className="btn btn-primary btn-block py-3 font-weight-bold font-18"
|
||||||
|
>
|
||||||
|
<i className="fa fa-plus pl-2"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-12">
|
||||||
|
<div className="px-4 py-4">
|
||||||
|
<ul className="pl-0">
|
||||||
|
<li className="py-2">
|
||||||
|
<a href="#">
|
||||||
|
<span className="nav align-items-center">
|
||||||
|
<span>
|
||||||
|
<i className="fa fa-envelope-o text-primary pr-4"></i>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<span>Inbox</span>
|
||||||
|
</span>
|
||||||
|
<span className="nav-item ml-auto text-right">
|
||||||
|
<span className="badge badge-pill badge-primary float-right">
|
||||||
|
{contactsData?.length}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{/*<li className="py-2">*/}
|
||||||
|
{/* <a href="#">*/}
|
||||||
|
{/* <span*/}
|
||||||
|
{/* className="nav align-items-center">*/}
|
||||||
|
{/* <span>*/}
|
||||||
|
{/* <i className="fa fa-paper-plane-o pr-4"></i>*/}
|
||||||
|
{/* </span>*/}
|
||||||
|
{/* <span>*/}
|
||||||
|
{/* <span>Replied Mail</span>*/}
|
||||||
|
{/* </span>*/}
|
||||||
|
{/* </span>*/}
|
||||||
|
{/* </a>*/}
|
||||||
|
{/*</li>*/}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul className="pl-0 mt-5">
|
||||||
|
<li
|
||||||
|
className="py-2"
|
||||||
|
onClick={() => changeActiveCategoryUID("0")}
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<span className="nav align-items-center">
|
||||||
|
<span>
|
||||||
|
<i
|
||||||
|
className={`fa fa-circle-o pr-4 ${
|
||||||
|
activeCategoryUID == "0"
|
||||||
|
? "text-primary"
|
||||||
|
: "text-warning"
|
||||||
|
}`}
|
||||||
|
></i>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<span>All</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{contactsCategory &&
|
||||||
|
contactsCategory.map((item) => (
|
||||||
|
<li
|
||||||
|
key={item?.cid}
|
||||||
|
className="py-2"
|
||||||
|
onClick={() =>
|
||||||
|
changeActiveCategoryUID(`${item?.cid}`)
|
||||||
|
}
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<span className="nav align-items-center">
|
||||||
|
<span>
|
||||||
|
<i
|
||||||
|
className={`fa fa-circle-o pr-4 ${
|
||||||
|
activeCategoryUID ==
|
||||||
|
`${item?.cid}`
|
||||||
|
? "text-primary"
|
||||||
|
: "text-warning"
|
||||||
|
}`}
|
||||||
|
></i>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<span>{item?.description}</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={`${filteredContactData.length > 0 ? 'col-md-8 col-xxl-4' : 'col-md-8 col-xxl-10'} border-md-t`}>
|
||||||
|
<div className="mail-content border-right border-n h-100" style={{placeContent: 'center'}}>
|
||||||
|
{/* <div className="mail-search border-bottom">
|
||||||
|
<div className="row align-items-center mx-0">
|
||||||
|
<div className="col-12">
|
||||||
|
<div className="form-group pt-3">
|
||||||
|
<input type="text" className="form-control" id="search" placeholder="Search.." />
|
||||||
|
<i className="fa fa-search"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div> */}
|
||||||
|
<div className="mail-msg scrollbar scroll_dark">
|
||||||
|
{ filteredContactData.length ?
|
||||||
|
filteredContactData?.map((contact, index) => {
|
||||||
|
const isActive =
|
||||||
|
contact?.uid == activeContactUID ||
|
||||||
|
(!activeContactUID && index == 0);
|
||||||
|
const avtarImage =
|
||||||
|
contact?.category === undefined
|
||||||
|
? "avtar/01.jpg"
|
||||||
|
: "avtar/" + contact.category + ".png";
|
||||||
|
return (
|
||||||
|
<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">
|
||||||
|
<div className="bg-img">
|
||||||
|
<img
|
||||||
|
src={getImage(avtarImage)}
|
||||||
|
className="img-fluid"
|
||||||
|
alt="user"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="w-100">
|
||||||
|
<div className="mail-msg-item-titel justify-content-between">
|
||||||
|
<p>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
fontSize: "14px",
|
||||||
|
color: "#148399",
|
||||||
|
fontWeight: "bolder",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{contact?.sender}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
{/* <p className="d-none d-xl-block">06:59 <span> PM </span></p> */}
|
||||||
|
<p className="d-none d-xl-block">
|
||||||
|
<span style={{ fontSize: "14px" }}>
|
||||||
|
{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>
|
||||||
|
<p className="d-xl-none">
|
||||||
|
<span>
|
||||||
|
{new Date(
|
||||||
|
contact?.added
|
||||||
|
).toDateString()}
|
||||||
|
{/* {getCustomTime(contact.added)} */}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
:
|
||||||
|
<p className="text-center">Messages will appear here as soon as they are available for selection</p>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{filteredContactData.length > 0 &&
|
||||||
|
<div className="col-xxl-6 border-t border-xxl-t">
|
||||||
|
<div className="mail-chat py-5 px-5">
|
||||||
|
<div className="media align-items-center">
|
||||||
|
<div className="bg-img mr-3">
|
||||||
|
<img
|
||||||
|
src={activeContactUID ? getImage("avtar/" + activeDetail[0].category + ".png") : getImage(filteredContactData[0] == undefined ? "avtar/01.jpg": "avtar/" + filteredContactData[0].category + ".png")}
|
||||||
|
className="img-fluid"
|
||||||
|
alt="user"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4 className="mb-0" style={{ color: "#148399" }}>
|
||||||
|
{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
|
||||||
|
: 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>*/}
|
||||||
|
{/*<a href="javascript:void(0)"><i className="fa fa-print font-22"></i></a>*/}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{activeContactUID
|
||||||
|
? activeDetail[0]?.message
|
||||||
|
: filteredContactData[0]?.message}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { getDashPayments } from '../../services/services'
|
||||||
|
import { useQuery } from '@tanstack/react-query'
|
||||||
|
import queryKeys from '../../services/queryKeys'
|
||||||
|
import getDateTimeFromDateString from '../../helpers/getDateTimeFromDateString'
|
||||||
|
import getImage from '../../utils/getImage'
|
||||||
|
|
||||||
|
export default function DashPayments() {
|
||||||
|
|
||||||
|
|
||||||
|
const {data, isFetching, isError, error} = useQuery({
|
||||||
|
queryKey: queryKeys.dash_payments,
|
||||||
|
queryFn: () => {
|
||||||
|
let reqData = {
|
||||||
|
token: localStorage.getItem('token'), // USER TOKEN
|
||||||
|
uid: localStorage.getItem('uid') // USER UID
|
||||||
|
}
|
||||||
|
return getDashPayments(reqData)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const payments = data?.data?.member_payments
|
||||||
|
// console.log('data', payments)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="col-xxl-4 m-b-30" style={{minHeight: '300px'}}>
|
||||||
|
<div className="card card-statistics h-100 mb-0 panel_round_c3">
|
||||||
|
<div className="card-header d-flex justify-content-between">
|
||||||
|
<div className="card-heading">
|
||||||
|
<h4 className="card-title">Payments</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="overflow-y-auto card-body scrollbar scroll_dark pt-0" style={{maxHeight: '350px'}}>
|
||||||
|
<div className="datatable-wrapper table-responsive">
|
||||||
|
{isFetching ?
|
||||||
|
<>
|
||||||
|
<div className="col-12">
|
||||||
|
<div className="p-4">
|
||||||
|
<p className='text-mute'>Loading...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
: isError ?
|
||||||
|
<div className="col-12">
|
||||||
|
<div className="p-4">
|
||||||
|
<p className='text-danger'>{error.message}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
:
|
||||||
|
<table id="datatable" className="table table-borderless table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
{/* <th style={{width: '30px'}}>#</th> */}
|
||||||
|
<th>Date</th>
|
||||||
|
|
||||||
|
<th style={{width: '130px'}}>Description</th>
|
||||||
|
<th style={{width: '80px'}}>Amount</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{payments.length > 0 ?
|
||||||
|
payments.map((item, index) => {
|
||||||
|
return (
|
||||||
|
<tr key={index}>
|
||||||
|
{/* <td>{Number(item?.id).toString().padStart(6,'0')}</td> */}
|
||||||
|
<td>
|
||||||
|
{getDateTimeFromDateString(item?.added)}
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>{item?.option_name}</td>
|
||||||
|
<td className='text-right'>${item?.amount}</td>
|
||||||
|
</tr>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
:
|
||||||
|
<td colSpan={3} className='text-center'>No record found</td>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import Products from "./Products";
|
|||||||
import TopBar from "./TopBar";
|
import TopBar from "./TopBar";
|
||||||
import ProductsURL from "./ProductsURL";
|
import ProductsURL from "./ProductsURL";
|
||||||
import { SocketContextValues } from "../context/SocketIOContext";
|
import { SocketContextValues } from "../context/SocketIOContext";
|
||||||
|
import DashPayments from "./DashPayments";
|
||||||
|
|
||||||
export default function HomeSections(){
|
export default function HomeSections(){
|
||||||
|
|
||||||
@@ -52,41 +53,7 @@ export default function HomeSections(){
|
|||||||
<div className="row">
|
<div className="row">
|
||||||
<ProductsURL />
|
<ProductsURL />
|
||||||
|
|
||||||
<div className="col-xxl-4 m-b-30" style={{minHeight: '300px'}}>
|
<DashPayments />
|
||||||
<div className="card card-statistics h-100 mb-0 panel_round_c3">
|
|
||||||
<div className="card-header d-flex justify-content-between">
|
|
||||||
<div className="card-heading">
|
|
||||||
<h4 className="card-title">Payments</h4>
|
|
||||||
</div>
|
|
||||||
{/*<div className="dropdown">*/}
|
|
||||||
{/* <a className="p-2" href="#!" data-toggle="dropdown" aria-haspopup="true"*/}
|
|
||||||
{/* aria-expanded="false">*/}
|
|
||||||
{/* <i className="fe fe-circle"></i>*/}
|
|
||||||
{/* </a>*/}
|
|
||||||
{/* <div className="dropdown-menu custom-dropdown dropdown-menu-right p-4">*/}
|
|
||||||
{/* <h6 className="mb-1">Action</h6>*/}
|
|
||||||
{/* <a className="dropdown-item" href="#!"><i className="fa-fw fa fa-file-o pr-2"></i>View*/}
|
|
||||||
{/* reports</a>*/}
|
|
||||||
{/* <a className="dropdown-item" href="#!"><i className="fa-fw fa fa-edit pr-2"></i>Edit reports</a>*/}
|
|
||||||
{/* <a className="dropdown-item" href="#!"><i className="fa-fw fa fa-bar-chart-o pr-2"></i>Statistics</a>*/}
|
|
||||||
{/* <h6 className="mb-1 mt-3">Export</h6>*/}
|
|
||||||
{/* <a className="dropdown-item" href="#!"><i className="fa-fw fa fa-file-pdf-o pr-2"></i>Export*/}
|
|
||||||
{/* to PDF</a>*/}
|
|
||||||
{/* <a className="dropdown-item" href="#!"><i className="fa-fw fa fa-file-excel-o pr-2"></i>Export*/}
|
|
||||||
{/* to CSV</a>*/}
|
|
||||||
{/* </div>*/}
|
|
||||||
{/*</div>*/}
|
|
||||||
</div>
|
|
||||||
<div className="card-body">
|
|
||||||
{/*<h5>We only started collecting data from February 2019 </h5>*/}
|
|
||||||
{/*<p>Questions about the Net Earnings number? <a*/}
|
|
||||||
{/* className="btn btn-square btn-inverse-success btn-xs ml-1" href="#">Click here</a></p>*/}
|
|
||||||
<div className="row mt-4">
|
|
||||||
.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</>;
|
</>;
|
||||||
|
|
||||||
|
|||||||
@@ -44,13 +44,13 @@ export default function Products() {
|
|||||||
{products && products.map((product, index) => (
|
{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)} >
|
<Link to={productPath(product?.product_id)} >
|
||||||
<div className={`d-flex align-items-center extraProductCard ${product?.icon_style}`} >
|
<div className={`d-flex align-items-center extraProductCard ${product?.icon_style}`} style={{borderColor:'black', borderWidth: '2px'}} >
|
||||||
<div className="icon-container img-icon m-r-20 bg-light-gray rounded">
|
<div className="icon-container img-icon m-r-20 bg-light-gray rounded">
|
||||||
<i className={`fa ${product?.product_icon} text-primary`}></i>
|
<i className={`fa ${product?.product_icon} text-primary`}></i>
|
||||||
</div>
|
</div>
|
||||||
<div className="report-details">
|
<div className="report-details">
|
||||||
<p>{product?.status_text}</p>
|
<p><span style={{fontWeight: 'bolder', color: '#00557A'}}>{product?.status_text}</span></p>
|
||||||
<h4>{product?.name}</h4>
|
<h4><span style={{paddingLeft: '10px'}}>{product?.name}</span></h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -57,29 +57,37 @@ export default function TopBar() {
|
|||||||
<>
|
<>
|
||||||
{data && data?.map((item, index)=>{
|
{data && data?.map((item, index)=>{
|
||||||
let textColor = item?.description == 'Contacts' ? 'text-danger' : item?.description == 'Site Traffic' ? 'text-primary' : item?.description == 'Appointments' ? 'text-orange' : 'text-success'
|
let textColor = item?.description == 'Contacts' ? 'text-danger' : item?.description == 'Site Traffic' ? 'text-primary' : item?.description == 'Appointments' ? 'text-orange' : 'text-success'
|
||||||
|
let dataSpan = ''
|
||||||
|
if(item?.extra_style){
|
||||||
|
const data = item.data_span.split(' ')
|
||||||
|
dataSpan = `${data[0]} ${data[1]}`
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={item.id + index} className="col-sm-6 col-xxl-3">
|
<div key={item.id + index} className="col-sm-6 col-xxl-3">
|
||||||
<div className={`card card-statistics ecommerce-contant overflow-h ${item?.extra_style} `}>
|
<Link to={item?.link}>
|
||||||
<div className="card-body p-0">
|
<div className={`card card-statistics ecommerce-contant overflow-h ${item?.extra_style} `} style={{borderRadius: '10px'}}>
|
||||||
<div className="d-flex m-b-0 ecommerce-contant-text h-100">
|
<div className="card-body p-0">
|
||||||
<div className="w-100">
|
<div className="d-flex m-b-0 ecommerce-contant-text h-100">
|
||||||
<div className="row p-3">
|
<div className="w-100">
|
||||||
<div className="col">
|
<div className="row p-3">
|
||||||
<h3 className="mb-0">{item?.value || 0}</h3>
|
<div className="col">
|
||||||
<small className="d-block">{item?.data_span}</small>
|
<h3 className="mb-0">{item?.value || 0}</h3>
|
||||||
|
<small className="d-block">{item?.extra_style ? dataSpan : item?.data_span}</small>
|
||||||
|
</div>
|
||||||
|
<div className="col text-right">
|
||||||
|
<h5 className="text-muted mb-0">{item?.description}</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="apexchart-wrapper">
|
||||||
|
<div id="ecommercedemo3" className="chart-fit"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col text-right">
|
|
||||||
<h5 className="text-muted mb-0"><Link to={item?.link}>{item?.description}</Link></h5>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="apexchart-wrapper">
|
|
||||||
<div id="ecommercedemo3" className="chart-fit"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export default function UserMenu() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="sidebar-nav scrollbar scroll_dark">
|
<div className="sidebar-nav scrollbar scroll_dark">
|
||||||
<ul className="metismenu " id="sidebarNav">
|
<ul className="metismenu h-100" id="sidebarNav">
|
||||||
<li className="nav-static-title">Panel</li>
|
<li className="nav-static-title">Panel</li>
|
||||||
<li className={`${pathname == siteLinks.dash ? 'active' : ''}`}>
|
<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">
|
<Link className="has-arrow" to='#' data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
|
||||||
@@ -30,7 +30,7 @@ export default function UserMenu() {
|
|||||||
<ul id="collapseOne" className="collapse show" aria-labelledby="headingOne" data-bs-parent="#sidebarNav">
|
<ul id="collapseOne" className="collapse show" aria-labelledby="headingOne" data-bs-parent="#sidebarNav">
|
||||||
<li className={`${pathname == siteLinks.dash ? 'active' : ''}`}><Link to={siteLinks.dash}>Home</Link></li>
|
<li className={`${pathname == siteLinks.dash ? 'active' : ''}`}><Link to={siteLinks.dash}>Home</Link></li>
|
||||||
<li className={`${pathname == siteLinks.calendar ? 'active' : ''}`}><Link to={siteLinks.calendar}>Calendar</Link></li>
|
<li className={`${pathname == siteLinks.calendar ? 'active' : ''}`}><Link to={siteLinks.calendar}>Calendar</Link></li>
|
||||||
<li className={`${pathname == siteLinks.contacts ? 'active' : ''}`}><Link to={siteLinks.contacts}>Contacts</Link></li>
|
<li className={`${pathname == siteLinks.contacts ? 'active' : ''}`}><Link to={siteLinks.contacts}>Sites Contacts</Link></li>
|
||||||
<li className={`${pathname == siteLinks.comments ? 'active' : ''}`}><Link to={siteLinks.comments}>Comments</Link></li>
|
<li className={`${pathname == siteLinks.comments ? 'active' : ''}`}><Link to={siteLinks.comments}>Comments</Link></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
@@ -54,7 +54,7 @@ export default function UserMenu() {
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li className="sidebar-banner p-4 bg-gradient text-center m-3 d-block rounded">
|
<li className="sidebar-banner p-4 bg-gradient text-center m-3 mt-auto d-block rounded">
|
||||||
<h5 className="text-white mb-1">MERMS Panel</h5>
|
<h5 className="text-white mb-1">MERMS Panel</h5>
|
||||||
<Link className="btn btn-square btn-inverse-light btn-xs d-inline-block mt-2 mb-0" to='' onClick={logout}> Log Out</Link>
|
<Link className="btn btn-square btn-inverse-light btn-xs d-inline-block mt-2 mb-0" to='' onClick={logout}> Log Out</Link>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -46,7 +46,9 @@ export default function ProductActive({productData}){
|
|||||||
<div className="card card-statistics">
|
<div className="card card-statistics">
|
||||||
<div className="card-header">
|
<div className="card-header">
|
||||||
<div className="card-heading d-flex justify-content-between">
|
<div className="card-heading d-flex justify-content-between">
|
||||||
<h4 className="card-title">{externalUrl}</h4>
|
{/*<h4 className="card-title">{externalUrl}</h4>*/}
|
||||||
|
<h4 style={{color: '#148399', fontWeight: 'bolder'}}>
|
||||||
|
<a href={externalUrl} target='_blank'>{externalUrl}</a></h4>
|
||||||
<button type="button" onClick={()=>iframe.current.src += ''} className="btn">
|
<button type="button" onClick={()=>iframe.current.src += ''} className="btn">
|
||||||
<img src={getImage('refresh.png')} style={{width: '30px', height: 'auto'}} alt='refresh page' />
|
<img src={getImage('refresh.png')} style={{width: '30px', height: 'auto'}} alt='refresh page' />
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -2,14 +2,16 @@ import { useQuery } from '@tanstack/react-query'
|
|||||||
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
|
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
|
||||||
// import getImage from "../../utils/getImage";
|
// import getImage from "../../utils/getImage";
|
||||||
import ProductStart from "./ProductStart";
|
import ProductStart from "./ProductStart";
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation, useNavigate } from 'react-router-dom';
|
||||||
import {MyProductData} from "../../services/services";
|
import {MyProductData} from "../../services/services";
|
||||||
import ProductActive from "./ProductActive";
|
import ProductActive from "./ProductActive";
|
||||||
import ProductProvision from "./ProductProvision";
|
import ProductProvision from "./ProductProvision";
|
||||||
import {productConst} from "../../constants/products";
|
import {productConst} from "../../constants/products";
|
||||||
import queryKeys from "../../services/queryKeys";
|
import queryKeys from "../../services/queryKeys";
|
||||||
|
import siteLinks from '../../links/siteLinks';
|
||||||
|
|
||||||
export default function ProductFactory(){
|
export default function ProductFactory(){
|
||||||
|
const navigate = useNavigate()
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const pathname = location.pathname;
|
const pathname = location.pathname;
|
||||||
|
|
||||||
@@ -45,8 +47,9 @@ export default function ProductFactory(){
|
|||||||
</>
|
</>
|
||||||
: isError ?
|
: isError ?
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-12">
|
<div className="text-center col-12" style={{minHeight: '500px', placeContent: 'center'}}>
|
||||||
<p className='text-danger'>{error?.message}</p>
|
<p className='text-danger'>{error?.message}</p>
|
||||||
|
<button onClick={() => navigate(siteLinks.home)} className='mt-3 btn btn-primary'>Return Home</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
:
|
:
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
const ColorStyleConfigure =()=>{
|
||||||
|
|
||||||
|
return <>COLOR CONFIG</>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ColorStyleConfigure
|
||||||
@@ -1,126 +1,190 @@
|
|||||||
import React, {memo, useState} from 'react'
|
import React, {memo, useEffect, useMemo, useState} from 'react'
|
||||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
import {useMutation, useQueryClient} from "@tanstack/react-query";
|
||||||
import { pageSettings } from "../../../services/services";
|
import {pageSettings} from "../../../services/services";
|
||||||
import SiteTemplateSelector from './SiteTemplateSelector';
|
import SiteTemplateSelector from './SiteTemplateSelector';
|
||||||
import NoYesBooleanDropdown from './NoYesBooleanDropdown';
|
import NoYesBooleanDropdown from './NoYesBooleanDropdown';
|
||||||
import { IoMdArrowDropdown } from 'react-icons/io';
|
import {IoMdArrowDropdown} from 'react-icons/io';
|
||||||
import queryKeys from '../../../services/queryKeys';
|
import queryKeys from '../../../services/queryKeys';
|
||||||
|
import sortObjectByListOrder from '../../../helpers/sortObjectByListOrder';
|
||||||
|
import URLConfiguration from "./URLConfiguration";
|
||||||
|
import ColorStyleConfigure from "./ColorStyleConfigure";
|
||||||
|
|
||||||
const GeneralTab = memo(({name='Full Name', data, isCustom, productData, backendValues, setFieldsChanged}) =>{
|
const GeneralTab = memo(({
|
||||||
|
name = 'Full Name',
|
||||||
|
data,
|
||||||
|
tabKey,
|
||||||
|
isCustom,
|
||||||
|
productData,
|
||||||
|
backendValues,
|
||||||
|
setFieldsChanged
|
||||||
|
}) => {
|
||||||
|
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
|
|
||||||
const [reqStatus, setReqStatus] = useState({error: null, message: ''})
|
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 computeFieldData = useMemo(()=>{
|
||||||
|
// const fieldData = {}
|
||||||
|
// Object.entries(data)?.forEach(([key, value]) => { // LOOP TO POPULATE FIELDDATA PROPERTIES WITH DATA OF EACH TAB
|
||||||
|
// fieldData[value?.name?.toLowerCase().replaceAll(" ", "_")] = ''
|
||||||
|
// })
|
||||||
|
// backendValues?.data?.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
|
||||||
|
// })
|
||||||
|
// return fieldData
|
||||||
|
// },[backendValues.data])
|
||||||
|
|
||||||
const [fields, setFields] = useState(fieldData)
|
|
||||||
|
|
||||||
const handleChange = ({target:{name, value}}) => {
|
|
||||||
setFields(prev => ({...prev, [name]:value}))
|
|
||||||
setFieldsChanged(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
const submitSettings = useMutation({
|
const [fields, setFields] = useState({})
|
||||||
mutationFn: (fields) => {
|
|
||||||
return pageSettings(fields)
|
const sortedData = sortObjectByListOrder(data ? data : {}) // SORTED SETTINGSCONFIG
|
||||||
},
|
|
||||||
onSuccess: (res) => {
|
useEffect(() => {
|
||||||
if(res?.data?.resultCode != '0'){
|
const fieldData = {}
|
||||||
return setReqStatus({error: true, message: 'Unable to complete, try again later'})
|
Object.entries(sortedData)?.forEach(([key, value]) => { // LOOP TO POPULATE FIELDDATA PROPERTIES WITH DATA OF EACH TAB
|
||||||
}
|
fieldData[value?.name?.toLowerCase().replaceAll(" ", "_")] = ''
|
||||||
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(()=>{
|
backendValues?.data?.forEach(item => { //LOOPING THROUGH USER ALREADY ADDED DATA FROM BACKEND IF ANY AND UPDATING THE FIELDDATA OBJECT
|
||||||
setReqStatus({error: null, message: ''})
|
fieldData[item?.setting_key?.toLowerCase().replaceAll(" ", "_")] = item?.setting_value
|
||||||
},3000)
|
})
|
||||||
},
|
setFields(fieldData)
|
||||||
})
|
}, [backendValues.data])
|
||||||
|
|
||||||
const handleSubmit = () => {
|
const handleChange = ({target: {name, value}}) => {
|
||||||
const reqData = {
|
setFields(prev => ({...prev, [name]: value}))
|
||||||
token: localStorage.getItem('token'), // USER TOKEN
|
setFieldsChanged(true)
|
||||||
uid: localStorage.getItem('uid'), // USER UID
|
|
||||||
product_id: productData?.product_id,
|
|
||||||
settings : {
|
|
||||||
...fields
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// console.log('formInfo', reqData)
|
|
||||||
submitSettings.mutate(reqData)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isCustom === true){
|
const submitSettings = useMutation({
|
||||||
return <SiteTemplateSelector name={name} data={data} isCustom={isCustom} productData={productData} />
|
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 = () => {
|
||||||
return (
|
const reqData = {
|
||||||
<div className="page-account-form">
|
token: localStorage.getItem('token'), // USER TOKEN
|
||||||
<div className="p-0" style={{ minHeight: '500px'}}>
|
uid: localStorage.getItem('uid'), // USER UID
|
||||||
|
product_id: productData?.product_id,
|
||||||
<form id='tab_form'>
|
settings: {
|
||||||
<div className="form-row">
|
...fields
|
||||||
<>
|
}
|
||||||
{Object.entries(data)?.map(([key, value]) => {
|
}
|
||||||
let fieldName = value.name.toLowerCase().replaceAll(" ", "_")
|
submitSettings.mutate(reqData)
|
||||||
let fieldValue = fields[value.name.toLowerCase().replaceAll(" ", "_")]
|
}
|
||||||
return (
|
console.log(tabKey);
|
||||||
<div key={key} className="form-group col-md-12">
|
return (
|
||||||
<label htmlFor="name1">{value.name}</label>
|
<>
|
||||||
{value.controls == 'TEXT' ?
|
{backendValues?.isFetching || !backendValues?.data ?
|
||||||
<input name={fieldName} type="text" className="form-control" id={key} value={fieldValue} onChange={handleChange} />
|
<>
|
||||||
:value.controls == 'TEXTAREA' ?
|
<div className="row">
|
||||||
<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">
|
<div className="col-12">
|
||||||
<p className={reqStatus.error ? 'text-danger' : 'text-success'}>{reqStatus.message}</p>
|
<p className='text-mute'>Loading...</p>
|
||||||
</div>
|
</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>
|
||||||
</div>
|
</>
|
||||||
</form>
|
: backendValues?.isError ?
|
||||||
</div>
|
<div className="row">
|
||||||
</div>
|
<div className="col-12">
|
||||||
)
|
<p className='text-danger'>{backendValues?.error.message}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
:
|
||||||
|
<>
|
||||||
|
{isCustom === true ?
|
||||||
|
<>
|
||||||
|
{(tabKey === 'template_tab') && <SiteTemplateSelector name={name} data={sortedData} isCustom={isCustom} productData={productData}/>}
|
||||||
|
{(tabKey === 'url_config_tab') && <URLConfiguration name={name} data={sortedData} isCustom={isCustom} productData={productData}/>}
|
||||||
|
{(tabKey === 'color_scheme_tab') && <ColorStyleConfigure name={name} data={sortedData} isCustom={isCustom} productData={productData}/>}
|
||||||
|
</>
|
||||||
|
:
|
||||||
|
<div className="page-account-form">
|
||||||
|
<div className="p-0" style={{minHeight: '500px'}}>
|
||||||
|
|
||||||
|
<form id='tab_form'>
|
||||||
|
<div className="form-row">
|
||||||
|
<>
|
||||||
|
{Object.entries(sortedData)?.map(([key, value]) => {
|
||||||
|
let fieldName = key; // value.key.toLowerCase().replaceAll(" ", "_")
|
||||||
|
let fieldValue = fields[key]; //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>
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,78 +1,35 @@
|
|||||||
import React, { memo, useMemo, useState } from 'react'
|
import React, { memo, useMemo, useState } from 'react'
|
||||||
import GeneralTab from './GeneralTab'
|
import GeneralTab from './GeneralTab'
|
||||||
import { getSettingsData } from '../../../services/services';
|
import { getSettingsData, getMyProductConfig } from '../../../services/services';
|
||||||
import queryKeys from '../../../services/queryKeys';
|
import queryKeys from '../../../services/queryKeys';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
import sortObjectByListOrder from '../../../helpers/sortObjectByListOrder'
|
||||||
|
|
||||||
const Settings = memo(({productData}) => {
|
const Settings = memo(({productData}) => {
|
||||||
|
|
||||||
const { userDetails: { uid }} = useSelector((state) => state?.userDetails); // GETS USER UID
|
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 ={
|
const {data:configData, isFetching:configIsFetching, configIsError, error:configError} = useQuery({
|
||||||
facebook: { name: 'Facebook', controls: 'TEXT', active: true },
|
queryKey: queryKeys.myProductConfig,
|
||||||
twitter: { name: 'Twitter', controls: 'TEXT', active: true },
|
queryFn: () => {
|
||||||
youtube: { name: 'Youtube', controls: 'TEXT', active: true },
|
let reqData = {
|
||||||
}
|
token: localStorage.getItem('token'), // USER TOKEN
|
||||||
|
uid: localStorage.getItem('uid'), // USER UID
|
||||||
const homeFields ={
|
product_id: productData?.product_id
|
||||||
banner_text: { name: 'Banner Text', controls: 'TEXT', active: true },
|
}
|
||||||
banner_description: { name: 'Banner Description', controls: 'TEXTAREA', active: true },
|
return getMyProductConfig(reqData)
|
||||||
}
|
},
|
||||||
|
staleTime: 0,
|
||||||
const footerFields ={
|
})
|
||||||
footer_description: { name: 'Footer Description', controls: 'TEXTAREA', active: true },
|
const settingsConfig = configData?.data?.settings_items
|
||||||
boolean_footer_show_email: { name: 'Show email in footer', controls: 'SELECT_NO_YES', active: true },
|
// console.log('CONFIG DATA...', settingsConfig)
|
||||||
}
|
|
||||||
|
|
||||||
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 [fieldsChanged, setFieldsChanged] = useState(false)
|
||||||
|
|
||||||
const [activeTab, setActiveTab] = useState(Object.entries(settingsObject)[0][1]?.controls)
|
// const [activeTab, setActiveTab] = useState(Object.entries(settingsConfig)[0][1]?.controls)
|
||||||
|
const [activeTab, setActiveTab] = useState(null)
|
||||||
|
|
||||||
const handleChangeTab = (value) => {
|
const handleChangeTab = (value) => {
|
||||||
// if(fieldsChanged){
|
// if(fieldsChanged){
|
||||||
@@ -97,15 +54,19 @@ const Settings = memo(({productData}) => {
|
|||||||
product_id: productData?.product_id
|
product_id: productData?.product_id
|
||||||
}
|
}
|
||||||
return getSettingsData(reqData)
|
return getSettingsData(reqData)
|
||||||
}
|
},
|
||||||
|
staleTime: 0,
|
||||||
|
enabled: settingsConfig ? true : false
|
||||||
})
|
})
|
||||||
|
|
||||||
const settingsData = data?.data?.settings
|
const settingsData = {data: data?.data?.settings, isFetching, isError, error}
|
||||||
// console.log('data', settingsData)
|
// console.log('data', settingsData)
|
||||||
|
|
||||||
|
const sortedSettingsConfig = sortObjectByListOrder(settingsConfig ? settingsConfig : {}) // SORTED SETTINGSCONFIG
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{isFetching ?
|
{configIsFetching ?
|
||||||
<>
|
<>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
@@ -113,19 +74,19 @@ const Settings = memo(({productData}) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
: isError ?
|
: configIsError ?
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
<p className='text-danger'>{error.message}</p>
|
<p className='text-danger'>{configError.message}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
:
|
:
|
||||||
<div className="tab tab-vertical">
|
<div className="tab tab-vertical">
|
||||||
<ul className="nav nav-tabs" role="tablist">
|
<ul className="nav nav-tabs" role="tablist">
|
||||||
<>
|
<>
|
||||||
{Object.entries(settingsObject).map(([key, value]) => (
|
{Object.entries(sortedSettingsConfig).map(([key, value], index) => (
|
||||||
<li key={key} className="nav-item">
|
<li key={key} className="nav-item">
|
||||||
<a className={`nav-link ${activeTab == value.controls && 'active show'}`}
|
<a className={`nav-link ${(activeTab == value.controls || (index == 0 & !activeTab)) && 'active show'}`}
|
||||||
id={key}
|
id={key}
|
||||||
// data-bs-toggle="pill"
|
// data-bs-toggle="pill"
|
||||||
// data-bs-target={`#${value.controls}`}
|
// data-bs-target={`#${value.controls}`}
|
||||||
@@ -143,12 +104,12 @@ const Settings = memo(({productData}) => {
|
|||||||
</ul>
|
</ul>
|
||||||
<div className="tab-content">
|
<div className="tab-content">
|
||||||
<>
|
<>
|
||||||
{Object.entries(settingsObject).map(([key, value]) => (
|
{Object.entries(sortedSettingsConfig).map(([key, value], index) => (
|
||||||
<div key={key} className={`tab-pane fade ${activeTab == value.controls && 'active show'}`}
|
<div key={key} className={`tab-pane fade ${(activeTab == value.controls || (index == 0 & !activeTab)) && 'active show'}`}
|
||||||
// id={value.controls} role="tabpanel"
|
// id={value.controls} role="tabpanel"
|
||||||
// aria-labelledby={key}
|
// aria-labelledby={key}
|
||||||
>
|
>
|
||||||
<GeneralTab name={value.title} data={value.data} isCustom={value.custom} productData={productData} backendValues={settingsData} setFieldsChanged={setFieldsChanged} />
|
<GeneralTab tabKey={key} name={value.title} data={value.data} isCustom={value.custom} productData={productData} backendValues={settingsData} setFieldsChanged={setFieldsChanged} />
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
@@ -160,4 +121,4 @@ const Settings = memo(({productData}) => {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
export default Settings
|
export default Settings
|
||||||
@@ -1,33 +1,114 @@
|
|||||||
import React, {memo} from 'react'
|
import React, {memo} from 'react'
|
||||||
import getImage from "../../../utils/getImage";
|
import getImage from "../../../utils/getImage";
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query';
|
||||||
import queryKeys from '../../../services/queryKeys';
|
import queryKeys from '../../../services/queryKeys';
|
||||||
import { getProductTemplateData } from '../../../services/services';
|
import {getProductTemplateData, activateTemplate} from '../../../services/services';
|
||||||
|
|
||||||
const SiteTemplateSelector = memo(({name='Full Name', data, productData}) =>{
|
const SiteTemplateSelector = memo(({name = 'Full Name', data, productData}) => {
|
||||||
|
|
||||||
const {data:templateData, isFetching, isError, error} = useQuery({
|
const queryClient = useQueryClient()
|
||||||
queryKey: queryKeys.productTemplateData,
|
|
||||||
queryFn: () => {
|
const {data: templateData, isFetching, isError, error} = useQuery({
|
||||||
let reqData = {
|
queryKey: queryKeys.productTemplateData,
|
||||||
|
queryFn: () => {
|
||||||
|
let reqData = {
|
||||||
|
token: localStorage.getItem('token'), // USER TOKEN
|
||||||
|
uid: localStorage.getItem('uid'), // USER UID
|
||||||
|
product_id: productData?.product_id
|
||||||
|
}
|
||||||
|
return getProductTemplateData(reqData)
|
||||||
|
},
|
||||||
|
staleTime: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
const templateResponse = templateData?.data
|
||||||
|
const currentTemUID = templateResponse?.current_template_uid
|
||||||
|
const templates = templateResponse?.templates
|
||||||
|
const custom_template_name = templateResponse?.custom_template_name
|
||||||
|
|
||||||
|
// console.log('data Template', templateResponse)
|
||||||
|
console.log("Page data == ", data)
|
||||||
|
|
||||||
|
const handleActivateTemplate = useMutation({
|
||||||
|
mutationFn: (fields) => {
|
||||||
|
return activateTemplate(fields)
|
||||||
|
},
|
||||||
|
onSuccess: (res) => {
|
||||||
|
if (res?.data?.resultCode != '0') {
|
||||||
|
throw new Error(res.data.resultDescription)
|
||||||
|
}
|
||||||
|
queryClient.refetchQueries({ // refetches productProvision API call
|
||||||
|
queryKey: [...queryKeys.settingsData],
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onSettled: () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
handleActivateTemplate.reset()
|
||||||
|
}, 3000)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleSubmit = (tem_uid) => {
|
||||||
|
const reqData = {
|
||||||
token: localStorage.getItem('token'), // USER TOKEN
|
token: localStorage.getItem('token'), // USER TOKEN
|
||||||
uid: localStorage.getItem('uid'), // USER UID
|
uid: localStorage.getItem('uid'), // USER UID
|
||||||
product_id: productData?.product_id
|
product_id: productData?.product_id,
|
||||||
|
template_uid: tem_uid
|
||||||
}
|
}
|
||||||
return getProductTemplateData(reqData)
|
// console.log(reqData)
|
||||||
|
handleActivateTemplate.mutate(reqData)
|
||||||
|
}
|
||||||
|
if (custom_template_name && custom_template_name != '') {
|
||||||
|
// This implies we have a custom template , just return here
|
||||||
|
return <>This product is using a custom template named {custom_template_name} </>
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
const settingsData = templateData?.data
|
|
||||||
console.log('data Template', settingsData)
|
|
||||||
|
|
||||||
console.log("Page data == ", data)
|
|
||||||
return (
|
return (
|
||||||
<div className="page-account-form">
|
<div className="page-account-form">
|
||||||
<div className="p-0">
|
<div className="p-0">
|
||||||
<div className="row">
|
{isFetching ?
|
||||||
<>
|
<>
|
||||||
{Object.entries(data)?.map(([key, value]) => (
|
<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="row">
|
||||||
|
<>
|
||||||
|
{!templates?.length ?
|
||||||
|
<p>No data Found</p>
|
||||||
|
:
|
||||||
|
templates.map(template => (
|
||||||
|
<div key={template.template_uid} 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('file-icon/svg.png')}
|
||||||
|
alt={template.title}/>
|
||||||
|
</div>
|
||||||
|
<h4 className="mb-0">{template.title}</h4>
|
||||||
|
{currentTemUID == template.template_uid ?
|
||||||
|
<button className="btn btn-light"
|
||||||
|
disabled={true}>Active</button>
|
||||||
|
:
|
||||||
|
<button onClick={() => handleSubmit(template.template_uid)}
|
||||||
|
className="btn btn-primary">Activate</button>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
{/* {Object.entries(data)?.map(([key, value]) => (
|
||||||
<div key={key} className="col-xl-6 col-sm-6">
|
<div key={key} className="col-xl-6 col-sm-6">
|
||||||
<div className="card card-statistics">
|
<div className="card card-statistics">
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
@@ -41,9 +122,27 @@ const SiteTemplateSelector = memo(({name='Full Name', data, productData}) =>{
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))} */}
|
||||||
</>
|
</>
|
||||||
</div>
|
|
||||||
|
<div className="col-12">
|
||||||
|
<>
|
||||||
|
{handleActivateTemplate.isPending ?
|
||||||
|
<p className={'text-center '}>loading...</p>
|
||||||
|
:
|
||||||
|
handleActivateTemplate.isError ?
|
||||||
|
<p className={'text-center text-danger'}>{handleActivateTemplate.error.message}</p>
|
||||||
|
:
|
||||||
|
handleActivateTemplate.isSuccess ?
|
||||||
|
<p className={'text-center text-success'}>Templated activated
|
||||||
|
successfully</p>
|
||||||
|
:
|
||||||
|
null
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
import { Form, Formik } from "formik";
|
||||||
|
import * as Yup from "yup";
|
||||||
|
import { useMutation } from '@tanstack/react-query';
|
||||||
|
import { completePWDReset } from '../../../services/services';
|
||||||
|
|
||||||
|
const validationSchema = Yup.object().shape({
|
||||||
|
url: Yup.string().required("URL is required").matches(/^https?:\/\/[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-]+\.[a-zA-Z]+/, 'Must be like: https://example.mysite.com'),
|
||||||
|
})
|
||||||
|
|
||||||
|
const initialValues = {
|
||||||
|
url: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
const URLConfiguration = ({productData}) => {
|
||||||
|
|
||||||
|
let defaultUrl= 'https://'+productData?.internal_url
|
||||||
|
|
||||||
|
// API to set url
|
||||||
|
const setURL = useMutation({
|
||||||
|
mutationFn: (fields) => {
|
||||||
|
return completePWDReset(fields)
|
||||||
|
},
|
||||||
|
// onSuccess: (res) => {
|
||||||
|
// },
|
||||||
|
// onError: (err) => {
|
||||||
|
// console.log('err', err)
|
||||||
|
// }
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleSubmit = (values) => {
|
||||||
|
let reqData = {
|
||||||
|
url: values.url
|
||||||
|
}
|
||||||
|
console.log('URL', values.url)
|
||||||
|
// setURL.mutate(reqData)
|
||||||
|
}
|
||||||
|
|
||||||
|
return <>
|
||||||
|
<div className="card card-statistics">
|
||||||
|
<div className="card-header">
|
||||||
|
<div className="card-heading">
|
||||||
|
<h4 className="card-title">Default URL</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="card-body">
|
||||||
|
<div className="form-group">
|
||||||
|
{/*<label htmlFor="exampleInputEmail1">Email address</label>*/}
|
||||||
|
<input type="email" className="form-control"
|
||||||
|
aria-describedby="defaultUrlHelp" value={defaultUrl} readOnly={true} />
|
||||||
|
</div>
|
||||||
|
{/*<button type="submit" className="btn btn-primary">Submit</button>*/}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Formik
|
||||||
|
initialValues={initialValues}
|
||||||
|
validationSchema={validationSchema}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
>
|
||||||
|
{(props) => {
|
||||||
|
return (
|
||||||
|
<Form className='w-full'>
|
||||||
|
<div className="card card-statistics" style={{backgroundColor:'#7affd92b'}}>
|
||||||
|
<div className="card-header">
|
||||||
|
<div className="card-heading">
|
||||||
|
<h4 className="card-title" style={{textTransform: 'none'}}>Set your own URL</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="card-body">
|
||||||
|
<div className="form-group">
|
||||||
|
<label htmlFor="exampleInputEmail1">Enter your full URL <span className={`${(props.errors.url && props.touched.url) && 'text-danger'}`}>{props.errors.url}</span></label>
|
||||||
|
<input value={props.values.url} onChange={props.handleChange} type="text" className="form-control" id="url" aria-describedby="url" placeholder="https://example.mysite.com"/>
|
||||||
|
</div>
|
||||||
|
<button type="submit" className="btn btn-primary">Submit</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</Formik>
|
||||||
|
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default URLConfiguration
|
||||||
@@ -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,179 @@
|
|||||||
|
import React, { memo, useMemo, useState } from 'react'
|
||||||
|
import GeneralTab from './GeneralTab'
|
||||||
|
import { getSettingsData, getMyProductConfig } 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 {data:configData, isFetching:configIsFetching, configIsError, error:configError} = useQuery({
|
||||||
|
queryKey: queryKeys.myProductConfig,
|
||||||
|
queryFn: () => {
|
||||||
|
let reqData = {
|
||||||
|
token: localStorage.getItem('token'), // USER TOKEN
|
||||||
|
uid: localStorage.getItem('uid'), // USER UID
|
||||||
|
product_id: productData?.product_id
|
||||||
|
}
|
||||||
|
return getMyProductConfig(reqData)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const settingsConfig = configData?.data?.settings_items
|
||||||
|
// console.log('CONFIG DATA...', settingsConfig)
|
||||||
|
|
||||||
|
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 },
|
||||||
|
boolean_footer_show_made_by: { name: 'Show made by in footer', controls: 'SELECT_NO_YES', active: true },
|
||||||
|
boolean_footer_show_socials: { name: 'Show social 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
|
||||||
@@ -1,76 +1,79 @@
|
|||||||
import React, { useEffect, useMemo, useState } from "react";
|
import React, {useCallback, useEffect, useMemo, useState} from "react";
|
||||||
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
|
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
|
||||||
// import { useLocation } from "react-router-dom";
|
// import { useLocation } from "react-router-dom";
|
||||||
// import { Form, Formik } from "formik";
|
import { Form, Formik } from "formik";
|
||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
import {useMutation, useQuery} from "@tanstack/react-query";
|
||||||
import getImage from "../../utils/getImage";
|
import getImage from "../../utils/getImage";
|
||||||
import { IoMdArrowDropdown } from "react-icons/io";
|
import {IoMdArrowDropdown} from "react-icons/io";
|
||||||
import { completeProfile, getCommonPractice } from '../../services/services';
|
import {completeProfile, getCommonPractice} from '../../services/services';
|
||||||
import siteLinks from "../../links/siteLinks";
|
import siteLinks from "../../links/siteLinks";
|
||||||
import { useLocation, useNavigate } from "react-router-dom";
|
import {useLocation, useNavigate} from "react-router-dom";
|
||||||
import { updateUserDetails } from "../../store/UserDetails";
|
import {updateUserDetails} from "../../store/UserDetails";
|
||||||
import { useDispatch } from "react-redux";
|
import {useDispatch} from "react-redux";
|
||||||
|
|
||||||
|
|
||||||
// const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
// practice: Yup.string().required("Required"),
|
practice: Yup.string().required("Required"),
|
||||||
// specialization: Yup.string().required("Required"),
|
specialization: Yup.string().when('practice', {
|
||||||
// introduction: Yup.string().min(1, "Minimum 10 characters").max(50, "Maximum 50 characters").required("Required"),
|
is: (value) => typeof value === 'string' && value.trim().length > 0,
|
||||||
// })
|
then: (schema) => schema.required('Required'),
|
||||||
|
otherwise: (schema) => schema,
|
||||||
// const initialValues = {
|
}),
|
||||||
// practice: '',
|
introduction: Yup.string().min(1, "Minimum 1 character").max(50, "Maximum 50 characters"),
|
||||||
// specialization: '',
|
url_name: Yup.string().min(6, "Minimum 6 characters").max(16, "Maximum 16 characters").required("Required").matches(
|
||||||
// introduction: '',
|
/^[a-zA-Z0-9]+$/, // Regex for alphanumeric characters
|
||||||
// };
|
'Must contain only alphanumeric characters' // Custom error message
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
export default function ProfileCompleteCom(){
|
export default function ProfileCompleteCom() {
|
||||||
|
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
|
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
|
|
||||||
const {state:{redirectLink}} = useLocation()
|
const {state: {redirectLink}} = useLocation()
|
||||||
|
|
||||||
const [practices, setPractices] = useState([])
|
const [practices, setPractices] = useState([])
|
||||||
|
const [specialties, setSpecialties] = useState([])
|
||||||
|
|
||||||
const [initialValues, setInitialValues] = useState({
|
const [initialValues, setInitialValues] = useState({
|
||||||
practice: '',
|
practice: '',
|
||||||
specialization: '',
|
specialization: '',
|
||||||
introduction: '',
|
introduction: '',
|
||||||
|
url_name: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
const specialties = useMemo(()=>{ // FUNCTION TO UPDATE SPECIALITY ARRAY EACH TIME PRACTICE CHANGES
|
const handleUpdateSpecialties = (e) => {
|
||||||
setInitialValues(prev => ({...prev, specialization: ''}))
|
setInitialValues(prev => ({...prev, specialization: ''}))
|
||||||
if(!initialValues.practice){
|
const specialtiesArr = practices.filter(item => item.practice == e.target.value)[0]?.specialties
|
||||||
return []
|
setSpecialties(specialtiesArr)
|
||||||
}
|
}
|
||||||
const specialtiesArr = practices.filter(item => item.practice == initialValues.practice)[0]?.specialties
|
|
||||||
return specialtiesArr
|
|
||||||
},[initialValues.practice])
|
|
||||||
|
|
||||||
|
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationFn: (fields) => {
|
mutationFn: (fields) => {
|
||||||
const {practice, specialization} = fields
|
const {practice, specialization, url_name} = fields
|
||||||
if(!practice || !specialization){
|
if (!practice || !specialization || !url_name) {
|
||||||
throw new Error('Please select both practice and specialization fields')
|
throw new Error('Please Select both Practice, Specialization and Enter URL_Name')
|
||||||
}
|
}
|
||||||
return completeProfile(fields)
|
return completeProfile(fields)
|
||||||
},
|
},
|
||||||
onError: () => {
|
onError: () => {
|
||||||
setTimeout(()=>{mutation.reset()}, 4000)
|
setTimeout(() => {
|
||||||
|
mutation.reset()
|
||||||
|
}, 4000)
|
||||||
},
|
},
|
||||||
onSuccess: (res) => {
|
onSuccess: (res) => {
|
||||||
if(res.data.resultCode != '0'){
|
if (res.data.resultCode != '0') {
|
||||||
throw({message: res?.data?.resultDescription})
|
throw({message: res?.data?.resultDescription})
|
||||||
}
|
}
|
||||||
dispatch(updateUserDetails({profile_completed: res?.data?.profile_completed }));
|
dispatch(updateUserDetails({profile_completed: res?.data?.profile_completed}));
|
||||||
setTimeout(()=>{
|
setTimeout(() => {
|
||||||
navigate(redirectLink)
|
navigate(redirectLink)
|
||||||
},2000)
|
}, 2000)
|
||||||
// console.log('res', res)
|
// console.log('res', res)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -79,11 +82,11 @@ export default function ProfileCompleteCom(){
|
|||||||
mutationFn: (fields) => {
|
mutationFn: (fields) => {
|
||||||
return getCommonPractice(fields)
|
return getCommonPractice(fields)
|
||||||
},
|
},
|
||||||
onError: ()=> {
|
onError: () => {
|
||||||
setPractices([])
|
setPractices([])
|
||||||
},
|
},
|
||||||
onSuccess: (res) => {
|
onSuccess: (res) => {
|
||||||
if(!res?.data){
|
if (!res?.data) {
|
||||||
return setPractices([])
|
return setPractices([])
|
||||||
}
|
}
|
||||||
let returnPractices = Object.entries(res?.data).filter(([key, value]) => typeof value == 'object')?.map(item => item[1])
|
let returnPractices = Object.entries(res?.data).filter(([key, value]) => typeof value == 'object')?.map(item => item[1])
|
||||||
@@ -91,30 +94,26 @@ export default function ProfileCompleteCom(){
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const handlePracticeChange = ({target:{name, value}}) => {
|
const handleCompleteProfile = (values) => { // FUNCTION TO COMPLETE PROFILE
|
||||||
setInitialValues(prev => ({...prev, [name]:value}))
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleCompleteProfile = () => { // FUNCTION TO COMPLETE PROFILE
|
|
||||||
let reqData = {
|
let reqData = {
|
||||||
token: localStorage.getItem('token'), // USER TOKEN
|
token: localStorage.getItem('token'), // USER TOKEN
|
||||||
uid: localStorage.getItem('uid'), // USER UID
|
uid: localStorage.getItem('uid'), // USER UID
|
||||||
...initialValues
|
...values
|
||||||
}
|
}
|
||||||
mutation.mutate(reqData)
|
mutation.mutate(reqData)
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(() => {
|
||||||
let reqData = {
|
let reqData = {
|
||||||
token: localStorage.getItem('token'), // USER TOKEN
|
token: localStorage.getItem('token'), // USER TOKEN
|
||||||
uid: localStorage.getItem('uid') // USER UID
|
uid: localStorage.getItem('uid') // USER UID
|
||||||
}
|
}
|
||||||
commonPractices.mutate(reqData)
|
commonPractices.mutate(reqData)
|
||||||
},[])
|
}, [])
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
|
|
||||||
<BreadcrumbComBS title='Tell us more about your practice.' paths={['Dashboard', 'Profile']} />
|
<BreadcrumbComBS title='Tell us more about your practice.' paths={['Dashboard', 'Profile']}/>
|
||||||
|
|
||||||
{commonPractices?.isFetching ?
|
{commonPractices?.isFetching ?
|
||||||
<>
|
<>
|
||||||
@@ -130,87 +129,170 @@ export default function ProfileCompleteCom(){
|
|||||||
<p className='text-danger'>{commonPractices?.error?.message}</p>
|
<p className='text-danger'>{commonPractices?.error?.message}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
:
|
:
|
||||||
<div className="row pt-1">
|
<div className="row pt-1">
|
||||||
<div className="col-md-6 m-b-30">
|
<div className="col-md-6 m-b-30">
|
||||||
<div className="card card-statistics h-100 mb-0">
|
<div className="card card-statistics h-100 mb-0" style={{borderRadius: '10px'}}>
|
||||||
{/* <div className="card-header d-flex align-items-center justify-content-between">
|
{/* <div className="card-header d-flex align-items-center justify-content-between">
|
||||||
<div className="card-heading">
|
<div className="card-heading">
|
||||||
<h4 className="card-title">My Product URLs</h4>
|
<h4 className="card-title">My Product URLs</h4>
|
||||||
</div>
|
</div>
|
||||||
</div> */}
|
</div> */}
|
||||||
{/* <div style={{minHeight: '400px'}}></div> */}
|
{/* <div style={{minHeight: '400px'}}></div> */}
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
<div className='h-100 row flex-column'>
|
<div className='h-100 row flex-column'>
|
||||||
{/* <div className="row"> */}
|
{/* <div className="row"> */}
|
||||||
<>
|
<Formik
|
||||||
<div className="">
|
initialValues={initialValues}
|
||||||
<div className="form-group position-relative">
|
validationSchema={validationSchema}
|
||||||
<label className={`text-black fw-bold control-label`}>Practice :</label>
|
onSubmit={handleCompleteProfile}
|
||||||
<div className="position-relative">
|
enableReinitialize={true}
|
||||||
{/* <select onChange={props.handleChange} name='practice' value={props.values.practice} className="form-control">
|
>
|
||||||
<option value=''>Select</option>
|
{(props) => {
|
||||||
{practices.map((practice, index)=>(
|
return (
|
||||||
<option key={index} value={practice.practice}>{practice.practice}</option>
|
<Form className='mt-2'>
|
||||||
))}
|
<>
|
||||||
</select> */}
|
<div className="">
|
||||||
<select onChange={handlePracticeChange} name='practice' value={initialValues.practice} className="form-control">
|
<div className="form-group position-relative">
|
||||||
<option value=''>Select</option>
|
<label className={`text-black fw-bold control-label`}>Practice : <span className="text-danger">{(props.errors.practice && props.touched.practice) && props.errors.practice}</span></label>
|
||||||
{practices.map((practice, index)=>(
|
<div className="position-relative">
|
||||||
<option key={index} value={practice.practice}>{practice.practice}</option>
|
{/* <select onChange={props.handleChange} name='practice' value={props.values.practice} className="form-control">
|
||||||
))}
|
<option value=''>Select</option>
|
||||||
</select>
|
{practices.map((practice, index)=>(
|
||||||
<IoMdArrowDropdown className='position-absolute w-auto' style={{top: '50%', right: '2px', transform: 'translateY(-50%)'}} />
|
<option key={index} value={practice.practice}>{practice.practice}</option>
|
||||||
</div>
|
))}
|
||||||
</div>
|
</select> */}
|
||||||
</div>
|
<select
|
||||||
|
onChange={(e) => {props.handleChange(e); props.setFieldValue('specialization', ''); handleUpdateSpecialties(e)}}
|
||||||
|
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>
|
||||||
|
<IoMdArrowDropdown className='position-absolute w-auto' style={{
|
||||||
|
top: '50%',
|
||||||
|
right: '2px',
|
||||||
|
transform: 'translateY(-50%)'
|
||||||
|
}}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="">
|
<div className="">
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className={`text-black fw-bold control-label`}>Specialization :</label>
|
<label className={`text-black fw-bold control-label`}>Your
|
||||||
<div className="position-relative">
|
Specialization : <span className="text-danger">{(props.errors.specialization && props.touched.specialization) && props.errors.specialization}</span></label>
|
||||||
<select onChange={handlePracticeChange} name='specialization' value={initialValues.specialization} className="form-control">
|
<div className="position-relative">
|
||||||
<option value=''>Select</option>
|
<select onChange={props.handleChange} name='specialization'
|
||||||
{specialties.map((specialty, index)=>(
|
value={props.values.specialization}
|
||||||
<option key={index} value={specialty}>{specialty}</option>
|
className="form-control">
|
||||||
))}
|
<option value=''>Select</option>
|
||||||
</select>
|
{specialties.map((specialty, index) => (
|
||||||
<IoMdArrowDropdown className='position-absolute w-auto' style={{top: '50%', right: '2px', transform: 'translateY(-50%)'}} />
|
<option key={index} value={specialty}>{specialty}</option>
|
||||||
</div>
|
))}
|
||||||
</div>
|
</select>
|
||||||
</div>
|
<IoMdArrowDropdown className='position-absolute w-auto' style={{
|
||||||
|
top: '50%',
|
||||||
|
right: '2px',
|
||||||
|
transform: 'translateY(-50%)'
|
||||||
|
}}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="">
|
<div className="">
|
||||||
<div className="form-group position-relative">
|
<div className="form-group position-relative">
|
||||||
<label className={`text-black fw-bold control-label`}>General Information :</label>
|
<label className={`text-black fw-bold control-label`}>Other General Information : <span className="text-danger">{(props.errors.introduction && props.touched.introduction) && props.errors.introduction}</span></label>
|
||||||
<textarea name='introduction' rows={10} style={{resize: 'none'}} className="form-control" value={initialValues.introduction} onChange={handlePracticeChange} />
|
<textarea name='introduction' rows={5} style={{resize: 'none'}}
|
||||||
</div>
|
className="form-control" value={props.values.introduction}
|
||||||
</div>
|
onChange={props.handleChange}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{(mutation.isError || mutation.isSuccess) &&
|
<div className="">
|
||||||
<>
|
<div className="form-group position-relativ'e">
|
||||||
<div className="">
|
{/*<label className={`text-black fw-bold control-label`}>What we use this*/}
|
||||||
<p className={`${mutation.isSuccess ? 'text-success' : 'text-danger'}`}>{mutation.isSuccess ? 'Completed successfully, redirecting...' : mutation.error.message}</p>
|
{/* information for :</label>*/}
|
||||||
</div>
|
<div style={{
|
||||||
</>
|
fontSize: '14px',
|
||||||
}
|
borderRadius: '10px',
|
||||||
|
backgroundColor: 'aliceblue',
|
||||||
|
fontWeight: 'bolder',
|
||||||
|
padding: '15px'
|
||||||
|
}}>
|
||||||
|
MERMS A.I. agents use the information supplied to help generate
|
||||||
|
useful entries for your product settings.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="mt-auto text-end">
|
<div className="">
|
||||||
<button type='button' onClick={handleCompleteProfile} className="btn btn-primary text-uppercase">{mutation.isPending ? 'loading...' : 'Continue'}</button>
|
<div className="form-group position-relative">
|
||||||
</div>
|
<label className={`text-black fw-bold control-label`}>URL Name : <span className="text-danger">{(props.errors.url_name && props.touched.url_name) && props.errors.url_name}</span></label>
|
||||||
</>
|
<div className="position-relative d-flex flex-column flex-xxl-row" style={{gap: '10px'}}>
|
||||||
{/* </div> */}
|
{/* <select onChange={handlePracticeChange} name='url_name'
|
||||||
|
value={initialValues.url_name} 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%)'
|
||||||
|
}}/> */}
|
||||||
|
<input
|
||||||
|
className="form-control"
|
||||||
|
onChange={props.handleChange} name='url_name'
|
||||||
|
value={props.values.url_name}
|
||||||
|
minLength={6}
|
||||||
|
maxLength={16}
|
||||||
|
/>
|
||||||
|
<p className="border-radius-10 p-2 border border-warning"
|
||||||
|
style={{fontSize: "1.0rem"}}>We use the URL Name to form part of
|
||||||
|
your default URL when we configure
|
||||||
|
a new URL for your products. You can always change your product
|
||||||
|
URL. <br/>
|
||||||
|
<b>Example : <span style={{color: 'red'}}>url_name</span>.product.mermsemr.com
|
||||||
|
</b>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</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='submit'
|
||||||
|
className="btn btn-primary text-uppercase">{mutation.isPending ? 'loading...' : 'Continue'}</button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</Formik>
|
||||||
|
{/* </div> */}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div className="col-md-6 m-b-30">
|
||||||
<div className="col-md-6 m-b-30">
|
<div className="text-center img-block left-column wow fadeInRight">
|
||||||
<div className="text-center img-block left-column wow fadeInRight">
|
<img className="img-fluid" src={getImage('tell-us-more.png')} alt="content-image"/>
|
||||||
<img className="img-fluid" src={getImage('img-07.png')} alt="content-image" />
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
</>;
|
</>;
|
||||||
|
|
||||||
|
|||||||
@@ -1,214 +1,274 @@
|
|||||||
import React from "react";
|
import React, { useEffect, useMemo, useState } from "react";
|
||||||
|
import { Form, Formik } from "formik";
|
||||||
|
import * as Yup from "yup";
|
||||||
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
|
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
|
||||||
|
import getImage from "../../utils/getImage";
|
||||||
|
import queryKeys from "../../services/queryKeys";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import { profileDetails } from "../../services/services";
|
||||||
|
|
||||||
|
|
||||||
export default function Settings(){
|
|
||||||
|
|
||||||
return(
|
|
||||||
|
const profileValidationSchema = Yup.object().shape({
|
||||||
|
// firstname: Yup.string().required("firstname is required"),
|
||||||
|
// lastname: Yup.string().required("lastname is required"),
|
||||||
|
// email: Yup.string().required("email is required"),
|
||||||
|
// account_name: Yup.string().required("account name is required"),
|
||||||
|
// phone: Yup.string().required("phone is required"),
|
||||||
|
// full_address: Yup.string().required("full address is required"),
|
||||||
|
})
|
||||||
|
|
||||||
|
const linksValidationSchema = Yup.object().shape({
|
||||||
|
// facebook_url: Yup.string().required("facebook is required"),
|
||||||
|
// twitter_url: Yup.string().required("twitter is required"),
|
||||||
|
// blogger_url: Yup.string().required("blog is required"),
|
||||||
|
// google_url: Yup.string().required("google is required"),
|
||||||
|
// linked_url: Yup.string().required("linkedin is required"),
|
||||||
|
// website_url: Yup.string().required("website is required"),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
export default function Settings() {
|
||||||
|
const avtarImage = "avtar/merms-user.png";
|
||||||
|
|
||||||
|
const [intialData, setInitialData] = useState({
|
||||||
|
external_links: {},
|
||||||
|
personal_data: {},
|
||||||
|
})
|
||||||
|
|
||||||
|
const {data:profileInfo, isFetching, isError, error} = useQuery({
|
||||||
|
queryKey: queryKeys.profile_data,
|
||||||
|
queryFn: () => {
|
||||||
|
let reqData = {
|
||||||
|
token: localStorage.getItem('token'), // USER TOKEN
|
||||||
|
uid: localStorage.getItem('uid') // USER UID
|
||||||
|
}
|
||||||
|
return profileDetails(reqData)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// const profileData = profileInfo?.data // profile data
|
||||||
|
useMemo(()=>{
|
||||||
|
const data = profileInfo?.data
|
||||||
|
setInitialData({external_links: data?.external_links, personal_data: data?.personal_data})
|
||||||
|
},[profileInfo])
|
||||||
|
// console.log('INI', intialData)
|
||||||
|
|
||||||
|
|
||||||
|
const updateProfile = (values, helpers) => {
|
||||||
|
console.log('Values', values)
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateLinks = (values, helpers) => {
|
||||||
|
console.log('Values', values)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
<>
|
<>
|
||||||
<BreadcrumbComBS title='Settings' paths={['Dashboard', 'Settings']} />
|
<BreadcrumbComBS title='Settings' paths={['Dashboard', 'Settings']}/>
|
||||||
{/*<div className="row">*/}
|
{/*<div className="row">*/}
|
||||||
{/* <div className="vh-100 col-12 flex align-items-center">Coming Soon</div>*/}
|
{/* <div className="vh-100 col-12 flex align-items-center">Coming Soon</div>*/}
|
||||||
{/*</div>*/}
|
{/*</div>*/}
|
||||||
|
|
||||||
|
{isFetching ?
|
||||||
<div className="row account-contant">
|
<>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-12">
|
||||||
|
<p className="text-mute">Loading...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
: isError ?
|
||||||
|
<div className="row">
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
<div className="card card-statistics">
|
<p className="text-danger">{error?.message}</p>
|
||||||
<div className="card-body p-0" style={{backgroundColor:"#f9f9fb"}}>
|
</div>
|
||||||
<div className="row no-gutters">
|
</div>
|
||||||
<div className="col-xl-3 pb-xl-0 pb-5 border-right">
|
:
|
||||||
<div className="page-account-profil pt-5">
|
<div className="row account-contant">
|
||||||
<div className="profile-img text-center rounded-circle">
|
<div className="col-12">
|
||||||
<div className="pt-5">
|
<div className="card card-statistics">
|
||||||
<div className="bg-img m-auto">
|
<div className="card-body p-0" style={{backgroundColor: "#f9f9fb"}}>
|
||||||
<img src="assets/img/avtar/01.jpg" className="img-fluid"
|
<div className="row no-gutters">
|
||||||
alt="users-avatar" />
|
<div className="col-xl-3 pb-xl-0 pb-5 border-right">
|
||||||
</div>
|
<div className="page-account-profil pt-5">
|
||||||
<div className="profile pt-4">
|
<div className="profile-img text-center rounded-circle">
|
||||||
<h4 className="mb-1">Alice Williams</h4>
|
<div className="pt-5">
|
||||||
<p>Enthusiast</p>
|
<div className="bg-img m-auto">
|
||||||
|
{/*<img src="assets/img/avtar/01.jpg" className="img-fluid"*/}
|
||||||
|
{/* alt="users-avatar" />*/}
|
||||||
|
<img src={getImage(avtarImage)}
|
||||||
|
className="img-fluid" alt="user"/>
|
||||||
|
</div>
|
||||||
|
<div className="profile pt-4">
|
||||||
|
<h4 className="mb-1">{intialData?.personal_data?.lastname} {intialData?.personal_data?.firstname}</h4>
|
||||||
|
<div style={{padding: '10px'}}>
|
||||||
|
<hr/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="py-5 profile-counter">
|
<div className="profile-btn text-center">
|
||||||
<ul className="nav justify-content-center text-center">
|
<div>
|
||||||
<li className="nav-item border-right px-3">
|
<button className="btn btn-light text-primary mb-2">Upload New Avatar
|
||||||
<div>
|
|
||||||
<h4 className="mb-0">90</h4>
|
|
||||||
<p>Post</p>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li className="nav-item border-right px-3">
|
|
||||||
<div>
|
|
||||||
<h4 className="mb-0">1.5K</h4>
|
|
||||||
<p>Messages</p>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li className="nav-item px-3">
|
|
||||||
<div>
|
|
||||||
<h4 className="mb-0">4.4K</h4>
|
|
||||||
<p>Members</p>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="profile-btn text-center">
|
|
||||||
<div>
|
|
||||||
<button className="btn btn-light text-primary mb-2">Upload New Avatar
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
{/*<div>*/}
|
|
||||||
{/* <button className="btn btn-danger">Delete</button>*/}
|
|
||||||
{/*</div>*/}
|
|
||||||
</div>
|
|
||||||
</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 Personal Settings</h5>
|
|
||||||
</div>
|
|
||||||
<div className="p-4">
|
|
||||||
<form>
|
|
||||||
<div className="form-row">
|
|
||||||
<div className="form-group col-md-12">
|
|
||||||
<label htmlFor="name1">First Name</label>
|
|
||||||
<input type="text" className="form-control" id="name1"
|
|
||||||
value="Alice" />
|
|
||||||
</div>
|
|
||||||
<div className="form-group col-md-12">
|
|
||||||
<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"
|
|
||||||
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>
|
|
||||||
|
|
||||||
{/*<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>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
{/*<div>*/}
|
||||||
</form>
|
{/* <button className="btn btn-danger">Delete</button>*/}
|
||||||
|
{/*</div>*/}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div className="col-xl-5 col-md-6 col-12 border-t border-right">
|
||||||
<div className="col-xl-4 col-md-6 border-t col-12">
|
<div className="page-account-form">
|
||||||
<div className="page-account-form">
|
<div className="form-titel border-bottom p-3">
|
||||||
<div className="form-titel border-bottom p-3">
|
<h5 className="mb-0 py-2">Edit Your Personal Settings</h5>
|
||||||
<h5 className="mb-0 py-2">Your External Link</h5>
|
</div>
|
||||||
|
<div className="p-4">
|
||||||
|
<Formik
|
||||||
|
initialValues={intialData?.personal_data}
|
||||||
|
validationSchema={profileValidationSchema}
|
||||||
|
onSubmit={updateProfile}
|
||||||
|
>
|
||||||
|
{(props) => {
|
||||||
|
return (
|
||||||
|
<Form className=''>
|
||||||
|
<div className="form-row">
|
||||||
|
<div className="form-group col-md-12">
|
||||||
|
<label htmlFor="name1">First Name {(props.errors.firstname && props.touched.firstname) && <span className="text-danger">*</span>}</label>
|
||||||
|
<input type="text" className="form-control" name="firstname" value={props.values?.firstname} onChange={props.handleChange} />
|
||||||
|
</div>
|
||||||
|
<div className="form-group col-md-12">
|
||||||
|
<label htmlFor="name1">Last Name {(props.errors.lastname && props.touched.lastname) && <span className="text-danger">*</span>}</label>
|
||||||
|
<input type="text" className="form-control" name="lastname" value={props.values?.lastname} onChange={props.handleChange} />
|
||||||
|
</div>
|
||||||
|
<div className="form-group col-md-12">
|
||||||
|
<label htmlFor="name1">Account Name {(props.errors.account_name && props.touched.account_name) && <span className="text-danger">*</span>}</label>
|
||||||
|
<input type="text" className="form-control" name="account_name" value={props.values?.account_name} onChange={props.handleChange} />
|
||||||
|
</div>
|
||||||
|
{/*<div className="form-group col-md-12">*/}
|
||||||
|
{/* <label htmlFor="title1">Email</label>*/}
|
||||||
|
{/* <input type="text" className="form-control" name="title1"*/}
|
||||||
|
{/* value="email@email.com" />*/}
|
||||||
|
{/*</div>*/}
|
||||||
|
<div className="form-group col-md-12">
|
||||||
|
<label htmlFor="phone1">Phone Number {(props.errors.phone && props.touched.phone) && <span className="text-danger">*</span>}</label>
|
||||||
|
<input type="text" className="form-control" name="phone" value={props.values?.phone} onChange={props.handleChange} />
|
||||||
|
</div>
|
||||||
|
<div className="form-group col-md-12">
|
||||||
|
<label htmlFor="email1">Email {(props.errors.email && props.touched.email) && <span className="text-danger">*</span>}</label>
|
||||||
|
<input type="text" className="form-control" name="email" value={props.values?.email} onChange={props.handleChange} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<label htmlFor="add1">Address {(props.errors.full_address && props.touched.full_address) && <span className="text-danger">*</span>}</label>
|
||||||
|
<input type="text" className="form-control" name="full_address" value={props.values?.full_address} onChange={props.handleChange} />
|
||||||
|
</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>*/}
|
||||||
|
|
||||||
|
{/*<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>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</Formik>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="p-4">
|
</div>
|
||||||
<form>
|
<div className="col-xl-4 col-md-6 border-t col-12">
|
||||||
<div className="form-group">
|
<div className="page-account-form">
|
||||||
<label htmlFor="fb">Facebook URL:</label>
|
<div className="form-titel border-bottom p-3">
|
||||||
<input type="text" className="form-control" id="fb"
|
<h5 className="mb-0 py-2">Your External Link</h5>
|
||||||
value="https://www.facebook.com/" />
|
</div>
|
||||||
</div>
|
<div className="p-4">
|
||||||
<div className="form-group">
|
<Formik
|
||||||
<label htmlFor="tr">Twitter URL:</label>
|
initialValues={intialData?.external_links}
|
||||||
<input type="text" className="form-control" id="tr"
|
validationSchema={linksValidationSchema}
|
||||||
value="https://twitter.com/" />
|
onSubmit={updateLinks}
|
||||||
</div>
|
>
|
||||||
|
{(props) => {
|
||||||
|
return (
|
||||||
|
<Form className=''>
|
||||||
|
<div className="form-group">
|
||||||
|
<label htmlFor="fb">Facebook URL: {(props.errors.facebook_url && props.touched.facebook_url) && <span className="text-danger">*</span>}</label>
|
||||||
|
<input type="text" className="form-control" name="facebook_url" value={props.values?.facebook_url} onChange={props.handleChange} />
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<label htmlFor="tr">Twitter URL: {(props.errors.twitter_url && props.touched.twitter_url) && <span className="text-danger">*</span>}</label>
|
||||||
|
<input type="text" className="form-control" name="twitter_url" value={props.values?.twitter_url} onChange={props.handleChange} />
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label htmlFor="br">Blogger URL:</label>
|
<label htmlFor="br">Blogger URL: {(props.errors.blogger_url && props.touched.blogger_url) && <span className="text-danger">*</span>}</label>
|
||||||
<input type="text" className="form-control" id="br"
|
<input type="text" className="form-control" name="blogger_url" value={props.values?.blogger_url} onChange={props.handleChange} />
|
||||||
value="https://www.blogger.com" />
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label htmlFor="go">Google+ URL:</label>
|
<label htmlFor="go">Google+ URL: {(props.errors.google_url && props.touched.google_url) && <span className="text-danger">*</span>}</label>
|
||||||
<input type="text" className="form-control" id="go"
|
<input type="text" className="form-control" name="google_url" value={props.values?.google_url} onChange={props.handleChange} />
|
||||||
value="https://plus.google.com/discover" />
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label htmlFor="li">LinkedIn URL:</label>
|
<label htmlFor="li">LinkedIn URL: {(props.errors.linked_url && props.touched.linked_url) && <span className="text-danger">*</span>}</label>
|
||||||
<input type="text" className="form-control" id="li"
|
<input type="text" className="form-control" name="linked_url" value={props.values?.linked_url} onChange={props.handleChange} />
|
||||||
value="https://in.linkedin.com/" />
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label htmlFor="we">Website URL:</label>
|
<label htmlFor="we">Website URL: {(props.errors.website_url && props.touched.website_url) && <span className="text-danger">*</span>}</label>
|
||||||
<input type="text" className="form-control" id="we"
|
<input type="text" className="form-control" name="website_url" value={props.values?.website_url} onChange={props.handleChange} />
|
||||||
value="https://yourwebsite.com" />
|
</div>
|
||||||
</div>
|
<div style={{textAlign: "right"}}>
|
||||||
<div style={{textAlign:"right"}}>
|
<button type="submit" className="btn btn-primary">Update Links
|
||||||
<button type="submit" className="btn btn-primary">Update Links</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</Form>
|
||||||
</form>
|
);
|
||||||
|
}}
|
||||||
|
</Formik>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -216,8 +276,7 @@ export default function Settings(){
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
}
|
||||||
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
import React from "react";
|
||||||
|
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
|
||||||
|
import getImage from "../../utils/getImage";
|
||||||
|
|
||||||
|
export default function Start() {
|
||||||
|
|
||||||
|
const bgImg = getImage("side-banner.jpg");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<BreadcrumbComBS title='Get Started...' paths={['Dashboard', 'Start']}/>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-xl-3 col-md-6">
|
||||||
|
<div className="card card-statistics text-center py-3"
|
||||||
|
style={{minHeight: '550px', borderRadius: '10px', backgroundImage: `url(${bgImg})`}}>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<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>Start with</h5>
|
||||||
|
<h2 className="text-primary pt-3"><a href="/product/A000001">Personal Website</a></h2>
|
||||||
|
<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="/product/A000001"
|
||||||
|
className="btn btn-primary btn-round btn-sm">Start</a></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<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>Start with</h5>
|
||||||
|
<h2 className="text-primary pt-3"><a href="/product/A000002">Business Website</a></h2>
|
||||||
|
<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="/product/A000001"
|
||||||
|
className="btn btn-primary btn-round btn-sm">Start</a></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<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>small</h5>*/}
|
||||||
|
{/* <h2 className="text-primary pt-3">$80</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 premium</a></div>*/}
|
||||||
|
{/*</div>*/}
|
||||||
|
{/*</div>*/}
|
||||||
|
{/*</div>*/}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ import {useQuery} from '@tanstack/react-query';
|
|||||||
import queryKeys from '../../services/queryKeys';
|
import queryKeys from '../../services/queryKeys';
|
||||||
import siteLinks from "../../links/siteLinks";
|
import siteLinks from "../../links/siteLinks";
|
||||||
import {Link, useNavigate} from 'react-router-dom'
|
import {Link, useNavigate} from 'react-router-dom'
|
||||||
import getDateFromDateString from '../../helpers/GetDateFromDateString';
|
import getDateTimeFromDateString from '../../helpers/getDateTimeFromDateString';
|
||||||
|
|
||||||
export default function Subscription() {
|
export default function Subscription() {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
@@ -57,8 +57,8 @@ export default function Subscription() {
|
|||||||
<h2 className="text-primary pt-3">{currentSubscription?.display_name}</h2>
|
<h2 className="text-primary pt-3">{currentSubscription?.display_name}</h2>
|
||||||
</div>
|
</div>
|
||||||
<div className="pt-2" style={{textAlign: 'left'}}>
|
<div className="pt-2" style={{textAlign: 'left'}}>
|
||||||
<div style={{fontSize: '10px'}}>
|
<div style={{fontSize: '12px', fontWeight: 'bolder' , color: "#3E3699" }}>
|
||||||
Next Payment: {getDateFromDateString(currentSubscription?.next_payment)}
|
Next Payment: {getDateTimeFromDateString(currentSubscription?.next_payment)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -84,11 +84,19 @@ export default function Subscription() {
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="pt-2">
|
<div className="pt-2" style={{fontWeight: 'bolder'}}>
|
||||||
<button onClick={() => {
|
{
|
||||||
navigate(siteLinks.subscribe, {state: {selectedSubscription: value, customerId: stripe_customer_id }})
|
(currentSubscription?.display_name == value.option_name) ? 'Current Subscription' :
|
||||||
}}
|
<button onClick={() => {
|
||||||
className="btn btn-inverse-secondary btn-round btn-sm">Go {value.display_name}</button>
|
navigate(siteLinks.subscribe, {
|
||||||
|
state: {
|
||||||
|
selectedSubscription: value,
|
||||||
|
customerId: stripe_customer_id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
className="btn btn-inverse-secondary btn-round btn-sm">Go {value.display_name}</button>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import React from "react";
|
||||||
|
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
|
||||||
|
import TrafficChart from "./TrafficChart";
|
||||||
|
|
||||||
|
|
||||||
|
export default function Traffic() {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<BreadcrumbComBS title='Traffic' paths={['Dashboard', 'Traffic']}/>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-4">
|
||||||
|
<div className="card card-statistics" style={{minHeight: '350px', borderRadius: '10px', backgroundColor: 'aliceblue'}}>
|
||||||
|
<div className="card-header">
|
||||||
|
<div className="card-heading">
|
||||||
|
<h4 className="card-title">Site Traffic Monitoring</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="card-body">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-lg-8">
|
||||||
|
<div className="card card-statistics">
|
||||||
|
<div className="card-header">
|
||||||
|
<div className="card-heading">
|
||||||
|
<h4 className="card-title">Plot</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="card-body">
|
||||||
|
<div className="apexchart-wrapper">
|
||||||
|
<TrafficChart />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import ReactApexChart from "react-apexcharts";
|
||||||
|
|
||||||
|
const TrafficChart = () => {
|
||||||
|
const [state, setState] = useState({
|
||||||
|
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
// name: "High - 2013",
|
||||||
|
name: 'Professional Website',
|
||||||
|
data: [28, 29, 33, 36, 32, 32, 33, 33, 36, 32, 32, 33]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// name: "Low - 2013",
|
||||||
|
name: 'Personal Website',
|
||||||
|
data: [12, 11, 14, 18, 17, 13, 13, 14, 18, 17, 13, 13]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// name: "Low - 2013",
|
||||||
|
name: 'Personal Forum',
|
||||||
|
data: [10, 11, 14, 19, 18, 23, 17, 14, 10, 17, 23, 10]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// name: "High - 2013",
|
||||||
|
name: 'Professional Forum',
|
||||||
|
data: [20, 19, 30, 36, 30, 35, 33, 33, 36, 32, 32, 30]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
options: {
|
||||||
|
chart: {
|
||||||
|
height: 350,
|
||||||
|
type: 'line',
|
||||||
|
dropShadow: {
|
||||||
|
enabled: true,
|
||||||
|
color: '#000',
|
||||||
|
top: 18,
|
||||||
|
left: 7,
|
||||||
|
blur: 10,
|
||||||
|
opacity: 0.5
|
||||||
|
},
|
||||||
|
zoom: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
toolbar: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
colors: ['#77B6EA', '#545454', '#F50898','#213ece'],
|
||||||
|
dataLabels: {
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
stroke: {
|
||||||
|
curve: 'smooth'
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
text: 'Recent Sites Traffic',
|
||||||
|
align: 'left'
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
borderColor: '#e7e7e7',
|
||||||
|
row: {
|
||||||
|
colors: ['#f3f3f3', 'transparent'], // takes an array which will be repeated on columns
|
||||||
|
opacity: 0.5
|
||||||
|
},
|
||||||
|
},
|
||||||
|
markers: {
|
||||||
|
size: 1
|
||||||
|
},
|
||||||
|
xaxis: {
|
||||||
|
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec'],
|
||||||
|
title: {
|
||||||
|
text: 'Month'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yaxis: {
|
||||||
|
title: {
|
||||||
|
text: 'Visits'
|
||||||
|
},
|
||||||
|
min: 5,
|
||||||
|
max: 40
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
position: 'top',
|
||||||
|
horizontalAlign: 'right',
|
||||||
|
floating: true,
|
||||||
|
offsetY: -25,
|
||||||
|
offsetX: -5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div id="chart">
|
||||||
|
<ReactApexChart options={state.options} series={state.series} type="line" height={450} />
|
||||||
|
</div>
|
||||||
|
<div id="html-dist"></div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default TrafficChart
|
||||||
@@ -99,8 +99,13 @@ $event-padding: 10px;
|
|||||||
border-radius: 5px !important;
|
border-radius: 5px !important;
|
||||||
}
|
}
|
||||||
.billing{
|
.billing{
|
||||||
background-color: darkgoldenrod;
|
background-color: #b9c2c5;
|
||||||
color: white;
|
color: #77117a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.next_billing{
|
||||||
|
background-color: #cff1f0;
|
||||||
|
color: #19548e;
|
||||||
}
|
}
|
||||||
.extraProductCard{
|
.extraProductCard{
|
||||||
background-color: aliceblue;
|
background-color: aliceblue;
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
function getDateFromDateString(dateString) {
|
||||||
|
const date = new Date(dateString);
|
||||||
|
|
||||||
|
// Ensure the date is valid
|
||||||
|
if (isNaN(date)) {
|
||||||
|
return "Invalid date string";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the year, month, and day
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = String(date.getMonth() + 1).padStart(2, '0'); // Months are 0-indexed, so we add 1
|
||||||
|
const day = String(date.getDate()).padStart(2, '0');
|
||||||
|
|
||||||
|
return `${year}-${month}-${day}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default getDateFromDateString
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
function getDateFromDateString(dateString) {
|
function getDateTimeFromDateString(dateString) {
|
||||||
const date = new Date(dateString);
|
const date = new Date(dateString);
|
||||||
|
|
||||||
const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
||||||
@@ -30,4 +30,4 @@ function getDateFromDateString(dateString) {
|
|||||||
return `${dayName}, ${monthName} ${day}${getOrdinal(day)} ${year} ${hours}:${minutes}${ampm}`;
|
return `${dayName}, ${monthName} ${day}${getOrdinal(day)} ${year} ${hours}:${minutes}${ampm}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default getDateFromDateString
|
export default getDateTimeFromDateString
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
const sortObjectByListOrder = (data) => {
|
||||||
|
const sortedEntriesByValue = Object.entries(data).sort((a, b) => {
|
||||||
|
if(a[1].list_order > b[1].list_order){
|
||||||
|
return 1
|
||||||
|
}else{
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
}); // Sorts numerically by value
|
||||||
|
|
||||||
|
const sortedObjectByValue = Object.fromEntries(sortedEntriesByValue);
|
||||||
|
return sortedObjectByValue
|
||||||
|
}
|
||||||
|
|
||||||
|
export default sortObjectByListOrder
|
||||||
@@ -3,6 +3,8 @@ const siteLinks = {
|
|||||||
help: '/help',
|
help: '/help',
|
||||||
home: '/',
|
home: '/',
|
||||||
dash: '/dash',
|
dash: '/dash',
|
||||||
|
traffic: '/traffic',
|
||||||
|
start: '/start',
|
||||||
profile_complete: '/profile-complete',
|
profile_complete: '/profile-complete',
|
||||||
product: '/product/*',
|
product: '/product/*',
|
||||||
contacts: '/contacts',
|
contacts: '/contacts',
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
const queryKeys = {
|
const queryKeys = {
|
||||||
user_details: ['user_details'],
|
user_details: ['user_details'],
|
||||||
product_url: ['product_url'],
|
product_url: ['product_url'],
|
||||||
|
dash_payments: ['dash_payments'],
|
||||||
products: ['product-data'],
|
products: ['product-data'],
|
||||||
myproduct_provision: ['myproduct_provision'],
|
myproduct_provision: ['myproduct_provision'],
|
||||||
product_page: ['product_page'],
|
product_page: ['product_page'],
|
||||||
recentAction: ['recent-action'],
|
recentAction: ['recent-action'],
|
||||||
settingsData: ['settings_data'],
|
settingsData: ['settings_data'],
|
||||||
|
myProductConfig: ['myproduct_config'],
|
||||||
productTemplateData: ['product_template_data'],
|
productTemplateData: ['product_template_data'],
|
||||||
subscriptions: ['subscriptions'],
|
subscriptions: ['subscriptions'],
|
||||||
|
profile_data: ['profile_data'],
|
||||||
|
|
||||||
dashboard: ['dashboard'],
|
dashboard: ['dashboard'],
|
||||||
topBar: ['top-bar'],
|
topBar: ['top-bar'],
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ const postAuxEnd = (path, postData, media=false) => {
|
|||||||
return axios.post(`${basePath}${path}`, postData).then(res => {
|
return axios.post(`${basePath}${path}`, postData).then(res => {
|
||||||
return res
|
return res
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
throw new Error(err.response.data.msg);
|
// console.log('res', err.response.data)
|
||||||
|
throw new Error(err.response.data.error_message);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,6 +76,14 @@ export const topBar = (reqData) => {
|
|||||||
return postAuxEnd(`/panel/account/bar`, postData, false)
|
return postAuxEnd(`/panel/account/bar`, postData, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FUNCTION TO GET PROFILE DATA
|
||||||
|
export const profileDetails = (reqData) => {
|
||||||
|
let postData = {
|
||||||
|
...reqData,
|
||||||
|
}
|
||||||
|
return postAuxEnd(`/panel/account/profile`, postData, false)
|
||||||
|
}
|
||||||
|
|
||||||
// FUNCTION TO GET PRODUCT BY ID
|
// FUNCTION TO GET PRODUCT BY ID
|
||||||
export const MyProductData = (reqData) => {
|
export const MyProductData = (reqData) => {
|
||||||
let postData = {
|
let postData = {
|
||||||
@@ -98,7 +107,7 @@ export const getCalendarEvents = (reqData) => {
|
|||||||
return postAuxEnd(`/panel/account/calendar`, postData, false)
|
return postAuxEnd(`/panel/account/calendar`, postData, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTION TO GET DASHBOARD PRODUCT DATA SECTION
|
// FUNCTION TO GET CONTACT DATA
|
||||||
export const contactData = (reqData) => {
|
export const contactData = (reqData) => {
|
||||||
let postData = {
|
let postData = {
|
||||||
...reqData,
|
...reqData,
|
||||||
@@ -106,6 +115,14 @@ export const contactData = (reqData) => {
|
|||||||
return postAuxEnd(`/panel/contacts`, postData, false)
|
return postAuxEnd(`/panel/contacts`, postData, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FUNCTION TO GET COMMENTS DATA
|
||||||
|
export const commentsData = (reqData) => {
|
||||||
|
let postData = {
|
||||||
|
...reqData,
|
||||||
|
}
|
||||||
|
return postAuxEnd(`/panel/comments`, postData, false)
|
||||||
|
}
|
||||||
|
|
||||||
// FUNCTION TO GET DASHBOARD PRODUCT URL DATA SECTION
|
// FUNCTION TO GET DASHBOARD PRODUCT URL DATA SECTION
|
||||||
export const productsURL = (reqData) => {
|
export const productsURL = (reqData) => {
|
||||||
let postData = {
|
let postData = {
|
||||||
@@ -114,6 +131,14 @@ export const productsURL = (reqData) => {
|
|||||||
return postAuxEnd(`/panel/account/products/url`, postData, false)
|
return postAuxEnd(`/panel/account/products/url`, postData, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FUNCTION TO GET DASHBOARD PAYMENTS
|
||||||
|
export const getDashPayments = (reqData) => {
|
||||||
|
let postData = {
|
||||||
|
...reqData,
|
||||||
|
}
|
||||||
|
return postAuxEnd(`/panel/account/payments`, postData, false)
|
||||||
|
}
|
||||||
|
|
||||||
// FUNCTION TO GET DASHBOARD PRODUCT DATA SECTION
|
// FUNCTION TO GET DASHBOARD PRODUCT DATA SECTION
|
||||||
export const productsData = (reqData) => {
|
export const productsData = (reqData) => {
|
||||||
let postData = {
|
let postData = {
|
||||||
@@ -173,6 +198,14 @@ export const getSettingsData = (reqData) => {
|
|||||||
return postAuxEnd(`/panel/myproduct/settings/values`, postData, false)
|
return postAuxEnd(`/panel/myproduct/settings/values`, postData, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FUNCTION TO GET MY PRODUCT CONFIGURATION
|
||||||
|
export const getMyProductConfig = (reqData) => {
|
||||||
|
let postData = {
|
||||||
|
...reqData,
|
||||||
|
}
|
||||||
|
return postAuxEnd(`/panel/myproduct/configuration`, postData, false)
|
||||||
|
}
|
||||||
|
|
||||||
// FUNCTION TO GET SETTINGS DATA
|
// FUNCTION TO GET SETTINGS DATA
|
||||||
export const getProductTemplateData = (reqData) => {
|
export const getProductTemplateData = (reqData) => {
|
||||||
let postData = {
|
let postData = {
|
||||||
@@ -181,6 +214,14 @@ export const getProductTemplateData = (reqData) => {
|
|||||||
return postAuxEnd(`/panel/account/products/templates`, postData, false)
|
return postAuxEnd(`/panel/account/products/templates`, postData, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FUNCTION TO ACTIVATE TEMPLATE
|
||||||
|
export const activateTemplate = (reqData) => {
|
||||||
|
let postData = {
|
||||||
|
...reqData,
|
||||||
|
}
|
||||||
|
return postAuxEnd(`/panel/account/template/activate`, postData, false)
|
||||||
|
}
|
||||||
|
|
||||||
// FUNCTION TO GET PRODUCT SUBSCRIPTIONS
|
// FUNCTION TO GET PRODUCT SUBSCRIPTIONS
|
||||||
export const completeProfile = (reqData) => {
|
export const completeProfile = (reqData) => {
|
||||||
let postData = {
|
let postData = {
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
import Start from "../component/start/Start";
|
||||||
|
|
||||||
|
|
||||||
|
export default function StartPage(){
|
||||||
|
return <Start />
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import Traffic from "../component/traffic/Traffic";
|
||||||
|
|
||||||
|
export default function TrafficPage() {
|
||||||
|
return (
|
||||||
|
<Traffic />
|
||||||
|
)
|
||||||
|
}
|
||||||