@brightlayer-ui/react-native-auth-workflow
Version:
Re-usable workflow components for Authentication and Registration within Eaton applications.
230 lines (229 loc) • 14.8 kB
JavaScript
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import React, { useCallback, useRef, useState } from 'react';
import { WorkflowCard } from '../../components/WorkflowCard';
import { WorkflowCardBody } from '../../components/WorkflowCard/WorkflowCardBody';
import { ErrorManager, PasswordTextField } from '../../components';
import { Image, View, StyleSheet, Keyboard } from 'react-native';
import { Button, Checkbox, HelperText, Text, TextInput } from 'react-native-paper';
import { useExtendedTheme } from '@brightlayer-ui/react-native-themes';
import { useScreenDimensions } from '../../hooks/useScreenDimensions';
const makeStyles = (isTablet) => StyleSheet.create({
container: {
flex: 1,
},
projectImageWrapper: {
display: 'flex',
maxWidth: '100%',
marginBottom: isTablet ? 24 : 16,
},
inputFieldsWrapper: {
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
width: '100%',
marginVertical: isTablet ? 32 : 24,
},
usernameWrapper: {
width: '100%',
marginVertical: isTablet ? 32 : 24,
},
passwordWrapper: {
width: '100%',
},
rememberMeLoginRowWrapper: {
display: 'flex',
alignItems: 'center',
width: '100%',
justifyContent: 'center',
flexDirection: 'row',
marginTop: isTablet ? 24 : 16,
marginBottom: isTablet ? 32 : 24,
},
rememberMeWrapper: {
display: 'flex',
flex: 1,
alignItems: 'center',
flexDirection: 'row',
},
loginButtonWrapper: {
display: 'flex',
flex: 1,
justifyContent: 'flex-end',
flexDirection: 'row',
},
rememberMeText: {
display: 'flex',
flex: 1,
},
loginButton: {
width: '100%',
},
forgotPasswordWrapper: {
display: 'flex',
justifyContent: 'center',
alignContent: 'center',
alignItems: 'center',
marginBottom: isTablet ? 32 : 24,
},
selfRegisterWrapper: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'column',
marginTop: 4,
alignContent: 'center',
marginBottom: isTablet ? 32 : 24,
},
contactSupportWrapper: {
display: 'flex',
justifyContent: 'center',
marginTop: 4,
alignContent: 'center',
alignItems: 'center',
marginBottom: isTablet ? 32 : 24,
},
footerWrapper: { display: 'flex', justifyContent: 'center' },
cyberSecurityBadgeWrapper: { display: 'flex', flexDirection: 'row', justifyContent: 'center', marginTop: 2 },
});
/**
* Component that renders a login screen that prompts a user to enter a username and password to login.
*
* @param {LoginScreenProps} props - Props of Login Screen component
*
* @category Component
*/
export const LoginScreenBase = (props) => {
const { usernameLabel, usernameTextFieldProps, usernameValidator, initialUsernameValue, passwordTextFieldProps, passwordValidator, showRememberMe, rememberMeLabel, rememberMeInitialValue, onRememberMeChanged, loginButtonLabel, onLogin, showForgotPassword, forgotPasswordLabel, onForgotPassword, showSelfRegistration, selfRegisterButtonLabel, selfRegisterInstructions, onSelfRegister, showContactSupport, contactSupportLabel, onContactSupport, errorDisplayConfig, showCyberSecurityBadge, projectImage, header, footer, cyberSecurityBadgeSize } = props, otherProps = __rest(props, ["usernameLabel", "usernameTextFieldProps", "usernameValidator", "initialUsernameValue", "passwordTextFieldProps", "passwordValidator", "showRememberMe", "rememberMeLabel", "rememberMeInitialValue", "onRememberMeChanged", "loginButtonLabel", "onLogin", "showForgotPassword", "forgotPasswordLabel", "onForgotPassword", "showSelfRegistration", "selfRegisterButtonLabel", "selfRegisterInstructions", "onSelfRegister", "showContactSupport", "contactSupportLabel", "onContactSupport", "errorDisplayConfig", "showCyberSecurityBadge", "projectImage", "header", "footer", "cyberSecurityBadgeSize"]);
const theme = useExtendedTheme();
const { isTablet } = useScreenDimensions();
const [username, setUsername] = React.useState(initialUsernameValue !== null && initialUsernameValue !== void 0 ? initialUsernameValue : '');
const [password, setPassword] = React.useState('');
const [rememberMe, setRememberMe] = React.useState(rememberMeInitialValue);
const [shouldValidateUsername, setShouldValidateUsername] = React.useState(false);
const [shouldValidatePassword, setShouldValidatePassword] = React.useState(false);
const passwordField = useRef(null);
const [isUsernameValid, setIsUsernameValid] = useState(usernameValidator ? usernameValidator(username) : true);
const [isPasswordValid, setIsPasswordValid] = useState(passwordValidator ? passwordValidator(password) : true);
const [usernameError, setUsernameError] = useState(isUsernameValid === true ? '' : isUsernameValid);
const [passwordError, setPasswordError] = useState(isPasswordValid === true ? '' : isPasswordValid);
const defaultStyles = makeStyles(isTablet);
const handleUsernameInputChange = useCallback((value) => {
setUsername(value);
const validatorResponse = usernameValidator === null || usernameValidator === void 0 ? void 0 : usernameValidator(value);
setIsUsernameValid(typeof validatorResponse === 'boolean' ? validatorResponse : false);
setUsernameError(typeof validatorResponse === 'string' ? validatorResponse : '');
}, [usernameValidator]);
const handlePasswordInputChange = useCallback((value) => {
setPassword(value);
const validatorResponse = passwordValidator === null || passwordValidator === void 0 ? void 0 : passwordValidator(value);
setIsPasswordValid(typeof validatorResponse === 'boolean' ? validatorResponse : false);
setPasswordError(typeof validatorResponse === 'string' ? validatorResponse : '');
}, [passwordValidator]);
const handleForgotPassword = () => {
if (onForgotPassword)
onForgotPassword();
};
const handleSelfRegister = () => {
if (onSelfRegister)
onSelfRegister();
};
const handleContactSupport = () => {
if (onContactSupport)
onContactSupport();
};
const handleRememberMeChanged = (value) => {
Keyboard.dismiss();
if (onRememberMeChanged) {
onRememberMeChanged(value);
setRememberMe(value);
}
};
const isFormValid = () => typeof isUsernameValid === 'boolean' &&
isUsernameValid &&
typeof isPasswordValid === 'boolean' &&
isPasswordValid;
const handleLogin = () => {
Keyboard.dismiss();
if (isFormValid() && onLogin)
void onLogin(username, password, rememberMe);
};
const handleLoginSubmit = () => {
if (isFormValid()) {
handleLogin();
}
};
return (React.createElement(WorkflowCard, Object.assign({ testID: "blui-login-workflow-card" }, otherProps),
React.createElement(WorkflowCardBody, null,
header,
React.createElement(View, { style: defaultStyles.projectImageWrapper, testID: "blui-login-project-image-wrapper" }, projectImage),
React.createElement(ErrorManager, Object.assign({}, errorDisplayConfig),
React.createElement(View, { style: defaultStyles.inputFieldsWrapper, testID: "blui-login-input-fields-wrapper" },
React.createElement(View, { style: defaultStyles.usernameWrapper },
React.createElement(TextInput, Object.assign({ testID: 'blui-login-username-text-field', label: usernameLabel !== null && usernameLabel !== void 0 ? usernameLabel : 'Username', value: username, error: shouldValidateUsername && !isUsernameValid, autoCapitalize: "none", mode: "flat" }, usernameTextFieldProps, { onChangeText: (e) => {
var _a;
(_a = usernameTextFieldProps === null || usernameTextFieldProps === void 0 ? void 0 : usernameTextFieldProps.onChangeText) === null || _a === void 0 ? void 0 : _a.call(usernameTextFieldProps, e);
handleUsernameInputChange(e);
}, onSubmitEditing: (e) => {
var _a;
(_a = usernameTextFieldProps === null || usernameTextFieldProps === void 0 ? void 0 : usernameTextFieldProps.onSubmitEditing) === null || _a === void 0 ? void 0 : _a.call(usernameTextFieldProps, e);
if (passwordField.current)
passwordField.current.focus();
}, onBlur: (e) => {
var _a;
(_a = usernameTextFieldProps === null || usernameTextFieldProps === void 0 ? void 0 : usernameTextFieldProps.onBlur) === null || _a === void 0 ? void 0 : _a.call(usernameTextFieldProps, e);
setShouldValidateUsername(true);
} })),
shouldValidateUsername && !isUsernameValid && (React.createElement(HelperText, { type: "error" }, usernameError))),
React.createElement(View, { style: defaultStyles.passwordWrapper },
React.createElement(PasswordTextField, { testID: 'blui-login-password-text-field', ref: passwordField, onChangeText: (e) => {
var _a;
(_a = passwordTextFieldProps === null || passwordTextFieldProps === void 0 ? void 0 : passwordTextFieldProps.onChange) === null || _a === void 0 ? void 0 : _a.call(passwordTextFieldProps, e);
handlePasswordInputChange(e);
}, onSubmitEditing: (e) => {
if (passwordTextFieldProps === null || passwordTextFieldProps === void 0 ? void 0 : passwordTextFieldProps.onSubmitEditing) {
passwordTextFieldProps.onSubmitEditing(e);
}
handleLoginSubmit();
}, onBlur: (e) => {
var _a;
(_a = passwordTextFieldProps === null || passwordTextFieldProps === void 0 ? void 0 : passwordTextFieldProps.onBlur) === null || _a === void 0 ? void 0 : _a.call(passwordTextFieldProps, e);
setShouldValidatePassword(true);
} }),
shouldValidatePassword && !isPasswordValid && (React.createElement(HelperText, { type: "error" }, passwordError))))),
React.createElement(View, { style: defaultStyles.rememberMeLoginRowWrapper, testID: 'blui-login-remember-me-row-wrapper' },
showRememberMe && (React.createElement(View, { style: defaultStyles.rememberMeWrapper, testID: 'blui-login-remember-me-wrapper' },
React.createElement(Checkbox.Android, { status: rememberMe ? 'checked' : 'unchecked', onPress: () => handleRememberMeChanged(!rememberMe), testID: 'blui-login-remember-me-checkbox' }),
React.createElement(Text, { variant: "bodyLarge", testID: 'blui-login-remember-me-login', style: defaultStyles.rememberMeText }, rememberMeLabel !== null && rememberMeLabel !== void 0 ? rememberMeLabel : 'Remember Me'))),
React.createElement(View, { style: [
defaultStyles.loginButtonWrapper,
{
width: showRememberMe ? 'auto' : '100%',
},
], testID: 'blui-login-login-button-wrapper' },
React.createElement(Button, { testID: 'blui-login-login-button', onPress: handleLogin, disabled: !isFormValid(), mode: "contained", style: defaultStyles.loginButton }, loginButtonLabel !== null && loginButtonLabel !== void 0 ? loginButtonLabel : 'Log In'))),
showForgotPassword && (React.createElement(View, { style: defaultStyles.forgotPasswordWrapper, testID: 'blui-login-forgot-password-wrapper' },
React.createElement(Text, { variant: "labelLarge", style: { color: theme.colors.primary }, onPress: handleForgotPassword, testID: 'blui-login-forgot-password-label' }, forgotPasswordLabel !== null && forgotPasswordLabel !== void 0 ? forgotPasswordLabel : 'Forgot your password?'))),
showSelfRegistration && (React.createElement(View, { style: defaultStyles.selfRegisterWrapper, testID: 'blui-login-self-register-wrapper' },
React.createElement(Text, { variant: "bodyMedium", testID: 'blui-login-self-register-instruction-label' }, selfRegisterInstructions !== null && selfRegisterInstructions !== void 0 ? selfRegisterInstructions : 'Need an account?'),
React.createElement(Text, { variant: "labelLarge", style: { color: theme.colors.primary }, onPress: handleSelfRegister, testID: 'blui-login-self-register-label' }, selfRegisterButtonLabel !== null && selfRegisterButtonLabel !== void 0 ? selfRegisterButtonLabel : 'Register now!'))),
showContactSupport && (React.createElement(View, { style: defaultStyles.contactSupportWrapper, testID: 'blui-login-contact-support-wrapper' },
React.createElement(Text, { variant: "labelLarge", style: { color: theme.colors.primary }, onPress: handleContactSupport, testID: 'blui-login-contact-support-label' }, contactSupportLabel !== null && contactSupportLabel !== void 0 ? contactSupportLabel : 'Contact Support'))),
React.createElement(View, { style: defaultStyles.footerWrapper }, footer),
showCyberSecurityBadge && (React.createElement(View, { style: defaultStyles.cyberSecurityBadgeWrapper, testID: 'blui-login-cyber-security-badge-wrapper' },
React.createElement(Image
//@ts-ignore
, {
//@ts-ignore
style: Object.assign({}, cyberSecurityBadgeSize), resizeMode: "contain", source: require('../../assets/images/cybersecurity_certified.png') }))))));
};