UNPKG

@brightlayer-ui/react-native-auth-workflow

Version:

Re-usable workflow components for Authentication and Registration within Eaton applications.

196 lines (195 loc) 9.03 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import React, { useEffect, useRef, useState } from 'react'; import { RegistrationWorkflowContextProvider, useErrorManager, useRegistrationContext, } from '../../contexts/index.js'; import PagerView from 'react-native-pager-view'; import { View, StyleSheet } from 'react-native'; import { ErrorManager } from '../Error/ErrorManager.js'; import { EulaScreen, CreateAccountScreen, VerifyCodeScreen, CreatePasswordScreen, AccountDetailsScreen, RegistrationSuccessScreen, ExistingAccountSuccessScreen, } from '../../screens/index.js'; import { Spinner } from '../Spinner/index.js'; import { timeOutDelay } from '../../constants/index.js'; const styles = StyleSheet.create({ pagerView: { flex: 1, }, }); /** * Component that contain the registration workflow and index of screens. * * @param {RegistrationWorkflowProps} props - props of RegistrationWorkflow component * * @category Component */ export const RegistrationWorkflow = (props) => { const { errorDisplayConfig: registrationWorkflowErrorConfig, eulaIsHtml = false } = props; const [isAccountExist, setIsAccountExist] = useState(false); const { triggerError, errorManagerConfig: globalErrorManagerConfig } = useErrorManager(); const { actions, navigate, routeConfig } = useRegistrationContext(); const viewPagerRef = useRef(null); const { messageBoxConfig: workflowMessageBoxConfig, dialogConfig: workflowDialogConfig, onClose: workflowOnClose, ...otherWorkflowErrorConfig } = registrationWorkflowErrorConfig ?? {}; const { messageBoxConfig: globalMessageBoxConfig, dialogConfig: globalDialogConfig, onClose: globalOnClose, ...otherGlobalErrorConfig } = globalErrorManagerConfig; const errorDisplayConfig = { messageBoxConfig: { ...globalMessageBoxConfig, ...workflowMessageBoxConfig }, dialogConfig: { ...globalDialogConfig, ...workflowDialogConfig }, onClose: () => { workflowOnClose?.(); globalOnClose?.(); }, ...otherGlobalErrorConfig, ...otherWorkflowErrorConfig, }; const { initialScreenIndex = 0, successScreen = _jsx(RegistrationSuccessScreen, {}), existingAccountSuccessScreen = _jsx(ExistingAccountSuccessScreen, {}), isInviteRegistration, children = isInviteRegistration ? [ _jsx(EulaScreen, { html: eulaIsHtml }, "EulaScreen"), _jsx(CreatePasswordScreen, {}, "CreatePasswordScreen"), _jsx(AccountDetailsScreen, {}, "AccountDetailsScreen"), ] : [ _jsx(EulaScreen, { html: eulaIsHtml }, "EulaScreen"), _jsx(CreateAccountScreen, {}, "CreateAccountScreen"), _jsx(VerifyCodeScreen, {}, "VerifyCodeScreen"), _jsx(CreatePasswordScreen, {}, "CreatePasswordScreen"), _jsx(AccountDetailsScreen, {}, "AccountDetailsScreen"), ], } = props; const screens = [...(Array.isArray(children) ? children : [children])]; const totalScreens = screens.length; const [currentScreen, setCurrentScreen] = useState(initialScreenIndex < 0 ? 0 : initialScreenIndex > totalScreens - 1 ? totalScreens - 1 : initialScreenIndex); const [showSuccessScreen, setShowSuccessScreen] = useState(false); const initialRegistrationWorkflowScreenData = { Eula: { accepted: false, }, CreateAccount: { emailAddress: '', }, VerifyCode: { code: '', isAccountExist: false, }, CreatePassword: { password: '', confirmPassword: '', }, AccountDetails: { firstName: '', lastName: '', }, Other: {}, }; const [screenData, setScreenData] = useState(initialRegistrationWorkflowScreenData); const [viewPagerIndex, setViewPagerIndex] = useState(0); const selectedPage = React.useRef(0); const updateScreenData = (data) => { const { Other } = screenData; const { screenId, values, isAccountExist: accountExists } = data; if (accountExists) { setIsAccountExist(accountExists); setShowSuccessScreen(accountExists); } if (!Object.keys(screenData).includes(screenId)) { setScreenData((oldData) => ({ ...oldData, Other: { ...oldData.Other, [screenId]: values }, })); } else if (Object.keys(Other).includes(screenId)) { setScreenData((oldData) => ({ ...oldData, Other: { ...Other, [screenId]: { ...Other[screenId], ...values } }, })); } else { setScreenData((oldData) => ({ ...oldData, [screenId]: values, })); } }; const resetScreenData = () => { setScreenData(initialRegistrationWorkflowScreenData); setViewPagerIndex(viewPagerIndex + 1); setIsAccountExist(false); setCurrentScreen(0); setShowSuccessScreen(false); viewPagerRef.current?.setPage(0); }; const [loading, setLoading] = useState(false); const finishRegistration = async (data) => { try { setTimeout(() => { setLoading(true); }, timeOutDelay); if (actions?.completeRegistration) { const { Eula, CreateAccount, VerifyCode, CreatePassword, AccountDetails, Other } = screenData; const userInfo = { ...Eula, ...CreateAccount, ...VerifyCode, ...CreatePassword, ...AccountDetails, ...Other, ...data.values, }; return await actions .completeRegistration(userInfo) .then(({ email, organizationName }) => { updateScreenData({ screenId: 'RegistrationSuccessScreen', values: { email, organizationName }, }); setShowSuccessScreen(true); }) .catch((_error) => { triggerError(_error); }); } } catch (err) { console.error(err); } finally { setTimeout(() => { setLoading(false); }, timeOutDelay); } }; useEffect(() => { if (isInviteRegistration === true) { const { initialRegistrationParams: { email, code }, } = props; updateScreenData({ screenId: 'CreateAccount', values: { emailAddress: email } }); updateScreenData({ screenId: 'VerifyCode', values: { code } }); } }, []); return (_jsx(RegistrationWorkflowContextProvider, { currentScreen: currentScreen, totalScreens: totalScreens, nextScreen: (data) => { try { updateScreenData(data); if (data.isAccountExist) { setIsAccountExist(true); setShowSuccessScreen(true); } if (currentScreen === totalScreens - 1) return finishRegistration(data); setCurrentScreen((i) => i + 1); viewPagerRef.current?.setPage(currentScreen + 1); } catch (_error) { triggerError(_error); } }, previousScreen: (data) => { updateScreenData(data); if (currentScreen === 0) { resetScreenData(); navigate(routeConfig.LOGIN); } else { setCurrentScreen((i) => i - 1); viewPagerRef.current?.setPage(currentScreen - 1); } }, screenData: screenData, updateScreenData: updateScreenData, resetScreenData: resetScreenData, isInviteRegistration: isInviteRegistration, eulaIsHtml: eulaIsHtml, children: _jsxs(ErrorManager, { ...errorDisplayConfig, mode: "dialog", children: [showSuccessScreen ? (isAccountExist ? (existingAccountSuccessScreen) : (successScreen)) : (_jsx(PagerView, { style: styles.pagerView, initialPage: currentScreen ?? initialScreenIndex, ref: viewPagerRef, scrollEnabled: false, collapsable: false, onPageSelected: (e) => { selectedPage.current = e.nativeEvent.position; }, onPageScrollStateChanged: (e) => { if (e.nativeEvent.pageScrollState === 'idle') { viewPagerRef.current?.setPageWithoutAnimation(0); viewPagerRef.current?.setPageWithoutAnimation(selectedPage.current); } }, children: screens.map((screen, index) => (_jsx(View, { style: { flex: 1 }, children: screen }, index + 1))) }, viewPagerIndex)), loading ? _jsx(Spinner, { visible: loading }) : null] }) })); };