Compare commits

...

22 Commits

Author SHA1 Message Date
victorAnumudu b7aaff7adc product page reload fixed 2025-07-15 20:04:37 +01:00
ameye d606b5682c Merge branch 'product-url-refresh' of MERMS/MermsPanelReactJS into master 2025-07-15 14:21:37 +00:00
victorAnumudu 25d4751935 fixed product url refresh on successful subscription 2025-07-15 12:51:40 +01:00
CHIEFSOFT\ameye a8d78c4c3f devsocket.mermsemr.com 2025-07-12 19:38:20 -04:00
CHIEFSOFT\ameye 9c672d4bf2 REACT_APP_MAIN_SOCKET="https://devsocket.mermsemr.com" 2025-07-12 19:22:59 -04:00
CHIEFSOFT\ameye c744eccd15 QA .env 2025-07-12 14:44:41 -04:00
CHIEFSOFT\ameye 302a3aa3bb Added more .env 2025-07-12 14:41:46 -04:00
ameye 23a295866a Merge branch 'route-fix' of MERMS/MermsPanelReactJS into master 2025-07-10 12:14:31 +00:00
victorAnumudu 487494fbff route bug fixed 2025-07-10 11:53:55 +01:00
victorAnumudu 919594d7b2 Merge branch 'master' of https://gitlab.chiefsoft.net/MERMS/MermsPanelReactJS 2025-07-10 11:08:41 +01:00
ameye 7eedae8fc2 Merge branch 'signup-payload' of MERMS/MermsPanelReactJS into master 2025-07-10 08:36:37 +00:00
victorAnumudu 51a3c60590 bug fix 2025-07-10 09:05:30 +01:00
victorAnumudu ab597039ba updated complete signup endpoint 2025-07-10 08:59:20 +01:00
victorAnumudu 6fd2dcdb3d updated signup payload 2025-07-10 08:54:41 +01:00
victorAnumudu 614910e29c updated signup payload 2025-07-10 08:52:51 +01:00
ameye 2c832699c2 Merge branch 'signup-payload' of MERMS/MermsPanelReactJS into master 2025-07-08 19:11:40 +00:00
victorAnumudu c8fe2eadf6 removed isChecked value 2025-07-08 19:23:51 +01:00
ameye 1e174b7432 Merge branch 'provision-bug' of MERMS/MermsPanelReactJS into master 2025-07-08 15:59:27 +00:00
victorAnumudu dda8fa7d30 fixed bug 2025-07-08 16:53:36 +01:00
ameye d0f1d5ee34 Merge branch 'product-url' of MERMS/MermsPanelReactJS into master 2025-07-08 14:24:05 +00:00
ameye a0e417fc68 Merge branch 'help-page' of MERMS/MermsPanelReactJS into master 2025-07-08 09:02:20 +00:00
victorAnumudu 10e65fa6ff added dummy help page 2025-07-07 19:56:45 +01:00
21 changed files with 219 additions and 111 deletions
+6 -6
View File
@@ -2,14 +2,14 @@ SKIP_PREFLIGHT_CHECK=true
REACT_APP_NODE_ENV="development"
REACT_APP_SOCKET_URL="https://devsocket.mermsemr.com"
REACT_APP_MAIN_API="https://devapi.mermsemr.com"
REACT_APP_MEDIA_SERVER="https://dev-media.mermsemr.com"
REACT_APP_MAIN_SOCKET="https://dev-socket.mermsemr.com"
REACT_APP_MEDIA_SERVER="https://qa-media.mermsemr.com"
REACT_APP_MAIN_SOCKET="https://devsocket.mermsemr.com"
# login footer links
REACT_APP_HOME_LINK='https://dev-www.mermsemr.com/'
REACT_APP_ABOUT_LINK='https://dev-www.mermsemr.com/about'
REACT_APP_CONTACTS_LINK='https://dev-www.mermsemr.com/contacts'
REACT_APP_TERMS_LINK='https://dev-www.mermsemr.com/terms'
REACT_APP_HOME_LINK='https://qa-www.mermsemr.com/'
REACT_APP_ABOUT_LINK='https://qa-www.mermsemr.com/about'
REACT_APP_CONTACTS_LINK='https://qa-www.mermsemr.com/contacts'
REACT_APP_TERMS_LINK='https://qa-www.mermsemr.com/terms'
# Inactivity timeout/logout AT 10MINS
REACT_APP_TIMEOUT=600000
+7 -6
View File
@@ -2,14 +2,15 @@ SKIP_PREFLIGHT_CHECK=true
REACT_APP_NODE_ENV="development"
REACT_APP_SOCKET_URL="https://devsocket.mermsemr.com"
REACT_APP_MAIN_API="https://devapi.mermsemr.com"
REACT_APP_MEDIA_SERVER="https://dev-media.mermsemr.com"
REACT_APP_MAIN_SOCKET="https://dev-socket.mermsemr.com"
REACT_APP_MEDIA_SERVER="https://qa-media.mermsemr.com"
REACT_APP_MAIN_SOCKET="https://devsocket.mermsemr.com"
# login footer links
REACT_APP_HOME_LINK='https://dev-www.mermsemr.com/'
REACT_APP_ABOUT_LINK='https://dev-www.mermsemr.com/about'
REACT_APP_CONTACTS_LINK='https://dev-www.mermsemr.com/contacts'
REACT_APP_TERMS_LINK='https://dev-www.mermsemr.com/terms'
REACT_APP_HOME_LINK='https://qa-www.mermsemr.com/'
REACT_APP_ABOUT_LINK='https://qa-www.mermsemr.com/about'
REACT_APP_CONTACTS_LINK='https://qa-www.mermsemr.com/contacts'
REACT_APP_TERMS_LINK='https://qa-www.mermsemr.com/terms'
# Inactivity timeout/logout AT 10MINS
REACT_APP_TIMEOUT=600000
+1
View File
@@ -3,6 +3,7 @@ REACT_APP_NODE_ENV="production"
REACT_APP_SOCKET_URL="https://socket.mermsemr.com"
REACT_APP_MAIN_API="https://devapi.mermsemr.com"
REACT_APP_MEDIA_SERVER="https://media.mermsemr.com"
REACT_APP_MAIN_SOCKET="https://socket.mermsemr.com"
# login footer links
REACT_APP_HOME_LINK='https://www.mermsemr.com/'
+15
View File
@@ -0,0 +1,15 @@
SKIP_PREFLIGHT_CHECK=true
REACT_APP_NODE_ENV="development"
REACT_APP_SOCKET_URL="https://devsocket.mermsemr.com"
REACT_APP_MAIN_API="https://devapi.mermsemr.com"
REACT_APP_MEDIA_SERVER="https://qa-media.mermsemr.com"
REACT_APP_MAIN_SOCKET="https://devsocket.mermsemr.com"
# login footer links
REACT_APP_HOME_LINK='https://qa-www.mermsemr.com/'
REACT_APP_ABOUT_LINK='https://qa-www.mermsemr.com/about'
REACT_APP_CONTACTS_LINK='https://qa-www.mermsemr.com/contacts'
REACT_APP_TERMS_LINK='https://qa-www.mermsemr.com/terms'
# Inactivity timeout/logout AT 10MINS
REACT_APP_TIMEOUT=600000
+1 -1
View File
@@ -20,7 +20,7 @@ services:
extra_hosts:
- api.mermsemr.com:10.10.33.15
- devapi.mermsemr.com:10.10.33.15
- dev-socket.mermsemr.com:10.10.33.15
- devsocket.mermsemr.com:10.10.33.15
- socket.mermsemr.com:10.10.33.15
- dev-media.mermsemr.com:10.10.33.15
- media.mermsemr.com:10.10.33.15
+8
View File
@@ -39,4 +39,12 @@
button{
font-size: 1rem!important;
font-weight: 700!important;
}
.font-600 {
font-weight: 600;
}
.accordion-button, .accordion-button:not(.collapsed) {
background-color: transparent!important;
}
+16 -11
View File
@@ -1,23 +1,28 @@
import { QueryClientProvider, QueryClient } from '@tanstack/react-query'
import { Provider } from 'react-redux';
import store from './store/store'
import AppRouters from './AppRouters';
import './App.css';
function App() {
const queryClient = new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
retry: 3,
// refetchOnMount: false,
staleTime: Infinity // can also be a number in millisecond
},
const queryClient = new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
retry: 3,
// refetchOnMount: false,
staleTime: 360000 // can also be a number in millisecond
},
})
},
})
function App() {
return (
<QueryClientProvider client={queryClient}>
<AppRouters />
<Provider store={store}>
<AppRouters />
</Provider>
</QueryClientProvider>
);
}
+2
View File
@@ -18,6 +18,7 @@ import SettingsPage from './views/SettingsPage'
import ProductPage from './views/ProductPage'
import SocketIOContextProvider from './component/context/SocketIOContext';
import CSignupPage from './views/CSignupPage';
import HelpPage from './views/HelpPage';
function AppRouters() {
return (
@@ -45,6 +46,7 @@ function AppRouters() {
<Route path={siteLinks.user} element={<UserPage />} />
<Route path={siteLinks.calendar} element={<CalendarPage />} />
<Route path={siteLinks.settings} element={<SettingsPage />} />
<Route path={siteLinks.help} element={<HelpPage />} />
</Route>
</Route>
</Route>
+18 -10
View File
@@ -1,11 +1,13 @@
import React, { useEffect, useState } from 'react'
import { Form, Formik } from "formik";
import * as Yup from "yup";
import { useDispatch } from 'react-redux'
import { Link, useNavigate, useParams } from 'react-router-dom'
import siteLinks from '../../links/siteLinks'
import { useMutation } from '@tanstack/react-query';
import { completeRegistration, verifyEmail } from '../../services/services';
import { updateUserDetails } from '../../store/UserDetails'
import { IoMdArrowDropdown } from "react-icons/io";
@@ -28,6 +30,8 @@ const validationSchema = Yup.object().shape({
export default function CSignup() {
const {jwt} = useParams()
const dispatch = useDispatch()
const navigate = useNavigate()
@@ -51,15 +55,19 @@ export default function CSignup() {
return completeRegistration(fields)
},
onSuccess: (res) => {
const {token, room} = res?.data?.data
if(token){
localStorage.setItem('token', token)
localStorage.setItem('room', room)
// const data = {token}
// dispatch(updateUserDetails({ ...data }));
navigate('/dash') // later add redux to dispatch state
if(res?.data?.resultCode != '0'){
throw({message: res?.data?.resultDescription})
}
}
const {token, room, uid} = res?.data
if(!token || !room){
throw({message: 'something went wrong, try again!'})
}
localStorage.setItem('token', token)
localStorage.setItem('room', room)
localStorage.setItem('uid', uid)
dispatch(updateUserDetails({ ...res?.data }));
navigate('/dash') // later add redux to dispatch state
},
// onError: (err) => {
// console.log('err', err)
// }
@@ -70,7 +78,7 @@ export default function CSignup() {
country : values.country,
username: values.username,
password: values.password,
verify_link: user.verify_link
verify_link: jwt
}
cSignup.mutate(reqData)
}
@@ -196,7 +204,7 @@ export default function CSignup() {
}
<div className="col-12 mt-3 text-center">
<Link to={siteLinks.login} className='text-primary' style={{color: '#6FCAEF'}}>Need help with logging in or signing up?</Link>
<Link to={siteLinks.signup} className='text-primary' style={{color: '#6FCAEF'}}>Need help with logging in or signing up?</Link>
</div>
<div className="col-12 mt-3 text-center">
+1
View File
@@ -49,6 +49,7 @@ export default function Signup2() {
const signUp = (values) => {
// helpers.resetForm()
// console.log('values', values, helpers)
delete values.isChecked
mutation.mutate(values)
}
+48
View File
@@ -0,0 +1,48 @@
import React from "react";
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
export default function HelpCom(){
return(
<>
<BreadcrumbComBS title='Frequesntly Asked Questions' paths={['Dashboard', 'Help']} />
{/*<div className="row">*/}
{/* <div className="vh-100 col-12 flex align-items-center">Coming Soon</div>*/}
{/*</div>*/}
<div className="row account-contant">
<div className="col-12">
<div className="card card-statistics">
<div className="card-body p-lg-15" style={{backgroundColor:"#f9f9fb"}}>
<p className="mb-4">First, a disclaimer the entire process of writing a blog post often takes more than a couple of hours, even if you can type eighty words as per minute and your writing skills are sharp.</p>
<div className="row">
<div className="accordion" id="accordionExample">
{['a', 'b', 'c', 'd'].map((item, index)=>{
return (
<div className="accordion-item">
<h2 className="accordion-header">
<button className="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target={`#${item}`} aria-expanded="true" aria-controls="collapseOne">
{`Accordion Item ${item} 1`}
</button>
</h2>
<div id={item} className={`accordion-collapse collapse ${index == 0 && 'show'}`} data-bs-parent="#accordionExample">
<div className="accordion-body">
<strong>This is the first items accordion body.</strong> It is shown by default, until the collapse plugin adds the appropriate classes that we use to style each element. These classes control the overall appearance, as well as the showing and hiding via CSS transitions. You can modify any of this with custom CSS or overriding our default variables. Its also worth noting that just about any HTML can go within the accordion-body, though the transition does limit overflow.
</div>
</div>
</div>
)
})}
</div>
</div>
</div>
</div>
</div>
</div>
</>
)
}
+1 -1
View File
@@ -13,7 +13,7 @@ export default function Products() {
uid: localStorage.getItem('uid') // USER UID
}
const {data, isFetching, isError, error} = useQuery({
queryKey: queryKeys.product,
queryKey: queryKeys.products,
queryFn: () => productsData(reqData)
})
const products = data?.data?.products_data // PRODUCTS DATA
+5 -2
View File
@@ -64,10 +64,13 @@ export default function ProductsURL() {
return (
<tr key={index}>
<td>{Number(item?.id)}</td>
<td>{item?.description} - <a href={productUrl} target='_blank'>{item?.external_url}</a></td>
<td>
{item?.description} -
{/* <a href={productUrl} target='_blank'>{item?.external_url}</a> */}
</td>
<td><span className={`badge ${statusColor}`}>{item?.status}</span></td>
<td><a className="mr-3" href=""><i className="fe fe-edit"></i></a></td>
<td><a className="mr-3" href={productUrl} target='_blank'><i className="fe fe-edit"></i></a></td>
</tr>
)
})}
@@ -74,8 +74,8 @@ export default function UserHeader(){
<div className="bg-gradient px-4 py-3">
<div className="d-flex align-items-center justify-content-between">
<div className="mr-1">
<h5 className="text-white mb-0">{userDetails?.firstname} {userDetails?.lastname}</h5>
<small className="text-white">{userDetails.email}</small>
<h4 className="text-white mb-0 font-600">{userDetails?.firstname} {userDetails?.lastname}</h4>
<p className="text-white font-600">{userDetails.email}</p>
</div>
<a href="#" onClick={logout} className="text-white font-20 tooltip-wrapper" data-toggle="tooltip"
data-placement="top" title="" data-original-title="Logout"> <i
@@ -92,8 +92,10 @@ export default function UserHeader(){
<Link className="dropdown-item d-flex nav-link" to={siteLinks.settings}>
<i className=" ti ti-settings pr-2 text-info"></i> Settings
</Link>
<a className="dropdown-item d-flex nav-link" href="#">
<i className="fa fa-compass pr-2 text-warning"></i> Need help?</a>
<Link className="dropdown-item d-flex nav-link" to={siteLinks.help}>
<i className="fa fa-compass pr-2 text-warning"></i>
Need help?
</Link>
{/*<div className="row mt-2">*/}
{/* <div className="col">*/}
+24 -37
View File
@@ -1,5 +1,4 @@
import {useEffect} from "react";
import { useMutation, useQuery } from '@tanstack/react-query'
import { useQuery } from '@tanstack/react-query'
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
// import getImage from "../../utils/getImage";
import ProductStart from "./ProductStart";
@@ -8,6 +7,7 @@ import {MyProductData} from "../../services/services";
import ProductActive from "./ProductActive";
import ProductProvision from "./ProductProvision";
import {productConst} from "../../constants/products";
import queryKeys from "../../services/queryKeys";
export default function ProductFactory(){
const location = useLocation();
@@ -16,30 +16,18 @@ export default function ProductFactory(){
// Split the pathname by '/' and get the last element
const productID = pathname.split('/').pop();
const getProductData = useMutation({
mutationFn: (reqData) => {
return MyProductData(reqData)
},
onError: (error) => {
console.log(error)
},
onSuccess: (res) => {
if(res?.data?.resultCode != '0'){
throw({message: 'Something went wrong'})
}
}
})
useEffect(()=>{
let reqData = {
product_id : productID,
token: localStorage.getItem('token'), // USER TOKEN
uid: localStorage.getItem('uid') // USER UID
}
getProductData.mutate(reqData)
},[])
const myproduct_data = getProductData?.data?.data?.myproduct?.myproudct // PRODUCT DETAILS
const {data, isFetching, isError, error} = useQuery({
queryKey: queryKeys.product_page,
queryFn: () => MyProductData(reqData),
staleTime: 0
})
const myproduct_data = data?.data?.myproduct?.myproudct // PRODUCT DETAILS
const product_name = myproduct_data?.product_name;
const product_status = myproduct_data?.status;
@@ -47,7 +35,7 @@ export default function ProductFactory(){
<>
<BreadcrumbComBS title={product_name} paths={['Dashboard', 'Product']} />
<div className="row">
{getProductData?.isPending ?
{isFetching ?
<>
<div className="row">
<div className="col-12">
@@ -55,27 +43,26 @@ export default function ProductFactory(){
</div>
</div>
</>
: getProductData?.error ?
: isError ?
<div className="row">
<div className="col-12">
<p className='text-danger'>{getProductData?.error?.message}</p>
<p className='text-danger'>{error?.message}</p>
</div>
</div>
:
<div>
{(product_status <= productConst.PRODUCT_AVAILABLE)?
<ProductStart productData={myproduct_data} />
:<></> }
:
<div>
{(product_status <= productConst.PRODUCT_AVAILABLE)?
<ProductStart productData={myproduct_data} />
:<></> }
{(product_status === productConst.PRODUCT_PROVISIONING)?
<ProductProvision productData={myproduct_data} />
:<></> }
{(product_status === productConst.PRODUCT_PROVISIONING)?
<ProductProvision productData={myproduct_data} />
:<></> }
{(product_status === productConst.PRODUCT_ACTIVE)?
<ProductActive productData={myproduct_data} />
:<></> }
</div>
{(product_status === productConst.PRODUCT_ACTIVE)?
<ProductActive productData={myproduct_data} />
:<></> }
</div>
}
</div>
</>
+5 -7
View File
@@ -25,7 +25,7 @@ export default function ProductProvision(props){
queryFn: () => productProvision(reqData)
})
const provisionData = provision?.data?.provision
const provisionData = provision?.data
useEffect(()=>{
joinRoom(productSubUID); // provision subscription room
@@ -60,7 +60,7 @@ export default function ProductProvision(props){
<div className="card-body">
<div className="progress">
<div className="progress-bar progress-bar-striped progress-bar-animated" role="progressbar"
aria-valuenow={`${provisionData.percent_completed}%`} aria-valuemin="0" aria-valuemax="100" style={{width:`${provisionData.percent_completed}%`}} ></div>
aria-valuenow={`${provisionData?.percent_completed}%`} aria-valuemin="0" aria-valuemax="100" style={{width:`${provisionData?.percent_completed}%`}} ></div>
</div>
</div>
</div>
@@ -110,11 +110,9 @@ export default function ProductProvision(props){
<div className="card card-statistics ">
<h4 className="card-title" style={{padding:'10px'}}>Started creating your selection</h4>
<img className="card-img-top" src={getImage('widget/working.jpg')} alt="Card image cap" />
<div className="card-body">
<p>
{productDescription}
</p>
</div>
{/* <div className="card-body">
<div className="" dangerouslySetInnerHTML={{__html: productDescription}}/>
</div> */}
</div>
</div>
+40 -18
View File
@@ -1,6 +1,7 @@
import React, { useRef, useState } from "react";
import {useNavigate} from 'react-router-dom'
import getImage from "../../utils/getImage";
// import { Modal } from "bootstrap";
import { Modal } from "bootstrap";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { subscribe } from '../../services/services'
import queryKeys from "../../services/queryKeys";
@@ -8,26 +9,28 @@ import queryKeys from "../../services/queryKeys";
export default function ProductStart(props){
const queryClient = useQueryClient()
const navigate = useNavigate()
const [requestStatus, setRequestStatus] = useState({status:false, message: ''})
const product_uid = props?.productData?.product_uid;
const product_id = props?.productData?.product_id;
const productBanner = "product/"+props.productData?.banner;
const productTitle = props.productData?.title;
const productDescription = props.productData?.description;
const promotion_text = props.productData?.promotion_text;
const product_status = props.productData?.status;
const saleText = props.productData?.sale_text;
const modalRef = useRef()
const productBanner = `product/${props.productData?.banner}`;
const productTitle = props?.productData?.title;
const productDescription = props?.productData?.description;
const promotion_text = props?.productData?.promotion_text;
const product_status = props?.productData?.status;
const saleText = props?.productData?.sale_text;
const refetch = () => {
queryClient.refetchQueries({
queryKey: [...queryKeys.product],
// type: 'active',
// exact: true,
})
const modalRef = useRef(null)
const invalidate = () => {
// queryClient.refetchQueries({
// queryKey: [...queryKeys.product],
// // type: 'active',
// // exact: true,
// })
queryClient.invalidateQueries({ queryKey: [...queryKeys.product_url] })
queryClient.invalidateQueries({ queryKey: [...queryKeys.product_page] })
}
const mutation = useMutation({
@@ -40,9 +43,12 @@ export default function ProductStart(props){
},
onSuccess: (res) => {
setRequestStatus({status:true, message:'successful'})
navigate(`/product/${product_id}`, {replace: true}) //'/product/'+ product_id
dismissModal()
console.log(res)
},
onSettled: () => {
invalidate() // Invalidates selected queries
setTimeout(()=>{
setRequestStatus({status:false, message:''})
},4000)
@@ -53,6 +59,22 @@ export default function ProductStart(props){
mutation.mutate({product_id: product_id})
}
const dismissModal = () => {
const body = document.querySelector('body')
body.removeAttribute('style')
// body.classList.toggle('modal-open')
const modalBackdrop = document.querySelectorAll('.modal-backdrop')
modalBackdrop.forEach(item => {
if (item) {
item.remove();
}
})
const modal = Modal.getInstance(modalRef.current);
modal && modal.hide();
};
return (
<>
<div className="row">
@@ -113,7 +135,7 @@ export default function ProductStart(props){
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title" id="verticalCenterTitle">{productTitle}</h5>
<button onClick={refetch} type="button" className="close" data-bs-dismiss="modal" aria-label="Close">
<button type="button" className="close" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
@@ -140,7 +162,7 @@ export default function ProductStart(props){
)}
</div>
<div className="modal-footer">
<button onClick={refetch} type="button" className="btn btn-danger" data-bs-dismiss="modal">Close</button>
<button type="button" className="btn btn-danger" data-bs-dismiss="modal">Close</button>
<button type="button" className="btn btn-success" disabled={mutation.isSuccess} onClick={handleSubscribe}>{mutation.isPending ? 'loading...' : 'Start'}</button>
</div>
</div>
+3 -5
View File
@@ -1,9 +1,9 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
// import './index.css';
import { Provider } from 'react-redux';
// import { Provider } from 'react-redux';
// import store from './store/store'
import { BrowserRouter } from 'react-router-dom';
import store from './store/store'
import App from './App';
//import reportWebVitals from './reportWebVitals';
@@ -17,9 +17,7 @@ const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter>
<Provider store={store}>
<App />
</Provider>
<App />
</BrowserRouter>
</React.StrictMode>
);
+1
View File
@@ -1,5 +1,6 @@
const siteLinks = {
error: '*',
help: '/help',
home: '/',
dash: '/dash',
product: '/product/*',
+4 -3
View File
@@ -1,12 +1,13 @@
const queryKeys = {
user_details: ['user_details'],
product_url: ['product_url'],
products: ['product-data'],
myproduct_provision: ['myproduct_provision'],
product_page: ['product_page'],
dashboard: ['dashboard'],
topBar: ['top-bar'],
recentAction: ['recent-action'],
product: ['product-data'],
product_url: ['product_url'],
myproduct_provision: ['myproduct_provision'],
calendar_events: ['calendar_events'],
contacts: ['contacts']
}
+7
View File
@@ -0,0 +1,7 @@
import HelpCom from '../component/help/HelpCom'
export default function HelpPage() {
return (
<HelpCom />
)
}