Skip to content

Commit

Permalink
Merge pull request #26862 from pac-guerreiro/feature/add-assigned-car…
Browse files Browse the repository at this point in the history
…d-tile-and-display-expensify-cards

Feature/add assigned card tile and display expensify cards
  • Loading branch information
grgia authored Oct 13, 2023
2 parents c158461 + 59aae97 commit 1db4115
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 11 deletions.
1 change: 1 addition & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1243,6 +1243,7 @@ const CONST = {
CLOSED: 6,
STATE_SUSPENDED: 7,
},
ACTIVE_STATES: [2, 3, 4, 7],
},
AVATAR_ROW_SIZE: {
DEFAULT: 4,
Expand Down
3 changes: 3 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -852,6 +852,9 @@ export default {
bankAccounts: 'Bank accounts',
addBankAccountToSendAndReceive: 'Add a bank account to send and receive payments directly in the app.',
addBankAccount: 'Add bank account',
assignedCards: 'Assigned cards',
assignedCardsDescription: 'These are cards assigned by a Workspace admin to manage company spend.',
expensifyCard: 'Expensify Card',
},
cardPage: {
expensifyCard: 'Expensify Card',
Expand Down
3 changes: 3 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,9 @@ export default {
bankAccounts: 'Cuentas bancarias',
addBankAccountToSendAndReceive: 'Añade una cuenta bancaria para enviar y recibir pagos directamente en la aplicación.',
addBankAccount: 'Agregar cuenta bancaria',
assignedCards: 'Tarjetas asignadas',
assignedCardsDescription: 'Son tarjetas asignadas por un administrador del Espacio de Trabajo para gestionar los gastos de la empresa.',
expensifyCard: 'Tarjeta Expensify',
},
cardPage: {
expensifyCard: 'Tarjeta Expensify',
Expand Down
4 changes: 2 additions & 2 deletions src/libs/CardUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ function getCompanyCards(cardList: {string: Card}) {
*/
function getDomainCards(cardList: Record<string, OnyxTypes.Card>) {
// eslint-disable-next-line you-dont-need-lodash-underscore/filter
const activeCards = lodash.filter(cardList, (card) => [2, 3, 4, 7].includes(card.state));
return lodash.groupBy(activeCards, (card) => card.domainName.toLowerCase());
const activeCards = lodash.filter(cardList, (card) => (CONST.EXPENSIFY_CARD.ACTIVE_STATES as ReadonlyArray<OnyxTypes.Card['state']>).includes(card.state));
return lodash.groupBy(activeCards, (card) => card.domainName);
}

/**
Expand Down
48 changes: 43 additions & 5 deletions src/pages/settings/Wallet/PaymentMethodList.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ import OfflineWithFeedback from '../../../components/OfflineWithFeedback';
import * as PaymentMethods from '../../../libs/actions/PaymentMethods';
import Log from '../../../libs/Log';
import stylePropTypes from '../../../styles/stylePropTypes';
import Navigation from '../../../libs/Navigation/Navigation';
import ROUTES from '../../../ROUTES';
import getBankIcon from '../../../components/Icon/BankIcons';
import assignedCardPropTypes from './assignedCardPropTypes';

const propTypes = {
/** What to do when a menu item is pressed */
Expand All @@ -31,12 +35,21 @@ const propTypes = {
/** List of bank accounts */
bankAccountList: PropTypes.objectOf(bankAccountPropTypes),

/** List of assigned cards */
cardList: PropTypes.objectOf(assignedCardPropTypes),

/** List of user's cards */
fundList: PropTypes.objectOf(cardPropTypes),

/** Whether the add bank account button should be shown on the list */
shouldShowAddBankAccount: PropTypes.bool,

/** Whether the add Payment button be shown on the list */
shouldShowAddPaymentMethodButton: PropTypes.bool,

/** Whether the assigned cards should be shown on the list */
shouldShowAssignedCards: PropTypes.bool,

/** Whether the empty list message should be shown when the list is empty */
shouldShowEmptyListMessage: PropTypes.bool,

Expand Down Expand Up @@ -84,13 +97,16 @@ const propTypes = {

const defaultProps = {
bankAccountList: {},
cardList: {},
fundList: null,
userWallet: {
walletLinkedAccountID: 0,
walletLinkedAccountType: '',
},
isLoadingPaymentMethods: true,
shouldShowAddBankAccount: true,
shouldShowAddPaymentMethodButton: true,
shouldShowAssignedCards: false,
shouldShowEmptyListMessage: true,
filterType: '',
actionPaymentMethodType: '',
Expand Down Expand Up @@ -161,6 +177,7 @@ function PaymentMethodList({
activePaymentMethodID,
bankAccountList,
buttonRef,
cardList,
fundList,
filterType,
isLoadingPaymentMethods,
Expand All @@ -171,13 +188,30 @@ function PaymentMethodList({
shouldEnableScroll,
shouldShowSelectedState,
shouldShowAddPaymentMethodButton,
shouldShowAddBankAccount,
shouldShowEmptyListMessage,
shouldShowAssignedCards,
selectedMethodID,
style,
translate,
}) {
const filteredPaymentMethods = useMemo(() => {
const paymentCardList = fundList || {};

if (shouldShowAssignedCards) {
const assignedCards = _.filter(cardList, (card) => CONST.EXPENSIFY_CARD.ACTIVE_STATES.includes(card.state));
return _.map(assignedCards, (card) => {
const icon = getBankIcon(card.bank);
return {
key: card.key,
title: translate('walletPage.expensifyCard'),
description: card.domainName,
onPress: () => Navigation.navigate(ROUTES.SETTINGS_WALLET_DOMAINCARDS.getRoute(card.domainName)),
...icon,
};
});
}

// Hide any billing cards that are not P2P debit cards for now because you cannot make them your default method, or delete them
const filteredCardList = _.filter(paymentCardList, (card) => card.accountData.additionalData.isP2PDebitCard);
let combinedPaymentMethods = PaymentUtils.formatPaymentMethods(bankAccountList, filteredCardList);
Expand All @@ -204,14 +238,14 @@ function PaymentMethodList({
}));

return combinedPaymentMethods;
}, [actionPaymentMethodType, activePaymentMethodID, bankAccountList, filterType, network, onPress, fundList]);
}, [fundList, shouldShowAssignedCards, bankAccountList, filterType, network.isOffline, cardList, translate, actionPaymentMethodType, activePaymentMethodID, onPress]);

/**
* Render placeholder when there are no payments methods
*
* @return {React.Component}
*/
const renderListEmptyComponent = useCallback(() => <Text style={[styles.popoverMenuItem]}>{translate('paymentMethodList.addFirstPaymentMethod')}</Text>, [translate]);
const renderListEmptyComponent = () => <Text style={[styles.popoverMenuItem]}>{translate('paymentMethodList.addFirstPaymentMethod')}</Text>;

const renderListFooterComponent = useCallback(
() => (
Expand Down Expand Up @@ -252,12 +286,13 @@ function PaymentMethodList({
iconWidth={item.iconSize}
badgeText={shouldShowDefaultBadge(filteredPaymentMethods, item.isDefault) ? translate('paymentMethodList.defaultPaymentMethod') : null}
wrapperStyle={styles.paymentMethod}
shouldShowRightIcon={shouldShowAssignedCards}
shouldShowSelectedState={shouldShowSelectedState}
isSelected={selectedMethodID === item.methodID}
/>
</OfflineWithFeedback>
),
[filteredPaymentMethods, translate, shouldShowSelectedState, selectedMethodID],
[filteredPaymentMethods, translate, shouldShowAssignedCards, shouldShowSelectedState, selectedMethodID],
);

return (
Expand All @@ -266,9 +301,9 @@ function PaymentMethodList({
data={filteredPaymentMethods}
renderItem={renderItem}
keyExtractor={(item) => item.key}
ListEmptyComponent={shouldShowEmptyListMessage ? renderListEmptyComponent(translate) : null}
ListEmptyComponent={shouldShowEmptyListMessage ? renderListEmptyComponent : null}
ListHeaderComponent={listHeaderComponent}
ListFooterComponent={renderListFooterComponent}
ListFooterComponent={shouldShowAddBankAccount ? renderListFooterComponent : null}
onContentSizeChange={onListContentSizeChange}
scrollEnabled={shouldEnableScroll}
style={style}
Expand Down Expand Up @@ -307,6 +342,9 @@ export default compose(
bankAccountList: {
key: ONYXKEYS.BANK_ACCOUNT_LIST,
},
cardList: {
key: ONYXKEYS.CARD_LIST,
},
fundList: {
key: ONYXKEYS.FUND_LIST,
},
Expand Down
21 changes: 21 additions & 0 deletions src/pages/settings/Wallet/WalletPage/WalletPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,27 @@ function WalletPage({bankAccountList, betas, cardList, fundList, isLoadingPaymen
</>
</WalletSection>
)}
{hasAssignedCard ? (
<WalletSection
icon={Illustrations.CreditCardsNew}
subtitle={translate('walletPage.assignedCardsDescription')}
title={translate('walletPage.assignedCards')}
>
<PaymentMethodList
shouldShowAddBankAccount={false}
shouldShowAddPaymentMethodButton={false}
shouldShowAssignedCards
shouldShowEmptyListMessage={false}
onPress={paymentMethodPressed}
style={styles.mt5}
isAddPaymentMenuActive={shouldShowAddPaymentMenu}
actionPaymentMethodType={shouldShowDefaultDeleteMenu ? paymentMethod.selectedPaymentMethodType : ''}
activePaymentMethodID={shouldShowDefaultDeleteMenu ? getSelectedPaymentMethodID() : ''}
buttonRef={addPaymentMethodAnchorRef}
onListContentSizeChange={shouldShowAddPaymentMenu || shouldShowDefaultDeleteMenu ? setMenuPosition : () => {}}
/>
</WalletSection>
) : null}
<WalletSection
icon={Illustrations.BankArrow}
subtitle={translate('walletPage.addBankAccountToSendAndReceive')}
Expand Down
5 changes: 1 addition & 4 deletions src/pages/settings/Wallet/assignedCardPropTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,11 @@ const assignedCardPropTypes = PropTypes.shape({
bank: PropTypes.string,
availableSpend: PropTypes.number,
domainName: PropTypes.string,
lastFourPAN: PropTypes.string,
cardName: PropTypes.string,
maskedPan: PropTypes.string,
isVirtual: PropTypes.bool,
fraud: PropTypes.oneOf([CONST.EXPENSIFY_CARD.FRAUD_TYPES.DOMAIN, CONST.EXPENSIFY_CARD.FRAUD_TYPES.USER, CONST.EXPENSIFY_CARD.FRAUD_TYPES.NONE]),
cardholderFirstName: PropTypes.string,
cardholderLastName: PropTypes.string,
errors: PropTypes.objectOf(PropTypes.string),
isLoading: PropTypes.bool,
});

export default assignedCardPropTypes;

0 comments on commit 1db4115

Please sign in to comment.