Skip to content

Commit

Permalink
Merge pull request #52356 from hungvu193/feat/validate-invoice
Browse files Browse the repository at this point in the history
Feat: Add account validation step to Invoices page
  • Loading branch information
pecanoro authored Nov 19, 2024
2 parents 5824bc0 + 260291f commit e046ebe
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ function BaseValidateCodeForm({
setValidateCode(text);
setFormError({});

if (validateError) {
if (!isEmptyObject(validateError)) {
clearError();
User.clearValidateCodeActionError('actionVerified');
}
Expand Down
15 changes: 14 additions & 1 deletion src/libs/actions/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ function validateLogin(accountID: number, validateCode: string) {
/**
* Validates a secondary login / contact method
*/
function validateSecondaryLogin(loginList: OnyxEntry<LoginList>, contactMethod: string, validateCode: string) {
function validateSecondaryLogin(loginList: OnyxEntry<LoginList>, contactMethod: string, validateCode: string, shouldResetActionCode?: boolean) {
const optimisticData: OnyxUpdate[] = [
{
onyxMethod: Onyx.METHOD.MERGE,
Expand Down Expand Up @@ -729,6 +729,19 @@ function validateSecondaryLogin(loginList: OnyxEntry<LoginList>, contactMethod:
},
];

// Sometimes we will also need to reset the validateCodeSent of ONYXKEYS.VALIDATE_ACTION_CODE in order to receive the magic code next time we open the ValidateCodeActionModal.
if (shouldResetActionCode) {
const optimisticResetActionCode = {
onyxMethod: Onyx.METHOD.MERGE,
key: ONYXKEYS.VALIDATE_ACTION_CODE,
value: {
validateCodeSent: null,
},
};
successData.push(optimisticResetActionCode);
failureData.push(optimisticResetActionCode);
}

const parameters: ValidateSecondaryLoginParams = {partnerUserID: contactMethod, validateCode};

API.write(WRITE_COMMANDS.VALIDATE_SECONDARY_LOGIN, parameters, {optimisticData, successData, failureData});
Expand Down
5 changes: 3 additions & 2 deletions src/pages/settings/Security/TwoFactorAuth/Steps/CodesStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,15 @@ function CodesStep({backTo}: CodesStepProps) {
const [account] = useOnyx(ONYXKEYS.ACCOUNT);
const [user] = useOnyx(ONYXKEYS.USER);
const [loginList] = useOnyx(ONYXKEYS.LOGIN_LIST);
const [validateCodeAction] = useOnyx(ONYXKEYS.VALIDATE_ACTION_CODE);

const isUserValidated = user?.validated;
const contactMethod = account?.primaryLogin ?? '';
const route = useRoute<RouteProp<SettingsNavigatorParamList, typeof SCREENS.SETTINGS.TWO_FACTOR_AUTH>>();

const loginData = useMemo(() => loginList?.[contactMethod], [loginList, contactMethod]);
const validateLoginError = ErrorUtils.getEarliestErrorField(loginData, 'validateLogin');
const hasMagicCodeBeenSent = !!loginData?.validateCodeSent;
const hasMagicCodeBeenSent = !!validateCodeAction?.validateCodeSent;

const {setStep} = useTwoFactorAuthContext();

Expand Down Expand Up @@ -176,7 +177,7 @@ function CodesStep({backTo}: CodesStepProps) {
hasMagicCodeBeenSent={hasMagicCodeBeenSent}
validatePendingAction={loginData?.pendingFields?.validateCodeSent}
sendValidateCode={() => User.requestValidateCodeAction()}
handleSubmitForm={(validateCode) => User.validateSecondaryLogin(loginList, contactMethod, validateCode)}
handleSubmitForm={(validateCode) => User.validateSecondaryLogin(loginList, contactMethod, validateCode, true)}
validateError={!isEmptyObject(validateLoginError) ? validateLoginError : ErrorUtils.getLatestErrorField(loginData, 'validateCodeSent')}
clearError={() => User.clearContactMethodErrors(contactMethod, !isEmptyObject(validateLoginError) ? 'validateLogin' : 'validateCodeSent')}
onModalHide={() => {}}
Expand Down
3 changes: 1 addition & 2 deletions src/pages/settings/Wallet/PaymentMethodList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,6 @@ function PaymentMethodList({
text={translate('walletPage.addBankAccount')}
large
success
isDisabled={!isUserValidated}
onPress={onPress}
/>
) : (
Expand All @@ -392,7 +391,7 @@ function PaymentMethodList({
/>
),

[shouldShowAddBankAccountButton, onPressItem, translate, onPress, buttonRef, styles.paymentMethod, listItemStyle, isUserValidated],
[shouldShowAddBankAccountButton, onPressItem, translate, onPress, buttonRef, styles.paymentMethod, listItemStyle],
);

/**
Expand Down
30 changes: 27 additions & 3 deletions src/pages/settings/Wallet/VerifyAccountPage.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
import type {StackScreenProps} from '@react-navigation/stack';
import React, {useCallback, useEffect, useState} from 'react';
import {useOnyx} from 'react-native-onyx';
import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import ValidateCodeActionModal from '@components/ValidateCodeActionModal';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as ErrorUtils from '@libs/ErrorUtils';
import Navigation from '@libs/Navigation/Navigation';
import type {SettingsNavigatorParamList} from '@libs/Navigation/types';
import * as User from '@userActions/User';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type SCREENS from '@src/SCREENS';

type VerifyAccountPageProps = StackScreenProps<SettingsNavigatorParamList, typeof SCREENS.SETTINGS.PROFILE.NEW_CONTACT_METHOD>;

function VerifyAccountPage({route}: VerifyAccountPageProps) {
const styles = useThemeStyles();
const [account] = useOnyx(ONYXKEYS.ACCOUNT);
const [loginList] = useOnyx(ONYXKEYS.LOGIN_LIST);
const contactMethod = account?.primaryLogin ?? '';
const {translate} = useLocalize();
const loginData = loginList?.[contactMethod];
const validateLoginError = ErrorUtils.getEarliestErrorField(loginData, 'validateLogin');
const [isUserValidated] = useOnyx(ONYXKEYS.USER, {selector: (user) => !!user?.validated});
const [validateCodeAction] = useOnyx(ONYXKEYS.VALIDATE_ACTION_CODE);
const [isValidateCodeActionModalVisible, setIsValidateCodeActionModalVisible] = useState(true);

const navigateBackTo = route?.params?.backTo;
Expand All @@ -28,7 +35,7 @@ function VerifyAccountPage({route}: VerifyAccountPageProps) {

const handleSubmitForm = useCallback(
(validateCode: string) => {
User.validateSecondaryLogin(loginList, contactMethod, validateCode);
User.validateSecondaryLogin(loginList, contactMethod, validateCode, true);
},
[loginList, contactMethod],
);
Expand All @@ -52,18 +59,35 @@ function VerifyAccountPage({route}: VerifyAccountPageProps) {
setIsValidateCodeActionModalVisible(false);

if (navigateBackTo) {
Navigation.navigate(navigateBackTo);
Navigation.navigate(navigateBackTo, CONST.NAVIGATION.TYPE.UP);
} else {
Navigation.goBack();
}
}, [isUserValidated, navigateBackTo]);

// Once user is validated or the modal is dismissed, we don't want to show empty content.
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
if (isUserValidated || !isValidateCodeActionModalVisible) {
return (
<ScreenWrapper
includeSafeAreaPaddingBottom={false}
testID={VerifyAccountPage.displayName}
>
<HeaderWithBackButton
title={translate('contacts.validateAccount')}
onBackButtonPress={() => Navigation.goBack()}
/>
<FullScreenLoadingIndicator style={[styles.flex1, styles.pRelative]} />
</ScreenWrapper>
);
}

return (
<ValidateCodeActionModal
sendValidateCode={() => User.requestValidateCodeAction()}
handleSubmitForm={handleSubmitForm}
validateError={validateLoginError}
hasMagicCodeBeenSent={!!loginData?.validateCodeSent}
hasMagicCodeBeenSent={validateCodeAction?.validateCodeSent}
isVisible={isValidateCodeActionModalVisible}
title={translate('contacts.validateAccount')}
descriptionPrimary={translate('contacts.featureRequiresValidate')}
Expand Down
3 changes: 2 additions & 1 deletion src/pages/workspace/invoices/WorkspaceInvoiceVBASection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ function WorkspaceInvoiceVBASection({policyID}: WorkspaceInvoiceVBASectionProps)
const {windowWidth} = useWindowDimensions();
const {translate} = useLocalize();
const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`);
const [isUserValidated] = useOnyx(ONYXKEYS.USER, {selector: (user) => !!user?.validated});
const [bankAccountList] = useOnyx(ONYXKEYS.BANK_ACCOUNT_LIST);
const {paymentMethod, setPaymentMethod, resetSelectedPaymentMethodData} = usePaymentMethodState();
const addPaymentMethodAnchorRef = useRef(null);
Expand Down Expand Up @@ -164,7 +165,7 @@ function WorkspaceInvoiceVBASection({policyID}: WorkspaceInvoiceVBASectionProps)
const addPaymentMethodTypePressed = (paymentType: string) => {
hideAddPaymentMenu();
if (paymentType === CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT || paymentType === CONST.PAYMENT_METHODS.BUSINESS_BANK_ACCOUNT) {
BankAccounts.openPersonalBankAccountSetupView();
BankAccounts.openPersonalBankAccountSetupView(undefined, isUserValidated);
return;
}

Expand Down

0 comments on commit e046ebe

Please sign in to comment.