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

Setup "Connect bank account" workspace flow #5703

Merged
merged 31 commits into from
Oct 8, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
73ff6ab
Move bank-account flow into workspace flow
marcaaron Oct 6, 2021
a7727f4
adding the basically done thing page but bank icons need a bankName a…
marcaaron Oct 6, 2021
16a458e
Create interstitial page to redirect or show continue button
marcaaron Oct 6, 2021
9e03ec0
fix subStep logic so that we remember the option selected;
marcaaron Oct 6, 2021
8519ad3
Fix bankName stuff
marcaaron Oct 6, 2021
74e4a55
add initial english translations
marcaaron Oct 6, 2021
235b3d9
clean up getPaymentMethods
marcaaron Oct 6, 2021
93e9d35
use initWithStoredValues
marcaaron Oct 6, 2021
d87cfc8
Remove add work email and replace with Concierge
marcaaron Oct 7, 2021
1038edf
Add noop onPress
marcaaron Oct 7, 2021
72fb8d7
dont show the continue setup screen if we are in an open state
marcaaron Oct 7, 2021
8db44a0
fix weird bug that silently breaks navigating to a new step
marcaaron Oct 7, 2021
cd2d639
pop the WorkspaceBankAccountPage before navigating to /bank-account
marcaaron Oct 7, 2021
10e27c7
remove unneeded link out to olddot
marcaaron Oct 7, 2021
62a5191
Navigate to correct next step
marcaaron Oct 7, 2021
183903a
add missing propTypes
marcaaron Oct 7, 2021
81dea7f
add translations
marcaaron Oct 7, 2021
ac85502
add translations and assets
marcaaron Oct 7, 2021
665da6d
Merge branch 'tgolen-workspace-settings' into marcaaron-connectBankAc…
marcaaron Oct 7, 2021
18b05d3
remove unneeded import
marcaaron Oct 7, 2021
6dce153
update copy
marcaaron Oct 7, 2021
89a326f
change icon
marcaaron Oct 7, 2021
198a064
remove assets
marcaaron Oct 7, 2021
c06423f
remove unused things
marcaaron Oct 7, 2021
87271a8
fix conflicts
marcaaron Oct 7, 2021
78da1f0
update route
marcaaron Oct 7, 2021
50ab411
move loading false so ACHContractStep does not reshow
marcaaron Oct 7, 2021
075fc07
add workaround for navigation
marcaaron Oct 7, 2021
d8a9be7
fix conflicts
marcaaron Oct 7, 2021
d68da52
remove pop
marcaaron Oct 7, 2021
a409a59
Remove extra dismissModal as it is no longer needed. Add a dismissMod…
marcaaron Oct 7, 2021
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
4 changes: 2 additions & 2 deletions src/ROUTES.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export default {
WORKSPACE_INVOICES: 'workspace/:policyID/invoices',
WORKSPACE_TRAVEL: 'workspace/:policyID/travel',
WORKSPACE_MEMBERS: 'workspace/:policyID/members',
WORKSPACE_BANKACCOUNT: 'workspace/:policyID/bankAccount',
WORKSPACE_BANK_ACCOUNT: 'workspace/:policyID/bank-account',
getWorkspaceInitialRoute: policyID => `workspace/${policyID}`,
getWorkspaceInviteRoute: policyID => `workspace/${policyID}/invite`,
getWorkspaceSettingsRoute: policyID => `workspace/${policyID}/settings`,
Expand All @@ -98,7 +98,7 @@ export default {
getWorkspaceInvoicesRoute: policyID => `workspace/${policyID}/invoices`,
getWorkspaceTravelRoute: policyID => `workspace/${policyID}/travel`,
getWorkspaceMembersRoute: policyID => `workspace/${policyID}/members`,
getWorkspaceBankAccountRoute: policyID => `workspace/${policyID}/bankAccount`,
getWorkspaceBankAccountRoute: policyID => `workspace/${policyID}/bank-account`,
getRequestCallRoute: taskID => `request-call/${taskID}`,
REQUEST_CALL: 'request-call/:taskID',

Expand Down
6 changes: 3 additions & 3 deletions src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -409,10 +409,10 @@ export default {
routingNumber: 'Routing number',
addBankAccount: 'Add bank account',
chooseAnAccount: 'Choose an account',
logIntoYourBank: 'Log into your bank',
logIntoYourBank: 'Connect online with Plaid',
connectManually: 'Connect manually',
yourDataIsSecure: 'Your data is secure',
toGetStarted: 'To get started with the Expensify Card, you first need to add a bank account.',
toGetStarted: 'Add a bank account and issue corporate cards, reimburse expenses, collect invoice payments, and pay bills, all from one place.',
plaidBodyCopy: 'Give your employees an easier way to pay - and get paid back - for company expenses.',
checkHelpLine: 'Your routing number and account number can be found on a check for the account.',
validateAccountError: 'In order to finish setting up your bank account, you must validate your account. Please check your email to validate your account, and return here to finish up!',
Expand Down Expand Up @@ -592,7 +592,7 @@ export default {
reviewingInfo: 'Thanks! We\'re reviewing your information, and will be in touch shortly. Please check your chat with Concierge ',
forNextSteps: ' for next steps to finish setting up your bank account.',
letsChatCTA: 'Yes, let\'s chat!',
letsChatText: 'Thanks for providing your information! We have a couple more things to work out, but it\'ll be easier over chat. Ready to get started?',
letsChatText: 'Thanks for doing that! We have a couple more things to work out, but itll be easier over chat. Ready to chat?',
letsChatTitle: 'Let\'s chat!',
},
beneficialOwnersStep: {
Expand Down
8 changes: 0 additions & 8 deletions src/libs/Navigation/AppNavigator/AuthScreens.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ import {
SettingsModalStackNavigator,
EnablePaymentsStackNavigator,
AddPersonalBankAccountModalStackNavigator,
ReimbursementAccountModalStackNavigator,
WorkspaceInviteModalStackNavigator,
RequestCallModalStackNavigator,
ReportDetailsModalStackNavigator,
Expand Down Expand Up @@ -399,13 +398,6 @@ class AuthScreens extends React.Component {
component={AddPersonalBankAccountModalStackNavigator}
listeners={modalScreenListeners}
/>
<RootStack.Screen
name="ReimbursementAccount"
options={modalScreenOptions}
component={ReimbursementAccountModalStackNavigator}
listeners={modalScreenListeners}
initialParams={{stepToOpen: CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT}}
/>
<RootStack.Screen
name="WorkspaceInvite"
options={modalScreenOptions}
Expand Down
7 changes: 7 additions & 0 deletions src/libs/Navigation/AppNavigator/ModalStackNavigators.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import WorkspaceBillsPage from '../../../pages/workspace/WorkspaceBillsPage';
import WorkspaceTravelPage from '../../../pages/workspace/WorkspaceTravelPage';
import WorkspaceMembersPage from '../../../pages/workspace/WorkspaceMembersPage';
import WorkspaceBankAccountPage from '../../../pages/workspace/WorkspaceBankAccountPage';
import CONST from '../../../CONST';

const defaultSubRouteOptions = {
cardStyle: styles.navigationScreenCardStyle,
Expand All @@ -63,6 +64,7 @@ function createModalStackNavigator(screens) {
key={screen.name}
name={screen.name}
component={screen.Component}
initialParams={screen.initialParams}
/>
))}
</ModalStackNavigator.Navigator>
Expand Down Expand Up @@ -174,6 +176,11 @@ const WorkspaceModalStackNavigator = createModalStackNavigator([
Component: WorkspaceBankAccountPage,
name: 'Workspace_BankAccount',
},
{
Component: ReimbursementAccountPage,
name: 'ReimbursementAccount',
initialParams: {stepToOpen: CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT},
},
]);

const SettingsModalStackNavigator = createModalStackNavigator([
Expand Down
13 changes: 6 additions & 7 deletions src/libs/Navigation/linkingConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,12 @@ export default {
path: ROUTES.WORKSPACE_MEMBERS,
exact: true,
},
WorkspaceBankAccountPage: {
path: ROUTES.WORKSPACE_BANKACCOUNT,
Workspace_BankAccount: {
path: ROUTES.WORKSPACE_BANK_ACCOUNT,
exact: true,
},
ReimbursementAccount: {
path: ROUTES.BANK_ACCOUNT,
exact: true,
},
},
Expand Down Expand Up @@ -182,11 +186,6 @@ export default {
EnablePayments_Root: ROUTES.ENABLE_PAYMENTS,
},
},
ReimbursementAccount: {
screens: {
ReimbursementAccount_Root: ROUTES.BANK_ACCOUNT,
},
},
WorkspaceInvite: {
screens: {
WorkspaceInvite_Root: ROUTES.WORKSPACE_INVITE,
Expand Down
18 changes: 15 additions & 3 deletions src/pages/ReimbursementAccount/BankAccountStep.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import compose from '../../libs/compose';
import * as ReimbursementAccountUtils from '../../libs/ReimbursementAccountUtils';
import ReimbursementAccountForm from './ReimbursementAccountForm';
import reimbursementAccountPropTypes from './reimbursementAccountPropTypes';
import variables from '../../styles/variables';

const propTypes = {
/** Bank account currently in setup */
Expand Down Expand Up @@ -167,15 +168,26 @@ class BankAccountStep extends React.Component {
return (
<View style={[styles.flex1, styles.justifyContentBetween]}>
<HeaderWithCloseButton
title={this.props.translate('bankAccount.addBankAccount')}
title={this.props.translate('workspace.common.bankAccount')}
stepCounter={subStep && {step: 1, total: 5}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is showing error when subStep is null

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

propTypes warning maybe? probably we should be passing either undefined or an Object. I don't think it will affect the code, but should be cleaned up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/** Data to display a step counter in the header */
stepCounter: PropTypes.shape({
step: PropTypes.number,
total: PropTypes.number,
}),

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stepCounter={subStep ? {step: 1, total: 5} : undefined}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I cleaned this up already.

onCloseButtonPress={Navigation.dismissModal}
onBackButtonPress={() => setBankAccountSubStep(null)}
shouldShowBackButton={Boolean(subStep)}
onBackButtonPress={() => {
// If we have a subStep then we will remove otherwise we will go back
if (subStep) {
setBankAccountSubStep(null);
return;
}
Navigation.goBack();
}}
shouldShowBackButton
/>
{!subStep && (
<>
<View style={[styles.flex1]}>
<View style={[styles.mh5, styles.mb5, styles.flexRow, styles.justifyContentBetween, styles.alignItemsCenter]}>
<Text style={[styles.textLarge, styles.textStrong]}>Streamline payments</Text>
<Icon src={Bank} fill={colors.green} height={variables.componentSizeNormal} width={variables.componentSizeNormal} />
</View>
<Text style={[styles.mh5, styles.mb5]}>
{this.props.translate('bankAccount.toGetStarted')}
</Text>
Expand Down
132 changes: 97 additions & 35 deletions src/pages/ReimbursementAccount/EnableStep.js
Original file line number Diff line number Diff line change
@@ -1,56 +1,118 @@
import _ from 'underscore';
import React from 'react';
import {Image, View} from 'react-native';
import {View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import styles from '../../styles/styles';
import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize';
import {navigateToConciergeChat} from '../../libs/actions/Report';
import HeaderWithCloseButton from '../../components/HeaderWithCloseButton';
import Navigation from '../../libs/Navigation/Navigation';
import Text from '../../components/Text';
import CONST from '../../CONST';
import TextLink from '../../components/TextLink';
import compose from '../../libs/compose';
import ONYXKEYS from '../../ONYXKEYS';
import Icon from '../../components/Icon';
import {Bank, Pencil} from '../../components/Icon/Expensicons';
import colors from '../../styles/colors';
import variables from '../../styles/variables';
import MenuItem from '../../components/MenuItem';
import {openSignedInLink} from '../../libs/actions/App';
import getBankIcon from '../../components/Icon/BankIcons';
import {getPaymentMethods} from '../../libs/actions/PaymentMethods';
import FullScreenLoadingIndicator from '../../components/FullscreenLoadingIndicator';

const propTypes = {
...withLocalizePropTypes,
};

const EnableStep = ({translate}) => {
const verifyingUrl = `${CONST.CLOUDFRONT_URL}/images/icons/emptystates/emptystate_reviewing.gif`;
return (
<View style={[styles.flex1, styles.justifyContentBetween]}>
<HeaderWithCloseButton
title={translate('validationStep.headerTitle')}
onCloseButtonPress={Navigation.dismissModal}
/>
<View style={[styles.flex1]}>
<Image
source={{uri: verifyingUrl}}
style={[styles.workspaceInviteWelcome]}
resizeMode="center"
class EnableStep extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoadingPaymentMethods: true,
};
}

componentDidMount() {
getPaymentMethods().then(() => {
this.setState({isLoadingPaymentMethods: false});
});
marcaaron marked this conversation as resolved.
Show resolved Hide resolved
}

render() {
if (this.state.isLoadingPaymentMethods) {
return (
<FullScreenLoadingIndicator visible />
marcaaron marked this conversation as resolved.
Show resolved Hide resolved
);
}

const {
user, reimbursementAccount, translate, bankAccountList,
} = this.props;
const isUsingExpensifyCard = user.isUsingExpensifyCard;
const account = _.find(bankAccountList, bankAccount => bankAccount.bankAccountID === reimbursementAccount.achData.bankAccountID);
if (!account) {
throw new Error('Account not found in EnableStep');
marcaaron marked this conversation as resolved.
Show resolved Hide resolved
}

const {icon} = getBankIcon(account.additionalData.bankName);
const formattedBankAccountNumber = account.accountNumber
? `${translate('paymentMethodList.accountLastFour')} ${
account.accountNumber.slice(-4)
}`
: '';
const bankName = account.addressName;
return (
<View style={[styles.flex1, styles.justifyContentBetween]}>
<HeaderWithCloseButton
title={translate('workspace.common.bankAccount')}
onCloseButtonPress={Navigation.dismissModal}
shouldShowBackButton
onBackButtonPress={() => Navigation.goBack()}
/>
<Text style={[styles.mh5, styles.mb5]}>
{translate('validationStep.reviewingInfo')}
<TextLink
onPress={() => {
// There are two modals that must be dismissed before we can reveal the Concierge
// chat underneath these screens
Navigation.dismissModal();
Navigation.dismissModal();
navigateToConciergeChat();
}}
>
{translate('common.here')}
</TextLink>
{translate('validationStep.forNextSteps')}
</Text>
<View style={[styles.flex1]}>
<View style={[styles.mh5, styles.mb5, styles.flexRow, styles.justifyContentBetween, styles.alignItemsCenter]}>
<Text style={[styles.textLarge, styles.textStrong]}>{!isUsingExpensifyCard ? 'Basically done!' : 'All set!'}</Text>
<Icon src={Bank} fill={colors.yellow} height={variables.componentSizeNormal} width={variables.componentSizeNormal} />
</View>
<MenuItem
title={bankName}
description={formattedBankAccountNumber}
icon={icon}
/>
<Text style={[styles.mh5, styles.mb5]}>
{!isUsingExpensifyCard
? 'This bank account will be used to reimburse expenses, collect invoices, and pay bills all from the same account. To enable the Expensify Card, please add a work email address.'
: 'This bank account will be used to issue corporate cards, reimburse expenses, collect invoices, and pay bills all from the same account.'}
</Text>
{!isUsingExpensifyCard && (
<MenuItem
title="Add work email"
icon={Pencil}
onPress={() => {
openSignedInLink('settings?param={“section”:”account”,”openModal”:”secondaryLogin”}');
}}
shouldShowRightIcon
/>
)}
</View>
</View>
</View>
);
};
);
}
}

EnableStep.propTypes = propTypes;
EnableStep.displayName = 'EnableStep';

export default compose(
withLocalize,
withOnyx({
user: {
key: ONYXKEYS.USER,
},
reimbursementAccount: {
key: ONYXKEYS.REIMBURSEMENT_ACCOUNT,
},
bankAccountList: {
key: ONYXKEYS.BANK_ACCOUNT_LIST,
},
}),
)(EnableStep);
11 changes: 9 additions & 2 deletions src/pages/ReimbursementAccount/ReimbursementAccountPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,10 @@ const defaultProps = {
class ReimbursementAccountPage extends React.Component {
componentDidMount() {
// We can specify a step to navigate to by using route params when the component mounts.
fetchFreePlanVerifiedBankAccount(this.getStepToOpenFromRouteParams());
const stepToOpen = this.getStepToOpenFromRouteParams();

// If we are trying to navigate to `/bank-account/new` and we already have a bank account then don't allow returning to `/new`
fetchFreePlanVerifiedBankAccount(stepToOpen !== CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT ? stepToOpen : '');
}

componentDidUpdate(prevProps) {
Expand Down Expand Up @@ -111,6 +114,8 @@ class ReimbursementAccountPage extends React.Component {
return CONST.BANK_ACCOUNT.STEP.ACH_CONTRACT;
case 'validate':
return CONST.BANK_ACCOUNT.STEP.VALIDATION;
case 'enable':
return CONST.BANK_ACCOUNT.STEP.ENABLE;
default:
return '';
}
Expand All @@ -130,6 +135,8 @@ class ReimbursementAccountPage extends React.Component {
return 'contract';
case CONST.BANK_ACCOUNT.STEP.VALIDATION:
return 'validate';
case CONST.BANK_ACCOUNT.STEP.ENABLE:
return 'enable';
case CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT:
default:
return 'new';
Expand Down Expand Up @@ -173,7 +180,7 @@ class ReimbursementAccountPage extends React.Component {
return (
<ScreenWrapper>
<HeaderWithCloseButton
title={this.props.translate('bankAccount.addBankAccount')}
title={this.props.translate('workspace.common.bankAccount')}
onCloseButtonPress={Navigation.dismissModal}
/>
{errorComponent}
Expand Down
Loading