@brightlayer-ui/react-auth-workflow
Version:
Re-usable workflow components for Authentication and Registration within Eaton applications.
168 lines (167 loc) • 7.46 kB
JavaScript
import React, { useEffect, useState } from 'react';
import { RegistrationWorkflowContextProvider, useRegistrationContext } from '../../contexts/index.js';
import { AccountDetailsScreen, CreateAccountScreen, CreatePasswordScreen, EulaScreen, ExistingAccountSuccessScreen, RegistrationSuccessScreen, VerifyCodeScreen, } from '../../screens/index.js';
import { parseQueryString } from '../../utils/index.js';
import { useErrorManager } from '../../contexts/ErrorContext/useErrorManager.js';
import ErrorManager from '../Error/ErrorManager.js';
import { Spinner } from '../Spinner/index.js';
/**
* 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 } = props;
const [isAccountExist, setIsAccountExist] = useState(false);
const { triggerError, errorManagerConfig: globalErrorManagerConfig } = useErrorManager();
const { actions, navigate } = useRegistrationContext();
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 = React.createElement(RegistrationSuccessScreen, null), existingAccountSuccessScreen = React.createElement(ExistingAccountSuccessScreen, null), isInviteRegistration = false, children = isInviteRegistration
? [
React.createElement(EulaScreen, { key: "EulaScreen" }),
React.createElement(CreatePasswordScreen, { key: "CreatePasswordScreen" }),
React.createElement(AccountDetailsScreen, { key: "AccountDetailsScreen" }),
]
: [
React.createElement(EulaScreen, { key: "EulaScreen" }),
React.createElement(CreateAccountScreen, { key: "CreateAccountScreen" }),
React.createElement(VerifyCodeScreen, { key: "VerifyCodeScreen" }),
React.createElement(CreatePasswordScreen, { key: "CreatePasswordScreen" }),
React.createElement(AccountDetailsScreen, { key: "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 [screenData, setScreenData] = useState({
Eula: {
accepted: false,
},
CreateAccount: {
emailAddress: '',
},
VerifyCode: {
code: '',
isAccountExist: false,
},
CreatePassword: {
password: '',
confirmPassword: '',
},
AccountDetails: {
firstName: '',
lastName: '',
},
Other: {},
});
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 [loading, setLoading] = useState(false);
const finishRegistration = async (data) => {
try {
setLoading(true);
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 {
setLoading(false);
}
};
useEffect(() => {
if (isInviteRegistration) {
const params = parseQueryString(window.location.search);
updateScreenData({ screenId: 'CreateAccount', values: { emailAddress: params.email } });
updateScreenData({ screenId: 'VerifyCode', values: { code: params.code } });
}
}, []);
return (React.createElement(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);
}
catch (_error) {
triggerError(_error);
}
}, previousScreen: (data) => {
updateScreenData(data);
if (currentScreen === 0) {
navigate(-1);
}
setCurrentScreen((i) => i - 1);
}, screenData: screenData, updateScreenData: updateScreenData, isInviteRegistration: isInviteRegistration },
React.createElement(ErrorManager, { ...errorDisplayConfig, mode: "dialog" },
showSuccessScreen
? isAccountExist
? existingAccountSuccessScreen
: successScreen
: screens[currentScreen],
loading ? React.createElement(Spinner, { visible: loading }) : null)));
};