Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: requires validate when opening bank account #49230

Merged
merged 16 commits into from
Oct 2, 2024
Merged
1 change: 1 addition & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ const ROUTES = {
SETTINGS_ABOUT: 'settings/about',
SETTINGS_APP_DOWNLOAD_LINKS: 'settings/about/app-download-links',
SETTINGS_WALLET: 'settings/wallet',
SETTINGS_WALLET_VERIFY_ACCOUNT: {route: 'settings/wallet/verify', getRoute: (backTo?: string) => getUrlWithBackToParam('settings/wallet/verify', backTo)},
SETTINGS_WALLET_DOMAINCARD: {
route: 'settings/wallet/card/:cardID?',
getRoute: (cardID: string) => `settings/wallet/card/${cardID}` as const,
Expand Down
1 change: 1 addition & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ const SCREENS = {
CARD_ACTIVATE: 'Settings_Wallet_Card_Activate',
REPORT_VIRTUAL_CARD_FRAUD: 'Settings_Wallet_ReportVirtualCardFraud',
CARDS_DIGITAL_DETAILS_UPDATE_ADDRESS: 'Settings_Wallet_Cards_Digital_Details_Update_Address',
VERIFY_ACCOUNT: 'Settings_Wallet_Verify_Account',
daledah marked this conversation as resolved.
Show resolved Hide resolved
},

EXIT_SURVEY: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import {useFocusEffect} from '@react-navigation/native';
import type {ForwardedRef} from 'react';
import React, {useCallback, useEffect, useImperativeHandle, useRef, useState} from 'react';
import {View} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import type {StyleProp, ViewStyle} from 'react-native';
import {useOnyx} from 'react-native-onyx';
import Button from '@components/Button';
import DotIndicatorMessage from '@components/DotIndicatorMessage';
import MagicCodeInput from '@components/MagicCodeInput';
Expand All @@ -22,7 +22,7 @@ import * as User from '@userActions/User';
import CONST from '@src/CONST';
import type {TranslationPaths} from '@src/languages/types';
import ONYXKEYS from '@src/ONYXKEYS';
import type {Account, ValidateMagicCodeAction} from '@src/types/onyx';
import type {ValidateMagicCodeAction} from '@src/types/onyx';
import type {Errors, PendingAction} from '@src/types/onyx/OnyxCommon';
import {isEmptyObject} from '@src/types/utils/EmptyObject';

Expand All @@ -35,11 +35,6 @@ type ValidateCodeFormError = {
validateCode?: TranslationPaths;
};

type BaseValidateCodeFormOnyxProps = {
/** The details about the account that the user is signing in with */
account: OnyxEntry<Account>;
};

type ValidateCodeFormProps = {
/** If the magic code has been resent previously */
hasMagicCodeBeenSent?: boolean;
Expand All @@ -62,14 +57,14 @@ type ValidateCodeFormProps = {
/** Function is called when submitting form */
handleSubmitForm: (validateCode: string) => void;

/** Styles for the button */
buttonStyles?: StyleProp<ViewStyle>;

/** Function to clear error of the form */
clearError: () => void;
};

type BaseValidateCodeFormProps = BaseValidateCodeFormOnyxProps & ValidateCodeFormProps;

function BaseValidateCodeForm({
account = {},
hasMagicCodeBeenSent,
autoComplete = 'one-time-code',
innerRef = () => {},
Expand All @@ -78,7 +73,8 @@ function BaseValidateCodeForm({
validateError,
handleSubmitForm,
clearError,
}: BaseValidateCodeFormProps) {
buttonStyles,
}: ValidateCodeFormProps) {
const {translate} = useLocalize();
const {isOffline} = useNetwork();
const theme = useTheme();
Expand All @@ -87,6 +83,7 @@ function BaseValidateCodeForm({
const [formError, setFormError] = useState<ValidateCodeFormError>({});
const [validateCode, setValidateCode] = useState('');
const inputValidateCodeRef = useRef<MagicCodeInputHandle>(null);
const [account = {}] = useOnyx(ONYXKEYS.ACCOUNT);
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- nullish coalescing doesn't achieve the same result in this case
const shouldDisableResendValidateCode = !!isOffline || account?.isLoading;
const focusTimeoutRef = useRef<NodeJS.Timeout | null>(null);
Expand Down Expand Up @@ -204,7 +201,7 @@ function BaseValidateCodeForm({
errorRowStyles={[styles.mt2]}
onClose={() => User.clearValidateCodeActionError('actionVerified')}
>
<View style={[styles.mt2, styles.dFlex, styles.flexColumn, styles.alignItemsStart]}>
<View style={[styles.mt5, styles.dFlex, styles.flexColumn, styles.alignItemsStart]}>
<PressableWithFeedback
disabled={shouldDisableResendValidateCode}
style={[styles.mr1]}
Expand Down Expand Up @@ -232,6 +229,7 @@ function BaseValidateCodeForm({
errors={validateError}
errorRowStyles={[styles.mt2]}
onClose={() => clearError()}
style={buttonStyles}
>
<Button
isDisabled={isOffline}
Expand All @@ -252,6 +250,4 @@ BaseValidateCodeForm.displayName = 'BaseValidateCodeForm';

export type {ValidateCodeFormProps, ValidateCodeFormHandle};

export default withOnyx<BaseValidateCodeFormProps, BaseValidateCodeFormOnyxProps>({
account: {key: ONYXKEYS.ACCOUNT},
})(BaseValidateCodeForm);
export default BaseValidateCodeForm;
2 changes: 2 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1085,6 +1085,8 @@ const translations = {
contacts: {
contactMethod: 'Contact method',
contactMethods: 'Contact methods',
featureRequiresValidate: 'This feature requires you to validate your account.',
validateAccount: 'Validate your account',
helpTextBeforeEmail: 'Add more ways for people to find you, and forward receipts to ',
helpTextAfterEmail: ' from multiple email addresses.',
pleaseVerify: 'Please verify this contact method',
Expand Down
2 changes: 2 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1079,6 +1079,8 @@ const translations = {
contacts: {
contactMethod: 'Método de contacto',
contactMethods: 'Métodos de contacto',
featureRequiresValidate: 'Esta función requiere que valides tu cuenta.',
validateAccount: 'Valida tu cuenta',
helpTextBeforeEmail: 'Añade más formas de que la gente te encuentre y reenvía los recibos a ',
helpTextAfterEmail: ' desde varias direcciones de correo electrónico.',
pleaseVerify: 'Por favor, verifica este método de contacto',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorP
[SCREENS.SETTINGS.WALLET.TRANSFER_BALANCE]: () => require<ReactComponentModule>('../../../../pages/settings/Wallet/TransferBalancePage').default,
[SCREENS.SETTINGS.WALLET.CHOOSE_TRANSFER_ACCOUNT]: () => require<ReactComponentModule>('../../../../pages/settings/Wallet/ChooseTransferAccountPage').default,
[SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS]: () => require<ReactComponentModule>('../../../../pages/EnablePayments/EnablePayments').default,
[SCREENS.SETTINGS.WALLET.VERIFY_ACCOUNT]: () => require<ReactComponentModule>('../../../../pages/settings/Wallet/VerifyAccountPage').default,
[SCREENS.SETTINGS.ADD_DEBIT_CARD]: () => require<ReactComponentModule>('../../../../pages/settings/Wallet/AddDebitCardPage').default,
[SCREENS.SETTINGS.ADD_BANK_ACCOUNT]: () => require<ReactComponentModule>('../../../../pages/AddPersonalBankAccountPage').default,
[SCREENS.SETTINGS.PROFILE.STATUS]: () => require<ReactComponentModule>('../../../../pages/settings/Profile/CustomStatus/StatusPage').default,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ const CENTRAL_PANE_TO_RHP_MAPPING: Partial<Record<CentralPaneName, string[]>> =
SCREENS.SETTINGS.WALLET.CARD_ACTIVATE,
SCREENS.SETTINGS.WALLET.REPORT_VIRTUAL_CARD_FRAUD,
SCREENS.SETTINGS.WALLET.CARDS_DIGITAL_DETAILS_UPDATE_ADDRESS,
SCREENS.SETTINGS.WALLET.VERIFY_ACCOUNT,
SCREENS.SETTINGS.ADD_BANK_ACCOUNT,
],
[SCREENS.SETTINGS.SECURITY]: [
SCREENS.SETTINGS.TWO_FACTOR_AUTH,
Expand Down
4 changes: 4 additions & 0 deletions src/libs/Navigation/linkingConfig/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ const config: LinkingOptions<RootStackParamList>['config'] = {
path: ROUTES.SETTINGS_CLOSE,
exact: true,
},
[SCREENS.SETTINGS.WALLET.VERIFY_ACCOUNT]: {
path: ROUTES.SETTINGS_WALLET_VERIFY_ACCOUNT.route,
exact: true,
},
[SCREENS.SETTINGS.WALLET.DOMAIN_CARD]: {
path: ROUTES.SETTINGS_WALLET_DOMAINCARD.route,
exact: true,
Expand Down
3 changes: 3 additions & 0 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@ type SettingsNavigatorParamList = {
[SCREENS.SETTINGS.WALLET.TRANSFER_BALANCE]: undefined;
[SCREENS.SETTINGS.WALLET.CHOOSE_TRANSFER_ACCOUNT]: undefined;
[SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS]: undefined;
[SCREENS.SETTINGS.WALLET.VERIFY_ACCOUNT]: {
backTo?: Routes;
};
[SCREENS.SETTINGS.ADD_DEBIT_CARD]: undefined;
[SCREENS.SETTINGS.ADD_BANK_ACCOUNT]: undefined;
[SCREENS.SETTINGS.PROFILE.STATUS]: undefined;
Expand Down
29 changes: 7 additions & 22 deletions src/pages/AddPersonalBankAccountPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, {useCallback, useEffect, useState} from 'react';
import {useOnyx, withOnyx} from 'react-native-onyx';
import type {OnyxEntry} from 'react-native-onyx';
import {useOnyx} from 'react-native-onyx';
import AddPlaidBankAccount from '@components/AddPlaidBankAccount';
import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
import ConfirmationPage from '@components/ConfirmationPage';
Expand All @@ -15,22 +14,16 @@ import Navigation from '@libs/Navigation/Navigation';
import * as BankAccounts from '@userActions/BankAccounts';
import * as PaymentMethods from '@userActions/PaymentMethods';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import INPUT_IDS from '@src/types/form/ReimbursementAccountForm';
import type {PersonalBankAccount, PlaidData} from '@src/types/onyx';

type AddPersonalBankAccountPageWithOnyxProps = {
/** Contains plaid data */
plaidData: OnyxEntry<PlaidData>;

/** The details about the Personal bank account we are adding saved in Onyx */
personalBankAccount: OnyxEntry<PersonalBankAccount>;
};

function AddPersonalBankAccountPage({personalBankAccount, plaidData}: AddPersonalBankAccountPageWithOnyxProps) {
function AddPersonalBankAccountPage() {
const styles = useThemeStyles();
const {translate} = useLocalize();
const [selectedPlaidAccountId, setSelectedPlaidAccountId] = useState('');
const [isUserValidated] = useOnyx(ONYXKEYS.USER, {selector: (user) => !!user?.validated});
const [personalBankAccount] = useOnyx(ONYXKEYS.PERSONAL_BANK_ACCOUNT);
const [plaidData] = useOnyx(ONYXKEYS.PLAID_DATA);
const shouldShowSuccess = personalBankAccount?.shouldShowSuccess ?? false;

const submitBankAccountForm = useCallback(() => {
Expand Down Expand Up @@ -97,7 +90,7 @@ function AddPersonalBankAccountPage({personalBankAccount, plaidData}: AddPersona
text={translate('walletPage.chooseAccountBody')}
plaidData={plaidData}
isDisplayedInWalletFlow
onExitPlaid={() => Navigation.goBack()}
onExitPlaid={() => Navigation.navigate(ROUTES.SETTINGS_WALLET)}
receivedRedirectURI={getPlaidOAuthReceivedRedirectURI()}
selectedPlaidAccountID={selectedPlaidAccountId}
/>
Expand All @@ -109,12 +102,4 @@ function AddPersonalBankAccountPage({personalBankAccount, plaidData}: AddPersona
}
AddPersonalBankAccountPage.displayName = 'AddPersonalBankAccountPage';

export default withOnyx<AddPersonalBankAccountPageWithOnyxProps, AddPersonalBankAccountPageWithOnyxProps>({
// @ts-expect-error: ONYXKEYS.PERSONAL_BANK_ACCOUNT is conflicting with ONYXKEYS.FORMS.PERSONAL_BANK_ACCOUNT_FORM
personalBankAccount: {
key: ONYXKEYS.PERSONAL_BANK_ACCOUNT,
},
plaidData: {
key: ONYXKEYS.PLAID_DATA,
},
})(AddPersonalBankAccountPage);
export default AddPersonalBankAccountPage;
32 changes: 8 additions & 24 deletions src/pages/EnablePayments/AddBankAccount/SetupMethod.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react';
import {View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import type {OnyxEntry} from 'react-native-onyx';
import {useOnyx} from 'react-native-onyx';
import Button from '@components/Button';
import * as Expensicons from '@components/Icon/Expensicons';
import * as Illustrations from '@components/Icon/Illustrations';
Expand All @@ -15,23 +14,13 @@ import * as BankAccounts from '@userActions/BankAccounts';
import * as Link from '@userActions/Link';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type {User} from '@src/types/onyx';

type SetupMethodOnyxProps = {
/** The user's data */
user: OnyxEntry<User>;

/** Whether Plaid is disabled */
isPlaidDisabled: OnyxEntry<boolean>;
};

type SetupMethodProps = SetupMethodOnyxProps;

const plaidDesktopMessage = getPlaidDesktopMessage();

function SetupMethod({isPlaidDisabled, user}: SetupMethodProps) {
function SetupMethod() {
const styles = useThemeStyles();
const {translate} = useLocalize();
const [isPlaidDisabled] = useOnyx(ONYXKEYS.IS_PLAID_DISABLED);

return (
<View>
Expand All @@ -51,8 +40,10 @@ function SetupMethod({isPlaidDisabled, user}: SetupMethodProps) {
<Button
icon={Expensicons.Bank}
text={translate('bankAccount.addBankAccount')}
onPress={() => BankAccounts.openPersonalBankAccountSetupWithPlaid()}
isDisabled={!!isPlaidDisabled || !user?.validated}
onPress={() => {
BankAccounts.openPersonalBankAccountSetupWithPlaid();
}}
isDisabled={!!isPlaidDisabled}
style={[styles.mt4, styles.mb2]}
iconStyles={styles.buttonCTAIcon}
shouldShowRightIcon
Expand All @@ -66,11 +57,4 @@ function SetupMethod({isPlaidDisabled, user}: SetupMethodProps) {

SetupMethod.displayName = 'SetupMethod';

export default withOnyx<SetupMethodProps, SetupMethodOnyxProps>({
isPlaidDisabled: {
key: ONYXKEYS.IS_PLAID_DISABLED,
},
user: {
key: ONYXKEYS.USER,
},
})(SetupMethod);
export default SetupMethod;
14 changes: 11 additions & 3 deletions src/pages/settings/Wallet/PaymentMethodList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ function PaymentMethodList({
const StyleUtils = useStyleUtils();
const {translate} = useLocalize();
const {isOffline} = useNetwork();

const [isUserValidated] = useOnyx(ONYXKEYS.USER, {selector: (user) => !!user?.validated});
const [bankAccountList = {}] = useOnyx(ONYXKEYS.BANK_ACCOUNT_LIST);
const [cardList = {}] = useOnyx(ONYXKEYS.CARD_LIST);
Expand Down Expand Up @@ -316,6 +317,14 @@ function PaymentMethodList({
*/
const renderListEmptyComponent = () => <Text style={styles.popoverMenuItem}>{translate('paymentMethodList.addFirstPaymentMethod')}</Text>;

const onPressItem = useCallback(() => {
if (!isUserValidated) {
Navigation.navigate(ROUTES.SETTINGS_WALLET_VERIFY_ACCOUNT.getRoute(ROUTES.SETTINGS_ADD_BANK_ACCOUNT));
return;
}
onPress();
}, [isUserValidated, onPress]);

const renderListFooterComponent = useCallback(
() =>
shouldShowAddBankAccountButton ? (
Expand All @@ -330,16 +339,15 @@ function PaymentMethodList({
/>
) : (
<MenuItem
onPress={onPress}
onPress={onPressItem}
title={translate('walletPage.addBankAccount')}
icon={Expensicons.Plus}
wrapperStyle={[styles.paymentMethod, listItemStyle]}
ref={buttonRef}
disabled={!isUserValidated}
/>
),

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

/**
Expand Down
Loading
Loading