Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add modal for existing owners error #4157

Merged
merged 7 commits into from
Jul 21, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/CONST.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 23 additions & 11 deletions src/components/ConfirmModal.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import {View} from 'react-native';
import _ from 'underscore';
import PropTypes from 'prop-types';
import Header from './Header';
import Modal from './Modal';
Expand All @@ -19,7 +20,7 @@ const propTypes = {
onConfirm: PropTypes.func.isRequired,

/** A callback to call when the form has been closed */
onCancel: PropTypes.func.isRequired,
onCancel: PropTypes.func,

/** Modal visibility */
isVisible: PropTypes.bool.isRequired,
Expand All @@ -30,12 +31,15 @@ const propTypes = {
/** Cancel button text */
cancelText: PropTypes.string,

/** Modal content text */
prompt: PropTypes.string,
/** Modal content text/element */
prompt: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),

/** Is the action destructive */
danger: PropTypes.bool,

/** Whether we should show the cancel button */
shouldShowCancelButton: PropTypes.bool,

...withLocalizePropTypes,

...windowDimensionsPropTypes,
Expand All @@ -46,6 +50,8 @@ const defaultProps = {
cancelText: '',
prompt: '',
danger: false,
onCancel: () => {},
shouldShowCancelButton: true,
};

const ConfirmModal = props => (
Expand All @@ -62,9 +68,12 @@ const ConfirmModal = props => (
<Header title={props.title} />
</View>

<Text>
{props.prompt}
</Text>
{_.isString(props.prompt)
? (
<Text>
{props.prompt}
</Text>
) : (props.prompt)}

<Button
success
Expand All @@ -74,11 +83,14 @@ const ConfirmModal = props => (
pressOnEnter
text={props.confirmText || props.translate('common.yes')}
/>
<Button
style={[styles.mt3]}
onPress={props.onCancel}
text={props.cancelText || props.translate('common.no')}
/>
{props.shouldShowCancelButton
&& (
<Button
style={[styles.mt3]}
onPress={props.onCancel}
text={props.cancelText || props.translate('common.no')}
/>
)}
</View>
</Modal>
);
Expand Down
9 changes: 9 additions & 0 deletions src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export default {
cancel: 'Cancel',
yes: 'Yes',
no: 'No',
ok: 'OK',
attachment: 'Attachment',
to: 'To',
optional: 'Optional',
Expand Down Expand Up @@ -354,6 +355,14 @@ export default {
dob: 'Please enter a valid date of birth',
ssnLast4: 'Please enter valid last 4 digits of SSN',
noDefaultDepositAccountOrDebitCardAvailable: 'Please add a default deposit bank account or debit card',
existingOwners: {
unableToAddBankAccount: 'Unable to add bank account',
alreadyInUse: 'This bank account is already in use by ',
pleaseAskThemToShare: 'Please ask them to share it with you.',
alternatively: 'Alternatively, you can ',
setUpThisAccountByYourself: 'set up this account by yourself',
validationProcessAgain: ' and go through the entire validation process again (may take up to a week).',
},
},
},
addPersonalBankAccountPage: {
Expand Down
8 changes: 8 additions & 0 deletions src/languages/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,14 @@ export default {
dob: 'Ingrese una fecha de nacimiento válida',
ssnLast4: 'Ingrese los últimos 4 dígitos del número de seguro social',
noDefaultDepositAccountOrDebitCardAvailable: 'Por favor agregue una cuenta bancaria para depósitos o una tarjeta de débito',
existingOwners: {
unableToAddBankAccount: 'No se pudo agregar la cuenta bancaria',
alreadyInUse: 'La cuenta bancaria ya se encuentra en uso por ',
pleaseAskThemToShare: 'Por favor, solicita que la compartan contigo.',
alternatively: 'En su defecto, puedes ',
setUpThisAccountByYourself: 'añadir la cuenta tú mismo',
validationProcessAgain: ' y completar el proceso de validación de nuevo (lo cual puede tardar hasta una semana).',
},
},
},
addPersonalBankAccountPage: {
Expand Down
21 changes: 19 additions & 2 deletions src/libs/actions/BankAccounts.js
Original file line number Diff line number Diff line change
Expand Up @@ -616,8 +616,20 @@ function setupWithdrawalAccount(data) {

// Show warning if another account already set up this bank account and promote share
if (response.existingOwners) {
// @TODO Show better error in UI about existing owners
console.error('Cannot set up withdrawal account due to existing owners');
console.error('Cannot set up withdrawal account due to existing owners', response);
const existingOwnersList = response.existingOwners.reduce((ownersStr, owner, i, ownersArr) => {
let separator = ',\n';
if (i === 0) {
separator = '\n';
} else if (i === ownersArr.length - 1) {
separator = ' and\n';
}
return `${ownersStr}${separator}${owner}`;
}, '');
Onyx.merge(
ONYXKEYS.REIMBURSEMENT_ACCOUNT,
{existingOwnersList, error: CONST.BANK_ACCOUNT.ERROR.EXISTING_OWNERS},
);
return;
}

Expand Down Expand Up @@ -721,6 +733,10 @@ function setupWithdrawalAccount(data) {
});
}

function hideExistingOwnersError() {
Onyx.merge(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {error: '', existingOwnersList: ''});
}

export {
activateWallet,
addPersonalBankAccount,
Expand All @@ -733,4 +749,5 @@ export {
goToWithdrawalAccountSetupStep,
setupWithdrawalAccount,
validateBankAccount,
hideExistingOwnersError,
};
77 changes: 74 additions & 3 deletions src/pages/ReimbursementAccount/BankAccountStep.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import _ from 'underscore';
import React from 'react';
import {View, Image} from 'react-native';
import PropTypes from 'prop-types';
import {withOnyx} from 'react-native-onyx';
import HeaderWithCloseButton from '../../components/HeaderWithCloseButton';
import MenuItem from '../../components/MenuItem';
import {Paycheck, Bank, Lock} from '../../components/Icon/Expensicons';
import {
Paycheck, Bank, Lock,
} from '../../components/Icon/Expensicons';
import styles from '../../styles/styles';
import TextLink from '../../components/TextLink';
import Button from '../../components/Button';
Expand All @@ -17,9 +21,25 @@ import CheckboxWithLabel from '../../components/CheckboxWithLabel';
import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize';
import exampleCheckImage from '../../../assets/images/example-check-image.png';
import Text from '../../components/Text';
import {setupWithdrawalAccount} from '../../libs/actions/BankAccounts';
import {
goToWithdrawalAccountSetupStep,
hideExistingOwnersError,
setupWithdrawalAccount,
} from '../../libs/actions/BankAccounts';
import ConfirmModal from '../../components/ConfirmModal';
import ONYXKEYS from '../../ONYXKEYS';
import compose from '../../libs/compose';

const propTypes = {
/** Bank account currently in setup */
reimbursementAccount: PropTypes.shape({
/** Error set when handling the API response */
error: PropTypes.string,

/** A list of existing owners, set if the bank account being added is already owned */
existingOwnersList: PropTypes.string,
}).isRequired,

...withLocalizePropTypes,
};

Expand Down Expand Up @@ -109,6 +129,8 @@ class BankAccountStep extends React.Component {
// Disable bank account fields once they've been added in db so they can't be changed
const isFromPlaid = this.props.achData.setupType === CONST.BANK_ACCOUNT.SETUP_TYPE.PLAID;
const shouldDisableInputs = Boolean(this.props.achData.bankAccountID) || isFromPlaid;
const isExistingOwnersErrorVisible = Boolean(this.props.reimbursementAccount.error
&& this.props.reimbursementAccount.existingOwnersList);
return (
<View style={[styles.flex1, styles.justifyContentBetween]}>
<HeaderWithCloseButton
Expand Down Expand Up @@ -223,11 +245,60 @@ class BankAccountStep extends React.Component {
/>
</>
)}

<ConfirmModal
title={this.props.translate('bankAccount.error.existingOwners.unableToAddBankAccount')}
isVisible={isExistingOwnersErrorVisible}
onConfirm={hideExistingOwnersError}
shouldShowCancelButton={false}
prompt={(
<View style={[styles.flex1]}>
<Text style={[styles.mb4]}>
<Text>
{this.props.translate('bankAccount.error.existingOwners.alreadyInUse')}
</Text>
<Text style={styles.textStrong}>
{this.props.reimbursementAccount.existingOwnersList}
</Text>
</Text>
<Text style={[styles.mb4]}>
{this.props.translate('bankAccount.error.existingOwners.pleaseAskThemToShare')}
</Text>
<Text>
<Text>
{this.props.translate('bankAccount.error.existingOwners.alternatively')}
</Text>
<Text
style={styles.link}
onPress={() => goToWithdrawalAccountSetupStep(
CONST.BANK_ACCOUNT.STEP.COMPANY,
this.props.achData,
)}
>
{this.props.translate(
'bankAccount.error.existingOwners.setUpThisAccountByYourself',
)}
</Text>
<Text>
{this.props.translate('bankAccount.error.existingOwners.validationProcessAgain')}
</Text>
</Text>
</View>
)}
confirmText={this.props.translate('common.ok')}
/>
</View>
);
}
}

BankAccountStep.propTypes = propTypes;

export default withLocalize(BankAccountStep);
export default compose(
withLocalize,
withOnyx({
reimbursementAccount: {
key: ONYXKEYS.REIMBURSEMENT_ACCOUNT,
},
}),
)(BankAccountStep);