Skip to content

Commit e006ecb

Browse files
committed
use new route for confirmation page
1 parent 29ded33 commit e006ecb

12 files changed

Lines changed: 143 additions & 219 deletions

File tree

src/ROUTES.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1492,6 +1492,10 @@ const ROUTES = {
14921492
return `${base}${pagePart}${subPagePart}${actionPart}` as const;
14931493
},
14941494
},
1495+
SETTINGS_ENABLE_PAYMENTS_CONFIRM_MAGIC_CODE: {
1496+
route: 'settings/wallet/enable-payments/confirm-magic-code',
1497+
getRoute: () => 'settings/wallet/enable-payments/confirm-magic-code' as const,
1498+
},
14951499
SETTINGS_WALLET_UNSHARE_BANK_ACCOUNT: {
14961500
route: 'settings/wallet/:bankAccountID/unshare-bank-account',
14971501
getRoute: (bankAccountID: number | undefined) => `settings/wallet/${bankAccountID}/unshare-bank-account` as const,

src/SCREENS.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ const SCREENS = {
178178
IMPORT_TRANSACTIONS_SPREADSHEET: 'Settings_Wallet_Import_Transactions_Spreadsheet',
179179
TRANSACTIONS_IMPORTED: 'Settings_Wallet_Transactions_Imported',
180180
ENABLE_PAYMENTS: 'Settings_Wallet_EnablePayments',
181+
ENABLE_PAYMENTS_CONFIRM_MAGIC_CODE: 'Settings_Wallet_EnablePayments_ConfirmMagicCode',
181182
CARD_ACTIVATE: 'Settings_Wallet_Card_Activate',
182183
CARD_CHANGE_PIN: 'Settings_Wallet_Card_Change_PIN',
183184
CARD_CHANGE_PIN_ATM: 'Settings_Wallet_Card_Change_PIN_ATM',

src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorP
448448
[SCREENS.SETTINGS.WALLET.IMPORT_TRANSACTIONS_SPREADSHEET]: () => require<ReactComponentModule>('../../../../pages/settings/Wallet/ImportTransactionsSpreadsheetPage').default,
449449
[SCREENS.SETTINGS.WALLET.TRANSACTIONS_IMPORTED]: () => require<ReactComponentModule>('../../../../pages/settings/Wallet/TransactionsImportedPage').default,
450450
[SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS]: () => require<ReactComponentModule>('../../../../pages/EnablePayments/Wallet/EnablePayments').default,
451+
[SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS_CONFIRM_MAGIC_CODE]: () => require<ReactComponentModule>('../../../../pages/EnablePayments/shared/WalletConfirmMagicCodePage').default,
451452
[SCREENS.SETTINGS.WALLET.UNSHARE_BANK_ACCOUNT]: () => require<ReactComponentModule>('../../../../pages/settings/Wallet/UnshareBankAccount/UnshareBankAccount').default,
452453
[SCREENS.SETTINGS.WALLET.ENABLE_GLOBAL_REIMBURSEMENTS_BUSINESS]: () =>
453454
require<ReactComponentModule>('../../../../pages/settings/Wallet/EnableGlobalReimbursements/EnableGlobalReimbursementsBusinessPage').default,

src/libs/Navigation/linkingConfig/RELATIONS/SETTINGS_TO_RHP.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ const SETTINGS_TO_RHP: Partial<Record<keyof SettingsSplitNavigatorParamList, str
4646
SCREENS.SETTINGS.WALLET.IMPORT_TRANSACTIONS_SPREADSHEET,
4747
SCREENS.SETTINGS.WALLET.TRANSACTIONS_IMPORTED,
4848
SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS,
49+
SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS_CONFIRM_MAGIC_CODE,
4950
SCREENS.SETTINGS.WALLET.UNSHARE_BANK_ACCOUNT,
5051
SCREENS.SETTINGS.WALLET.ENABLE_GLOBAL_REIMBURSEMENTS_BUSINESS,
5152
SCREENS.SETTINGS.WALLET.ENABLE_GLOBAL_REIMBURSEMENTS_AGREEMENTS,

src/libs/Navigation/linkingConfig/config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,10 @@ const config: LinkingOptions<RootNavigatorParamList>['config'] = {
219219
path: ROUTES.SETTINGS_ENABLE_PAYMENTS.route,
220220
exact: true,
221221
},
222+
[SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS_CONFIRM_MAGIC_CODE]: {
223+
path: ROUTES.SETTINGS_ENABLE_PAYMENTS_CONFIRM_MAGIC_CODE.route,
224+
exact: true,
225+
},
222226
[SCREENS.SETTINGS.WALLET.UNSHARE_BANK_ACCOUNT]: {
223227
path: ROUTES.SETTINGS_WALLET_UNSHARE_BANK_ACCOUNT.route,
224228
exact: true,

src/libs/Navigation/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ type SettingsNavigatorParamList = {
205205
subPage?: EnablePaymentsSubPageType;
206206
action?: 'edit';
207207
};
208+
[SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS_CONFIRM_MAGIC_CODE]: undefined;
208209
[SCREENS.SETTINGS.WALLET.UNSHARE_BANK_ACCOUNT]: {
209210
bankAccountID: string;
210211
};

src/pages/EnablePayments/Pay/AdditionalDetails/AdditionalDetailsStep.tsx

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@ import useLocalize from '@hooks/useLocalize';
1414
import useOnyx from '@hooks/useOnyx';
1515
import useThemeStyles from '@hooks/useThemeStyles';
1616

17-
import type {UpdatePersonalDetailsForWalletParams} from '@libs/API/parameters';
1817
import {extractFirstAndLastNameFromAvailableDetails} from '@libs/PersonalDetailsUtils';
19-
import {parsePhoneNumber} from '@libs/PhoneNumber';
2018
import {
2119
getFieldRequiredErrors,
2220
getInvalidAddressErrorTranslationPath,
@@ -29,9 +27,9 @@ import {
2927
meetsMinimumAgeRequirement,
3028
} from '@libs/ValidationUtils';
3129

30+
import getWalletPersonalDetailsParams from '@pages/EnablePayments/shared/getWalletPersonalDetailsParams';
3231
import IdologyQuestions from '@pages/EnablePayments/shared/IdologyQuestions';
3332
import useWalletPhoneMagicCode from '@pages/EnablePayments/shared/useWalletPhoneMagicCode';
34-
import WalletMagicCodePrompt from '@pages/EnablePayments/shared/WalletMagicCodePrompt';
3533
import AddressFormFields from '@pages/ReimbursementAccount/AddressFormFields';
3634

3735
import {setAdditionalDetailsQuestions} from '@userActions/Wallet';
@@ -84,7 +82,7 @@ function AdditionalDetailsStep({currentUserPersonalDetails}: AdditionalDetailsSt
8482
const maxDate = subYears(currentDate, CONST.DATE_BIRTH.MIN_AGE_FOR_PAYMENT);
8583
const shouldAskForFullSSN = walletAdditionalDetails?.errorCode === CONST.WALLET.ERROR.SSN;
8684

87-
const {isMagicCodeRequired, submitPersonalDetails, confirmPersonalDetailsWithMagicCode, closeMagicCodePrompt} = useWalletPhoneMagicCode();
85+
const {submitPersonalDetails} = useWalletPhoneMagicCode();
8886

8987
const validate = (values: FormOnyxValues<typeof ONYXKEYS.FORMS.WALLET_ADDITIONAL_DETAILS>): FormInputErrors<typeof ONYXKEYS.FORMS.WALLET_ADDITIONAL_DETAILS> => {
9088
const errors = getFieldRequiredErrors(values, STEP_FIELDS, translate);
@@ -124,29 +122,9 @@ function AdditionalDetailsStep({currentUserPersonalDetails}: AdditionalDetailsSt
124122
};
125123

126124
const activateWallet = (values: FormOnyxValues<typeof ONYXKEYS.FORMS.WALLET_ADDITIONAL_DETAILS>) => {
127-
const personalDetails: UpdatePersonalDetailsForWalletParams = {
128-
phoneNumber: (values.phoneNumber && parsePhoneNumber(values.phoneNumber, {regionCode: CONST.COUNTRY.US}).number?.significant) ?? '',
129-
legalFirstName: values.legalFirstName ?? '',
130-
legalLastName: values.legalLastName ?? '',
131-
addressStreet: values.addressStreet ?? '',
132-
addressCity: values.addressCity ?? '',
133-
addressState: values.addressState ?? '',
134-
addressZip: values.addressZipCode ?? '',
135-
dob: values.dob ?? '',
136-
ssn: values.ssn ?? '',
137-
};
138-
submitPersonalDetails(personalDetails);
125+
submitPersonalDetails(getWalletPersonalDetailsParams(values));
139126
};
140127

141-
if (isMagicCodeRequired) {
142-
return (
143-
<WalletMagicCodePrompt
144-
onConfirm={confirmPersonalDetailsWithMagicCode}
145-
onClose={closeMagicCodePrompt}
146-
/>
147-
);
148-
}
149-
150128
if (walletAdditionalDetails?.questions && walletAdditionalDetails.questions.length > 0) {
151129
return (
152130
<ScreenWrapper

src/pages/EnablePayments/Wallet/PersonalInfo/PersonalInfo.tsx

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,9 @@ import useOnyx from '@hooks/useOnyx';
66
import useSubPage from '@hooks/useSubPage';
77
import type {SubPageProps} from '@hooks/useSubPage/types';
88

9-
import type {UpdatePersonalDetailsForWalletParams} from '@libs/API/parameters';
10-
import {parsePhoneNumber} from '@libs/PhoneNumber';
11-
9+
import getWalletPersonalDetailsParams from '@pages/EnablePayments/shared/getWalletPersonalDetailsParams';
1210
import IdologyQuestions from '@pages/EnablePayments/shared/IdologyQuestions';
1311
import useWalletPhoneMagicCode from '@pages/EnablePayments/shared/useWalletPhoneMagicCode';
14-
import WalletMagicCodePrompt from '@pages/EnablePayments/shared/WalletMagicCodePrompt';
1512
import getInitialSubstepForPersonalInfo from '@pages/EnablePayments/Wallet/utils/getInitialSubstepForPersonalInfo';
1613
import getSubstepValues from '@pages/EnablePayments/Wallet/utils/getSubstepValues';
1714

@@ -23,7 +20,7 @@ import ONYXKEYS from '@src/ONYXKEYS';
2320
import ROUTES from '@src/ROUTES';
2421
import INPUT_IDS from '@src/types/form/WalletAdditionalDetailsForm';
2522

26-
import React, {useMemo} from 'react';
23+
import {useMemo} from 'react';
2724

2825
import Address from './substeps/AddressStep';
2926
import Confirmation from './substeps/ConfirmationStep';
@@ -52,23 +49,12 @@ function PersonalInfoPage() {
5249

5350
const showIdologyQuestions = walletAdditionalDetails?.questions && walletAdditionalDetails?.questions.length > 0;
5451

55-
const {isMagicCodeRequired, submitPersonalDetails, confirmPersonalDetailsWithMagicCode, closeMagicCodePrompt} = useWalletPhoneMagicCode();
52+
const {submitPersonalDetails} = useWalletPhoneMagicCode();
5653

5754
const values = useMemo(() => getSubstepValues(PERSONAL_INFO_STEP_KEYS, walletAdditionalDetailsDraft, walletAdditionalDetails), [walletAdditionalDetails, walletAdditionalDetailsDraft]);
5855

5956
const submit = () => {
60-
const personalDetails: UpdatePersonalDetailsForWalletParams = {
61-
phoneNumber: (values.phoneNumber && parsePhoneNumber(values.phoneNumber, {regionCode: CONST.COUNTRY.US}).number?.significant) ?? '',
62-
legalFirstName: values?.[PERSONAL_INFO_STEP_KEYS.FIRST_NAME] ?? '',
63-
legalLastName: values?.[PERSONAL_INFO_STEP_KEYS.LAST_NAME] ?? '',
64-
addressStreet: values?.[PERSONAL_INFO_STEP_KEYS.STREET] ?? '',
65-
addressCity: values?.[PERSONAL_INFO_STEP_KEYS.CITY] ?? '',
66-
addressState: values?.[PERSONAL_INFO_STEP_KEYS.STATE] ?? '',
67-
addressZip: values?.[PERSONAL_INFO_STEP_KEYS.ZIP_CODE] ?? '',
68-
dob: values?.[PERSONAL_INFO_STEP_KEYS.DOB] ?? '',
69-
ssn: values?.[PERSONAL_INFO_STEP_KEYS.SSN_LAST_4] ?? '',
70-
};
71-
submitPersonalDetails(personalDetails);
57+
submitPersonalDetails(getWalletPersonalDetailsParams(values));
7258
};
7359

7460
const startFrom = useMemo(() => getInitialSubstepForPersonalInfo(values), [values]);
@@ -108,15 +94,6 @@ function PersonalInfoPage() {
10894
return <FullScreenLoadingIndicator reasonAttributes={{context: 'EnablePaymentsPersonalInfo', isRedirecting}} />;
10995
}
11096

111-
if (isMagicCodeRequired) {
112-
return (
113-
<WalletMagicCodePrompt
114-
onConfirm={confirmPersonalDetailsWithMagicCode}
115-
onClose={closeMagicCodePrompt}
116-
/>
117-
);
118-
}
119-
12097
return (
12198
<InteractiveStepWrapper
12299
wrapperID="PersonalInfoPage"
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import useOnyx from '@hooks/useOnyx';
2+
3+
import Navigation from '@libs/Navigation/Navigation';
4+
5+
import getSubstepValues from '@pages/EnablePayments/Wallet/utils/getSubstepValues';
6+
7+
import {clearWalletAdditionalDetailsErrors, updatePersonalDetails} from '@userActions/Wallet';
8+
9+
import CONST from '@src/CONST';
10+
import ONYXKEYS from '@src/ONYXKEYS';
11+
import ROUTES from '@src/ROUTES';
12+
import INPUT_IDS from '@src/types/form/WalletAdditionalDetailsForm';
13+
import {isEmptyObject} from '@src/types/utils/EmptyObject';
14+
15+
import {useEffect, useRef} from 'react';
16+
17+
import getWalletPersonalDetailsParams from './getWalletPersonalDetailsParams';
18+
import WalletMagicCodePrompt from './WalletMagicCodePrompt';
19+
20+
const PERSONAL_INFO_STEP_KEYS = INPUT_IDS.PERSONAL_INFO_STEP;
21+
22+
/**
23+
* Dedicated screen for entering the magic code that authorizes a wallet phone-number change. Living on its own route
24+
* (rather than being rendered inline in the step page) keeps the code form stably mounted, so a wrong-code error is
25+
* not wiped by a remount while the submission response settles.
26+
*/
27+
function WalletConfirmMagicCodePage() {
28+
const [walletAdditionalDetails] = useOnyx(ONYXKEYS.WALLET_ADDITIONAL_DETAILS);
29+
const [walletAdditionalDetailsDraft] = useOnyx(ONYXKEYS.FORMS.WALLET_ADDITIONAL_DETAILS_DRAFT);
30+
const [formData] = useOnyx(ONYXKEYS.FORMS.WALLET_ADDITIONAL_DETAILS);
31+
32+
// The submitted details live in the form draft, so rebuild them here and submit together with the entered code.
33+
const values = getSubstepValues(PERSONAL_INFO_STEP_KEYS, walletAdditionalDetailsDraft, walletAdditionalDetails);
34+
const personalDetails = getWalletPersonalDetailsParams(values);
35+
36+
const confirm = (validateCode: string) => {
37+
updatePersonalDetails({...personalDetails, validateCode});
38+
};
39+
40+
useEffect(
41+
() => () => {
42+
clearWalletAdditionalDetailsErrors();
43+
},
44+
[],
45+
);
46+
47+
const hasErrors = !!walletAdditionalDetails?.errorCode || !isEmptyObject(walletAdditionalDetails?.errors);
48+
49+
const wasLoading = useRef(false);
50+
useEffect(() => {
51+
if (formData?.isLoading) {
52+
wasLoading.current = true;
53+
return;
54+
}
55+
// Once a submission finishes cleanly the code was accepted, so advance to the identity-verification step;
56+
// EnablePaymentsPage corrects the URL if the real next step differs (e.g. KBA questions). Any error (incorrect
57+
// code, SSN, or a generic failure) keeps the screen open to retry.
58+
if (wasLoading.current && !hasErrors) {
59+
wasLoading.current = false;
60+
Navigation.navigate(ROUTES.SETTINGS_ENABLE_PAYMENTS.getRoute({page: CONST.ENABLE_PAYMENTS.PAGE_NAMES.VERIFY_IDENTITY}));
61+
}
62+
wasLoading.current = false;
63+
}, [formData?.isLoading, hasErrors]);
64+
65+
return (
66+
<WalletMagicCodePrompt
67+
onConfirm={confirm}
68+
onClose={() => Navigation.goBack()}
69+
/>
70+
);
71+
}
72+
73+
WalletConfirmMagicCodePage.displayName = 'WalletConfirmMagicCodePage';
74+
75+
export default WalletConfirmMagicCodePage;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import type {UpdatePersonalDetailsForWalletParams} from '@libs/API/parameters';
2+
import {parsePhoneNumber} from '@libs/PhoneNumber';
3+
4+
import CONST from '@src/CONST';
5+
import type {PersonalInfoStepProps} from '@src/types/form/WalletAdditionalDetailsForm';
6+
7+
/**
8+
* Builds the wallet personal-details API params from the collected form values. Shared by the personal-info and
9+
* additional-details flows and by the magic-code confirmation screen so the phone-change check and the
10+
* code submission always build identical params. The phone number is normalized to significant digits to match how
11+
* the backend stores it.
12+
*/
13+
function getWalletPersonalDetailsParams(values: PersonalInfoStepProps): UpdatePersonalDetailsForWalletParams {
14+
return {
15+
phoneNumber: (values.phoneNumber && parsePhoneNumber(values.phoneNumber, {regionCode: CONST.COUNTRY.US}).number?.significant) ?? '',
16+
legalFirstName: values.legalFirstName ?? '',
17+
legalLastName: values.legalLastName ?? '',
18+
addressStreet: values.addressStreet ?? '',
19+
addressCity: values.addressCity ?? '',
20+
addressState: values.addressState ?? '',
21+
addressZip: values.addressZipCode ?? '',
22+
dob: values.dob ?? '',
23+
ssn: values.ssn ?? '',
24+
};
25+
}
26+
27+
export default getWalletPersonalDetailsParams;

0 commit comments

Comments
 (0)