From 1e0e916ffc25a7573657d1680f3c859fe6ddb326 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Wed, 17 Apr 2024 21:49:04 +0200 Subject: [PATCH 01/26] feat: verify identity step setup --- .../VerifyIdentity/VerifyIdentity.tsx | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 src/pages/EnablePayments/VerifyIdentity/VerifyIdentity.tsx diff --git a/src/pages/EnablePayments/VerifyIdentity/VerifyIdentity.tsx b/src/pages/EnablePayments/VerifyIdentity/VerifyIdentity.tsx new file mode 100644 index 000000000000..f402f52255ab --- /dev/null +++ b/src/pages/EnablePayments/VerifyIdentity/VerifyIdentity.tsx @@ -0,0 +1,120 @@ +import React, {useCallback} from 'react'; +import {View} from 'react-native'; +import type {OnyxEntry} from 'react-native-onyx'; +import {withOnyx} from 'react-native-onyx'; +import FullPageOfflineBlockingView from '@components/BlockingViews/FullPageOfflineBlockingView'; +import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import InteractiveStepSubHeader from '@components/InteractiveStepSubHeader'; +import Onfido from '@components/Onfido'; +import type {OnfidoData} from '@components/Onfido/types'; +import ScreenWrapper from '@components/ScreenWrapper'; +import ScrollView from '@components/ScrollView'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import Growl from '@libs/Growl'; +import * as BankAccounts from '@userActions/BankAccounts'; +import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import type {PersonalBankAccount, WalletOnfido} from '@src/types/onyx'; + +const DEFAULT_WALLET_ONFIDO_DATA = { + loading: false, + hasAcceptedPrivacyPolicy: false, +}; + +type VerifyIdentityOnyxProps = { + /** Reimbursement account from ONYX */ + personalBankAccount: OnyxEntry; + + /** Onfido applicant ID from ONYX */ + onfidoApplicantID: OnyxEntry; + + /** The token required to initialize the Onfido SDK */ + onfidoToken: OnyxEntry; + + /** The wallet onfido data */ + walletOnfidoData: OnyxEntry; +}; + +type VerifyIdentityProps = VerifyIdentityOnyxProps & { + /** Goes to the previous step */ + onBackButtonPress: () => void; +}; + +const ONFIDO_ERROR_DISPLAY_DURATION = 10000; + +function VerifyIdentity({personalBankAccount, onBackButtonPress, onfidoApplicantID, onfidoToken, walletOnfidoData = DEFAULT_WALLET_ONFIDO_DATA}: VerifyIdentityProps) { + const styles = useThemeStyles(); + const {translate} = useLocalize(); + + const handleOnfidoSuccess = useCallback( + (onfidoData: OnfidoData) => { + BankAccounts.verifyIdentity({ + onfidoData: JSON.stringify({ + ...onfidoData, + applicantID: walletOnfidoData?.applicantID, + }), + }); + BankAccounts.updateAddPersonalBankAccountDraft({isOnfidoSetupComplete: true}); + }, + [personalBankAccount, onfidoApplicantID], + ); + + const handleOnfidoError = () => { + // In case of any unexpected error we log it to the server, show a growl, and return the user back to the requestor step so they can try again. + Growl.error(translate('onfidoStep.genericError'), ONFIDO_ERROR_DISPLAY_DURATION); + BankAccounts.clearOnfidoToken(); + // BankAccounts.goToWithdrawalAccountSetupStep(CONST.BANK_ACCOUNT.STEP.REQUESTOR); + }; + + const handleOnfidoUserExit = () => { + BankAccounts.clearOnfidoToken(); + // BankAccounts.goToWithdrawalAccountSetupStep(CONST.BANK_ACCOUNT.STEP.REQUESTOR); + }; + + return ( + + + + + + + + + + + + ); +} + +VerifyIdentity.displayName = 'VerifyIdentity'; + +export default withOnyx({ + // @ts-expect-error: ONYXKEYS.PERSONAL_BANK_ACCOUNT is conflicting with ONYXKEYS.FORMS.PERSONAL_BANK_ACCOUNT_FORM + personalBankAccount: { + key: ONYXKEYS.PERSONAL_BANK_ACCOUNT, + }, + onfidoApplicantID: { + key: ONYXKEYS.ONFIDO_APPLICANT_ID, + }, + onfidoToken: { + key: ONYXKEYS.ONFIDO_TOKEN, + }, + walletOnfidoData: { + key: ONYXKEYS.WALLET_ONFIDO, + + // Let's get a new onfido token each time the user hits this flow (as it should only be once) + initWithStoredValues: false, + }, +})(VerifyIdentity); From ca6201f94fdf16b0977ea208b746ee0da495dde0 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Tue, 7 May 2024 15:13:55 +0200 Subject: [PATCH 02/26] refactor: wip - connect all the steps --- .../ModalStackNavigators/index.tsx | 4 +- .../AddBankAccount/AddBankAccount.tsx | 2 +- src/pages/EnablePayments/EnablePayments.tsx | 102 ++++++++++++++++++ .../PersonalInfo/PersonalInfo.tsx | 30 +++--- .../VerifyIdentity/VerifyIdentity.tsx | 16 +-- 5 files changed, 126 insertions(+), 28 deletions(-) create mode 100644 src/pages/EnablePayments/EnablePayments.tsx diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index ce8ea271182d..b9c1e94f0497 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -216,9 +216,7 @@ const SettingsModalStackNavigator = createModalStackNavigator require('../../../../pages/settings/Wallet/ChooseTransferAccountPage').default as React.ComponentType, [SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS]: () => require('../../../../pages/EnablePayments/EnablePaymentsPage').default as React.ComponentType, // TODO: Added temporarily for testing purposes, remove after refactor - https://github.com/Expensify/App/issues/36648 - [SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS_REFACTOR]: () => require('../../../../pages/EnablePayments/PersonalInfo/PersonalInfo').default as React.ComponentType, - // TODO: Added temporarily for testing purposes, remove after refactor - https://github.com/Expensify/App/issues/36648 - [SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS_TEMPORARY_TERMS]: () => require('../../../../pages/EnablePayments/FeesAndTerms/FeesAndTerms').default as React.ComponentType, + [SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS_REFACTOR]: () => require('../../../../pages/EnablePayments/EnablePayments').default as React.ComponentType, [SCREENS.SETTINGS.ADD_DEBIT_CARD]: () => require('../../../../pages/settings/Wallet/AddDebitCardPage').default as React.ComponentType, [SCREENS.SETTINGS.ADD_BANK_ACCOUNT]: () => require('../../../../pages/AddPersonalBankAccountPage').default as React.ComponentType, [SCREENS.SETTINGS.ADD_BANK_ACCOUNT_REFACTOR]: () => require('../../../../pages/EnablePayments/AddBankAccount/AddBankAccount').default as React.ComponentType, diff --git a/src/pages/EnablePayments/AddBankAccount/AddBankAccount.tsx b/src/pages/EnablePayments/AddBankAccount/AddBankAccount.tsx index 79c91af178c3..9fde5456226b 100644 --- a/src/pages/EnablePayments/AddBankAccount/AddBankAccount.tsx +++ b/src/pages/EnablePayments/AddBankAccount/AddBankAccount.tsx @@ -44,7 +44,7 @@ function AddBankAccount({personalBankAccount, plaidData, personalBankAccountDraf if (selectedPlaidBankAccount) { BankAccounts.addPersonalBankAccount(selectedPlaidBankAccount); - Navigation.navigate(ROUTES.SETTINGS_ENABLE_PAYMENTS); + Navigation.navigate(ROUTES.SETTINGS_ENABLE_PAYMENTS_REFACTOR); } }, [personalBankAccountDraft?.plaidAccountID, plaidData?.bankAccounts]); diff --git a/src/pages/EnablePayments/EnablePayments.tsx b/src/pages/EnablePayments/EnablePayments.tsx new file mode 100644 index 000000000000..6df56afced57 --- /dev/null +++ b/src/pages/EnablePayments/EnablePayments.tsx @@ -0,0 +1,102 @@ +import React, {useEffect} from 'react'; +import {withOnyx} from 'react-native-onyx'; +import type {OnyxEntry} from 'react-native-onyx'; +import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; +import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import ScreenWrapper from '@components/ScreenWrapper'; +import useLocalize from '@hooks/useLocalize'; +import useNetwork from '@hooks/useNetwork'; +import Navigation from '@libs/Navigation/Navigation'; +import FeesAndTerms from '@pages/EnablePayments/FeesAndTerms/FeesAndTerms'; +import PersonalInfo from '@pages/EnablePayments/PersonalInfo/PersonalInfo'; +import VerifyIdentity from '@pages/EnablePayments/VerifyIdentity/VerifyIdentity'; +import * as Wallet from '@userActions/Wallet'; +import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; +import type {UserWallet} from '@src/types/onyx'; +import {isEmptyObject} from '@src/types/utils/EmptyObject'; +import ActivateStep from './ActivateStep'; +import FailedKYC from './FailedKYC'; + +type EnablePaymentsPageOnyxProps = { + /** The user's wallet */ + userWallet: OnyxEntry; +}; + +type EnablePaymentsPageProps = EnablePaymentsPageOnyxProps; + +function EnablePaymentsPage({userWallet}: EnablePaymentsPageProps) { + const {translate} = useLocalize(); + const {isOffline} = useNetwork(); + + const {isPendingOnfidoResult, hasFailedOnfido} = userWallet ?? {}; + + useEffect(() => { + if (isOffline) { + return; + } + + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + if (isPendingOnfidoResult || hasFailedOnfido) { + Navigation.navigate(ROUTES.SETTINGS_WALLET, CONST.NAVIGATION.TYPE.UP); + return; + } + + Wallet.openEnablePaymentsPage(); + }, [isOffline, isPendingOnfidoResult, hasFailedOnfido]); + + if (isEmptyObject(userWallet)) { + return ; + } + + return ( + + {() => { + if (userWallet?.errorCode === CONST.WALLET.ERROR.KYC) { + return ( + <> + Navigation.goBack(ROUTES.SETTINGS_WALLET)} + /> + + + ); + } + + const currentStep = userWallet?.currentStep || CONST.WALLET.STEP.ADDITIONAL_DETAILS; + + switch (currentStep) { + case CONST.WALLET.STEP.ADDITIONAL_DETAILS: + case CONST.WALLET.STEP.ADDITIONAL_DETAILS_KBA: + return ; + case CONST.WALLET.STEP.ONFIDO: + return ; + case CONST.WALLET.STEP.TERMS: + return ; + case CONST.WALLET.STEP.ACTIVATE: + return ; + default: + return null; + } + }} + + ); +} + +EnablePaymentsPage.displayName = 'EnablePaymentsPage'; + +export default withOnyx({ + userWallet: { + key: ONYXKEYS.USER_WALLET, + + // We want to refresh the wallet each time the user attempts to activate the wallet so we won't use the + // stored values here. + initWithStoredValues: false, + }, +})(EnablePaymentsPage); diff --git a/src/pages/EnablePayments/PersonalInfo/PersonalInfo.tsx b/src/pages/EnablePayments/PersonalInfo/PersonalInfo.tsx index c23b8bcb12fa..22e9a3731581 100644 --- a/src/pages/EnablePayments/PersonalInfo/PersonalInfo.tsx +++ b/src/pages/EnablePayments/PersonalInfo/PersonalInfo.tsx @@ -9,8 +9,7 @@ import useLocalize from '@hooks/useLocalize'; import useSubStep from '@hooks/useSubStep'; import type {SubStepProps} from '@hooks/useSubStep/types'; import useThemeStyles from '@hooks/useThemeStyles'; -// TODO: uncomment after connecting steps https://github.com/Expensify/App/issues/36648 -// import {parsePhoneNumber} from '@libs/PhoneNumber'; +import {parsePhoneNumber} from '@libs/PhoneNumber'; import Navigation from '@navigation/Navigation'; import getInitialSubstepForPersonalInfo from '@pages/EnablePayments/utils/getInitialSubstepForPersonalInfo'; import getSubstepValues from '@pages/EnablePayments/utils/getSubstepValues'; @@ -47,22 +46,19 @@ function PersonalInfoPage({walletAdditionalDetails, walletAdditionalDetailsDraft const values = useMemo(() => getSubstepValues(PERSONAL_INFO_STEP_KEYS, walletAdditionalDetailsDraft, walletAdditionalDetails), [walletAdditionalDetails, walletAdditionalDetailsDraft]); const submit = () => { - // TODO: uncomment after connecting steps https://github.com/Expensify/App/issues/36648 - // const personalDetails = { - // phoneNumber: (values.phoneNumber && parsePhoneNumber(values.phoneNumber, {regionCode: CONST.COUNTRY.US}).number?.significant) ?? '', - // legalFirstName: values?.[PERSONAL_INFO_STEP_KEYS.FIRST_NAME] ?? '', - // legalLastName: values?.[PERSONAL_INFO_STEP_KEYS.LAST_NAME] ?? '', - // addressStreet: values?.[PERSONAL_INFO_STEP_KEYS.STREET] ?? '', - // addressCity: values?.[PERSONAL_INFO_STEP_KEYS.CITY] ?? '', - // addressState: values?.[PERSONAL_INFO_STEP_KEYS.STATE] ?? '', - // addressZip: values?.[PERSONAL_INFO_STEP_KEYS.ZIP_CODE] ?? '', - // dob: values?.[PERSONAL_INFO_STEP_KEYS.DOB] ?? '', - // ssn: values?.[PERSONAL_INFO_STEP_KEYS.SSN_LAST_4] ?? '', - // }; + const personalDetails = { + phoneNumber: (values.phoneNumber && parsePhoneNumber(values.phoneNumber, {regionCode: CONST.COUNTRY.US}).number?.significant) ?? '', + legalFirstName: values?.[PERSONAL_INFO_STEP_KEYS.FIRST_NAME] ?? '', + legalLastName: values?.[PERSONAL_INFO_STEP_KEYS.LAST_NAME] ?? '', + addressStreet: values?.[PERSONAL_INFO_STEP_KEYS.STREET] ?? '', + addressCity: values?.[PERSONAL_INFO_STEP_KEYS.CITY] ?? '', + addressState: values?.[PERSONAL_INFO_STEP_KEYS.STATE] ?? '', + addressZip: values?.[PERSONAL_INFO_STEP_KEYS.ZIP_CODE] ?? '', + dob: values?.[PERSONAL_INFO_STEP_KEYS.DOB] ?? '', + ssn: values?.[PERSONAL_INFO_STEP_KEYS.SSN_LAST_4] ?? '', + }; // Attempt to set the personal details - // Wallet.updatePersonalDetails(personalDetails); - Navigation.goBack(ROUTES.SETTINGS_WALLET); - Wallet.resetWalletAdditionalDetailsDraft(); + Wallet.updatePersonalDetails(personalDetails); }; const startFrom = useMemo(() => getInitialSubstepForPersonalInfo(values), [values]); diff --git a/src/pages/EnablePayments/VerifyIdentity/VerifyIdentity.tsx b/src/pages/EnablePayments/VerifyIdentity/VerifyIdentity.tsx index f402f52255ab..40aab5ba8b35 100644 --- a/src/pages/EnablePayments/VerifyIdentity/VerifyIdentity.tsx +++ b/src/pages/EnablePayments/VerifyIdentity/VerifyIdentity.tsx @@ -13,6 +13,7 @@ import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import Growl from '@libs/Growl'; import * as BankAccounts from '@userActions/BankAccounts'; +import * as Wallet from '@userActions/Wallet'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {PersonalBankAccount, WalletOnfido} from '@src/types/onyx'; @@ -36,14 +37,11 @@ type VerifyIdentityOnyxProps = { walletOnfidoData: OnyxEntry; }; -type VerifyIdentityProps = VerifyIdentityOnyxProps & { - /** Goes to the previous step */ - onBackButtonPress: () => void; -}; +type VerifyIdentityProps = VerifyIdentityOnyxProps; const ONFIDO_ERROR_DISPLAY_DURATION = 10000; -function VerifyIdentity({personalBankAccount, onBackButtonPress, onfidoApplicantID, onfidoToken, walletOnfidoData = DEFAULT_WALLET_ONFIDO_DATA}: VerifyIdentityProps) { +function VerifyIdentity({personalBankAccount, onfidoApplicantID, onfidoToken, walletOnfidoData = DEFAULT_WALLET_ONFIDO_DATA}: VerifyIdentityProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); @@ -72,16 +70,20 @@ function VerifyIdentity({personalBankAccount, onBackButtonPress, onfidoApplicant // BankAccounts.goToWithdrawalAccountSetupStep(CONST.BANK_ACCOUNT.STEP.REQUESTOR); }; + const handleBackButtonPress = () => { + Wallet.updateCurrentStep(CONST.WALLET.STEP.ADDITIONAL_DETAILS); + }; + return ( From 5c427c1d9fc66c8bce90ad22e9492d24ee2dfe21 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Wed, 15 May 2024 14:40:43 +0200 Subject: [PATCH 03/26] feat: add verify identity intro page --- src/languages/en.ts | 2 + src/languages/es.ts | 2 + .../VerifyIdentity/VerifyIdentity.tsx | 50 ++++++++++++++++--- 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index c174c2182ef2..b079a7ecc624 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1571,6 +1571,8 @@ export default { facialScan: 'Onfido’s Facial Scan Policy and Release', tryAgain: 'Try again', verifyIdentity: 'Verify identity', + letsVerifyIdentity: "Let's verify your identity.", + butFirst: `But first, the boring stuff. Read up on the legalese in the next step and click "Accept" when you're ready.`, genericError: 'There was an error while processing this step. Please try again.', cameraPermissionsNotGranted: 'Enable camera access', cameraRequestMessage: 'We need access to your camera to complete bank account verification. Please enable via Settings > New Expensify.', diff --git a/src/languages/es.ts b/src/languages/es.ts index e9e1ed6eb815..eca0e3ac16ad 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -1590,6 +1590,8 @@ export default { facialScan: 'Política y lanzamiento de la exploración facial de Onfido', tryAgain: 'Intentar otra vez', verifyIdentity: 'Verificar identidad', + letsVerifyIdentity: '¡Vamos a verificar tu identidad!', + butFirst: 'Pero primero, lo aburrido. Lee la jerga legal en el siguiente paso y haz clic en "Aceptar" cuando estés listo.', genericError: 'Hubo un error al procesar este paso. Inténtalo de nuevo.', cameraPermissionsNotGranted: 'Permiso para acceder a la cámara', cameraRequestMessage: 'Necesitamos acceso a tu cámara para completar la verificación de tu cuenta de banco. Por favor habilita los permisos en Configuración > Nuevo Expensify.', diff --git a/src/pages/EnablePayments/VerifyIdentity/VerifyIdentity.tsx b/src/pages/EnablePayments/VerifyIdentity/VerifyIdentity.tsx index 40aab5ba8b35..0bcb0beb675f 100644 --- a/src/pages/EnablePayments/VerifyIdentity/VerifyIdentity.tsx +++ b/src/pages/EnablePayments/VerifyIdentity/VerifyIdentity.tsx @@ -3,14 +3,20 @@ import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import FullPageOfflineBlockingView from '@components/BlockingViews/FullPageOfflineBlockingView'; +import FixedFooter from '@components/FixedFooter'; +import FormAlertWithSubmitButton from '@components/FormAlertWithSubmitButton'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import Icon from '@components/Icon'; +import * as Illustrations from '@components/Icon/Illustrations'; import InteractiveStepSubHeader from '@components/InteractiveStepSubHeader'; import Onfido from '@components/Onfido'; import type {OnfidoData} from '@components/Onfido/types'; import ScreenWrapper from '@components/ScreenWrapper'; import ScrollView from '@components/ScrollView'; +import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; +import * as ErrorUtils from '@libs/ErrorUtils'; import Growl from '@libs/Growl'; import * as BankAccounts from '@userActions/BankAccounts'; import * as Wallet from '@userActions/Wallet'; @@ -45,6 +51,8 @@ function VerifyIdentity({personalBankAccount, onfidoApplicantID, onfidoToken, wa const styles = useThemeStyles(); const {translate} = useLocalize(); + console.log({personalBankAccount, onfidoApplicantID, onfidoToken, walletOnfidoData}); + const handleOnfidoSuccess = useCallback( (onfidoData: OnfidoData) => { BankAccounts.verifyIdentity({ @@ -58,6 +66,8 @@ function VerifyIdentity({personalBankAccount, onfidoApplicantID, onfidoToken, wa [personalBankAccount, onfidoApplicantID], ); + const onfidoError = ErrorUtils.getLatestErrorMessage(walletOnfidoData) ?? ''; + const handleOnfidoError = () => { // In case of any unexpected error we log it to the server, show a growl, and return the user back to the requestor step so they can try again. Growl.error(translate('onfidoStep.genericError'), ONFIDO_ERROR_DISPLAY_DURATION); @@ -74,6 +84,8 @@ function VerifyIdentity({personalBankAccount, onfidoApplicantID, onfidoToken, wa Wallet.updateCurrentStep(CONST.WALLET.STEP.ADDITIONAL_DETAILS); }; + const {isLoading = false, hasAcceptedPrivacyPolicy} = walletOnfidoData; + return ( - + {hasAcceptedPrivacyPolicy ? ( + + ) : ( + <> + + + {translate('onfidoStep.letsVerifyIdentity')} + {translate('onfidoStep.butFirst')} + + + {}} + onFixTheErrorsLinkPressed={() => {}} + message={onfidoError} + isLoading={isLoading} + buttonText={onfidoError ? translate('onfidoStep.tryAgain') : translate('common.continue')} + containerStyles={[styles.mh0, styles.mv0, styles.mb0]} + /> + + + )} From 2ec341172ba1daa9bd17d29659b9bfbbf62270f4 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Thu, 16 May 2024 20:43:38 +0200 Subject: [PATCH 04/26] fix: get token and applicantID from walletOnfidoData --- .../VerifyIdentity/VerifyIdentity.tsx | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/pages/EnablePayments/VerifyIdentity/VerifyIdentity.tsx b/src/pages/EnablePayments/VerifyIdentity/VerifyIdentity.tsx index 0bcb0beb675f..c2023077af50 100644 --- a/src/pages/EnablePayments/VerifyIdentity/VerifyIdentity.tsx +++ b/src/pages/EnablePayments/VerifyIdentity/VerifyIdentity.tsx @@ -47,11 +47,15 @@ type VerifyIdentityProps = VerifyIdentityOnyxProps; const ONFIDO_ERROR_DISPLAY_DURATION = 10000; -function VerifyIdentity({personalBankAccount, onfidoApplicantID, onfidoToken, walletOnfidoData = DEFAULT_WALLET_ONFIDO_DATA}: VerifyIdentityProps) { +function VerifyIdentity({personalBankAccount, walletOnfidoData = DEFAULT_WALLET_ONFIDO_DATA}: VerifyIdentityProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); - console.log({personalBankAccount, onfidoApplicantID, onfidoToken, walletOnfidoData}); + const openOnfidoFlow = () => { + BankAccounts.openOnfidoFlow(); + }; + + const {isLoading = false, hasAcceptedPrivacyPolicy, sdkToken, applicantID} = walletOnfidoData; const handleOnfidoSuccess = useCallback( (onfidoData: OnfidoData) => { @@ -63,7 +67,7 @@ function VerifyIdentity({personalBankAccount, onfidoApplicantID, onfidoToken, wa }); BankAccounts.updateAddPersonalBankAccountDraft({isOnfidoSetupComplete: true}); }, - [personalBankAccount, onfidoApplicantID], + [personalBankAccount, applicantID], ); const onfidoError = ErrorUtils.getLatestErrorMessage(walletOnfidoData) ?? ''; @@ -84,8 +88,6 @@ function VerifyIdentity({personalBankAccount, onfidoApplicantID, onfidoToken, wa Wallet.updateCurrentStep(CONST.WALLET.STEP.ADDITIONAL_DETAILS); }; - const {isLoading = false, hasAcceptedPrivacyPolicy} = walletOnfidoData; - return ( {hasAcceptedPrivacyPolicy ? ( {}} + onSubmit={openOnfidoFlow} onFixTheErrorsLinkPressed={() => {}} message={onfidoError} isLoading={isLoading} @@ -145,12 +147,6 @@ export default withOnyx({ personalBankAccount: { key: ONYXKEYS.PERSONAL_BANK_ACCOUNT, }, - onfidoApplicantID: { - key: ONYXKEYS.ONFIDO_APPLICANT_ID, - }, - onfidoToken: { - key: ONYXKEYS.ONFIDO_TOKEN, - }, walletOnfidoData: { key: ONYXKEYS.WALLET_ONFIDO, From 4706357c1d51789d9f747f5f0b90ac472e04952b Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Mon, 20 May 2024 18:09:32 +0200 Subject: [PATCH 05/26] feat: change wallet agreement url for bancorp --- src/CONST.ts | 1 + .../FeesAndTerms/substeps/TermsStep.tsx | 16 ++++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index 6517ece4276d..af5f32808034 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -574,6 +574,7 @@ const CONST = { LICENSES_URL: `${USE_EXPENSIFY_URL}/licenses`, ACH_TERMS_URL: `${USE_EXPENSIFY_URL}/achterms`, WALLET_AGREEMENT_URL: `${USE_EXPENSIFY_URL}/walletagreement`, + BANCORP_WALLET_AGREEMENT_URL: `${USE_EXPENSIFY_URL}/bancorp-bank-wallet-terms-of-service`, HELP_LINK_URL: `${USE_EXPENSIFY_URL}/usa-patriot-act`, ELECTRONIC_DISCLOSURES_URL: `${USE_EXPENSIFY_URL}/esignagreement`, GITHUB_RELEASE_URL: 'https://api.github.com/repos/expensify/app/releases/latest', diff --git a/src/pages/EnablePayments/FeesAndTerms/substeps/TermsStep.tsx b/src/pages/EnablePayments/FeesAndTerms/substeps/TermsStep.tsx index fe17ea7e1afb..270f0c1f1699 100644 --- a/src/pages/EnablePayments/FeesAndTerms/substeps/TermsStep.tsx +++ b/src/pages/EnablePayments/FeesAndTerms/substeps/TermsStep.tsx @@ -9,8 +9,7 @@ import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ErrorUtils from '@libs/ErrorUtils'; import Navigation from '@navigation/Navigation'; -// TODO: uncomment at the end of the refactor https://github.com/Expensify/App/issues/36648 -// import * as BankAccounts from '@userActions/BankAccounts'; +import * as BankAccounts from '@userActions/BankAccounts'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; @@ -28,13 +27,15 @@ function HaveReadAndAgreeLabel() { function AgreeToTheLabel() { const {translate} = useLocalize(); + const [userWallet] = useOnyx(ONYXKEYS.USER_WALLET); + const walletAgreementUrl = userWallet?.walletProgramID === CONST.WALLET.MTL_WALLET_PROGRAM_ID ? CONST.WALLET_AGREEMENT_URL : CONST.BANCORP_WALLET_AGREEMENT_URL; return ( {`${translate('termsStep.agreeToThe')} `} {`${translate('common.privacy')} `} {`${translate('common.and')} `} - {`${translate('termsStep.walletAgreement')}.`} + {`${translate('termsStep.walletAgreement')}.`} ); } @@ -93,11 +94,10 @@ function TermsStep() { } setError(false); - // TODO: uncomment at the end of the refactor https://github.com/Expensify/App/issues/36648 - // BankAccounts.acceptWalletTerms({ - // hasAcceptedTerms: hasAcceptedDisclosure && hasAcceptedPrivacyPolicyAndWalletAgreement, - // reportID: walletTerms?.chatReportID ?? '', - // }); + BankAccounts.acceptWalletTerms({ + hasAcceptedTerms: hasAcceptedDisclosure && hasAcceptedPrivacyPolicyAndWalletAgreement, + reportID: walletTerms?.chatReportID ?? '', + }); Navigation.navigate(ROUTES.SETTINGS_WALLET); }} message={errorMessage} From c6028f762608b9dc68b863b24e7e32006b50c1e2 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Wed, 22 May 2024 20:39:27 +0200 Subject: [PATCH 06/26] refactor: cleanup --- src/pages/EnablePayments/EnablePayments.tsx | 20 ++------- .../FeesAndTerms/FeesAndTerms.tsx | 16 ++++++- .../FeesAndTerms/substeps/TermsStep.tsx | 6 +-- .../VerifyIdentity/VerifyIdentity.tsx | 42 ++++++------------- src/types/form/PersonalBankAccountForm.ts | 6 ++- 5 files changed, 36 insertions(+), 54 deletions(-) diff --git a/src/pages/EnablePayments/EnablePayments.tsx b/src/pages/EnablePayments/EnablePayments.tsx index 6df56afced57..fdee18e8147d 100644 --- a/src/pages/EnablePayments/EnablePayments.tsx +++ b/src/pages/EnablePayments/EnablePayments.tsx @@ -7,17 +7,16 @@ import ScreenWrapper from '@components/ScreenWrapper'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import Navigation from '@libs/Navigation/Navigation'; -import FeesAndTerms from '@pages/EnablePayments/FeesAndTerms/FeesAndTerms'; -import PersonalInfo from '@pages/EnablePayments/PersonalInfo/PersonalInfo'; -import VerifyIdentity from '@pages/EnablePayments/VerifyIdentity/VerifyIdentity'; import * as Wallet from '@userActions/Wallet'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {UserWallet} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; -import ActivateStep from './ActivateStep'; import FailedKYC from './FailedKYC'; +import FeesAndTerms from './FeesAndTerms/FeesAndTerms'; +import PersonalInfo from './PersonalInfo/PersonalInfo'; +import VerifyIdentity from './VerifyIdentity/VerifyIdentity'; type EnablePaymentsPageOnyxProps = { /** The user's wallet */ @@ -30,21 +29,13 @@ function EnablePaymentsPage({userWallet}: EnablePaymentsPageProps) { const {translate} = useLocalize(); const {isOffline} = useNetwork(); - const {isPendingOnfidoResult, hasFailedOnfido} = userWallet ?? {}; - useEffect(() => { if (isOffline) { return; } - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - if (isPendingOnfidoResult || hasFailedOnfido) { - Navigation.navigate(ROUTES.SETTINGS_WALLET, CONST.NAVIGATION.TYPE.UP); - return; - } - Wallet.openEnablePaymentsPage(); - }, [isOffline, isPendingOnfidoResult, hasFailedOnfido]); + }, [isOffline]); if (isEmptyObject(userWallet)) { return ; @@ -73,14 +64,11 @@ function EnablePaymentsPage({userWallet}: EnablePaymentsPageProps) { switch (currentStep) { case CONST.WALLET.STEP.ADDITIONAL_DETAILS: - case CONST.WALLET.STEP.ADDITIONAL_DETAILS_KBA: return ; case CONST.WALLET.STEP.ONFIDO: return ; case CONST.WALLET.STEP.TERMS: return ; - case CONST.WALLET.STEP.ACTIVATE: - return ; default: return null; } diff --git a/src/pages/EnablePayments/FeesAndTerms/FeesAndTerms.tsx b/src/pages/EnablePayments/FeesAndTerms/FeesAndTerms.tsx index b54564eff254..64e99bd9be05 100644 --- a/src/pages/EnablePayments/FeesAndTerms/FeesAndTerms.tsx +++ b/src/pages/EnablePayments/FeesAndTerms/FeesAndTerms.tsx @@ -1,5 +1,6 @@ import React from 'react'; import {View} from 'react-native'; +import {useOnyx} from 'react-native-onyx'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import InteractiveStepSubHeader from '@components/InteractiveStepSubHeader'; import ScreenWrapper from '@components/ScreenWrapper'; @@ -8,7 +9,10 @@ import useSubStep from '@hooks/useSubStep'; import type {SubStepProps} from '@hooks/useSubStep/types'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@navigation/Navigation'; +import * as BankAccounts from '@userActions/BankAccounts'; +import * as Wallet from '@userActions/Wallet'; import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import FeesStep from './substeps/FeesStep'; import TermsStep from './substeps/TermsStep'; @@ -18,13 +22,21 @@ const termsAndFeesSubsteps: Array> = [FeesStep function FeesAndTerms() { const {translate} = useLocalize(); const styles = useThemeStyles(); + const [walletTerms] = useOnyx(ONYXKEYS.WALLET_TERMS); - const submit = () => {}; + const submit = () => { + BankAccounts.acceptWalletTerms({ + hasAcceptedTerms: true, + reportID: walletTerms?.chatReportID ?? '', + }); + BankAccounts.clearPersonalBankAccount(); + // TODO: clear wallet draft + Navigation.navigate(ROUTES.SETTINGS_WALLET); + }; const {componentToRender: SubStep, isEditing, screenIndex, nextScreen, prevScreen, moveTo} = useSubStep({bodyContent: termsAndFeesSubsteps, startFrom: 0, onFinished: submit}); const handleBackButtonPress = () => { if (screenIndex === 0) { - // TODO: temporary for refactor https://github.com/Expensify/App/issues/36648 Navigation.navigate(ROUTES.SETTINGS_WALLET); return; } diff --git a/src/pages/EnablePayments/FeesAndTerms/substeps/TermsStep.tsx b/src/pages/EnablePayments/FeesAndTerms/substeps/TermsStep.tsx index 270f0c1f1699..afbd6d594274 100644 --- a/src/pages/EnablePayments/FeesAndTerms/substeps/TermsStep.tsx +++ b/src/pages/EnablePayments/FeesAndTerms/substeps/TermsStep.tsx @@ -28,6 +28,7 @@ function HaveReadAndAgreeLabel() { function AgreeToTheLabel() { const {translate} = useLocalize(); const [userWallet] = useOnyx(ONYXKEYS.USER_WALLET); + const walletAgreementUrl = userWallet?.walletProgramID === CONST.WALLET.MTL_WALLET_PROGRAM_ID ? CONST.WALLET_AGREEMENT_URL : CONST.BANCORP_WALLET_AGREEMENT_URL; return ( @@ -94,11 +95,6 @@ function TermsStep() { } setError(false); - BankAccounts.acceptWalletTerms({ - hasAcceptedTerms: hasAcceptedDisclosure && hasAcceptedPrivacyPolicyAndWalletAgreement, - reportID: walletTerms?.chatReportID ?? '', - }); - Navigation.navigate(ROUTES.SETTINGS_WALLET); }} message={errorMessage} isAlertVisible={error || Boolean(errorMessage)} diff --git a/src/pages/EnablePayments/VerifyIdentity/VerifyIdentity.tsx b/src/pages/EnablePayments/VerifyIdentity/VerifyIdentity.tsx index c2023077af50..0c27fb5980af 100644 --- a/src/pages/EnablePayments/VerifyIdentity/VerifyIdentity.tsx +++ b/src/pages/EnablePayments/VerifyIdentity/VerifyIdentity.tsx @@ -22,23 +22,16 @@ import * as BankAccounts from '@userActions/BankAccounts'; import * as Wallet from '@userActions/Wallet'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {PersonalBankAccount, WalletOnfido} from '@src/types/onyx'; +import type {WalletOnfido} from '@src/types/onyx'; const DEFAULT_WALLET_ONFIDO_DATA = { - loading: false, + isLoading: false, hasAcceptedPrivacyPolicy: false, + sdkToken: '', + applicantID: '', }; type VerifyIdentityOnyxProps = { - /** Reimbursement account from ONYX */ - personalBankAccount: OnyxEntry; - - /** Onfido applicant ID from ONYX */ - onfidoApplicantID: OnyxEntry; - - /** The token required to initialize the Onfido SDK */ - onfidoToken: OnyxEntry; - /** The wallet onfido data */ walletOnfidoData: OnyxEntry; }; @@ -47,7 +40,7 @@ type VerifyIdentityProps = VerifyIdentityOnyxProps; const ONFIDO_ERROR_DISPLAY_DURATION = 10000; -function VerifyIdentity({personalBankAccount, walletOnfidoData = DEFAULT_WALLET_ONFIDO_DATA}: VerifyIdentityProps) { +function VerifyIdentity({walletOnfidoData = DEFAULT_WALLET_ONFIDO_DATA}: VerifyIdentityProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); @@ -55,8 +48,6 @@ function VerifyIdentity({personalBankAccount, walletOnfidoData = DEFAULT_WALLET_ BankAccounts.openOnfidoFlow(); }; - const {isLoading = false, hasAcceptedPrivacyPolicy, sdkToken, applicantID} = walletOnfidoData; - const handleOnfidoSuccess = useCallback( (onfidoData: OnfidoData) => { BankAccounts.verifyIdentity({ @@ -67,24 +58,16 @@ function VerifyIdentity({personalBankAccount, walletOnfidoData = DEFAULT_WALLET_ }); BankAccounts.updateAddPersonalBankAccountDraft({isOnfidoSetupComplete: true}); }, - [personalBankAccount, applicantID], + [walletOnfidoData?.applicantID], ); const onfidoError = ErrorUtils.getLatestErrorMessage(walletOnfidoData) ?? ''; const handleOnfidoError = () => { - // In case of any unexpected error we log it to the server, show a growl, and return the user back to the requestor step so they can try again. Growl.error(translate('onfidoStep.genericError'), ONFIDO_ERROR_DISPLAY_DURATION); - BankAccounts.clearOnfidoToken(); - // BankAccounts.goToWithdrawalAccountSetupStep(CONST.BANK_ACCOUNT.STEP.REQUESTOR); - }; - - const handleOnfidoUserExit = () => { - BankAccounts.clearOnfidoToken(); - // BankAccounts.goToWithdrawalAccountSetupStep(CONST.BANK_ACCOUNT.STEP.REQUESTOR); }; - const handleBackButtonPress = () => { + const goBack = () => { Wallet.updateCurrentStep(CONST.WALLET.STEP.ADDITIONAL_DETAILS); }; @@ -92,7 +75,7 @@ function VerifyIdentity({personalBankAccount, walletOnfidoData = DEFAULT_WALLET_ - {hasAcceptedPrivacyPolicy ? ( + {walletOnfidoData?.hasAcceptedPrivacyPolicy ? ( @@ -125,9 +108,8 @@ function VerifyIdentity({personalBankAccount, walletOnfidoData = DEFAULT_WALLET_ {}} message={onfidoError} - isLoading={isLoading} + isLoading={walletOnfidoData?.isLoading} buttonText={onfidoError ? translate('onfidoStep.tryAgain') : translate('common.continue')} containerStyles={[styles.mh0, styles.mv0, styles.mb0]} /> diff --git a/src/types/form/PersonalBankAccountForm.ts b/src/types/form/PersonalBankAccountForm.ts index 1a1922bf8013..a5b95b20e684 100644 --- a/src/types/form/PersonalBankAccountForm.ts +++ b/src/types/form/PersonalBankAccountForm.ts @@ -32,7 +32,11 @@ type PlaidAccountProps = { [INPUT_IDS.BANK_INFO_STEP.SELECTED_PLAID_ACCOUNT_ID]: string; }; -type PersonalBankAccountForm = Form; +type OnfidoStepProps = { + isOnfidoSetupComplete: boolean; +}; + +type PersonalBankAccountForm = Form & OnfidoStepProps; export type {BankAccountStepProps, PlaidAccountProps, PersonalBankAccountForm}; From 9764c602fbf58b74790457f1b4836bf6c4c32da4 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Thu, 23 May 2024 16:56:27 +0200 Subject: [PATCH 07/26] chore: clean wallet draft after finishing the flow --- src/pages/EnablePayments/FeesAndTerms/FeesAndTerms.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/EnablePayments/FeesAndTerms/FeesAndTerms.tsx b/src/pages/EnablePayments/FeesAndTerms/FeesAndTerms.tsx index 64e99bd9be05..5b462c278509 100644 --- a/src/pages/EnablePayments/FeesAndTerms/FeesAndTerms.tsx +++ b/src/pages/EnablePayments/FeesAndTerms/FeesAndTerms.tsx @@ -30,7 +30,7 @@ function FeesAndTerms() { reportID: walletTerms?.chatReportID ?? '', }); BankAccounts.clearPersonalBankAccount(); - // TODO: clear wallet draft + Wallet.resetWalletAdditionalDetailsDraft(); Navigation.navigate(ROUTES.SETTINGS_WALLET); }; const {componentToRender: SubStep, isEditing, screenIndex, nextScreen, prevScreen, moveTo} = useSubStep({bodyContent: termsAndFeesSubsteps, startFrom: 0, onFinished: submit}); From aa7d744a1736bf3cde203caacc2dd2eabb7ba307 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Thu, 23 May 2024 18:50:24 +0200 Subject: [PATCH 08/26] fix: remove old add plaid bank account layout --- src/components/AddPlaidBankAccount.tsx | 68 +++++-------------- src/pages/AddPersonalBankAccountPage.tsx | 1 + .../BankInfo/substeps/Plaid.tsx | 1 - 3 files changed, 18 insertions(+), 52 deletions(-) diff --git a/src/components/AddPlaidBankAccount.tsx b/src/components/AddPlaidBankAccount.tsx index 366f14ec9780..fddfe5b8e8d9 100644 --- a/src/components/AddPlaidBankAccount.tsx +++ b/src/components/AddPlaidBankAccount.tsx @@ -59,9 +59,6 @@ type AddPlaidBankAccountProps = AddPlaidBankAccountOnyxProps & { /** Are we adding a withdrawal account? */ allowDebit?: boolean; - /** Is displayed in new VBBA */ - isDisplayedInNewVBBA?: boolean; - /** Is displayed in new enable wallet flow */ isDisplayedInWalletFlow?: boolean; @@ -84,7 +81,6 @@ function AddPlaidBankAccount({ bankAccountID = 0, allowDebit = false, isPlaidDisabled, - isDisplayedInNewVBBA = false, errorText = '', onInputChange = () => {}, isDisplayedInWalletFlow = false, @@ -259,62 +255,32 @@ function AddPlaidBankAccount({ return {renderPlaidLink()}; } - if (isDisplayedInNewVBBA || isDisplayedInWalletFlow) { - return ( - - {translate(isDisplayedInWalletFlow ? 'walletPage.chooseYourBankAccount' : 'bankAccount.chooseAnAccount')} - {!!text && {text}} - - - - {bankName} - {selectedPlaidAccountMask.length > 0 && ( - {`${translate('bankAccount.accountEnding')} ${selectedPlaidAccountMask}`} - )} - - - {`${translate('bankAccount.chooseAnAccountBelow')}:`} - - - - ); - } - - // Plaid bank accounts view return ( - {!!text && {text}} - + {translate(isDisplayedInWalletFlow ? 'walletPage.chooseYourBankAccount' : 'bankAccount.chooseAnAccount')} + {!!text && {text}} + - {bankName} - - - + + {bankName} + {selectedPlaidAccountMask.length > 0 && ( + {`${translate('bankAccount.accountEnding')} ${selectedPlaidAccountMask}`} + )} + + {`${translate('bankAccount.chooseAnAccountBelow')}:`} + + ); } diff --git a/src/pages/AddPersonalBankAccountPage.tsx b/src/pages/AddPersonalBankAccountPage.tsx index 5cd0f3ef8026..98506477eaf9 100644 --- a/src/pages/AddPersonalBankAccountPage.tsx +++ b/src/pages/AddPersonalBankAccountPage.tsx @@ -90,6 +90,7 @@ function AddPersonalBankAccountPage({personalBankAccount, plaidData}: AddPersona Navigation.goBack()} receivedRedirectURI={getPlaidOAuthReceivedRedirectURI()} selectedPlaidAccountID={selectedPlaidAccountId} diff --git a/src/pages/ReimbursementAccount/BankInfo/substeps/Plaid.tsx b/src/pages/ReimbursementAccount/BankInfo/substeps/Plaid.tsx index c58c2f40aa07..03409e4adddf 100644 --- a/src/pages/ReimbursementAccount/BankInfo/substeps/Plaid.tsx +++ b/src/pages/ReimbursementAccount/BankInfo/substeps/Plaid.tsx @@ -88,7 +88,6 @@ function Plaid({reimbursementAccount, reimbursementAccountDraft, onNext, plaidDa allowDebit bankAccountID={bankAccountID} selectedPlaidAccountID={selectedPlaidAccountID} - isDisplayedInNewVBBA inputID={BANK_INFO_STEP_KEYS.SELECTED_PLAID_ACCOUNT_ID} defaultValue={selectedPlaidAccountID} /> From f189a8cc3cbf50a5c7758d004a46011454cb5853 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Thu, 23 May 2024 21:23:02 +0200 Subject: [PATCH 09/26] fix: include add bank acount to the flow --- src/CONST.ts | 1 + src/pages/AddPersonalBankAccountPage.tsx | 1 + src/pages/EnablePayments/AddBankAccount/AddBankAccount.tsx | 4 ++-- src/pages/EnablePayments/EnablePayments.tsx | 5 ++++- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index af5f32808034..6ef98d656e14 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -1423,6 +1423,7 @@ const CONST = { }, STEP: { // In the order they appear in the Wallet flow + ADD_BANK_ACCOUNT: 'AddBankAccountStep', ADDITIONAL_DETAILS: 'AdditionalDetailsStep', ADDITIONAL_DETAILS_KBA: 'AdditionalDetailsKBAStep', ONFIDO: 'OnfidoStep', diff --git a/src/pages/AddPersonalBankAccountPage.tsx b/src/pages/AddPersonalBankAccountPage.tsx index 98506477eaf9..59046e103c6b 100644 --- a/src/pages/AddPersonalBankAccountPage.tsx +++ b/src/pages/AddPersonalBankAccountPage.tsx @@ -89,6 +89,7 @@ function AddPersonalBankAccountPage({personalBankAccount, plaidData}: AddPersona > Navigation.goBack()} diff --git a/src/pages/EnablePayments/AddBankAccount/AddBankAccount.tsx b/src/pages/EnablePayments/AddBankAccount/AddBankAccount.tsx index 9fde5456226b..149d6a41aac7 100644 --- a/src/pages/EnablePayments/AddBankAccount/AddBankAccount.tsx +++ b/src/pages/EnablePayments/AddBankAccount/AddBankAccount.tsx @@ -12,9 +12,9 @@ import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@navigation/Navigation'; import * as BankAccounts from '@userActions/BankAccounts'; import * as PaymentMethods from '@userActions/PaymentMethods'; +import * as Wallet from '@userActions/Wallet'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; import type {PersonalBankAccountForm} from '@src/types/form'; import type {PersonalBankAccount, PlaidData} from '@src/types/onyx'; import SetupMethod from './SetupMethod'; @@ -44,7 +44,7 @@ function AddBankAccount({personalBankAccount, plaidData, personalBankAccountDraf if (selectedPlaidBankAccount) { BankAccounts.addPersonalBankAccount(selectedPlaidBankAccount); - Navigation.navigate(ROUTES.SETTINGS_ENABLE_PAYMENTS_REFACTOR); + Wallet.updateCurrentStep(CONST.WALLET.STEP.ADDITIONAL_DETAILS); } }, [personalBankAccountDraft?.plaidAccountID, plaidData?.bankAccounts]); diff --git a/src/pages/EnablePayments/EnablePayments.tsx b/src/pages/EnablePayments/EnablePayments.tsx index fdee18e8147d..752705cd6d27 100644 --- a/src/pages/EnablePayments/EnablePayments.tsx +++ b/src/pages/EnablePayments/EnablePayments.tsx @@ -7,6 +7,7 @@ import ScreenWrapper from '@components/ScreenWrapper'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import Navigation from '@libs/Navigation/Navigation'; +import AddBankAccount from '@pages/EnablePayments/AddBankAccount/AddBankAccount'; import * as Wallet from '@userActions/Wallet'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -60,9 +61,11 @@ function EnablePaymentsPage({userWallet}: EnablePaymentsPageProps) { ); } - const currentStep = userWallet?.currentStep || CONST.WALLET.STEP.ADDITIONAL_DETAILS; + const currentStep = userWallet?.currentStep || (userWallet?.bankAccountID ? CONST.WALLET.STEP.ADDITIONAL_DETAILS : CONST.WALLET.STEP.ADD_BANK_ACCOUNT); switch (currentStep) { + case CONST.WALLET.STEP.ADD_BANK_ACCOUNT: + return ; case CONST.WALLET.STEP.ADDITIONAL_DETAILS: return ; case CONST.WALLET.STEP.ONFIDO: From 034b82df570a5822c65be0d8a1f475ef4104cf8a Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Fri, 24 May 2024 11:55:44 +0200 Subject: [PATCH 10/26] fix: show loading when confirming personal info, fetch userWallet only when missing data --- src/pages/EnablePayments/EnablePayments.tsx | 10 ++++------ .../PersonalInfo/substeps/ConfirmationStep.tsx | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/pages/EnablePayments/EnablePayments.tsx b/src/pages/EnablePayments/EnablePayments.tsx index 752705cd6d27..5d7dd52c1e89 100644 --- a/src/pages/EnablePayments/EnablePayments.tsx +++ b/src/pages/EnablePayments/EnablePayments.tsx @@ -35,8 +35,10 @@ function EnablePaymentsPage({userWallet}: EnablePaymentsPageProps) { return; } - Wallet.openEnablePaymentsPage(); - }, [isOffline]); + if (isEmptyObject(userWallet)) { + Wallet.openEnablePaymentsPage(); + } + }, [isOffline, userWallet]); if (isEmptyObject(userWallet)) { return ; @@ -85,9 +87,5 @@ EnablePaymentsPage.displayName = 'EnablePaymentsPage'; export default withOnyx({ userWallet: { key: ONYXKEYS.USER_WALLET, - - // We want to refresh the wallet each time the user attempts to activate the wallet so we won't use the - // stored values here. - initWithStoredValues: false, }, })(EnablePaymentsPage); diff --git a/src/pages/EnablePayments/PersonalInfo/substeps/ConfirmationStep.tsx b/src/pages/EnablePayments/PersonalInfo/substeps/ConfirmationStep.tsx index b24400face07..ea1b70cd6074 100644 --- a/src/pages/EnablePayments/PersonalInfo/substeps/ConfirmationStep.tsx +++ b/src/pages/EnablePayments/PersonalInfo/substeps/ConfirmationStep.tsx @@ -29,7 +29,7 @@ function ConfirmationStep({onNext, onMove}: SubStepProps) { const [walletAdditionalDetails] = useOnyx(ONYXKEYS.WALLET_ADDITIONAL_DETAILS); const [walletAdditionalDetailsDraft] = useOnyx(ONYXKEYS.FORMS.WALLET_ADDITIONAL_DETAILS_DRAFT); - const isLoading = walletAdditionalDetailsDraft?.isLoading ?? false; + const isLoading = walletAdditionalDetails?.isLoading ?? false; const error = ErrorUtils.getLatestErrorMessage(walletAdditionalDetails ?? {}); const values = useMemo(() => getSubstepValues(PERSONAL_INFO_STEP_KEYS, walletAdditionalDetailsDraft, walletAdditionalDetails), [walletAdditionalDetails, walletAdditionalDetailsDraft]); From c5291d7abd9521f9ea0b6d8afb7853b8f049c1fd Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Fri, 24 May 2024 13:25:22 +0200 Subject: [PATCH 11/26] fix: proper submit/go back handling for the terms step --- .../FeesAndTerms/FeesAndTerms.tsx | 2 +- .../FeesAndTerms/substeps/TermsStep.tsx | 24 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/pages/EnablePayments/FeesAndTerms/FeesAndTerms.tsx b/src/pages/EnablePayments/FeesAndTerms/FeesAndTerms.tsx index 5b462c278509..512abc57a990 100644 --- a/src/pages/EnablePayments/FeesAndTerms/FeesAndTerms.tsx +++ b/src/pages/EnablePayments/FeesAndTerms/FeesAndTerms.tsx @@ -37,7 +37,7 @@ function FeesAndTerms() { const handleBackButtonPress = () => { if (screenIndex === 0) { - Navigation.navigate(ROUTES.SETTINGS_WALLET); + Wallet.updateCurrentStep(CONST.WALLET.STEP.ONFIDO); return; } prevScreen(); diff --git a/src/pages/EnablePayments/FeesAndTerms/substeps/TermsStep.tsx b/src/pages/EnablePayments/FeesAndTerms/substeps/TermsStep.tsx index afbd6d594274..12fce0b2ec50 100644 --- a/src/pages/EnablePayments/FeesAndTerms/substeps/TermsStep.tsx +++ b/src/pages/EnablePayments/FeesAndTerms/substeps/TermsStep.tsx @@ -6,13 +6,11 @@ import FormAlertWithSubmitButton from '@components/FormAlertWithSubmitButton'; import Text from '@components/Text'; import TextLink from '@components/TextLink'; import useLocalize from '@hooks/useLocalize'; +import type {SubStepProps} from '@hooks/useSubStep/types'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ErrorUtils from '@libs/ErrorUtils'; -import Navigation from '@navigation/Navigation'; -import * as BankAccounts from '@userActions/BankAccounts'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; function HaveReadAndAgreeLabel() { const {translate} = useLocalize(); @@ -41,7 +39,7 @@ function AgreeToTheLabel() { ); } -function TermsStep() { +function TermsStep({onNext}: SubStepProps) { const styles = useThemeStyles(); const [hasAcceptedDisclosure, setHasAcceptedDisclosure] = useState(false); const [hasAcceptedPrivacyPolicyAndWalletAgreement, setHasAcceptedPrivacyPolicyAndWalletAgreement] = useState(false); @@ -60,6 +58,15 @@ function TermsStep() { setHasAcceptedPrivacyPolicyAndWalletAgreement(!hasAcceptedPrivacyPolicyAndWalletAgreement); }; + const submit = () => { + if (!hasAcceptedDisclosure || !hasAcceptedPrivacyPolicyAndWalletAgreement) { + setError(true); + return; + } + setError(false); + onNext(); + }; + /** clear error */ useEffect(() => { if (!hasAcceptedDisclosure || !hasAcceptedPrivacyPolicyAndWalletAgreement) { @@ -88,14 +95,7 @@ function TermsStep() { { - if (!hasAcceptedDisclosure || !hasAcceptedPrivacyPolicyAndWalletAgreement) { - setError(true); - return; - } - - setError(false); - }} + onSubmit={submit} message={errorMessage} isAlertVisible={error || Boolean(errorMessage)} isLoading={!!walletTerms?.isLoading} From 3538c6951b2b98a88ed5430d60f657061b1d9220 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Fri, 24 May 2024 14:43:47 +0200 Subject: [PATCH 12/26] fix: properly show the first step --- src/pages/EnablePayments/EnablePayments.tsx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/pages/EnablePayments/EnablePayments.tsx b/src/pages/EnablePayments/EnablePayments.tsx index 5d7dd52c1e89..ff0aa7b353bb 100644 --- a/src/pages/EnablePayments/EnablePayments.tsx +++ b/src/pages/EnablePayments/EnablePayments.tsx @@ -7,13 +7,13 @@ import ScreenWrapper from '@components/ScreenWrapper'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import Navigation from '@libs/Navigation/Navigation'; -import AddBankAccount from '@pages/EnablePayments/AddBankAccount/AddBankAccount'; import * as Wallet from '@userActions/Wallet'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import type {UserWallet} from '@src/types/onyx'; +import type {BankAccountList, UserWallet} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; +import AddBankAccount from './AddBankAccount/AddBankAccount'; import FailedKYC from './FailedKYC'; import FeesAndTerms from './FeesAndTerms/FeesAndTerms'; import PersonalInfo from './PersonalInfo/PersonalInfo'; @@ -22,11 +22,14 @@ import VerifyIdentity from './VerifyIdentity/VerifyIdentity'; type EnablePaymentsPageOnyxProps = { /** The user's wallet */ userWallet: OnyxEntry; + + /** The list of bank accounts */ + bankAccountList: OnyxEntry; }; type EnablePaymentsPageProps = EnablePaymentsPageOnyxProps; -function EnablePaymentsPage({userWallet}: EnablePaymentsPageProps) { +function EnablePaymentsPage({userWallet, bankAccountList}: EnablePaymentsPageProps) { const {translate} = useLocalize(); const {isOffline} = useNetwork(); @@ -63,7 +66,7 @@ function EnablePaymentsPage({userWallet}: EnablePaymentsPageProps) { ); } - const currentStep = userWallet?.currentStep || (userWallet?.bankAccountID ? CONST.WALLET.STEP.ADDITIONAL_DETAILS : CONST.WALLET.STEP.ADD_BANK_ACCOUNT); + const currentStep = userWallet?.currentStep || (isEmptyObject(bankAccountList) ? CONST.WALLET.STEP.ADD_BANK_ACCOUNT : CONST.WALLET.STEP.ADDITIONAL_DETAILS); switch (currentStep) { case CONST.WALLET.STEP.ADD_BANK_ACCOUNT: @@ -88,4 +91,7 @@ export default withOnyx({ userWallet: { key: ONYXKEYS.USER_WALLET, }, + bankAccountList: { + key: ONYXKEYS.BANK_ACCOUNT_LIST, + }, })(EnablePaymentsPage); From c1bea82678c9a16796fdef26b914c48a2795691f Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Fri, 24 May 2024 15:02:55 +0200 Subject: [PATCH 13/26] fix: remove unnecessary comment --- src/pages/EnablePayments/AddBankAccount/AddBankAccount.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/EnablePayments/AddBankAccount/AddBankAccount.tsx b/src/pages/EnablePayments/AddBankAccount/AddBankAccount.tsx index 149d6a41aac7..574034159e06 100644 --- a/src/pages/EnablePayments/AddBankAccount/AddBankAccount.tsx +++ b/src/pages/EnablePayments/AddBankAccount/AddBankAccount.tsx @@ -54,7 +54,6 @@ function AddBankAccount({personalBankAccount, plaidData, personalBankAccountDraf const exitFlow = (shouldContinue = false) => { const exitReportID = personalBankAccount?.exitReportID; - // TODO: https://github.com/Expensify/App/issues/36648 This should be updated to the correct route once the refactor is complete const onSuccessFallbackRoute = personalBankAccount?.onSuccessFallbackRoute ?? ''; if (exitReportID) { From f3287b8e9acfc57977821d6ccd918fb3a46a5d9f Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Fri, 24 May 2024 15:27:06 +0200 Subject: [PATCH 14/26] feat: routes cleanup --- src/ROUTES.ts | 5 ----- src/SCREENS.ts | 3 --- .../AppNavigator/ModalStackNavigators/index.tsx | 5 +---- src/libs/Navigation/linkingConfig/config.ts | 14 -------------- .../EnablePayments/AddBankAccount/SetupMethod.tsx | 4 ++-- src/pages/EnablePayments/EnablePayments.tsx | 2 +- .../settings/Wallet/WalletPage/WalletPage.tsx | 2 +- 7 files changed, 5 insertions(+), 30 deletions(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 2bc04c4a99ea..20520a2eb9ce 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -123,12 +123,7 @@ const ROUTES = { }, SETTINGS_ADD_DEBIT_CARD: 'settings/wallet/add-debit-card', SETTINGS_ADD_BANK_ACCOUNT: 'settings/wallet/add-bank-account', - SETTINGS_ADD_BANK_ACCOUNT_REFACTOR: 'settings/wallet/add-bank-account-refactor', SETTINGS_ENABLE_PAYMENTS: 'settings/wallet/enable-payments', - // TODO: Added temporarily for testing purposes, remove after refactor - https://github.com/Expensify/App/issues/36648 - SETTINGS_ENABLE_PAYMENTS_REFACTOR: 'settings/wallet/enable-payments-refactor', - // TODO: Added temporarily for testing purposes, remove after refactor - https://github.com/Expensify/App/issues/36648 - SETTINGS_ENABLE_PAYMENTS_TEMPORARY_TERMS: 'settings/wallet/enable-payments-temporary-terms', SETTINGS_WALLET_CARD_DIGITAL_DETAILS_UPDATE_ADDRESS: { route: 'settings/wallet/card/:domain/digital-details/update-address', getRoute: (domain: string) => `settings/wallet/card/${domain}/digital-details/update-address` as const, diff --git a/src/SCREENS.ts b/src/SCREENS.ts index f74002312623..fc57724614b5 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -42,7 +42,6 @@ const SCREENS = { APP_DOWNLOAD_LINKS: 'Settings_App_Download_Links', ADD_DEBIT_CARD: 'Settings_Add_Debit_Card', ADD_BANK_ACCOUNT: 'Settings_Add_Bank_Account', - ADD_BANK_ACCOUNT_REFACTOR: 'Settings_Add_Bank_Account_Refactor', CLOSE: 'Settings_Close', TWO_FACTOR_AUTH: 'Settings_TwoFactorAuth', REPORT_CARD_LOST_OR_DAMAGED: 'Settings_ReportCardLostOrDamaged', @@ -91,8 +90,6 @@ const SCREENS = { ENABLE_PAYMENTS: 'Settings_Wallet_EnablePayments', // TODO: Added temporarily for testing purposes, remove after refactor - https://github.com/Expensify/App/issues/36648 ENABLE_PAYMENTS_REFACTOR: 'Settings_Wallet_EnablePayments_Refactor', - // TODO: Added temporarily for testing purposes, remove after refactor - https://github.com/Expensify/App/issues/36648 - ENABLE_PAYMENTS_TEMPORARY_TERMS: 'Settings_Wallet_EnablePayments_Temporary_Terms', 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', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index ca46a61787b9..f19a9f5be1ad 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -203,12 +203,9 @@ const SettingsModalStackNavigator = createModalStackNavigator require('../../../../pages/settings/Wallet/Card/GetPhysicalCardConfirm').default as React.ComponentType, [SCREENS.SETTINGS.WALLET.TRANSFER_BALANCE]: () => require('../../../../pages/settings/Wallet/TransferBalancePage').default as React.ComponentType, [SCREENS.SETTINGS.WALLET.CHOOSE_TRANSFER_ACCOUNT]: () => require('../../../../pages/settings/Wallet/ChooseTransferAccountPage').default as React.ComponentType, - [SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS]: () => require('../../../../pages/EnablePayments/EnablePaymentsPage').default as React.ComponentType, - // TODO: Added temporarily for testing purposes, remove after refactor - https://github.com/Expensify/App/issues/36648 - [SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS_REFACTOR]: () => require('../../../../pages/EnablePayments/EnablePayments').default as React.ComponentType, + [SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS]: () => require('../../../../pages/EnablePayments/EnablePayments').default as React.ComponentType, [SCREENS.SETTINGS.ADD_DEBIT_CARD]: () => require('../../../../pages/settings/Wallet/AddDebitCardPage').default as React.ComponentType, [SCREENS.SETTINGS.ADD_BANK_ACCOUNT]: () => require('../../../../pages/AddPersonalBankAccountPage').default as React.ComponentType, - [SCREENS.SETTINGS.ADD_BANK_ACCOUNT_REFACTOR]: () => require('../../../../pages/EnablePayments/AddBankAccount/AddBankAccount').default as React.ComponentType, [SCREENS.SETTINGS.PROFILE.STATUS]: () => require('../../../../pages/settings/Profile/CustomStatus/StatusPage').default as React.ComponentType, [SCREENS.SETTINGS.PROFILE.STATUS_CLEAR_AFTER]: () => require('../../../../pages/settings/Profile/CustomStatus/StatusClearAfterPage').default as React.ComponentType, [SCREENS.SETTINGS.PROFILE.STATUS_CLEAR_AFTER_DATE]: () => require('../../../../pages/settings/Profile/CustomStatus/SetDatePage').default as React.ComponentType, diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index a093b778360e..d9982a0bf00c 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -161,16 +161,6 @@ const config: LinkingOptions['config'] = { path: ROUTES.SETTINGS_ENABLE_PAYMENTS, exact: true, }, - // TODO: Added temporarily for testing purposes, remove after refactor - https://github.com/Expensify/App/issues/36648 - [SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS_REFACTOR]: { - path: ROUTES.SETTINGS_ENABLE_PAYMENTS_REFACTOR, - exact: true, - }, - // TODO: Added temporarily for testing purposes, remove after refactor - https://github.com/Expensify/App/issues/36648 - [SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS_TEMPORARY_TERMS]: { - path: ROUTES.SETTINGS_ENABLE_PAYMENTS_TEMPORARY_TERMS, - exact: true, - }, [SCREENS.SETTINGS.WALLET.TRANSFER_BALANCE]: { path: ROUTES.SETTINGS_WALLET_TRANSFER_BALANCE, exact: true, @@ -199,10 +189,6 @@ const config: LinkingOptions['config'] = { path: ROUTES.SETTINGS_ADD_BANK_ACCOUNT, exact: true, }, - [SCREENS.SETTINGS.ADD_BANK_ACCOUNT_REFACTOR]: { - path: ROUTES.SETTINGS_ADD_BANK_ACCOUNT_REFACTOR, - exact: true, - }, [SCREENS.SETTINGS.PROFILE.PRONOUNS]: { path: ROUTES.SETTINGS_PRONOUNS, exact: true, diff --git a/src/pages/EnablePayments/AddBankAccount/SetupMethod.tsx b/src/pages/EnablePayments/AddBankAccount/SetupMethod.tsx index e70d5979e92e..f58c158ba448 100644 --- a/src/pages/EnablePayments/AddBankAccount/SetupMethod.tsx +++ b/src/pages/EnablePayments/AddBankAccount/SetupMethod.tsx @@ -28,7 +28,7 @@ type SetupMethodOnyxProps = { type SetupMethodProps = SetupMethodOnyxProps; const plaidDesktopMessage = getPlaidDesktopMessage(); -const bankAccountRoute = `${CONFIG.EXPENSIFY.NEW_EXPENSIFY_URL}${ROUTES.SETTINGS_ADD_BANK_ACCOUNT_REFACTOR}`; +const enablePayments = `${CONFIG.EXPENSIFY.NEW_EXPENSIFY_URL}${ROUTES.SETTINGS_ENABLE_PAYMENTS}`; function SetupMethod({isPlaidDisabled, user}: SetupMethodProps) { const styles = useThemeStyles(); @@ -46,7 +46,7 @@ function SetupMethod({isPlaidDisabled, user}: SetupMethodProps) { {!!plaidDesktopMessage && ( - {translate(plaidDesktopMessage)} + {translate(plaidDesktopMessage)} )}