Compare commits

...

54 Commits

Author SHA1 Message Date
victorAnumudu 7ad1a585ea added refresh message display 2025-10-06 17:13:28 +01:00
CHIEFSOFT\ameye a8c2dd84f1 provison room 2025-10-06 11:52:38 -04:00
CHIEFSOFT\ameye ddcc6f0cd2 Rebuild site text change 2025-10-05 14:00:30 -04:00
CHIEFSOFT\ameye 683f81e8a6 customn temaplte 2025-10-05 13:53:11 -04:00
CHIEFSOFT\ameye 8e09c30c5c fix error on display 2025-10-05 13:18:16 -04:00
ameye af0d4db5de Merge branch 'external-url-populate' of MERMS/MermsPanelReactJS into master 2025-10-04 10:02:39 +00:00
victorAnumudu 6f3dae4116 populated externl URL 2025-10-04 10:23:29 +01:00
CHIEFSOFT\ameye 13900793af added external URL 2025-10-03 20:34:31 -04:00
CHIEFSOFT\ameye 698c89edfc fix URL page 2025-10-03 15:46:03 -04:00
CHIEFSOFT\ameye 4f5a383c99 Url configuration 2025-10-03 15:16:16 -04:00
ameye a5b6a11880 Merge branch 'set-url-endpoint' of MERMS/MermsPanelReactJS into master 2025-10-03 18:30:58 +00:00
victorAnumudu 0f58da3dce added set external url endpoint 2025-10-03 17:36:10 +01:00
ameye 1101e80d91 Merge branch 'set-url' of MERMS/MermsPanelReactJS into master 2025-09-30 20:17:32 +00:00
victorAnumudu b39a7ab58c url display fixed 2025-09-30 20:58:27 +01:00
ameye ad90def3c9 Merge branch 'url-alphanumeric-validator' of MERMS/MermsPanelReactJS into master 2025-09-30 09:54:33 +00:00
CHIEFSOFT\ameye 737430bf04 text transform 2025-09-30 05:38:08 -04:00
CHIEFSOFT\ameye d371ada805 configure url page 2025-09-30 05:21:01 -04:00
CHIEFSOFT\ameye b77f1d6213 display fix 2025-09-28 22:43:39 -04:00
victorAnumudu 64085c6be5 added alphanumeric validation for url name 2025-09-28 06:58:21 +01:00
ameye 3f8b45b6d6 Merge branch 'validation-fix' of MERMS/MermsPanelReactJS into master 2025-09-23 12:06:58 +00:00
victorAnumudu 4b6c927efc fixed validation bug 2025-09-23 05:56:33 +01:00
CHIEFSOFT\ameye 8a8adcbbc7 url name 2025-09-22 19:26:28 -04:00
CHIEFSOFT\ameye 706baadb33 url_name 2025-09-22 19:18:07 -04:00
ameye 58128fdd96 Merge branch 'url-name-payload' of MERMS/MermsPanelReactJS into master 2025-09-22 16:33:02 +00:00
victorAnumudu 14e8b1b01d made url name a required payload 2025-09-22 17:30:49 +01:00
ameye 504bfbcae4 Merge branch 'url-length' of MERMS/MermsPanelReactJS into master 2025-09-22 15:51:46 +00:00
victorAnumudu ec47aa5f9c added min and max length for url name 2025-09-22 15:53:22 +01:00
CHIEFSOFT\ameye 9267ded0f1 send URL name 2025-09-22 08:58:41 -04:00
ameye 0b24ca650d Merge branch 'url-name-field' of MERMS/MermsPanelReactJS into master 2025-09-19 23:16:46 +00:00
victorAnumudu b535a656a0 added url name field 2025-09-19 17:28:01 +01:00
CHIEFSOFT\ameye e69cc9130e fix page 2025-09-16 06:07:40 -04:00
CHIEFSOFT\ameye daafb66cbb url configure 2025-09-14 23:37:57 -04:00
CHIEFSOFT\ameye 3852468afe text fix 2025-09-14 23:19:49 -04:00
CHIEFSOFT\ameye d32204e08f test data 2025-09-14 23:14:24 -04:00
CHIEFSOFT\ameye 8372209923 cleanop plot 2025-09-14 22:45:23 -04:00
CHIEFSOFT\ameye 6c3f96d9a3 config url 2025-09-14 22:25:13 -04:00
CHIEFSOFT\ameye c25acecb1a Color config added 2025-09-14 07:24:48 -04:00
CHIEFSOFT\ameye 3f5ae4685e URL Configuration 2025-09-14 07:21:33 -04:00
ameye a80298c824 Merge branch 'login-input' of MERMS/MermsPanelReactJS into master 2025-09-13 20:24:28 +00:00
victorAnumudu e9bc1c1318 added login input fields max length 2025-09-13 16:47:18 +01:00
ameye 2543a91b19 Merge branch 'profile-name-fix' of MERMS/MermsPanelReactJS into master 2025-09-08 21:34:30 +00:00
victorAnumudu 4c38b0a31f profile name fixed 2025-09-08 22:30:18 +01:00
ameye 6ed396a34c Merge branch 'profile-settings' of MERMS/MermsPanelReactJS into master 2025-09-08 20:45:21 +00:00
victorAnumudu 465a480f02 profile details endpoint added 2025-09-08 21:24:22 +01:00
CHIEFSOFT\ameye 4409ed45f3 comments page cleanup 2025-09-08 11:32:08 -04:00
CHIEFSOFT\ameye 470c94ae5e remove address 2 2025-09-08 11:08:13 -04:00
CHIEFSOFT\ameye 52fd4275e9 plot page 2025-09-06 12:53:43 -04:00
CHIEFSOFT\ameye 0dadaf00b0 page style 2025-09-06 12:52:19 -04:00
CHIEFSOFT\ameye 0fbe0f4c3f start plot page 2025-09-06 12:38:17 -04:00
CHIEFSOFT\ameye 464182e583 Traffic page 2025-09-06 12:17:14 -04:00
ameye 517886df7e Merge branch 'config-reload' of MERMS/MermsPanelReactJS into master 2025-09-05 15:32:06 +00:00
victorAnumudu 3db5d56410 reloads config settings endpoint on change of product 2025-09-05 15:43:35 +01:00
CHIEFSOFT\ameye 6c107c8000 page c;leanup 2025-09-04 13:57:49 -04:00
ameye 225a3d36e4 Merge branch 'settings-page-sort' of MERMS/MermsPanelReactJS into master 2025-09-04 17:47:39 +00:00
25 changed files with 1431 additions and 1077 deletions
+4
View File
@@ -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;
+2
View File
@@ -25,6 +25,7 @@ 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 StartPage from "./views/StartPage";
import TrafficPage from "./views/TrafficPage";
function AppRouters() { function AppRouters() {
return ( return (
@@ -47,6 +48,7 @@ function AppRouters() {
<Route element={<UserExist/>}> <Route element={<UserExist/>}>
<Route path={siteLinks.start} element={<StartPage/>}/> <Route path={siteLinks.start} element={<StartPage/>}/>
<Route path={siteLinks.dash} element={<HomePage/>}/> <Route path={siteLinks.dash} element={<HomePage/>}/>
<Route path={siteLinks.traffic} element={<TrafficPage/>}/>
<Route path={siteLinks.profile_complete} element={<ProfileCompletePage/>}/> <Route path={siteLinks.profile_complete} element={<ProfileCompletePage/>}/>
<Route path={siteLinks.product} element={<ProductPage/>}/> <Route path={siteLinks.product} element={<ProductPage/>}/>
<Route path={siteLinks.reports} element={<ReportsPage/>}/> <Route path={siteLinks.reports} element={<ReportsPage/>}/>
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

+2 -2
View File
@@ -93,13 +93,13 @@ export default function Login() {
<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">
+5 -1
View File
@@ -82,9 +82,13 @@ export default function Signup() {
</button> </button>
</div> </div>
<div className="mt-3"> <div className="mt-3">
<hr />
<p className='font-medium'>Already have an account ? <p className='font-medium'>Already have an account ?
<Link to={siteLinks.login} <Link to={siteLinks.login}
className='hover:text-primary font-bold'> Sign In className='bg-secondary; hover:text-primary font-bold' style={{paddingRight: '10px'}}>
<button className="btn btn-warning text-uppercase">
Sign In
</button>
</Link> </Link>
</p> </p>
</div> </div>
+150 -111
View File
@@ -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">{process.env.REACT_APP_PANEL_NAME}</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> )
)
} }
+323 -532
View File
@@ -1,558 +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()
// })
const [activeCategoryUID, setActiveCategoryUID] = useState("0"); // HOLDS VALUE OF THE ACTIVE CATEGORY
const [activeContactUID, setActiveContactUID] = useState("");
const [activeDetail, setActiveDetail] = useState([]);
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 ( return (
<> <>
<BreadcrumbComBS title="Comments" paths={["Dashboard", "Comments"]} /> <BreadcrumbComBS title="Comments" paths={["Dashboard", "Comments"]} />
<div className="row"> {getContactData?.isPending ? (
{/*<div className="vh-100 col-12 flex align-items-center">Coming Soon</div>*/} <>
<div className="col-12"> <div className="row">
<div className="card card-statistics mail-contant"> <div className="col-12">
<div className="card-body p-0"> <p className="text-mute">Loading...</p>
<div className="row no-gutters"> </div>
<div className="col-md-4 col-xxl-2 col-md-4"> </div>
<div className="mail-sidebar"> </>
<div className="row justify-content-center"> ) : getContactData?.error ? (
<div className="col-12"> <div className="row">
<div className="text-center mail-sidebar-title px-4"> <div className="col-12">
<a <p className="text-danger">{getContactData?.error?.message}</p>
href="javascript:void(0)" </div>
className="btn btn-primary btn-block py-3 font-weight-bold font-18" </div>
> ) : (
<i className="fa fa-plus pl-2"></i> <div className="row">
</a> {/*<div className="vh-100 col-12 flex align-items-center">Coming Soon</div>*/}
</div> <div className="col-12">
</div> <div
<div className="col-12"> className="card card-statistics mail-contant"
<div className="px-4 py-4"> style={{ minHeight: "200px", borderRadius: "10px" }}
<ul className="pl-0"> >
<li className="py-2"> <div className="card-body p-0">
<a href="javascript:void(0)"> <div className="row no-gutters">
<span className="nav align-items-center"> <div className="col-md-4 col-xxl-2 col-md-4">
<span> <div className="mail-sidebar">
<i className="fa fa-envelope-o text-primary pr-4"></i> <div className="row justify-content-center">
</span> <div className="d-none col-12">
<span> <div className="text-center mail-sidebar-title px-4">
<span>Inbox</span> <a
</span> href="#"
<span className="nav-item ml-auto text-right"> className="btn btn-primary btn-block py-3 font-weight-bold font-18"
<span className="badge badge-pill badge-primary float-right"> >
0+ <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>
</span> </span>
</span> </a>
</a> </li>
</li> {/*<li className="py-2">*/}
<li className="py-2"> {/* <a href="#">*/}
<a href="javascript:void(0)"> {/* <span*/}
<span className="nav align-items-center"> {/* className="nav align-items-center">*/}
<span> {/* <span>*/}
<i className="fa fa-paper-plane-o pr-4"></i> {/* <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> </span>
<span> </div>
<span>Sent Mail</span> </li>
</span> {contactsCategory &&
</span> contactsCategory.map((item) => (
</a> <li
</li> key={item?.cid}
</ul> className="py-2"
<ul className="pl-0 mt-5"> onClick={() =>
<li className="py-2"> changeActiveCategoryUID(`${item?.cid}`)
<a href="javascript:void(0)"> }
<span className="nav align-items-center"> style={{ cursor: "pointer" }}
<span> >
<i className="fa fa-circle-o text-danger pr-4"></i> <div>
</span> <span className="nav align-items-center">
<span> <span>
<span>Personal</span> <i
</span> className={`fa fa-circle-o pr-4 ${
</span> activeCategoryUID ==
</a> `${item?.cid}`
</li> ? "text-primary"
<li className="py-2"> : "text-warning"
<a href="javascript:void(0)"> }`}
<span className="nav align-items-center"> ></i>
<span> </span>
<i className="fa fa-circle-o pr-4 text-warning"></i> <span>
</span> <span>{item?.description}</span>
<span> </span>
<span>Work</span> </span>
</span> </div>
</span> </li>
</a> ))}
</li> </ul>
<li className="py-2"> </div>
<a href="javascript:void(0)"> </div>
<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> </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-msg scrollbar scroll_dark"> <div className="mail-content border-right border-n h-100" style={{placeContent: 'center'}}>
<div className="mail-msg-item"> {/* <div className="mail-search border-bottom">
<a href="javascript:void(0)"> <div className="row align-items-center mx-0">
<div className="media align-items-center"> <div className="col-12">
<div className="mr-3"> <div className="form-group pt-3">
<div className="bg-img"> <input type="text" className="form-control" id="search" placeholder="Search.." />
<img <i className="fa fa-search"></i>
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>
</div> </div>
</a> </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> </div>
<div className="mail-msg-item"> {filteredContactData.length > 0 &&
<a href="javascript:void(0)"> <div className="col-xxl-6 border-t border-xxl-t">
<div className="media align-items-center"> <div className="mail-chat py-5 px-5">
<div className="mr-3"> <div className="media align-items-center">
<div className="bg-img"> <div className="bg-img mr-3">
<img <img
src={getImage("avtar/02.jpg")} src={activeContactUID ? getImage("avtar/" + activeDetail[0].category + ".png") : getImage(filteredContactData[0] == undefined ? "avtar/01.jpg": "avtar/" + filteredContactData[0].category + ".png")}
className="img-fluid" className="img-fluid"
alt="user" 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>
</div> <div className="mt-4 d-flex justify-content-between">
<div className="w-100"> <div>
<div className="mail-msg-item-titel justify-content-between"> <h3>
<p>DutcaPatrick</p> {activeContactUID
<p className="d-none d-xl-block"> ? activeDetail[0]?.title
06:59 <span> PM </span> : 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>
</div> </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>
</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 Augustines 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> </div>
</div> )}
</div> </>
</div>
</>
); );
} }
+1 -1
View File
@@ -41,7 +41,7 @@ export default function SocketIOContextProvider({children}) {
socket.on(socketOnEvents.receive_message, (data) => { socket.on(socketOnEvents.receive_message, (data) => {
// setSocketMsgReceived(data.message); // setSocketMsgReceived(data.message);
// dispatch(tableReload({type:'CHATMESSAGELIST'})) // dispatches to update chat message sending from owner to worker and vice versa // dispatch(tableReload({type:'CHATMESSAGELIST'})) // dispatches to update chat message sending from owner to worker and vice versa
console.log('DATA', data) console.log('SOCKET RECEIVED DATA *** ', data)
queryClient.refetchQueries({ queryClient.refetchQueries({
queryKey: [...queryKeys.recentAction], queryKey: [...queryKeys.recentAction],
// type: 'active', // type: 'active',
+2 -2
View File
@@ -54,12 +54,12 @@ export default function DashPayments() {
{/* <th style={{width: '30px'}}>#</th> */} {/* <th style={{width: '30px'}}>#</th> */}
<th>Date</th> <th>Date</th>
<th style={{width: '130px'}}>Subscription</th> <th style={{width: '130px'}}>Description</th>
<th style={{width: '80px'}}>Amount</th> <th style={{width: '80px'}}>Amount</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{payments.length > 0 ? {payments && payments?.length > 0 ?
payments.map((item, index) => { payments.map((item, index) => {
return ( return (
<tr key={index}> <tr key={index}>
+21 -4
View File
@@ -1,21 +1,26 @@
import React, { useMemo, useRef, useState } from "react"; import React, {useEffect, useMemo, useRef, useState} from "react";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import getImage from "../../utils/getImage"; import getImage from "../../utils/getImage";
import { useMutation, useQuery } from "@tanstack/react-query"; import { useMutation, useQuery } from "@tanstack/react-query";
import { productRefreshSite, getSettingsData } from "../../services/services"; import { productRefreshSite, getSettingsData } from "../../services/services";
import Settings from "./settingsTab/Settings"; import Settings from "./settingsTab/Settings";
import queryKeys from "../../services/queryKeys"; import queryKeys from "../../services/queryKeys";
import {SocketContextValues} from "../context/SocketIOContext";
export default function ProductActive({productData}){ export default function ProductActive({productData}){
const {joinRoom} = SocketContextValues() // Destructures values from socket context
const iframe = useRef() const iframe = useRef()
const [refreshMsg, setRefreshMsg] = useState('')
const refresh = useMutation({ const refresh = useMutation({
mutationFn: (fields) => { mutationFn: (fields) => {
return productRefreshSite(fields) return productRefreshSite(fields)
}, },
onSuccess: (res) => { onSuccess: (res) => {
setRefreshMsg(res?.data?.message)
setTimeout(()=>{setRefreshMsg('')},3000)
iframe.current.src += '' iframe.current.src += ''
} }
}) })
@@ -31,6 +36,13 @@ export default function ProductActive({productData}){
} }
let externalUrl= 'https://'+productData?.internal_url let externalUrl= 'https://'+productData?.internal_url
const productSubUID = productData.subscription_uid;
useEffect(() => {
const provision_room = "PROVISION_"+productSubUID;
console.log("JOINING ROOM ON ACTIVE *** ", provision_room);
joinRoom(provision_room); // provision subscription room
}, [])
return( return(
<> <>
{/*<BreadcrumbComBS title='Active Product Name' paths={['Dashboard', 'Product']} />*/} {/*<BreadcrumbComBS title='Active Product Name' paths={['Dashboard', 'Product']} />*/}
@@ -58,8 +70,13 @@ export default function ProductActive({productData}){
<iframe ref={iframe} style={{borderWidth: '0px'}} src={externalUrl} width="100%" height="600" title={externalUrl}></iframe> <iframe ref={iframe} style={{borderWidth: '0px'}} src={externalUrl} width="100%" height="600" title={externalUrl}></iframe>
</div> </div>
<div className="p-4 ml-auto"> <div className="p-4 ml-auto">
<button type="button" onClick={handleRefresh} className="btn btn-primary">{refresh.isPending ? 'Loading...' : 'Refresh Site'} <div className="d-flex justify-end gap-3">
</button> {refreshMsg &&
<p className="text-success text-center">{refreshMsg}</p>
}
<button type="button" onClick={handleRefresh} className="btn btn-primary">{refresh.isPending ? 'Initiating...' : 'Rebuild Site'}
</button>
</div>
</div> </div>
</div> </div>
</div> </div>
+70 -63
View File
@@ -1,39 +1,41 @@
import { useEffect } from "react"; import {useEffect} from "react";
import { useQuery } from "@tanstack/react-query"; import {useQuery} from "@tanstack/react-query";
import queryKeys from "../../services/queryKeys"; import queryKeys from "../../services/queryKeys";
import { productProvision } from "../../services/services"; import {productProvision} from "../../services/services";
import getImage from "../../utils/getImage"; import getImage from "../../utils/getImage";
import { SocketContextValues } from "../context/SocketIOContext"; import {SocketContextValues} from "../context/SocketIOContext";
export default function ProductProvision(props){ export default function ProductProvision(props) {
const {joinRoom} = SocketContextValues() // Destructures values from socket context const {joinRoom} = SocketContextValues() // Destructures values from socket context
const productTitle = props?.productData?.title; const productTitle = props?.productData?.title;
const productDescription = props?.productData?.description; const productDescription = props?.productData?.description;
const productID = props?.productData?.product_id const productID = props?.productData?.product_id
const productUID = props?.productData?.product_uid const productUID = props?.productData?.product_uid
const productSubUID = props?.productData?.product_subscription_uid const productSubUID = props?.productData?.product_subscription_uid
const reqData = { const reqData = {
product_id : productID, product_id: productID,
product_subscription_uid: productSubUID product_subscription_uid: productSubUID
} }
const {data:provision, isFetching, isError, error} = useQuery({ const {data: provision, isFetching, isError, error} = useQuery({
queryKey: queryKeys.myproduct_provision, queryKey: queryKeys.myproduct_provision,
queryFn: () => productProvision(reqData) queryFn: () => productProvision(reqData)
}) })
const provisionData = provision?.data const provisionData = provision?.data
useEffect(()=>{ useEffect(() => {
joinRoom(productSubUID); // provision subscription room const provision_room = "PROVISION_"+productSubUID;
},[]) console.log("JOINING ROOM ON START *** ", provision_room);
joinRoom(provision_room); // provision subscription room
}, [])
return ( return (
<> <>
{isFetching ? {isFetching ?
<> <>
<div className="row"> <div className="row">
<div className="col-12"> <div className="col-12">
@@ -42,82 +44,87 @@ export default function ProductProvision(props){
</div> </div>
</> </>
: isError ? : isError ?
<div className="row">
<div className="col-12">
<p className='text-danger'>{error.message}</p>
</div>
</div>
:
<>
<div className="row"> <div className="row">
<div className="col-md-12"> <div className="col-12">
<div className="card card-statistics"> <p className='text-danger'>{error.message}</p>
<div className="card-header"> </div>
</div>
:
<>
<div className="row">
<div className="col-md-12">
<div className="card card-statistics">
<div className="card-header">
<div className="card-heading"> <div className="card-heading">
<h4 className="card-title">Creating - {productTitle} </h4> <h4 className="card-title">Creating - {productTitle} </h4>
</div> </div>
</div> </div>
<div className="card-body"> <div className="card-body">
<div className="progress"> <div className="progress">
<div className="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" <div className="progress-bar progress-bar-striped progress-bar-animated"
aria-valuenow={`${provisionData?.percent_completed}%`} aria-valuemin="0" aria-valuemax="100" style={{width:`${provisionData?.percent_completed}%`}} ></div> role="progressbar"
aria-valuenow={`${provisionData?.percent_completed}%`}
aria-valuemin="0" aria-valuemax="100"
style={{width: `${provisionData?.percent_completed}%`}}></div>
</div> </div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> <div className="row">
<div className="row"> <div className="col-md-12">
<div className="col-md-12">
</div>
</div> </div>
</div> <div className="row">
<div className="row"> <div className="col-lg-6">
<div className="col-lg-6">
<div className="card card-statistics"> <div className="card card-statistics">
<div className="card-header"> <div className="card-header">
<div className="card-heading"> <div className="card-heading">
<h4 className="card-title">Progress Information</h4> <h4 className="card-title">Progress Information</h4>
</div>
</div> </div>
</div> <div className="card-body">
<div className="card-body"> <div className="table-responsive">
<div className="table-responsive"> <table className="table table-info mb-0">
<table className="table table-info mb-0"> <thead>
<thead> <tr>
<tr> <th scope="col" style={{width: '10px'}}>#</th>
<th scope="col" style={{width: '10px'}}>#</th> <th scope="col">Action</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
{provisionData?.activities?.map(item => (
<tr key={item.id}>
<th scope="row">{item.id}</th>
<td>{item.action}</td>
</tr> </tr>
</thead>
<tbody>
{provisionData?.activities?.map(item => (
<tr key={item.id}>
<th scope="row">{item.id}</th>
<td>{item.action}</td>
</tr>
))} ))}
</tbody> </tbody>
</table> </table>
</div>
</div> </div>
</div> </div>
</div> </div>
</div>
<div className="col-lg-6"> <div className="col-lg-6">
<div className="card card-statistics "> <div className="card card-statistics ">
<h4 className="card-title" style={{padding:'10px'}}>Started creating your selection</h4> <h4 className="card-title" style={{padding: '10px'}}>Started creating your
<img className="card-img-top" src={getImage('widget/working.jpg')} alt="Card image cap" /> selection</h4>
{/* <div className="card-body"> <img className="card-img-top" src={getImage('widget/working.jpg')}
alt="Card image cap"/>
{/* <div className="card-body">
<div className="" dangerouslySetInnerHTML={{__html: productDescription}}/> <div className="" dangerouslySetInnerHTML={{__html: productDescription}}/>
</div> */} </div> */}
</div> </div>
</div>
</div> </div>
</div> </>
</>
} }
</> </>
) )
@@ -0,0 +1,6 @@
const ColorStyleConfigure =()=>{
return <>COLOR CONFIG</>
}
export default ColorStyleConfigure
@@ -6,8 +6,18 @@ 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 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()
@@ -81,7 +91,7 @@ const GeneralTab = memo(({name = 'Full Name', data, isCustom, productData, backe
} }
submitSettings.mutate(reqData) submitSettings.mutate(reqData)
} }
console.log(tabKey);
return ( return (
<> <>
{backendValues?.isFetching || !backendValues?.data ? {backendValues?.isFetching || !backendValues?.data ?
@@ -101,8 +111,11 @@ const GeneralTab = memo(({name = 'Full Name', data, isCustom, productData, backe
: :
<> <>
{isCustom === true ? {isCustom === true ?
<SiteTemplateSelector name={name} data={sortedData} isCustom={isCustom} <>
productData={productData}/> {(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="page-account-form">
<div className="p-0" style={{minHeight: '500px'}}> <div className="p-0" style={{minHeight: '500px'}}>
@@ -20,6 +20,7 @@ const Settings = memo(({productData}) => {
} }
return getMyProductConfig(reqData) return getMyProductConfig(reqData)
}, },
staleTime: 0,
}) })
const settingsConfig = configData?.data?.settings_items const settingsConfig = configData?.data?.settings_items
// console.log('CONFIG DATA...', settingsConfig) // console.log('CONFIG DATA...', settingsConfig)
@@ -54,6 +55,7 @@ const Settings = memo(({productData}) => {
} }
return getSettingsData(reqData) return getSettingsData(reqData)
}, },
staleTime: 0,
enabled: settingsConfig ? true : false enabled: settingsConfig ? true : false
}) })
@@ -107,7 +109,7 @@ const Settings = memo(({productData}) => {
// 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>
))} ))}
</> </>
@@ -1,14 +1,16 @@
import React, {memo} from 'react' import React, {memo} from 'react'
import getImage from "../../../utils/getImage"; import getImage from "../../../utils/getImage";
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query';
import queryKeys from '../../../services/queryKeys'; import queryKeys from '../../../services/queryKeys';
import { getProductTemplateData, activateTemplate } from '../../../services/services'; import {getProductTemplateData, activateTemplate} from '../../../services/services';
import {Link} from "react-router-dom";
import siteLinks from "../../../links/siteLinks";
const SiteTemplateSelector = memo(({name='Full Name', data, productData}) =>{ const SiteTemplateSelector = memo(({name = 'Full Name', data, productData}) => {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const {data:templateData, isFetching, isError, error} = useQuery({ const {data: templateData, isFetching, isError, error} = useQuery({
queryKey: queryKeys.productTemplateData, queryKey: queryKeys.productTemplateData,
queryFn: () => { queryFn: () => {
let reqData = { let reqData = {
@@ -16,7 +18,7 @@ const SiteTemplateSelector = memo(({name='Full Name', data, productData}) =>{
uid: localStorage.getItem('uid'), // USER UID uid: localStorage.getItem('uid'), // USER UID
product_id: productData?.product_id product_id: productData?.product_id
} }
return getProductTemplateData(reqData) return getProductTemplateData(reqData)
}, },
staleTime: 0 staleTime: 0
}) })
@@ -24,16 +26,17 @@ const SiteTemplateSelector = memo(({name='Full Name', data, productData}) =>{
const templateResponse = templateData?.data const templateResponse = templateData?.data
const currentTemUID = templateResponse?.current_template_uid const currentTemUID = templateResponse?.current_template_uid
const templates = templateResponse?.templates const templates = templateResponse?.templates
const custom_template_name = templateResponse?.custom_template_name
// console.log('data Template', templateResponse) // console.log('data Template', templateResponse)
// console.log("Page data == ", data) console.log("Page data == ", data)
const handleActivateTemplate = useMutation({ const handleActivateTemplate = useMutation({
mutationFn: (fields) => { mutationFn: (fields) => {
return activateTemplate(fields) return activateTemplate(fields)
}, },
onSuccess: (res) => { onSuccess: (res) => {
if(res?.data?.resultCode != '0'){ if (res?.data?.resultCode != '0') {
throw new Error(res.data.resultDescription) throw new Error(res.data.resultDescription)
} }
queryClient.refetchQueries({ // refetches productProvision API call queryClient.refetchQueries({ // refetches productProvision API call
@@ -41,7 +44,7 @@ const SiteTemplateSelector = memo(({name='Full Name', data, productData}) =>{
}) })
}, },
onSettled: () => { onSettled: () => {
setTimeout(()=>{ setTimeout(() => {
handleActivateTemplate.reset() handleActivateTemplate.reset()
}, 3000) }, 3000)
} }
@@ -57,51 +60,73 @@ const SiteTemplateSelector = memo(({name='Full Name', data, productData}) =>{
// console.log(reqData) // console.log(reqData)
handleActivateTemplate.mutate(reqData) handleActivateTemplate.mutate(reqData)
} }
if (custom_template_name && custom_template_name != '') {
// This implies we have a custom template , just return here
return <>
<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: '20px'}}>Custom Product Template.</h4>
<img className='' style={{width: '200px'}}
src={getImage('custom-template.png')}
alt='mail-alert'/>
<h4 className='p-4 text-black'
style={{marginTop: '20px'}}>This product is using a custom template named <span
style={{color: 'darkred'}}>&ldquo;{custom_template_name}&rdquo;</span> .</h4>
</div>
</div>
</>
}
return ( return (
<div className="page-account-form"> <div className="page-account-form">
<div className="p-0"> <div className="p-0">
{isFetching ? {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="row">
<> <>
{!templates?.length ? <div className="row">
<p>No data Found</p> <div className="col-12">
: <p className='text-mute'>Loading...</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> </div>
)) </div>
} </>
{/* {Object.entries(data)?.map(([key, value]) => ( : 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">
@@ -116,24 +141,25 @@ const SiteTemplateSelector = memo(({name='Full Name', data, productData}) =>{
</div> </div>
</div> </div>
))} */} ))} */}
</> </>
<div className="col-12"> <div className="col-12">
<> <>
{handleActivateTemplate.isPending ? {handleActivateTemplate.isPending ?
<p className={'text-center '}>loading...</p> <p className={'text-center '}>loading...</p>
: :
handleActivateTemplate.isError ? handleActivateTemplate.isError ?
<p className={'text-center text-danger'}>{handleActivateTemplate.error.message}</p> <p className={'text-center text-danger'}>{handleActivateTemplate.error.message}</p>
: :
handleActivateTemplate.isSuccess? handleActivateTemplate.isSuccess ?
<p className={'text-center text-success'}>Templated activated successfully</p> <p className={'text-center text-success'}>Templated activated
: successfully</p>
null :
} null
</> }
</div> </>
</div> </div>
</div>
} }
</div> </div>
</div> </div>
@@ -0,0 +1,141 @@
import {Form, Formik} from "formik";
import * as Yup from "yup";
import {useMutation} from '@tanstack/react-query';
import {setExternalURL} from '../../../services/services';
import { useState } from "react";
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}) => {
const [externalURLChanged, setExternalURLChanged] = useState(true)
const initialValues = {
url: productData?.external_url || '',
};
let defaultUrl = 'https://' + productData?.internal_url
let externalUrl = productData?.external_url
const handleExternalURLChanged = (e) => {
if(e.target.value == externalUrl){
setExternalURLChanged(true)
}else{
setExternalURLChanged(false)
}
}
// API to set url
const setURL = useMutation({
mutationFn: (fields) => {
return setExternalURL(fields)
},
onSuccess: (res) => {
if (res.data.resultCode != '0') {
// throw({message: res?.data?.resultDescription})
throw({message: 'Something went wrong!'})
}
},
onSettled: () => {
setTimeout(() => {
setURL.reset()
}, 3000)
}
// onError: (err) => {
// console.log('err', err)
// }
})
const handleSubmit = (values) => {
let reqData = {
token: localStorage.getItem('token'), // USER TOKEN
uid: localStorage.getItem('uid'), // USER UID
subscription_uid: productData?.subscription_uid,
external_url: values.url
}
setURL.mutate(reqData)
}
return <>
<div className="card card-statistics">
<div className="card-header">
<div className="card-heading">
<h4 className="card-title" style={{textTransform: 'none'}}>{defaultUrl}</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>*/}
{/*</div>*/}
</div>
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleSubmit}
>
{(props) => {
return (
<Form className='w-full'>
<div className="card card-statistics" style={{backgroundColor: '#b6e5ef'}}>
<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={(e)=>{props.handleChange(e); handleExternalURLChanged(e)}} type="text"
className="form-control" id="url" aria-describedby="url"
placeholder="https://example.mysite.com"/>
</div>
<div style={{width: '100%', textAlign: 'right'}}>
<button
type="submit"
disabled={setURL.isPending || externalURLChanged}
className="btn btn-primary"
>
{setURL.isPending ? 'Loading...' : 'Submit'}
</button>
</div>
</div>
{setURL.error &&
<div className="col-12">
<p className='text-danger'>{setURL.error.message}</p>
</div>
}
{setURL.isSuccess &&
<div className="col-12">
<p className='text-success'>{'Completed successfully'}</p>
</div>
}
<div style={{backgroundColor: '#94b8c0', borderRadius: '10px', padding: '10px'}}>
Final steps to configure your URL:<br/>
DNS:<br/>
DNS:<br/>
DNS:<br/>
</div>
</div>
</Form>
);
}}
</Formik>
</>
}
export default URLConfiguration
@@ -1,7 +1,7 @@
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";
@@ -13,17 +13,19 @@ 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() {
@@ -35,28 +37,27 @@ export default function ProfileCompleteCom() {
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)
}, },
@@ -93,15 +94,11 @@ 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)
} }
@@ -145,89 +142,146 @@ export default function ProfileCompleteCom() {
<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' <div className="form-group position-relative">
value={initialValues.practice} className="form-control"> <label className={`text-black fw-bold control-label`}>Practice : <span className="text-danger">{(props.errors.practice && props.touched.practice) && props.errors.practice}</span></label>
<option value=''>Select</option> <div className="position-relative">
{practices.map((practice, index) => ( {/* <select onChange={props.handleChange} name='practice' value={props.values.practice} className="form-control">
<option key={index} <option value=''>Select</option>
value={practice.practice}>{practice.practice}</option> {practices.map((practice, index)=>(
))} <option key={index} value={practice.practice}>{practice.practice}</option>
</select> ))}
<IoMdArrowDropdown className='position-absolute w-auto' style={{ </select> */}
top: '50%', <select
right: '2px', onChange={(e) => {props.handleChange(e); props.setFieldValue('specialization', ''); handleUpdateSpecialties(e)}}
transform: 'translateY(-50%)' name='practice'
}}/> value={props.values.practice} className="form-control">
</div> <option value=''>Select</option>
</div> {practices.map((practice, index) => (
</div> <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`}>Your <label className={`text-black fw-bold control-label`}>Your
Specialization :</label> Specialization : <span className="text-danger">{(props.errors.specialization && props.touched.specialization) && props.errors.specialization}</span></label>
<div className="position-relative"> <div className="position-relative">
<select onChange={handlePracticeChange} name='specialization' <select onChange={props.handleChange} name='specialization'
value={initialValues.specialization} value={props.values.specialization}
className="form-control"> className="form-control">
<option value=''>Select</option> <option value=''>Select</option>
{specialties.map((specialty, index) => ( {specialties.map((specialty, index) => (
<option key={index} value={specialty}>{specialty}</option> <option key={index} value={specialty}>{specialty}</option>
))} ))}
</select> </select>
<IoMdArrowDropdown className='position-absolute w-auto' style={{ <IoMdArrowDropdown className='position-absolute w-auto' style={{
top: '50%', top: '50%',
right: '2px', right: '2px',
transform: 'translateY(-50%)' transform: 'translateY(-50%)'
}}/> }}/>
</div> </div>
</div> </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`}>Other General <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>
Information :</label> <textarea name='introduction' rows={5} style={{resize: 'none'}}
<textarea name='introduction' rows={10} style={{resize: 'none'}} className="form-control" value={props.values.introduction}
className="form-control" value={initialValues.introduction} onChange={props.handleChange}/>
onChange={handlePracticeChange}/> </div>
</div> </div>
</div>
<div className=""> <div className="">
<div className="form-group position-relativ'e"> <div className="form-group position-relativ'e">
{/*<label className={`text-black fw-bold control-label`}>What we use this*/} {/*<label className={`text-black fw-bold control-label`}>What we use this*/}
{/* information for :</label>*/} {/* information for :</label>*/}
<div style={{fontSize: '14px', borderRadius: '10px', backgroundColor: 'aliceblue', fontWeight:'bolder', padding: '15px' }}> <div style={{
MERMS A.I. agents use the information supplied to help generate useful entries for your product settings. fontSize: '14px',
</div> borderRadius: '10px',
</div> backgroundColor: 'aliceblue',
</div> fontWeight: 'bolder',
padding: '15px'
}}>
MERMS A.I. agents use the information supplied to help generate
useful entries for your product settings.
</div>
</div>
</div>
{(mutation.isError || mutation.isSuccess) && <div className="">
<> <div className="form-group position-relative">
<div className=""> <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>
<p className={`${mutation.isSuccess ? 'text-success' : 'text-danger'}`}>{mutation.isSuccess ? 'Completed successfully, redirecting...' : mutation.error.message}</p> <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>
<div className="mt-auto text-end"> {(mutation.isError || mutation.isSuccess) &&
<button type='button' onClick={handleCompleteProfile} <>
className="btn btn-primary text-uppercase">{mutation.isPending ? 'loading...' : 'Continue'}</button> <div className="">
</div> <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>
+244 -166
View File
@@ -1,10 +1,68 @@
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 getImage from "../../utils/getImage";
import queryKeys from "../../services/queryKeys";
import { useQuery } from "@tanstack/react-query";
import { profileDetails } from "../../services/services";
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() { export default function Settings() {
const avtarImage = "avtar/merms-user.png"; 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 ( return (
<> <>
<BreadcrumbComBS title='Settings' paths={['Dashboard', 'Settings']}/> <BreadcrumbComBS title='Settings' paths={['Dashboard', 'Settings']}/>
@@ -12,184 +70,205 @@ export default function Settings() {
{/* <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">
<img src={getImage(avtarImage)} <div className="page-account-profil pt-5">
className="img-fluid" alt="user"/> <div className="profile-img text-center rounded-circle">
</div> <div className="pt-5">
<div className="profile pt-4"> <div className="bg-img m-auto">
<h4 className="mb-1">Alice Williams</h4> {/*<img src="assets/img/avtar/01.jpg" className="img-fluid"*/}
<div style={{padding: '10px'}}> {/* alt="users-avatar" />*/}
<hr/> <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>
<div className="profile-btn text-center"> <div className="profile-btn text-center">
<div> <div>
<button className="btn btn-light text-primary mb-2">Upload New Avatar <button className="btn btn-light text-primary mb-2">Upload New Avatar
</button> </button>
</div>
{/*<div>*/}
{/* <button className="btn btn-danger">Delete</button>*/}
{/*</div>*/}
</div> </div>
{/*<div>*/}
{/* <button className="btn btn-danger">Delete</button>*/}
{/*</div>*/}
</div> </div>
</div> </div>
</div> <div className="col-xl-5 col-md-6 col-12 border-t border-right">
<div className="col-xl-5 col-md-6 col-12 border-t border-right"> <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">Edit Your Personal Settings</h5> </div>
</div> <div className="p-4">
<div className="p-4"> <Formik
<form> initialValues={intialData?.personal_data}
<div className="form-row"> validationSchema={profileValidationSchema}
<div className="form-group col-md-12"> onSubmit={updateProfile}
<label htmlFor="name1">First Name</label> >
<input type="text" className="form-control" id="name1" {(props) => {
value="Alice"/> return (
</div> <Form className=''>
<div className="form-group col-md-12"> <div className="form-row">
<label htmlFor="name1">Last Name</label> <div className="form-group col-md-12">
<input type="text" className="form-control" id="name1" <label htmlFor="name1">First Name {(props.errors.firstname && props.touched.firstname) && <span className="text-danger">*</span>}</label>
value="Williams"/> <input type="text" className="form-control" name="firstname" value={props.values?.firstname} onChange={props.handleChange} />
</div> </div>
<div className="form-group col-md-12"> <div className="form-group col-md-12">
<label htmlFor="name1">Account Name</label> <label htmlFor="name1">Last Name {(props.errors.lastname && props.touched.lastname) && <span className="text-danger">*</span>}</label>
<input type="text" className="form-control" id="name1" <input type="text" className="form-control" name="lastname" value={props.values?.lastname} onChange={props.handleChange} />
value="This is the best hospital name"/> </div>
</div> <div className="form-group col-md-12">
{/*<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>
{/* <label htmlFor="title1">Email</label>*/} <input type="text" className="form-control" name="account_name" value={props.values?.account_name} onChange={props.handleChange} />
{/* <input type="text" className="form-control" id="title1"*/} </div>
{/* value="email@email.com" />*/} {/*<div className="form-group col-md-12">*/}
{/*</div>*/} {/* <label htmlFor="title1">Email</label>*/}
<div className="form-group col-md-12"> {/* <input type="text" className="form-control" name="title1"*/}
<label htmlFor="phone1">Phone Number</label> {/* value="email@email.com" />*/}
<input type="text" className="form-control" id="phone1" {/*</div>*/}
value="(01) 97 563 15613"/> <div className="form-group col-md-12">
</div> <label htmlFor="phone1">Phone Number {(props.errors.phone && props.touched.phone) && <span className="text-danger">*</span>}</label>
<div className="form-group col-md-12"> <input type="text" className="form-control" name="phone" value={props.values?.phone} onChange={props.handleChange} />
<label htmlFor="email1">Email</label> </div>
<input type="email" className="form-control" id="email1" <div className="form-group col-md-12">
value="alicewilliams@gmail.com"/> <label htmlFor="email1">Email {(props.errors.email && props.touched.email) && <span className="text-danger">*</span>}</label>
</div> <input type="text" className="form-control" name="email" value={props.values?.email} onChange={props.handleChange} />
</div> </div>
<div className="form-group"> </div>
<label htmlFor="add1">Address</label> <div className="form-group">
<input type="text" className="form-control" id="add1" <label htmlFor="add1">Address {(props.errors.full_address && props.touched.full_address) && <span className="text-danger">*</span>}</label>
value="17504 Carlton Cuevas Rd, Gulfport, MS, 39503"/> <input type="text" className="form-control" name="full_address" value={props.values?.full_address} onChange={props.handleChange} />
</div> </div>
<div className="form-group"> {/*<div className="form-group">*/}
<label htmlFor="add2">Address 2</label> {/* <label htmlFor="add2">Address 2</label>*/}
<input type="text" className="form-control" id="add2" {/* <input type="text" className="form-control" id="add2"*/}
value="1234 North Avenue Luke Lane, South Bend, IN 360001"/> {/* value="1234 North Avenue Luke Lane, South Bend, IN 360001"/>*/}
</div> {/*</div>*/}
{/*<div className="form-row">*/} {/*<div className="form-row">*/}
{/* <div className="form-group col-md-4">*/} {/* <div className="form-group col-md-4">*/}
{/* <label htmlFor="inputState3">City</label>*/} {/* <label htmlFor="inputState3">City</label>*/}
{/* <select id="inputState3" className="form-control">*/} {/* <select id="inputState3" className="form-control">*/}
{/* <option>Choose...</option>*/} {/* <option>Choose...</option>*/}
{/* <option selected="">London</option>*/} {/* <option selected="">London</option>*/}
{/* <option>Montreal</option>*/} {/* <option>Montreal</option>*/}
{/* <option>Delhi</option>*/} {/* <option>Delhi</option>*/}
{/* <option>Tokyo</option>*/} {/* <option>Tokyo</option>*/}
{/* </select>*/} {/* </select>*/}
{/* </div>*/} {/* </div>*/}
{/* <div className="form-group col-md-4">*/} {/* <div className="form-group col-md-4">*/}
{/* <label htmlFor="inputState4">State</label>*/} {/* <label htmlFor="inputState4">State</label>*/}
{/* <select id="inputState4" className="form-control">*/} {/* <select id="inputState4" className="form-control">*/}
{/* <option>Choose...</option>*/} {/* <option>Choose...</option>*/}
{/* <option selected="">England</option>*/} {/* <option selected="">England</option>*/}
{/* <option>California</option>*/} {/* <option>California</option>*/}
{/* <option>Texas</option>*/} {/* <option>Texas</option>*/}
{/* <option>Scotland</option>*/} {/* <option>Scotland</option>*/}
{/* </select>*/} {/* </select>*/}
{/* </div>*/} {/* </div>*/}
{/* <div className="form-group col-md-4">*/} {/* <div className="form-group col-md-4">*/}
{/* <label htmlFor="inputZip">Zip</label>*/} {/* <label htmlFor="inputZip">Zip</label>*/}
{/* <input type="text" className="form-control" id="inputZip"*/} {/* <input type="text" className="form-control" id="inputZip"*/}
{/* value="EC1A 1BB" />*/} {/* value="EC1A 1BB" />*/}
{/* </div>*/} {/* </div>*/}
{/*</div>*/} {/*</div>*/}
{/*<div className="form-group">*/} {/*<div className="form-group">*/}
{/* <div className="form-check">*/} {/* <div className="form-check">*/}
{/* <input className="form-check-input" type="checkbox"*/} {/* <input className="form-check-input" type="checkbox"*/}
{/* id="gridCheck" />*/} {/* id="gridCheck" />*/}
{/* <label className="form-check-label" htmlFor="gridCheck">*/} {/* <label className="form-check-label" htmlFor="gridCheck">*/}
{/* I agree to receive email notification.*/} {/* I agree to receive email notification.*/}
{/* </label>*/} {/* </label>*/}
{/* </div>*/} {/* </div>*/}
{/*</div>*/} {/*</div>*/}
<div style={{textAlign: "right"}}> <div style={{textAlign: "right"}}>
<button type="submit" className="btn btn-primary">Update Profile <button type="submit" className="btn btn-primary">Update Profile
</button> </button>
</div> </div>
</Form>
</form> );
}}
</Formik>
</div>
</div> </div>
</div> </div>
</div> <div className="col-xl-4 col-md-6 border-t col-12">
<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">Your External Link</h5>
<h5 className="mb-0 py-2">Your External Link</h5> </div>
</div> <div className="p-4">
<div className="p-4"> <Formik
<form> initialValues={intialData?.external_links}
<div className="form-group"> validationSchema={linksValidationSchema}
<label htmlFor="fb">Facebook URL:</label> onSubmit={updateLinks}
<input type="text" className="form-control" id="fb" >
value="https://www.facebook.com/"/> {(props) => {
</div> return (
<div className="form-group"> <Form className=''>
<label htmlFor="tr">Twitter URL:</label> <div className="form-group">
<input type="text" className="form-control" id="tr" <label htmlFor="fb">Facebook URL: {(props.errors.facebook_url && props.touched.facebook_url) && <span className="text-danger">*</span>}</label>
value="https://twitter.com/"/> <input type="text" className="form-control" name="facebook_url" value={props.values?.facebook_url} onChange={props.handleChange} />
</div> </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>
@@ -197,8 +276,7 @@ export default function Settings() {
</div> </div>
</div> </div>
</div> </div>
</div> }
</> </>
) )
} }
+1 -17
View File
@@ -1,7 +1,6 @@
import React from "react"; import React from "react";
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS"; import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
import getImage from "../../utils/getImage"; import getImage from "../../utils/getImage";
//const imP = '../../../../src/assets/img/side-banner.jpg'
export default function Start() { export default function Start() {
@@ -13,22 +12,7 @@ export default function Start() {
<div className="row"> <div className="row">
<div className="col-xl-3 col-md-6"> <div className="col-xl-3 col-md-6">
<div className="card card-statistics text-center py-3" <div className="card card-statistics text-center py-3"
style={{minHeight: '350px', backgroundImage: `url(${bgImg})`}}> style={{minHeight: '550px', borderRadius: '10px', backgroundImage: `url(${bgImg})`}}>
<div className="card-body pricing-content">
{/*<div className="pricing-content-card">*/}
{/* <h5>Premium</h5>*/}
{/* <h2 className="text-primary pt-3">$150</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-primary btn-round btn-sm">go premium</a></div>*/}
{/*</div>*/}
</div>
</div> </div>
</div> </div>
+44
View File
@@ -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>
</>
)
}
+108
View File
@@ -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
+1
View File
@@ -3,6 +3,7 @@ const siteLinks = {
help: '/help', help: '/help',
home: '/', home: '/',
dash: '/dash', dash: '/dash',
traffic: '/traffic',
start: '/start', start: '/start',
profile_complete: '/profile-complete', profile_complete: '/profile-complete',
product: '/product/*', product: '/product/*',
+1
View File
@@ -10,6 +10,7 @@ const queryKeys = {
myProductConfig: ['myproduct_config'], 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'],
+25 -1
View File
@@ -76,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 = {
@@ -99,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,
@@ -107,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 = {
@@ -230,6 +246,14 @@ export const getCommonPractice = (reqData) => {
return postAuxEnd(`/panel/common/practice`, postData, false) return postAuxEnd(`/panel/common/practice`, postData, false)
} }
// FUNCTION TO SET EXTERNAL URL
export const setExternalURL = (reqData) => {
let postData = {
...reqData
}
return postAuxEnd('/panel/myproduct/external-url', postData, false)
}
+8
View File
@@ -0,0 +1,8 @@
import React from 'react'
import Traffic from "../component/traffic/Traffic";
export default function TrafficPage() {
return (
<Traffic />
)
}