diff --git a/assets/images/companyCards/card-bank_of_america.svg b/assets/images/companyCards/card-bank_of_america.svg
deleted file mode 100644
index 684a6a0a28f5..000000000000
--- a/assets/images/companyCards/card-bank_of_america.svg
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
\ No newline at end of file
diff --git a/assets/images/companyCards/card-other.svg b/assets/images/companyCards/card-other.svg
deleted file mode 100644
index 11ff21285626..000000000000
--- a/assets/images/companyCards/card-other.svg
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
\ No newline at end of file
diff --git a/src/CONST.ts b/src/CONST.ts
index e7a5d10b81ae..c485517e41e2 100755
--- a/src/CONST.ts
+++ b/src/CONST.ts
@@ -2518,6 +2518,7 @@ const CONST = {
},
COMPANY_CARDS: {
STEP: {
+ SELECT_BANK: 'SelectBank',
CARD_TYPE: 'CardType',
CARD_INSTRUCTIONS: 'CardInstructions',
CARD_NAME: 'CardName',
@@ -2528,6 +2529,17 @@ const CONST = {
VISA: 'visa',
MASTERCARD: 'mastercard',
},
+ BANKS: {
+ AMEX: 'American Express',
+ BANK_OF_AMERICA: 'Bank of America',
+ BREX: 'Brex',
+ CAPITAL_ONE: 'Capital One',
+ CHASE: 'Chase',
+ CITI_BANK: 'Citibank',
+ STRIPE: 'Stripe',
+ WELLS_FARGO: 'Wells Fargo',
+ OTHER: 'Other',
+ },
DELETE_TRANSACTIONS: {
RESTRICT: 'corporate',
ALLOW: 'personal',
diff --git a/src/components/Icon/Illustrations.ts b/src/components/Icon/Illustrations.ts
index e3604dc5a86e..bae8f6af1ab2 100644
--- a/src/components/Icon/Illustrations.ts
+++ b/src/components/Icon/Illustrations.ts
@@ -1,7 +1,15 @@
import AmexCompanyCards from '@assets/images/companyCards/amex.svg';
import AmexCardCompanyCardDetail from '@assets/images/companyCards/card-amex.svg';
+import BankOfAmericaCompanyCardDetail from '@assets/images/companyCards/card-bofa.svg';
+import BrexCompanyCardDetail from '@assets/images/companyCards/card-brex.svg';
+import CapitalOneCompanyCardDetail from '@assets/images/companyCards/card-capitalone.svg';
+import ChaseCompanyCardDetail from '@assets/images/companyCards/card-chase.svg';
+import CitibankCompanyCardDetail from '@assets/images/companyCards/card-citi.svg';
import MasterCardCompanyCardDetail from '@assets/images/companyCards/card-mastercard.svg';
+import StripeCompanyCardDetail from '@assets/images/companyCards/card-stripe.svg';
import VisaCompanyCardDetail from '@assets/images/companyCards/card-visa.svg';
+import WellsFargoCompanyCardDetail from '@assets/images/companyCards/card-wellsfargo.svg';
+import OtherCompanyCardDetail from '@assets/images/companyCards/card=-generic.svg';
import CompanyCardsEmptyState from '@assets/images/companyCards/emptystate__card-pos.svg';
import MasterCardCompanyCards from '@assets/images/companyCards/mastercard.svg';
import CompanyCardsPendingState from '@assets/images/companyCards/pendingstate_laptop-with-hourglass-and-cards.svg';
@@ -244,4 +252,12 @@ export {
MasterCardCompanyCardDetail,
AmexCardCompanyCardDetail,
TurtleInShell,
+ BankOfAmericaCompanyCardDetail,
+ BrexCompanyCardDetail,
+ CapitalOneCompanyCardDetail,
+ ChaseCompanyCardDetail,
+ CitibankCompanyCardDetail,
+ OtherCompanyCardDetail,
+ StripeCompanyCardDetail,
+ WellsFargoCompanyCardDetail,
};
diff --git a/src/languages/en.ts b/src/languages/en.ts
index 27c0a1025651..e82907ce9915 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -2953,12 +2953,14 @@ const translations = {
selectCardFeed: 'Select card feed',
addCardFeed: 'Add card feed',
addNewCard: {
+ other: 'Other',
cardProviders: {
amex: 'American Express Corporate Cards',
mastercard: 'Mastercard Commercial Cards',
visa: 'Visa Commercial Cards',
},
yourCardProvider: `Who's your card provider?`,
+ whoIsYourBankAccount: 'Who’s your bank?',
enableFeed: {
title: ({provider}: GoBackMessageParams) => `Enable your ${provider} feed`,
heading: 'We have a direct integration with your card issuer and can import your transaction data into Expensify quickly and accurately.\n\nTo get started, simply:',
@@ -2986,6 +2988,7 @@ const translations = {
},
error: {
pleaseSelectProvider: 'Please select a card provider before continuing.',
+ pleaseSelectBankAccount: 'Please select a bank account before continuing.',
},
},
assignCard: 'Assign card',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 58316a37c523..1ed32df2a818 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -2989,12 +2989,14 @@ const translations = {
selectCardFeed: 'Seleccionar feed de tarjetas',
addCardFeed: 'Añadir alimentación de tarjeta',
addNewCard: {
+ other: 'Otros',
cardProviders: {
amex: 'Tarjetas de empresa American Express',
mastercard: 'Tarjetas comerciales Mastercard',
visa: 'Tarjetas comerciales Visa',
},
yourCardProvider: `¿Quién es su proveedor de tarjetas?`,
+ whoIsYourBankAccount: '¿Cuál es tu banco?',
enableFeed: {
title: ({provider}: GoBackMessageParams) => `Habilita tu feed ${provider}`,
heading:
@@ -3023,6 +3025,7 @@ const translations = {
},
error: {
pleaseSelectProvider: 'Seleccione un proveedor de tarjetas antes de continuar.',
+ pleaseSelectBankAccount: 'Seleccione una cuenta bancaria antes de continuar.',
},
},
assignCard: 'Asignar tarjeta',
diff --git a/src/libs/CardUtils.ts b/src/libs/CardUtils.ts
index 07ed431a0bc0..bd8499fa168f 100644
--- a/src/libs/CardUtils.ts
+++ b/src/libs/CardUtils.ts
@@ -227,6 +227,21 @@ function getMemberCards(policy: OnyxEntry, allCardsList: OnyxCollection<
return cards;
}
+const getBankCardDetailsImage = (bank: ValueOf): IconAsset => {
+ const iconMap: Record, IconAsset> = {
+ [CONST.COMPANY_CARDS.BANKS.AMEX]: Illustrations.AmexCardCompanyCardDetail,
+ [CONST.COMPANY_CARDS.BANKS.BANK_OF_AMERICA]: Illustrations.BankOfAmericaCompanyCardDetail,
+ [CONST.COMPANY_CARDS.BANKS.CAPITAL_ONE]: Illustrations.CapitalOneCompanyCardDetail,
+ [CONST.COMPANY_CARDS.BANKS.CHASE]: Illustrations.ChaseCompanyCardDetail,
+ [CONST.COMPANY_CARDS.BANKS.CITI_BANK]: Illustrations.CitibankCompanyCardDetail,
+ [CONST.COMPANY_CARDS.BANKS.WELLS_FARGO]: Illustrations.WellsFargoCompanyCardDetail,
+ [CONST.COMPANY_CARDS.BANKS.BREX]: Illustrations.BrexCompanyCardDetail,
+ [CONST.COMPANY_CARDS.BANKS.STRIPE]: Illustrations.StripeCompanyCardDetail,
+ [CONST.COMPANY_CARDS.BANKS.OTHER]: Illustrations.OtherCompanyCardDetail,
+ };
+ return iconMap[bank];
+};
+
export {
isExpensifyCard,
isCorporateCard,
@@ -245,4 +260,5 @@ export {
getCardFeedIcon,
getCardDetailsImage,
getMemberCards,
+ getBankCardDetailsImage,
};
diff --git a/src/pages/workspace/companyCards/addNew/AddNewCardPage.tsx b/src/pages/workspace/companyCards/addNew/AddNewCardPage.tsx
index 8d42b3e8408e..9b263299739b 100644
--- a/src/pages/workspace/companyCards/addNew/AddNewCardPage.tsx
+++ b/src/pages/workspace/companyCards/addNew/AddNewCardPage.tsx
@@ -1,5 +1,6 @@
import React from 'react';
import {useOnyx} from 'react-native-onyx';
+import usePermissions from '@hooks/usePermissions';
import withPolicyAndFullscreenLoading from '@pages/workspace/withPolicyAndFullscreenLoading';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
@@ -7,23 +8,42 @@ import CardInstructionsStep from './CardInstructionsStep';
import CardNameStep from './CardNameStep';
import CardTypeStep from './CardTypeStep';
import DetailsStep from './DetailsStep';
+import SelectBankStep from './SelectBankStep';
function AddNewCardPage() {
const [addNewCardFeed] = useOnyx(ONYXKEYS.ADD_NEW_COMPANY_CARD);
+ const {canUseDirectFeeds} = usePermissions();
const {currentStep} = addNewCardFeed ?? {};
- switch (currentStep) {
- case CONST.COMPANY_CARDS.STEP.CARD_TYPE:
- return ;
- case CONST.COMPANY_CARDS.STEP.CARD_INSTRUCTIONS:
- return ;
- case CONST.COMPANY_CARDS.STEP.CARD_NAME:
- return ;
- case CONST.COMPANY_CARDS.STEP.CARD_DETAILS:
- return ;
- default:
- return ;
+ if (canUseDirectFeeds) {
+ switch (currentStep) {
+ case CONST.COMPANY_CARDS.STEP.SELECT_BANK:
+ return ;
+ case CONST.COMPANY_CARDS.STEP.CARD_TYPE:
+ return ;
+ case CONST.COMPANY_CARDS.STEP.CARD_INSTRUCTIONS:
+ return ;
+ case CONST.COMPANY_CARDS.STEP.CARD_NAME:
+ return ;
+ case CONST.COMPANY_CARDS.STEP.CARD_DETAILS:
+ return ;
+ default:
+ return ;
+ }
+ } else {
+ switch (currentStep) {
+ case CONST.COMPANY_CARDS.STEP.CARD_TYPE:
+ return ;
+ case CONST.COMPANY_CARDS.STEP.CARD_INSTRUCTIONS:
+ return ;
+ case CONST.COMPANY_CARDS.STEP.CARD_NAME:
+ return ;
+ case CONST.COMPANY_CARDS.STEP.CARD_DETAILS:
+ return ;
+ default:
+ return ;
+ }
}
}
diff --git a/src/pages/workspace/companyCards/addNew/CardTypeStep.tsx b/src/pages/workspace/companyCards/addNew/CardTypeStep.tsx
index 391799851f8c..28d6ac834918 100644
--- a/src/pages/workspace/companyCards/addNew/CardTypeStep.tsx
+++ b/src/pages/workspace/companyCards/addNew/CardTypeStep.tsx
@@ -11,6 +11,7 @@ import SelectionList from '@components/SelectionList';
import RadioListItem from '@components/SelectionList/RadioListItem';
import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
+import usePermissions from '@hooks/usePermissions';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@navigation/Navigation';
import variables from '@styles/variables';
@@ -23,6 +24,7 @@ function CardTypeStep() {
const styles = useThemeStyles();
const [addNewCard] = useOnyx(ONYXKEYS.ADD_NEW_COMPANY_CARD);
const [typeSelected, setTypeSelected] = useState>();
+ const {canUseDirectFeeds} = usePermissions();
const [isError, setIsError] = useState(false);
const submit = () => {
@@ -44,7 +46,11 @@ function CardTypeStep() {
}, [addNewCard?.data.cardType]);
const handleBackButtonPress = () => {
- Navigation.goBack();
+ if (canUseDirectFeeds) {
+ CompanyCards.setAddNewCompanyCardStepAndData({step: CONST.COMPANY_CARDS.STEP.SELECT_BANK});
+ } else {
+ Navigation.goBack();
+ }
};
const data = [
diff --git a/src/pages/workspace/companyCards/addNew/SelectBankStep.tsx b/src/pages/workspace/companyCards/addNew/SelectBankStep.tsx
new file mode 100644
index 000000000000..be0479327832
--- /dev/null
+++ b/src/pages/workspace/companyCards/addNew/SelectBankStep.tsx
@@ -0,0 +1,108 @@
+import React, {useEffect, useState} from 'react';
+import {View} from 'react-native';
+import {useOnyx} from 'react-native-onyx';
+import type {ValueOf} from 'type-fest';
+import FormHelpMessage from '@components/FormHelpMessage';
+import HeaderWithBackButton from '@components/HeaderWithBackButton';
+import Icon from '@components/Icon';
+import ScreenWrapper from '@components/ScreenWrapper';
+import SelectionList from '@components/SelectionList';
+import RadioListItem from '@components/SelectionList/RadioListItem';
+import Text from '@components/Text';
+import useLocalize from '@hooks/useLocalize';
+import useThemeStyles from '@hooks/useThemeStyles';
+import * as CardUtils from '@libs/CardUtils';
+import Navigation from '@navigation/Navigation';
+import variables from '@styles/variables';
+import * as CompanyCards from '@userActions/CompanyCards';
+import CONST from '@src/CONST';
+import ONYXKEYS from '@src/ONYXKEYS';
+
+function SelectBankStep() {
+ const {translate} = useLocalize();
+ const styles = useThemeStyles();
+ const [addNewCard] = useOnyx(ONYXKEYS.ADD_NEW_COMPANY_CARD);
+ const [bankSelected, setBankSelected] = useState>();
+ const [hasError, setHasError] = useState(false);
+
+ const submit = () => {
+ if (!bankSelected) {
+ setHasError(true);
+ } else {
+ // TODO: https://github.com/Expensify/App/issues/50447 - update the navigation when new screen exists
+ CompanyCards.setAddNewCompanyCardStepAndData({
+ step: bankSelected === CONST.COMPANY_CARDS.BANKS.OTHER ? CONST.COMPANY_CARDS.STEP.CARD_TYPE : CONST.COMPANY_CARDS.STEP.CARD_TYPE,
+ data: {
+ selectedBank: bankSelected,
+ },
+ isEditing: false,
+ });
+ }
+ };
+
+ useEffect(() => {
+ setBankSelected(addNewCard?.data.selectedBank);
+ }, [addNewCard?.data.selectedBank]);
+
+ const handleBackButtonPress = () => {
+ Navigation.goBack();
+ };
+
+ const data = Object.values(CONST.COMPANY_CARDS.BANKS).map((bank) => ({
+ value: bank,
+ text: bank === CONST.COMPANY_CARDS.BANKS.OTHER ? translate('workspace.companyCards.addNewCard.other') : bank,
+ keyForList: bank,
+ isSelected: bankSelected === bank,
+ leftElement: (
+
+ ),
+ }));
+
+ return (
+
+
+
+ {translate('workspace.companyCards.addNewCard.whoIsYourBankAccount')}
+ {
+ setBankSelected(value);
+ setHasError(false);
+ }}
+ sections={[{data}]}
+ shouldSingleExecuteRowSelect
+ initiallyFocusedOptionKey={addNewCard?.data.selectedBank}
+ shouldUpdateFocusedIndex
+ showConfirmButton
+ confirmButtonText={translate('common.next')}
+ onConfirm={submit}
+ >
+ {hasError && (
+
+
+
+ )}
+
+
+ );
+}
+
+SelectBankStep.displayName = 'SelectBankStep';
+
+export default SelectBankStep;
diff --git a/src/types/onyx/CardFeeds.ts b/src/types/onyx/CardFeeds.ts
index bd78d54db71b..8b80fabac8ae 100644
--- a/src/types/onyx/CardFeeds.ts
+++ b/src/types/onyx/CardFeeds.ts
@@ -45,6 +45,9 @@ type AddNewCardFeedData = {
/** Card type */
cardType: ValueOf;
+ /** Selected bank */
+ selectedBank: ValueOf;
+
/** Name of the card */
cardTitle: string;
};