Skip to content

Commit

Permalink
Merge pull request #31121 from MrMuzyk/michal/bank-info-screen
Browse files Browse the repository at this point in the history
  • Loading branch information
mountiny authored Nov 17, 2023
2 parents ab237f5 + 42ae28e commit 57da62e
Show file tree
Hide file tree
Showing 34 changed files with 784 additions and 121 deletions.
14 changes: 14 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,21 @@ const CONST = {
DOMAIN: '@expensify.sms',
},
BANK_ACCOUNT: {
BANK_INFO_STEP: {
INPUT_KEY: {
BANK_ACCOUNT_ID: 'bankAccountID',
ROUTING_NUMBER: 'routingNumber',
ACCOUNT_NUMBER: 'accountNumber',
PLAID_MASK: 'plaidMask',
IS_SAVINGS: 'isSavings',
BANK_NAME: 'bankName',
PLAID_ACCOUNT_ID: 'plaidAccountID',
PLAID_ACCESS_TOKEN: 'plaidAccessToken',
},
},
PERSONAL_INFO_STEP: {
INPUT_KEY: {
BANK_ACCOUNT_ID: 'bankAccountID',
FIRST_NAME: 'firstName',
LAST_NAME: 'lastName',
DOB: 'dob',
Expand Down Expand Up @@ -223,6 +236,7 @@ const CONST = {
},
SUBSTEP: {
MANUAL: 'manual',
PLAID: 'plaid',
},
VERIFICATIONS: {
ERROR_MESSAGE: 'verifications.errorMessage',
Expand Down
59 changes: 56 additions & 3 deletions src/components/AddPlaidBankAccount.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import lodashGet from 'lodash/get';
import PropTypes from 'prop-types';
import React, {useCallback, useEffect, useRef} from 'react';
import React, {useCallback, useEffect, useRef, useState} from 'react';
import {ActivityIndicator, View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import _ from 'underscore';
Expand All @@ -20,6 +20,7 @@ import Icon from './Icon';
import getBankIcon from './Icon/BankIcons';
import Picker from './Picker';
import PlaidLink from './PlaidLink';
import RadioButtons from './RadioButtons';
import Text from './Text';

const propTypes = {
Expand Down Expand Up @@ -55,6 +56,9 @@ const propTypes = {

/** Are we adding a withdrawal account? */
allowDebit: PropTypes.bool,

/** Is displayed in new VBBA */
isDisplayedInNewVBBA: PropTypes.bool,
};

const defaultProps = {
Expand All @@ -68,6 +72,7 @@ const defaultProps = {
allowDebit: false,
bankAccountID: 0,
isPlaidDisabled: false,
isDisplayedInNewVBBA: false,
};

function AddPlaidBankAccount({
Expand All @@ -82,11 +87,21 @@ function AddPlaidBankAccount({
bankAccountID,
allowDebit,
isPlaidDisabled,
isDisplayedInNewVBBA,
}) {
const theme = useTheme();
const styles = useThemeStyles();
const plaidBankAccounts = lodashGet(plaidData, 'bankAccounts', []);
const defaultSelectedPlaidAccount = _.find(plaidBankAccounts, (account) => account.plaidAccountID === selectedPlaidAccountID);
const defaultSelectedPlaidAccountID = lodashGet(defaultSelectedPlaidAccount, 'plaidAccountID', '');
const defaultSelectedPlaidAccountMask = lodashGet(
_.find(plaidBankAccounts, (account) => account.plaidAccountID === selectedPlaidAccountID),
'mask',
'',
);
const subscribedKeyboardShortcuts = useRef([]);
const previousNetworkState = useRef();
const [selectedPlaidAccountMask, setSelectedPlaidAccountMask] = useState(defaultSelectedPlaidAccountMask);

const {translate} = useLocalize();
const {isOffline} = useNetwork();
Expand Down Expand Up @@ -162,17 +177,27 @@ function AddPlaidBankAccount({
previousNetworkState.current = isOffline;
}, [allowDebit, bankAccountID, isAuthenticatedWithPlaid, isOffline]);

const plaidBankAccounts = lodashGet(plaidData, 'bankAccounts') || [];
const token = getPlaidLinkToken();
const options = _.map(plaidBankAccounts, (account) => ({
value: account.plaidAccountID,
label: `${account.addressName} ${account.mask}`,
label: account.addressName,
}));
const {icon, iconSize, iconStyles} = getBankIcon();
const plaidErrors = lodashGet(plaidData, 'errors');
const plaidDataErrorMessage = !_.isEmpty(plaidErrors) ? _.chain(plaidErrors).values().first().value() : '';
const bankName = lodashGet(plaidData, 'bankName');

/**
* @param {String} plaidAccountID
*
* When user selects one of plaid accounts we need to set the mask in order to display it on UI
*/
const handleSelectingPlaidAccount = (plaidAccountID) => {
const mask = _.find(plaidBankAccounts, (account) => account.plaidAccountID === plaidAccountID).mask;
setSelectedPlaidAccountMask(mask);
onSelect(plaidAccountID);
};

if (isPlaidDisabled) {
return (
<View>
Expand Down Expand Up @@ -229,6 +254,34 @@ function AddPlaidBankAccount({
);
}

if (isDisplayedInNewVBBA) {
return (
<FullPageOfflineBlockingView>
<Text style={[styles.mb5, styles.textHeadline]}>{translate('bankAccount.chooseAnAccount')}</Text>
{!_.isEmpty(text) && <Text style={[styles.mb5]}>{text}</Text>}
<View style={[styles.flexRow, styles.alignItemsCenter, styles.mb5]}>
<Icon
src={icon}
height={iconSize}
width={iconSize}
/>
<View>
<Text style={[styles.ml3, styles.textStrong]}>{bankName}</Text>
{selectedPlaidAccountMask.length > 0 && (
<Text style={[styles.ml3, styles.textLabelSupporting]}>{`${translate('bankAccount.accountEnding')} ${selectedPlaidAccountMask}`}</Text>
)}
</View>
</View>
<Text style={[styles.textLabelSupporting]}>{`${translate('bankAccount.chooseAnAccountBelow')}:`}</Text>
<RadioButtons
items={options}
defaultCheckedValue={defaultSelectedPlaidAccountID}
onPress={handleSelectingPlaidAccount}
/>
</FullPageOfflineBlockingView>
);
}

// Plaid bank accounts view
return (
<FullPageOfflineBlockingView>
Expand Down
21 changes: 19 additions & 2 deletions src/components/NewDatePicker/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import * as Expensicons from '@components/Icon/Expensicons';
import TextInput from '@components/TextInput';
import {propTypes as baseTextInputPropTypes, defaultProps as defaultBaseTextInputPropTypes} from '@components/TextInput/BaseTextInput/baseTextInputPropTypes';
import withLocalize, {withLocalizePropTypes} from '@components/withLocalize';
import * as FormActions from '@userActions/FormActions';
import useThemeStyles from '@styles/useThemeStyles';
import * as FormActions from '@userActions/FormActions';
import CONST from '@src/CONST';
import CalendarPicker from './CalendarPicker';

Expand Down Expand Up @@ -53,7 +53,24 @@ const datePickerDefaultProps = {
formID: '',
};

function NewDatePicker({containerStyles, defaultValue, disabled, errorText, inputID, isSmallScreenWidth, label, maxDate, minDate, onInputChange, onTouched, placeholder, translate, value, shouldSaveDraft, formID}) {
function NewDatePicker({
containerStyles,
defaultValue,
disabled,
errorText,
inputID,
isSmallScreenWidth,
label,
maxDate,
minDate,
onInputChange,
onTouched,
placeholder,
translate,
value,
shouldSaveDraft,
formID,
}) {
const styles = useThemeStyles();
const [selectedDate, setSelectedDate] = useState(value || defaultValue || undefined);

Expand Down
7 changes: 5 additions & 2 deletions src/components/RadioButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@ type RadioButtonsProps = {
/** List of choices to display via radio buttons */
items: Choice[];

/** Default checked value */
defaultCheckedValue?: string;

/** Callback to fire when selecting a radio button */
onPress: (value: string) => void;
};

function RadioButtons({items, onPress}: RadioButtonsProps) {
function RadioButtons({items, onPress, defaultCheckedValue = ''}: RadioButtonsProps) {
const styles = useThemeStyles();
const [checkedValue, setCheckedValue] = useState('');
const [checkedValue, setCheckedValue] = useState(defaultCheckedValue);

return (
<View>
Expand Down
8 changes: 8 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1140,8 +1140,16 @@ export default {
return result;
},
bankAccount: {
bankInfo: 'Bank info',
confirmBankInfo: 'Confirm bank info',
manuallyAdd: 'Manually add your bank account',
letsDoubleCheck: "Let's double check that everything looks right.",
accountEnding: 'Account ending in',
thisBankAccount: 'This bank account will be used for business payments on your workspace',
connectDifferentAccount: 'Connect a different account',
accountNumber: 'Account number',
routingNumber: 'Routing number',
chooseAnAccountBelow: 'Choose an account below',
addBankAccount: 'Add bank account',
chooseAnAccount: 'Choose an account',
connectOnlineWithPlaid: 'Connect online with Plaid',
Expand Down
8 changes: 8 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1154,8 +1154,16 @@ export default {
return result;
},
bankAccount: {
bankInfo: 'Información bancaria',
confirmBankInfo: 'Confirmar información bancaria',
manuallyAdd: 'Agregar manualmente tu cuenta bancaria',
letsDoubleCheck: 'Verifiquemos que todo esté correcto.',
accountEnding: 'Cuenta terminada en',
thisBankAccount: 'Esta cuenta bancaria se utilizará para pagos comerciales en tu espacio de trabajo',
connectDifferentAccount: 'Conectar una cuenta diferente',
accountNumber: 'Número de cuenta',
routingNumber: 'Número de ruta',
chooseAnAccountBelow: 'Elige una cuenta a continuación',
addBankAccount: 'Añadir cuenta bancaria',
chooseAnAccount: 'Elige una cuenta',
connectOnlineWithPlaid: 'Conéctate a Plaid online',
Expand Down
28 changes: 27 additions & 1 deletion src/pages/ReimbursementAccount/BankAccountStep.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ import useTheme from '@styles/themes/useTheme';
import useThemeStyles from '@styles/useThemeStyles';
import * as BankAccounts from '@userActions/BankAccounts';
import * as Link from '@userActions/Link';
import * as ReimbursementAccount from '@userActions/ReimbursementAccount';
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';

const propTypes = {
Expand Down Expand Up @@ -63,6 +65,8 @@ const defaultProps = {
policyID: '',
};

const bankInfoStepKeys = CONST.BANK_ACCOUNT.BANK_INFO_STEP.INPUT_KEY;

function BankAccountStep(props) {
const theme = useTheme();
const styles = useThemeStyles();
Expand All @@ -78,6 +82,23 @@ function BankAccountStep(props) {
ROUTES.WORKSPACE_INITIAL.getRoute(props.policyID),
)}`;

const removeExistingBankAccountDetails = () => {
const bankAccountData = {
[bankInfoStepKeys.ROUTING_NUMBER]: '',
[bankInfoStepKeys.ACCOUNT_NUMBER]: '',
[bankInfoStepKeys.PLAID_MASK]: '',
[bankInfoStepKeys.IS_SAVINGS]: '',
[bankInfoStepKeys.BANK_NAME]: '',
[bankInfoStepKeys.PLAID_ACCOUNT_ID]: '',
[bankInfoStepKeys.PLAID_ACCESS_TOKEN]: '',
};
ReimbursementAccount.updateReimbursementAccountDraft(bankAccountData);
};

if (subStep === CONST.BANK_ACCOUNT.SETUP_TYPE.PLAID || subStep === CONST.BANK_ACCOUNT.SETUP_TYPE.MANUAL) {
return <BankInfo />;
}

if (subStep === CONST.BANK_ACCOUNT.SETUP_TYPE.MANUAL) {
return (
<BankAccountManualStep
Expand All @@ -100,6 +121,7 @@ function BankAccountStep(props) {
);
}

// 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 (
<ScreenWrapper
includeSafeAreaPaddingBottom={false}
Expand Down Expand Up @@ -134,6 +156,7 @@ function BankAccountStep(props) {
if (props.isPlaidDisabled || !props.user.validated) {
return;
}
removeExistingBankAccountDetails();
BankAccounts.openPlaidView();
}}
isDisabled={props.isPlaidDisabled || !props.user.validated}
Expand All @@ -149,7 +172,10 @@ function BankAccountStep(props) {
icon={Expensicons.Connect}
title={props.translate('bankAccount.connectManually')}
disabled={!props.user.validated}
onPress={() => BankAccounts.setBankAccountSubStep(CONST.BANK_ACCOUNT.SETUP_TYPE.MANUAL)}
onPress={() => {
removeExistingBankAccountDetails();
BankAccounts.setBankAccountSubStep(CONST.BANK_ACCOUNT.SETUP_TYPE.MANUAL);
}}
shouldShowRightIcon
wrapperStyle={[styles.cardMenuItem]}
/>
Expand Down
Loading

0 comments on commit 57da62e

Please sign in to comment.