@wenn/onb
Version:
onb-core
345 lines (318 loc) • 8.68 kB
JavaScript
import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { Switch, Route, Redirect } from 'react-router-dom'
import { Helmet } from 'react-helmet'
import { ContainerDesktop, Onboarding, Logo, LogoMobile } from './ui/Global'
import Loading from '@bit/wenance.common-ui.web.loading' //v2
import Stepper from '@bit/wenance.common-ui.web.stepper'
import notificationMessages from './notifications'
import { saveNextPage } from './redux/actions/pages.actions'
import { loadingPage } from './redux/actions/loading.actions'
import { globalNotification } from './redux/actions/notifications.actions'
import { saveFlowError } from './redux/actions/run.actions'
import { getFakeData, saveFakeData } from './redux/actions/fakeData.actions'
const ZoneHelmet = ({ config }) => (
<Helmet
htmlAttributes={{ lang: config.LANG }}
title={config.TITLE}
meta={[
{
name: 'description',
content: config.DESCRIPTION
},
{
name: 'keywords',
content: config.KEYWORDS
}
]}
/>
)
const notificacion = '/notificacion',
felicitaciones = '/felicitaciones',
landing = '/'
class App extends React.Component {
static getDerivedStateFromProps(props, state) {
const { location } = window
const {
currentPage,
camunda: { resendSMS },
pages
} = props
let selectData,
nextPage = ''
const params = new URLSearchParams(window.location.search)
if (params.get('dev') === 'true') {
props.getFakeData()
}
if (params.get('redirect') === 'true') {
props.loadingPage(true)
}
// preguntar antes de refrescar la página, o volver hacia atras
// solo deber hacerlo en la pantallas del onboarding
const notAskBeforeUpdate = [notificacion, felicitaciones, landing].includes(
currentPage
)
window.onbeforeunload = e =>
notAskBeforeUpdate ?
e.preventDefault() :
(
sendlog('event', { event_action: 'dropout' }) ||
true
);
window.onpopstate = function() {
sendlog('event', { event_action: 'gobackEvent' });
if (
!notAskBeforeUpdate &&
// eslint-disable-next-line no-alert
!window.confirm(
'¿Deseas volver a cargar el sitio ? \n Es posible que los cambios que implementaste no se puedan guardar.'
)
) {
window.history.pushState(null, null, currentPage)
window.history.go(1)
}
}
//
if (currentPage !== notificacion && !props.flowerror) {
const index = pages.map(x => x.url).indexOf(currentPage)
selectData = index + 1
nextPage = pages[selectData].url
}
if ((!resendSMS || resendSMS.value === 'false') && !props.flowerror) {
props.saveNextPage(nextPage)
return App.handleFlowError(props, nextPage)
}
const isentEmpty =
Object.keys(props.notification).length === 0 &&
props.notification.constructor === Object
if (resendSMS && resendSMS.value === 'true') {
return App.handleFlowError(props, currentPage)
}
if (!isentEmpty) {
const snackError = notificationMessages[props.notification.bpmStep.code]
props.loadingPage(false)
if (!snackError) {
props.saveNextPage(notificacion)
return {
nextPage: notificacion
}
} else {
if(window.location.path === '/notificacion'){
props.globalNotification({})
}else{
props.globalNotification(snackError)
}
}
} else {
if (location.pathname !== props.currentPage) {
if (
params.get('dev') === 'true' &&
process.env.NODE_ENV === 'development'
) {
const pathname = location.pathname
props.saveFakeData()
App.saveNextPage(props, pathname)
} else {
props.globalNotification(notificationMessages.location_error)
App.saveNextPage(props, notificacion)
return {
nextPage: notificacion
}
}
}
}
return {
nextPage: nextPage
}
}
static saveNextPage = (props, pathname) => {
props.saveNextPage(pathname)
}
static handleFlowError = (props, nextPage) => {
props.loadingPage(false)
props.saveFlowError(true)
return { nextPage }
}
constructor(props) {
super(props)
this.state = {
nextPage: ''
}
window.sendlog = (type, data = {}) => {
if (typeof data !== 'object' || data.length !== undefined) {
data = {
message: `${data}`
}
} else {
data = Object.keys(data).reduce((acc, current) => {
let currentValue = data[current];
acc[current] = typeof currentValue === 'string' ?
currentValue :
JSON.stringify(currentValue);
return acc;
}, {});
}
const {
bpmStep,
camunda: {
brand,
country,
fingerprint,
userName
}
} = this.props;
if (userName && fingerprint) {
const fp =
(JSON.parse(fingerprint.value))
.filter(x =>
["user_agent", "resolution", "available_resolution", "adblock", "touch_support", "ip"].includes(x.key)
);
logger({
websocketid: userName.value,
data: {
serviceName: 'onboarding',
brand: brand.value,
country: country.value,
step: bpmStep,
logtype: type, // "view_page" / "error" / "event"
url: window.location.pathname,
fingerprint: JSON.stringify(fp),
...data
}
});
}
};
}
render() {
const { nextPage } = this.state
const {
width,
config,
currentPage,
currentStep,
flowerror,
pages,
assets,
routes,
loading,
Desktop,
theme,
stepperType
} = this.props
const isSamePage = currentPage === nextPage
const showSteper = pages.find(
page =>
page.url === currentPage &&
![notificacion, felicitaciones, landing].includes(page.url)
)
const STEPS = pages.filter(page => page.currentStep).length + 1
if (!flowerror || nextPage === notificacion) {
if (!isSamePage) {
return (
<div>
<ZoneHelmet config={config} />
<Redirect to={nextPage} />
</div>
)
}
}
const routesMap =
!loading && routes.map((route, i) => <Route key={i} {...route} />)
const stepperStyle = {
position: 'sticky',
zIndex: 1021,
top: '0'
}
if (width > 1000) {
return (
<ContainerDesktop>
<ZoneHelmet config={config} />
<Desktop />
<Onboarding id="container">
{showSteper && (
<Stepper
style={stepperStyle}
type={stepperType}
steps={STEPS}
currentStep={currentStep + 1}
/>
)}
{!loading && <Switch>{routesMap}</Switch>}
</Onboarding>
<Loading loading={loading} />
</ContainerDesktop>
)
}
return (
<div>
<Loading loading={loading} />
<ZoneHelmet config={config} />
{showSteper && (
<Stepper
style={stepperStyle}
type={stepperType}
steps={STEPS}
currentStep={currentStep + 1}
/>
)}
{currentPage === landing ? (
<Logo src={assets.logoInverse} alt="logo" height="32" />
) : (
<LogoMobile style={theme.logoMobile} src={assets.logo} alt="logo" height="32" />
)}
{!loading && <Switch>{routesMap}</Switch>}
</div>
)
}
}
App.proptypes = {
config: PropTypes.object.isRequired,
pages: PropTypes.array.isRequired,
currentPage: PropTypes.string.isRequired,
notification: PropTypes.object.isRequired,
flowerror: PropTypes.bool.isRequired
}
const mapState = ({
settings: {
config,
config: { pages },
assets,
wording,
width,
theme
},
bpmStep,
camunda,
currentPage,
currentStep,
notification,
flowerror,
loading
}) => ({
config,
pages,
width,
assets,
wording: wording.landing,
currentPage,
currentStep,
notification,
flowerror,
bpmStep,
camunda,
theme,
loading
})
const mapDispatch = {
saveNextPage,
loadingPage,
globalNotification,
saveFlowError,
saveFakeData,
getFakeData
}
export default connect(
mapState,
mapDispatch
)(App)