diff --git a/src/components/MenuItem.tsx b/src/components/MenuItem.tsx index 96e6ea0bbc44..a2f33b0527f1 100644 --- a/src/components/MenuItem.tsx +++ b/src/components/MenuItem.tsx @@ -84,7 +84,7 @@ type MenuItemProps = (ResponsiveProps | UnresponsiveProps) & titleStyle?: ViewStyle; /** Any adjustments to style when menu item is hovered or pressed */ - hoverAndPressStyle: StyleProp>; + hoverAndPressStyle?: StyleProp>; /** Additional styles to style the description text below the title */ descriptionTextStyle?: StyleProp; @@ -174,7 +174,7 @@ type MenuItemProps = (ResponsiveProps | UnresponsiveProps) & isSelected?: boolean; /** Prop to identify if we should load avatars vertically instead of diagonally */ - shouldStackHorizontally: boolean; + shouldStackHorizontally?: boolean; /** Prop to represent the size of the avatar images to be shown */ avatarSize?: (typeof CONST.AVATAR_SIZE)[keyof typeof CONST.AVATAR_SIZE]; @@ -219,10 +219,10 @@ type MenuItemProps = (ResponsiveProps | UnresponsiveProps) & furtherDetails?: string; /** The function that should be called when this component is LongPressed or right-clicked. */ - onSecondaryInteraction: () => void; + onSecondaryInteraction?: () => void; /** Array of objects that map display names to their corresponding tooltip */ - titleWithTooltips: DisplayNameWithTooltip[]; + titleWithTooltips?: DisplayNameWithTooltip[]; }; function MenuItem( diff --git a/src/hooks/useSubStep.ts b/src/hooks/useSubStep/index.ts similarity index 86% rename from src/hooks/useSubStep.ts rename to src/hooks/useSubStep/index.ts index 18519ba5b343..08a9089148b9 100644 --- a/src/hooks/useSubStep.ts +++ b/src/hooks/useSubStep/index.ts @@ -1,12 +1,7 @@ -import {ReactNode, useCallback, useRef, useState} from 'react'; +import {useCallback, useRef, useState} from 'react'; +import {UseSubStep} from './types'; -type Props = { - bodyContent: ReactNode[]; - onFinished: () => void; - startFrom?: number; -}; - -export default function useSubStep({bodyContent, onFinished, startFrom = 0}: Props) { +export default function useSubStep({bodyContent, onFinished, startFrom = 0}: UseSubStep) { const [screenIndex, setScreenIndex] = useState(startFrom); const isEditing = useRef(false); diff --git a/src/hooks/useSubStep/types.ts b/src/hooks/useSubStep/types.ts new file mode 100644 index 000000000000..a039cad3a23b --- /dev/null +++ b/src/hooks/useSubStep/types.ts @@ -0,0 +1,31 @@ +import {ComponentType} from 'react'; + +type SubStepProps = { + /** value indicating whether user is editing one of the sub steps */ + isEditing: boolean; + + /** continues to next sub step */ + onNext: () => void; + + /** moves user to passed sub step */ + onMove: (step: number) => void; + + /** index of currently displayed sub step */ + screenIndex?: number; + + /** moves user to previous sub step */ + prevScreen?: () => void; +}; + +type UseSubStep = { + /** array of components that will become sub steps */ + bodyContent: Array>; + + /** called on last sub step */ + onFinished: () => void; + + /** index of initial sub step to display */ + startFrom?: number; +}; + +export type {SubStepProps, UseSubStep}; diff --git a/src/libs/actions/BankAccounts.ts b/src/libs/actions/BankAccounts.ts index 2d0b7d4dfa8b..01b26223e495 100644 --- a/src/libs/actions/BankAccounts.ts +++ b/src/libs/actions/BankAccounts.ts @@ -41,6 +41,8 @@ type ReimbursementAccountStep = BankAccountStep | ''; type ReimbursementAccountSubStep = BankAccountSubStep | ''; +type PlaidBankAccountToConnect = Omit; + function clearPlaid(): Promise { Onyx.set(ONYXKEYS.PLAID_LINK_TOKEN, ''); Onyx.set(ONYXKEYS.PLAID_CURRENT_EVENT, null); @@ -142,7 +144,7 @@ function addPersonalAddressForDraft(personalAddress: {requestorAddressStreet?: s /** * Submit Bank Account step with Plaid data so php can perform some checks. */ -function connectBankAccountWithPlaid(bankAccountID: number, selectedPlaidBankAccount: PlaidBankAccount) { +function connectBankAccountWithPlaid(bankAccountID: number, selectedPlaidBankAccount: PlaidBankAccountToConnect) { const commandName = 'ConnectBankAccountWithPlaid'; type ConnectBankAccountWithPlaidParams = { diff --git a/src/libs/actions/ReimbursementAccount/index.js b/src/libs/actions/ReimbursementAccount/index.js index 0404115f086b..da55a73ae6e6 100644 --- a/src/libs/actions/ReimbursementAccount/index.js +++ b/src/libs/actions/ReimbursementAccount/index.js @@ -12,7 +12,7 @@ export {setBankAccountFormValidationErrors, setPersonalBankAccountFormValidation * - CONST.BANK_ACCOUNT.SETUP_TYPE.MANUAL to ask them to enter their accountNumber and routingNumber * - CONST.BANK_ACCOUNT.SETUP_TYPE.PLAID to ask them to login to their bank via Plaid * - * @param {String} subStep + * @param {String | null} subStep */ function setBankAccountSubStep(subStep) { Onyx.merge(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {achData: {subStep}}); diff --git a/src/pages/ReimbursementAccount/BankAccountManualStep.js b/src/pages/ReimbursementAccount/BankAccountManualStep.js deleted file mode 100644 index 8e79a492bfe3..000000000000 --- a/src/pages/ReimbursementAccount/BankAccountManualStep.js +++ /dev/null @@ -1,146 +0,0 @@ -import lodashGet from 'lodash/get'; -import React, {useCallback} from 'react'; -import _ from 'underscore'; -import CheckboxWithLabel from '@components/CheckboxWithLabel'; -import FormProvider from '@components/Form/FormProvider'; -import InputWrapper from '@components/Form/InputWrapper'; -import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import ScreenWrapper from '@components/ScreenWrapper'; -import Text from '@components/Text'; -import TextInput from '@components/TextInput'; -import TextLink from '@components/TextLink'; -import {withLocalizePropTypes} from '@components/withLocalize'; -import useLocalize from '@hooks/useLocalize'; -import useThemeStyles from '@hooks/useThemeStyles'; -import shouldDelayFocus from '@libs/shouldDelayFocus'; -import * as ValidationUtils from '@libs/ValidationUtils'; -import * as BankAccounts from '@userActions/BankAccounts'; -import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; -import ExampleCheck from './ExampleCheck'; -import StepPropTypes from './StepPropTypes'; - -const propTypes = { - ..._.omit(StepPropTypes, _.keys(withLocalizePropTypes)), -}; - -function BankAccountManualStep(props) { - const styles = useThemeStyles(); - const {translate} = useLocalize(); - const {reimbursementAccount, reimbursementAccountDraft} = props; - - const shouldDisableInputs = Boolean(lodashGet(reimbursementAccount, 'achData.bankAccountID')); - - /** - * @param {Object} values - form input values passed by the Form component - * @returns {Object} - */ - const validate = useCallback( - (values) => { - const requiredFields = ['routingNumber', 'accountNumber']; - const errors = ValidationUtils.getFieldRequiredErrors(values, requiredFields); - const routingNumber = values.routingNumber && values.routingNumber.trim(); - - if ( - values.accountNumber && - !CONST.BANK_ACCOUNT.REGEX.US_ACCOUNT_NUMBER.test(values.accountNumber.trim()) && - !(shouldDisableInputs && CONST.BANK_ACCOUNT.REGEX.MASKED_US_ACCOUNT_NUMBER.test(values.accountNumber.trim())) - ) { - errors.accountNumber = 'bankAccount.error.accountNumber'; - } else if (values.accountNumber && values.accountNumber === routingNumber) { - errors.accountNumber = translate('bankAccount.error.routingAndAccountNumberCannotBeSame'); - } - if (routingNumber && (!CONST.BANK_ACCOUNT.REGEX.SWIFT_BIC.test(routingNumber) || !ValidationUtils.isValidRoutingNumber(routingNumber))) { - errors.routingNumber = 'bankAccount.error.routingNumber'; - } - if (!values.acceptTerms) { - errors.acceptTerms = 'common.error.acceptTerms'; - } - - return errors; - }, - [translate, shouldDisableInputs], - ); - - const submit = useCallback( - (values) => { - BankAccounts.connectBankAccountManually( - lodashGet(reimbursementAccount, 'achData.bankAccountID') || 0, - values.accountNumber, - values.routingNumber, - lodashGet(reimbursementAccountDraft, ['plaidMask']), - ); - }, - [reimbursementAccount, reimbursementAccountDraft], - ); - - return ( - - - - {translate('bankAccount.checkHelpLine')} - - - - ( - - {translate('common.iAcceptThe')} - {translate('common.expensifyTermsOfService')} - - )} - defaultValue={props.getDefaultStateForField('acceptTerms', false)} - shouldSaveDraft - /> - - - ); -} - -BankAccountManualStep.propTypes = propTypes; -BankAccountManualStep.displayName = 'BankAccountManualStep'; -export default BankAccountManualStep; diff --git a/src/pages/ReimbursementAccount/BankAccountPlaidStep.js b/src/pages/ReimbursementAccount/BankAccountPlaidStep.js deleted file mode 100644 index c235a31f626f..000000000000 --- a/src/pages/ReimbursementAccount/BankAccountPlaidStep.js +++ /dev/null @@ -1,156 +0,0 @@ -import {useIsFocused} from '@react-navigation/native'; -import lodashGet from 'lodash/get'; -import PropTypes from 'prop-types'; -import React, {useCallback, useEffect} from 'react'; -import {withOnyx} from 'react-native-onyx'; -import _ from 'underscore'; -import AddPlaidBankAccount from '@components/AddPlaidBankAccount'; -import CheckboxWithLabel from '@components/CheckboxWithLabel'; -import FormProvider from '@components/Form/FormProvider'; -import InputWrapper from '@components/Form/InputWrapper'; -import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import ScreenWrapper from '@components/ScreenWrapper'; -import Text from '@components/Text'; -import TextLink from '@components/TextLink'; -import withLocalize from '@components/withLocalize'; -import useThemeStyles from '@hooks/useThemeStyles'; -import compose from '@libs/compose'; -import * as BankAccounts from '@userActions/BankAccounts'; -import * as ReimbursementAccount from '@userActions/ReimbursementAccount'; -import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; -import * as PlaidDataProps from './plaidDataPropTypes'; -import StepPropTypes from './StepPropTypes'; - -const propTypes = { - ...StepPropTypes, - - /** Contains plaid data */ - plaidData: PlaidDataProps.plaidDataPropTypes, - - /** The OAuth URI + stateID needed to re-initialize the PlaidLink after the user logs into their bank */ - receivedRedirectURI: PropTypes.string, - - /** During the OAuth flow we need to use the plaidLink token that we initially connected with */ - plaidLinkOAuthToken: PropTypes.string, -}; - -const defaultProps = { - plaidData: PlaidDataProps.plaidDataDefaultProps, - receivedRedirectURI: null, - plaidLinkOAuthToken: '', -}; - -function BankAccountPlaidStep(props) { - const styles = useThemeStyles(); - const {plaidData, receivedRedirectURI, plaidLinkOAuthToken, reimbursementAccount, reimbursementAccountDraft, onBackButtonPress, getDefaultStateForField, translate} = props; - const isFocused = useIsFocused(); - - const validate = useCallback((values) => { - const errorFields = {}; - if (!values.acceptTerms) { - errorFields.acceptTerms = 'common.error.acceptTerms'; - } - - return errorFields; - }, []); - - useEffect(() => { - const plaidBankAccounts = lodashGet(plaidData, 'bankAccounts') || []; - if (isFocused || plaidBankAccounts.length) { - return; - } - BankAccounts.setBankAccountSubStep(null); - }, [isFocused, plaidData]); - - const submit = useCallback(() => { - const selectedPlaidBankAccount = _.findWhere(lodashGet(plaidData, 'bankAccounts', []), { - plaidAccountID: lodashGet(reimbursementAccountDraft, 'plaidAccountID', ''), - }); - - const bankAccountData = { - routingNumber: selectedPlaidBankAccount.routingNumber, - accountNumber: selectedPlaidBankAccount.accountNumber, - plaidMask: selectedPlaidBankAccount.mask, - isSavings: selectedPlaidBankAccount.isSavings, - bankName: lodashGet(plaidData, 'bankName') || '', - plaidAccountID: selectedPlaidBankAccount.plaidAccountID, - plaidAccessToken: lodashGet(plaidData, 'plaidAccessToken') || '', - }; - ReimbursementAccount.updateReimbursementAccountDraft(bankAccountData); - - const bankAccountID = lodashGet(reimbursementAccount, 'achData.bankAccountID') || 0; - BankAccounts.connectBankAccountWithPlaid(bankAccountID, bankAccountData); - }, [reimbursementAccount, reimbursementAccountDraft, plaidData]); - - const bankAccountID = lodashGet(reimbursementAccount, 'achData.bankAccountID') || 0; - const selectedPlaidAccountID = lodashGet(reimbursementAccountDraft, 'plaidAccountID', ''); - - return ( - - - - { - ReimbursementAccount.updateReimbursementAccountDraft({plaidAccountID}); - }} - plaidData={plaidData} - onExitPlaid={() => BankAccounts.setBankAccountSubStep(null)} - receivedRedirectURI={receivedRedirectURI} - plaidLinkOAuthToken={plaidLinkOAuthToken} - allowDebit - bankAccountID={bankAccountID} - selectedPlaidAccountID={selectedPlaidAccountID} - /> - {Boolean(selectedPlaidAccountID) && !_.isEmpty(lodashGet(plaidData, 'bankAccounts')) && ( - ( - - {translate('common.iAcceptThe')} - {translate('common.expensifyTermsOfService')} - - )} - defaultValue={getDefaultStateForField('acceptTerms', false)} - shouldSaveDraft - /> - )} - - - ); -} - -BankAccountPlaidStep.propTypes = propTypes; -BankAccountPlaidStep.defaultProps = defaultProps; -BankAccountPlaidStep.displayName = 'BankAccountPlaidStep'; -export default compose( - withLocalize, - withOnyx({ - plaidData: { - key: ONYXKEYS.PLAID_DATA, - }, - }), -)(BankAccountPlaidStep); diff --git a/src/pages/ReimbursementAccount/BankAccountStep.js b/src/pages/ReimbursementAccount/BankAccountStep.js index cab656e1268b..21b2ee991be1 100644 --- a/src/pages/ReimbursementAccount/BankAccountStep.js +++ b/src/pages/ReimbursementAccount/BankAccountStep.js @@ -28,8 +28,6 @@ import CONFIG from '@src/CONFIG'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import BankAccountManualStep from './BankAccountManualStep'; -import BankAccountPlaidStep from './BankAccountPlaidStep'; import BankInfo from './BankInfo/BankInfo'; import StepPropTypes from './StepPropTypes'; @@ -101,29 +99,6 @@ function BankAccountStep(props) { return ; } - if (subStep === CONST.BANK_ACCOUNT.SETUP_TYPE.MANUAL) { - return ( - - ); - } - - if (subStep === CONST.BANK_ACCOUNT.SETUP_TYPE.PLAID) { - return ( - - ); - } - - // TODO Move initial screen where you select setup type to new ReimbursementAccount page as the begining of whole flow; also cleanup once this is done return ( ; /** Reimbursement account from ONYX */ - reimbursementAccount: reimbursementAccountPropTypes, + reimbursementAccount: OnyxEntry; /** The draft values of the bank account being setup */ - reimbursementAccountDraft: reimbursementAccountDraftPropTypes, + reimbursementAccountDraft: OnyxEntry; }; -const defaultProps = { - plaidLinkToken: '', - reimbursementAccount: ReimbursementAccountProps.reimbursementAccountDefaultProps, - reimbursementAccountDraft: {}, -}; +type BankInfoProps = BankInfoOnyxProps; const bankInfoStepKeys = CONST.BANK_ACCOUNT.BANK_INFO_STEP.INPUT_KEY; -const manualSubsteps = [Manual, Confirmation]; -const plaidSubsteps = [Plaid, Confirmation]; +const manualSubsteps: Array> = [Manual, Confirmation]; +const plaidSubsteps: Array> = [Plaid, Confirmation]; const receivedRedirectURI = getPlaidOAuthReceivedRedirectURI(); -function BankInfo({reimbursementAccount, reimbursementAccountDraft, plaidLinkToken}) { +function BankInfo({reimbursementAccount, reimbursementAccountDraft, plaidLinkToken}: BankInfoProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const [redirectedFromPlaidToManual, setRedirectedFromPlaidToManual] = React.useState(false); - const values = useMemo(() => getSubstepValues(bankInfoStepKeys, reimbursementAccountDraft, reimbursementAccount), [reimbursementAccount, reimbursementAccountDraft]); + const values = useMemo(() => getSubstepValues(bankInfoStepKeys, reimbursementAccountDraft ?? {}, reimbursementAccount ?? {}), [reimbursementAccount, reimbursementAccountDraft]); - let setupType = getDefaultValueForReimbursementAccountField(reimbursementAccount, 'subStep'); + let setupType = reimbursementAccount?.achData?.subStep ?? ''; const shouldReinitializePlaidLink = plaidLinkToken && receivedRedirectURI && setupType !== CONST.BANK_ACCOUNT.SUBSTEP.MANUAL; if (shouldReinitializePlaidLink) { @@ -60,20 +54,18 @@ function BankInfo({reimbursementAccount, reimbursementAccountDraft, plaidLinkTok const submit = useCallback(() => { if (setupType === CONST.BANK_ACCOUNT.SETUP_TYPE.MANUAL) { BankAccounts.connectBankAccountManually( - Number(getDefaultValueForReimbursementAccountField(reimbursementAccount, bankInfoStepKeys.BANK_ACCOUNT_ID, '0')), + Number(reimbursementAccount?.achData?.[bankInfoStepKeys.BANK_ACCOUNT_ID] ?? '0'), values[bankInfoStepKeys.ACCOUNT_NUMBER], values[bankInfoStepKeys.ROUTING_NUMBER], values[bankInfoStepKeys.PLAID_MASK], ); } else if (setupType === CONST.BANK_ACCOUNT.SETUP_TYPE.PLAID) { - BankAccounts.connectBankAccountWithPlaid(Number(getDefaultValueForReimbursementAccountField(reimbursementAccount, bankInfoStepKeys.BANK_ACCOUNT_ID, '0')), { - [bankInfoStepKeys.ROUTING_NUMBER]: values[bankInfoStepKeys.ROUTING_NUMBER], - [bankInfoStepKeys.ACCOUNT_NUMBER]: values[bankInfoStepKeys.ACCOUNT_NUMBER], - [bankInfoStepKeys.PLAID_MASK]: values[bankInfoStepKeys.PLAID_MASK], - [bankInfoStepKeys.IS_SAVINGS]: values[bankInfoStepKeys.IS_SAVINGS], - [bankInfoStepKeys.BANK_NAME]: values[bankInfoStepKeys.BANK_NAME], - [bankInfoStepKeys.PLAID_ACCOUNT_ID]: values[bankInfoStepKeys.PLAID_ACCOUNT_ID], - [bankInfoStepKeys.PLAID_ACCESS_TOKEN]: values[bankInfoStepKeys.PLAID_ACCESS_TOKEN], + BankAccounts.connectBankAccountWithPlaid(Number(reimbursementAccount?.achData?.[bankInfoStepKeys.BANK_ACCOUNT_ID] ?? '0'), { + [bankInfoStepKeys.ROUTING_NUMBER]: values[bankInfoStepKeys.ROUTING_NUMBER] ?? '', + [bankInfoStepKeys.ACCOUNT_NUMBER]: values[bankInfoStepKeys.ACCOUNT_NUMBER] ?? '', + [bankInfoStepKeys.BANK_NAME]: values[bankInfoStepKeys.BANK_NAME] ?? '', + [bankInfoStepKeys.PLAID_ACCOUNT_ID]: values[bankInfoStepKeys.PLAID_ACCOUNT_ID] ?? '', + [bankInfoStepKeys.PLAID_ACCESS_TOKEN]: values[bankInfoStepKeys.PLAID_ACCESS_TOKEN] ?? '', }); } }, [reimbursementAccount, setupType, values]); @@ -89,7 +81,7 @@ function BankInfo({reimbursementAccount, reimbursementAccountDraft, plaidLinkTok return; } - if (setupType === CONST.BANK_ACCOUNT.SETUP_TYPE.MANUAL && values[bankInfoStepKeys.BANK_NAME] !== '' && !redirectedFromPlaidToManual) { + if (setupType === CONST.BANK_ACCOUNT.SETUP_TYPE.MANUAL && values.bankName !== '' && !redirectedFromPlaidToManual) { setRedirectedFromPlaidToManual(true); moveTo(0); } @@ -97,7 +89,6 @@ function BankInfo({reimbursementAccount, reimbursementAccountDraft, plaidLinkTok const handleBackButtonPress = () => { if (screenIndex === 0) { - // TODO replace it with navigation to ReimbursementAccountPage once base is updated BankAccounts.setBankAccountSubStep(null); } else { prevScreen(); @@ -105,6 +96,7 @@ function BankInfo({reimbursementAccount, reimbursementAccountDraft, plaidLinkTok }; return ( + // @ts-expect-error TODO: Remove this once ScreenWrapper (https://github.com/Expensify/App/issues/25128) is migrated to TypeScript. ({ reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/BankInfo/substeps/Confirmation.js b/src/pages/ReimbursementAccount/BankInfo/substeps/Confirmation.tsx similarity index 80% rename from src/pages/ReimbursementAccount/BankInfo/substeps/Confirmation.js rename to src/pages/ReimbursementAccount/BankInfo/substeps/Confirmation.tsx index e7482648c8f4..287e18fb02d0 100644 --- a/src/pages/ReimbursementAccount/BankInfo/substeps/Confirmation.js +++ b/src/pages/ReimbursementAccount/BankInfo/substeps/Confirmation.tsx @@ -1,7 +1,7 @@ -import lodashGet from 'lodash/get'; import React, {useMemo} from 'react'; import {ScrollView, Text, View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; +import {OnyxEntry} from 'react-native-onyx/lib/types'; import Button from '@components/Button'; import DotIndicatorMessage from '@components/DotIndicatorMessage'; import Icon from '@components/Icon'; @@ -9,46 +9,38 @@ import * as Expensicons from '@components/Icon/Expensicons'; import MenuItem from '@components/MenuItem'; import ScreenWrapper from '@components/ScreenWrapper'; import useLocalize from '@hooks/useLocalize'; +import {SubStepProps} from '@hooks/useSubStep/types'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ErrorUtils from '@libs/ErrorUtils'; -import reimbursementAccountDraftPropTypes from '@pages/ReimbursementAccount/ReimbursementAccountDraftPropTypes'; -import {reimbursementAccountPropTypes} from '@pages/ReimbursementAccount/reimbursementAccountPropTypes'; -import * as ReimbursementAccountProps from '@pages/ReimbursementAccount/reimbursementAccountPropTypes'; -import subStepPropTypes from '@pages/ReimbursementAccount/subStepPropTypes'; -import getDefaultValueForReimbursementAccountField from '@pages/ReimbursementAccount/utils/getDefaultValueForReimbursementAccountField'; import getSubstepValues from '@pages/ReimbursementAccount/utils/getSubstepValues'; import * as BankAccounts from '@userActions/BankAccounts'; import * as ReimbursementAccount from '@userActions/ReimbursementAccount'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import * as OnyxTypes from '@src/types/onyx'; -const propTypes = { +type ConfirmationOnyxProps = { /** Reimbursement account from ONYX */ - reimbursementAccount: reimbursementAccountPropTypes, + reimbursementAccount: OnyxEntry; /** The draft values of the bank account being setup */ - reimbursementAccountDraft: reimbursementAccountDraftPropTypes, - - ...subStepPropTypes, + reimbursementAccountDraft: OnyxEntry; }; -const defaultProps = { - reimbursementAccount: ReimbursementAccountProps.reimbursementAccountDefaultProps, - reimbursementAccountDraft: {}, -}; +type ConfirmationProps = ConfirmationOnyxProps & SubStepProps; const bankInfoStepKeys = CONST.BANK_ACCOUNT.BANK_INFO_STEP.INPUT_KEY; -function Confirmation({reimbursementAccount, reimbursementAccountDraft, onNext}) { +function Confirmation({reimbursementAccount, reimbursementAccountDraft, onNext}: ConfirmationProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const theme = useTheme(); - const isLoading = lodashGet(reimbursementAccount, 'isLoading', false); - const setupType = getDefaultValueForReimbursementAccountField(reimbursementAccount, 'subStep'); - const values = useMemo(() => getSubstepValues(bankInfoStepKeys, reimbursementAccountDraft, reimbursementAccount), [reimbursementAccount, reimbursementAccountDraft]); - const error = ErrorUtils.getLatestErrorMessage(reimbursementAccount); + const isLoading = reimbursementAccount?.isLoading ?? false; + const setupType = reimbursementAccount?.achData?.subStep ?? ''; + const values = useMemo(() => getSubstepValues(bankInfoStepKeys, reimbursementAccountDraft ?? {}, reimbursementAccount ?? {}), [reimbursementAccount, reimbursementAccountDraft]); + const error = ErrorUtils.getLatestErrorMessage(reimbursementAccount ?? {}); const handleConnectDifferentAccount = () => { const bankAccountData = { @@ -66,6 +58,7 @@ function Confirmation({reimbursementAccount, reimbursementAccountDraft, onNext}) }; return ( + // @ts-expect-error TODO: Remove this once ScreenWrapper (https://github.com/Expensify/App/issues/25128) is migrated to TypeScript. )} {translate('bankAccount.thisBankAccount')} )}