diff --git a/assets/images/simple-illustrations/simple-illustration__creditcards--green.svg b/assets/images/simple-illustrations/simple-illustration__creditcards--green.svg new file mode 100644 index 000000000000..bd74430af00a --- /dev/null +++ b/assets/images/simple-illustrations/simple-illustration__creditcards--green.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/Icon/Illustrations.ts b/src/components/Icon/Illustrations.ts index fd5eb9f6fd58..93c233321916 100644 --- a/src/components/Icon/Illustrations.ts +++ b/src/components/Icon/Illustrations.ts @@ -89,6 +89,7 @@ import ConciergeBubble from '@assets/images/simple-illustrations/simple-illustra import ConciergeNew from '@assets/images/simple-illustrations/simple-illustration__concierge.svg'; import CreditCardsNew from '@assets/images/simple-illustrations/simple-illustration__credit-cards.svg'; import CreditCardEyes from '@assets/images/simple-illustrations/simple-illustration__creditcardeyes.svg'; +import CreditCardsNewGreen from '@assets/images/simple-illustrations/simple-illustration__creditcards--green.svg'; import EmailAddress from '@assets/images/simple-illustrations/simple-illustration__email-address.svg'; import EmptyState from '@assets/images/simple-illustrations/simple-illustration__empty-state.svg'; import EnvelopeReceipt from '@assets/images/simple-illustrations/simple-illustration__envelopereceipt.svg'; @@ -198,6 +199,7 @@ export { MoneyReceipts, PinkBill, CreditCardsNew, + CreditCardsNewGreen, InvoiceBlue, LaptopwithSecondScreenandHourglass, LockOpen, diff --git a/src/languages/en.ts b/src/languages/en.ts index 5ee0b939049e..70a3b2db9144 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -3804,6 +3804,9 @@ const translations = { noAccountsFound: 'No accounts found', defaultCard: 'Default card', noAccountsFoundDescription: ({connection}: ConnectionParams) => `Please add the account in ${connection} and sync the connection again.`, + expensifyCardBannerTitle: 'Get the Expensify Card', + expensifyCardBannerSubtitle: 'Enjoy cash back on every US purchase, up to 50% off your Expensify bill, unlimited virtual cards, and so much more.', + expensifyCardBannerLearnMoreButton: 'Learn more', }, workflows: { title: 'Workflows', diff --git a/src/languages/es.ts b/src/languages/es.ts index 104dc52fd85b..8096bff07ae0 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -3850,6 +3850,10 @@ const translations = { noAccountsFound: 'No se han encontrado cuentas', defaultCard: 'Tarjeta predeterminada', noAccountsFoundDescription: ({connection}: ConnectionParams) => `Añade la cuenta en ${connection} y sincroniza la conexión de nuevo.`, + expensifyCardBannerTitle: 'Obtén la Tarjeta Expensify', + expensifyCardBannerSubtitle: + 'Disfruta de una devolución en cada compra en Estados Unidos, hasta un 50% de descuento en tu factura de Expensify, tarjetas virtuales ilimitadas y mucho más.', + expensifyCardBannerLearnMoreButton: 'Más información', }, workflows: { title: 'Flujos de trabajo', diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index dae199a34dd7..5798f45dde72 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -1091,6 +1091,12 @@ function goBackWhenEnableFeature(policyID: string) { }, CONST.WORKSPACE_ENABLE_FEATURE_REDIRECT_DELAY); } +function navigateToExpensifyCardPage(policyID: string) { + Navigation.setNavigationActionToMicrotaskQueue(() => { + Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD.getRoute(policyID)); + }); +} + function getConnectedIntegration(policy: Policy | undefined, accountingIntegrations?: ConnectionName[]) { return (accountingIntegrations ?? Object.values(CONST.POLICY.CONNECTIONS.NAME)).find((integration) => !!policy?.connections?.[integration]); } @@ -1422,6 +1428,7 @@ export { sortWorkspacesBySelected, removePendingFieldsFromCustomUnit, goBackWhenEnableFeature, + navigateToExpensifyCardPage, getIntegrationLastSuccessfulDate, getCurrentConnectionName, getCustomersOrJobsLabelNetSuite, diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 2cad24efea7f..a65b3493171e 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -73,7 +73,7 @@ import * as NumberUtils from '@libs/NumberUtils'; import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as PhoneNumber from '@libs/PhoneNumber'; import * as PolicyUtils from '@libs/PolicyUtils'; -import {goBackWhenEnableFeature} from '@libs/PolicyUtils'; +import {goBackWhenEnableFeature, navigateToExpensifyCardPage} from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import type {PolicySelector} from '@pages/home/sidebar/FloatingActionButtonAndPopover'; import * as PaymentMethods from '@userActions/PaymentMethods'; @@ -2851,7 +2851,7 @@ function savePreferredExportMethod(policyID: string, exportMethod: ReportExportT Onyx.merge(`${ONYXKEYS.LAST_EXPORT_METHOD}`, {[policyID]: exportMethod}); } -function enableExpensifyCard(policyID: string, enabled: boolean) { +function enableExpensifyCard(policyID: string, enabled: boolean, shouldNavigateToExpensifyCardPage = false) { const authToken = NetworkStore.getAuthToken(); if (!authToken) { return; @@ -2898,6 +2898,11 @@ function enableExpensifyCard(policyID: string, enabled: boolean) { API.write(WRITE_COMMANDS.ENABLE_POLICY_EXPENSIFY_CARDS, parameters, onyxData); + if (enabled && shouldNavigateToExpensifyCardPage) { + navigateToExpensifyCardPage(policyID); + return; + } + if (enabled && getIsNarrowLayout()) { goBackWhenEnableFeature(policyID); } diff --git a/src/pages/workspace/companyCards/WorkspaceCompanyCardExpensifyCardPromotionBanner.tsx b/src/pages/workspace/companyCards/WorkspaceCompanyCardExpensifyCardPromotionBanner.tsx new file mode 100644 index 000000000000..0a4d73bb9e7e --- /dev/null +++ b/src/pages/workspace/companyCards/WorkspaceCompanyCardExpensifyCardPromotionBanner.tsx @@ -0,0 +1,71 @@ +import React, {useCallback, useMemo} from 'react'; +import {View} from 'react-native'; +import type {OnyxEntry} from 'react-native-onyx'; +import Button from '@components/Button'; +import {CreditCardsNewGreen} from '@components/Icon/Illustrations'; +import useLocalize from '@hooks/useLocalize'; +import useResponsiveLayout from '@hooks/useResponsiveLayout'; +import useStyleUtils from '@hooks/useStyleUtils'; +import useTheme from '@hooks/useTheme'; +import useThemeStyles from '@hooks/useThemeStyles'; +import {enableExpensifyCard} from '@libs/actions/Policy/Policy'; +import {navigateToExpensifyCardPage} from '@libs/PolicyUtils'; +import BillingBanner from '@pages/settings/Subscription/CardSection/BillingBanner/BillingBanner'; +import type {Policy} from '@src/types/onyx'; + +type WorkspaceCompanyCardExpensifyCardPromotionBannerProps = { + policy: OnyxEntry; +}; + +function WorkspaceCompanyCardExpensifyCardPromotionBanner({policy}: WorkspaceCompanyCardExpensifyCardPromotionBannerProps) { + const theme = useTheme(); + const styles = useThemeStyles(); + const {translate} = useLocalize(); + const StyleUtils = useStyleUtils(); + const {shouldUseNarrowLayout} = useResponsiveLayout(); + const policyID = policy?.id; + const areExpensifyCardsEnabled = policy?.areExpensifyCardsEnabled; + + const handleLearnMore = useCallback(() => { + if (!policyID) { + return; + } + + if (areExpensifyCardsEnabled) { + navigateToExpensifyCardPage(policyID); + return; + } + + enableExpensifyCard(policyID, true, true); + }, [policyID, areExpensifyCardsEnabled]); + + const rightComponent = useMemo(() => { + const smallScreenStyle = shouldUseNarrowLayout ? [styles.flex0, styles.flexBasis100, styles.justifyContentCenter] : []; + return ( + +