From 715a48af7bd2557edf04dbea6440ffc9195fa52c Mon Sep 17 00:00:00 2001 From: lubega-deriv Date: Wed, 13 Nov 2024 14:09:02 +0800 Subject: [PATCH 1/3] chore: enter existing mt5 password modal --- .../WalletPasswordField.tsx | 35 ++++++--- .../WalletPasswordFieldLazy.tsx | 1 + .../MT5PasswordModal/MT5PasswordModal.tsx | 78 ++++++++++++------- .../MT5PasswordModalFooters.tsx | 2 +- .../__tests__/MT5PasswordModal.spec.tsx | 18 ++++- .../MT5PasswordModalFooters.spec.tsx | 4 +- .../screens/EnterPassword/EnterPassword.tsx | 19 ++--- .../__test__/EnterPassword.spec.tsx | 47 ++++++----- 8 files changed, 125 insertions(+), 79 deletions(-) diff --git a/packages/wallets/src/components/Base/WalletPasswordField/WalletPasswordField.tsx b/packages/wallets/src/components/Base/WalletPasswordField/WalletPasswordField.tsx index 5be9cba5668a..5abf2317772a 100644 --- a/packages/wallets/src/components/Base/WalletPasswordField/WalletPasswordField.tsx +++ b/packages/wallets/src/components/Base/WalletPasswordField/WalletPasswordField.tsx @@ -50,6 +50,7 @@ export const validatePassword = ( const WalletPasswordField: React.FC = ({ autoComplete, + hideValidation = false, label, mt5Policy = false, name = 'walletPasswordField', @@ -67,10 +68,17 @@ const WalletPasswordField: React.FC = ({ const [errorMessage, setErrorMessage] = useState(''); const { score, validationErrorMessage } = useMemo( - () => validatePassword(password, mt5Policy, localize), - [password, mt5Policy, localize] + () => + hideValidation ? { score: 0, validationErrorMessage: '' } : validatePassword(password, mt5Policy, localize), + [password, mt5Policy, localize, hideValidation] ); const passwordValidation = mt5Policy ? !validPasswordMT5(password) : !validPassword(password); + const getErrorMessage = () => { + if (hideValidation) { + return passwordError ? getPasswordErrorMessage(localize).PasswordError : ''; + } + return isTouched && (serverErrorMessage || errorMessage); + }; const handleChange = useCallback( (e: React.ChangeEvent) => { @@ -90,18 +98,27 @@ const WalletPasswordField: React.FC = ({ }, [isTouched]); useEffect(() => { - setShowErrorMessage(!!passwordError); - setErrorMessage(passwordError ? getPasswordErrorMessage(localize).PasswordError : validationErrorMessage); - }, [passwordError, validationErrorMessage, localize]); + if (!hideValidation) { + setShowErrorMessage(!!passwordError); + setErrorMessage(passwordError ? getPasswordErrorMessage(localize).PasswordError : validationErrorMessage); + } else { + setShowErrorMessage(!!passwordError); + setErrorMessage(passwordError ? getPasswordErrorMessage(localize).PasswordError : ''); + } + }, [passwordError, validationErrorMessage, localize, hideValidation]); return (
= ({ type={isPasswordVisible ? 'text' : 'password'} value={password} /> - {!shouldDisablePasswordMeter && } + {!hideValidation && !shouldDisablePasswordMeter && }
); }; diff --git a/packages/wallets/src/components/Base/WalletPasswordFieldLazy/WalletPasswordFieldLazy.tsx b/packages/wallets/src/components/Base/WalletPasswordFieldLazy/WalletPasswordFieldLazy.tsx index 722ca5a7798c..f0c681d0b20a 100644 --- a/packages/wallets/src/components/Base/WalletPasswordFieldLazy/WalletPasswordFieldLazy.tsx +++ b/packages/wallets/src/components/Base/WalletPasswordFieldLazy/WalletPasswordFieldLazy.tsx @@ -3,6 +3,7 @@ import { Loader } from '@deriv-com/ui'; import { WalletTextFieldProps } from '../WalletTextField/WalletTextField'; export interface WalletPasswordFieldProps extends WalletTextFieldProps { + hideValidation?: boolean; mt5Policy?: boolean; // This prop is used to utilize the new password validation for MT5. password: string; passwordError?: boolean; diff --git a/packages/wallets/src/features/cfd/modals/MT5PasswordModal/MT5PasswordModal.tsx b/packages/wallets/src/features/cfd/modals/MT5PasswordModal/MT5PasswordModal.tsx index ecf769d71019..0c07acfbe831 100644 --- a/packages/wallets/src/features/cfd/modals/MT5PasswordModal/MT5PasswordModal.tsx +++ b/packages/wallets/src/features/cfd/modals/MT5PasswordModal/MT5PasswordModal.tsx @@ -13,8 +13,8 @@ import { SentEmailContent } from '../../../../components'; import { ModalStepWrapper, ModalWrapper } from '../../../../components/Base'; import { useModal } from '../../../../components/ModalProvider'; import { platformPasswordResetRedirectLink } from '../../../../utils/cfd'; -import { validPassword, validPasswordMT5 } from '../../../../utils/password-validation'; -import { CFD_PLATFORMS, JURISDICTION, MARKET_TYPE, PlatformDetails } from '../../constants'; +import { validPasswordMT5 } from '../../../../utils/password-validation'; +import { CFD_PLATFORMS, getMarketTypeDetails, JURISDICTION, MARKET_TYPE, PlatformDetails } from '../../constants'; import { CreatePassword, CreatePasswordMT5, EnterPassword, MT5ResetPasswordModal } from '../../screens'; import { TAvailableMT5Account } from '../../types'; import { MT5AccountAdded } from '../MT5AccountAdded'; @@ -79,6 +79,7 @@ const MT5PasswordModal: React.FC = ({ account, isVirtual = false }) => { const marketType = account.market_type ?? 'synthetic'; const platform = account.platform; const product = account.product; + const marketTypeTitle = getMarketTypeDetails(localize, product)[marketType].title; const isMT5PasswordNotSet = accountStatusData?.is_mt5_password_not_set; const { platform: mt5Platform, title } = PlatformDetails.mt5; @@ -90,6 +91,10 @@ const MT5PasswordModal: React.FC = ({ account, isVirtual = false }) => { createMT5AccountStatus === 'error' && (createMT5AccountError?.error?.code === 'InvalidTradingPlatformPasswordFormat' || createMT5AccountError?.error?.code === 'IncorrectMT5PasswordFormat'); + const hasCreateMT5AccountError = !updateMT5Password && createMT5AccountStatus === 'error'; + const isPasswordError = createMT5AccountError?.error?.code === 'PasswordError'; + const isPasswordResetError = createMT5AccountError?.error?.code === 'PasswordReset'; + const isInputValidationError = createMT5AccountError?.error?.code === 'InputValidationFailed'; const onSubmit = useCallback(async () => { // ====== Create MT5 Account ====== @@ -183,16 +188,28 @@ const MT5PasswordModal: React.FC = ({ account, isVirtual = false }) => { ); const renderTitle = useCallback(() => { - const accountAction = isMT5PasswordNotSet ? localize('Create a') : localize('Enter your'); - const accountTitle = isVirtual ? localize('demo {{title}}', { title }) : title; + let modalTitle; - return updateMT5Password - ? localize('{{title}} latest password requirements', { title }) - : localize('{{accountAction}} {{accountTitle}} password', { - accountAction, - accountTitle, - }); - }, [isMT5PasswordNotSet, isVirtual, localize, title, updateMT5Password]); + if (updateMT5Password) { + modalTitle = localize('{{title}} latest password requirements', { title }); + } else if (isMT5PasswordNotSet) { + modalTitle = isVirtual + ? localize('Create a demo {{title}} password', { title }) + : localize('Create a {{title}} password', { title }); + } else { + modalTitle = isVirtual + ? localize('Add an {{title}} {{marketTypeTitle}} demo account', { + marketTypeTitle, + title: CFD_PLATFORMS.MT5.toLocaleUpperCase(), + }) + : localize('Add an {{title}} {{marketTypeTitle}} account', { + marketTypeTitle, + title: CFD_PLATFORMS.MT5.toLocaleUpperCase(), + }); + } + + return modalTitle; + }, [isMT5PasswordNotSet, isVirtual, localize, marketTypeTitle, title, updateMT5Password]); const renderFooter = useCallback(() => { if (isMT5PasswordNotSet) @@ -221,11 +238,7 @@ const MT5PasswordModal: React.FC = ({ account, isVirtual = false }) => {
= ({ account, isVirtual = false }) => { marketType={marketType} modalTitle={ isVirtual - ? localize('Enter your demo {{title}} password', { title }) - : localize('Enter your {{title}} password', { title }) + ? localize('Add an {{title}} {{marketTypeTitle}} demo account', { + marketTypeTitle, + title: CFD_PLATFORMS.MT5.toLocaleUpperCase(), + }) + : localize('Add an {{title}} {{marketTypeTitle}} account', { + marketTypeTitle, + title: CFD_PLATFORMS.MT5.toLocaleUpperCase(), + }) } onPasswordChange={e => setPassword(e.target.value)} onPrimaryClick={onSubmit} onSecondaryClick={() => sendEmailVerification()} onTncChange={() => setIsTncChecked(prev => !prev)} password={password} - passwordError={createMT5AccountError?.error?.code === 'PasswordError'} + passwordError={ + createMT5AccountError?.error?.code === 'PasswordError' || + createMT5AccountError?.error?.code === 'InputValidationFailed' + } platform={mt5Platform} product={product} setPassword={setPassword} @@ -321,14 +343,14 @@ const MT5PasswordModal: React.FC = ({ account, isVirtual = false }) => { account, isTncChecked, isVirtual, - product, updateMT5Password, tradingPasswordChangeError, onSubmitPasswordChange, marketType, localize, - title, + marketTypeTitle, createMT5AccountError?.error?.code, + product, sendEmailVerification, ]); @@ -358,18 +380,16 @@ const MT5PasswordModal: React.FC = ({ account, isVirtual = false }) => { /> ); } - if ( - createMT5AccountStatus === 'error' && - createMT5AccountError?.error?.code === 'PasswordReset' && - !updateMT5Password - ) { + + if (hasCreateMT5AccountError && isPasswordResetError) { return sendEmailVerification()} />; } if ( - createMT5AccountStatus === 'error' && - createMT5AccountError?.error?.code !== 'PasswordError' && - !updateMT5Password + isMT5PasswordNotSet + ? hasCreateMT5AccountError && !isPasswordError + : hasCreateMT5AccountError && !isPasswordError && !isInputValidationError ) { + if (!createMT5AccountError?.error) return null; return ; } diff --git a/packages/wallets/src/features/cfd/modals/MT5PasswordModal/MT5PasswordModalFooters.tsx b/packages/wallets/src/features/cfd/modals/MT5PasswordModal/MT5PasswordModalFooters.tsx index 03504c77d111..a0e6442b3ae2 100644 --- a/packages/wallets/src/features/cfd/modals/MT5PasswordModal/MT5PasswordModalFooters.tsx +++ b/packages/wallets/src/features/cfd/modals/MT5PasswordModal/MT5PasswordModalFooters.tsx @@ -25,7 +25,7 @@ export const MT5PasswordModalFooter = ({ disabled, isLoading, onPrimaryClick, on textSize='sm' variant='outlined' > - +