diff --git a/src/components/Icon/Illustrations.ts b/src/components/Icon/Illustrations.ts index 80b1d6b64e03..95cdc44356fc 100644 --- a/src/components/Icon/Illustrations.ts +++ b/src/components/Icon/Illustrations.ts @@ -52,39 +52,9 @@ import ToddBehindCloud from '@assets/images/product-illustrations/todd-behind-cl import ToddInCar from '@assets/images/product-illustrations/todd-in-car.svg'; import ToddWithPhones from '@assets/images/product-illustrations/todd-with-phones.svg'; import RunningTurtle from '@assets/images/running-turtle.svg'; -import Puzzle from '@assets/images/simple-illustrations/emptystate__puzzlepieces.svg'; -import Abacus from '@assets/images/simple-illustrations/simple-illustration__abacus.svg'; -import Alert from '@assets/images/simple-illustrations/simple-illustration__alert.svg'; -import Approval from '@assets/images/simple-illustrations/simple-illustration__approval.svg'; -import Binoculars from '@assets/images/simple-illustrations/simple-illustration__binoculars.svg'; import BlueShield from '@assets/images/simple-illustrations/simple-illustration__blueshield.svg'; -import Buildings from '@assets/images/simple-illustrations/simple-illustration__buildings.svg'; import CarIce from '@assets/images/simple-illustrations/simple-illustration__car-ice.svg'; -import Car from '@assets/images/simple-illustrations/simple-illustration__car.svg'; -import PinkCar from '@assets/images/simple-illustrations/simple-illustration__car_pink.svg'; -import ChatBubbles from '@assets/images/simple-illustrations/simple-illustration__chatbubbles.svg'; -import CheckmarkCircle from '@assets/images/simple-illustrations/simple-illustration__checkmarkcircle.svg'; -import CommentBubbles from '@assets/images/simple-illustrations/simple-illustration__commentbubbles.svg'; -import ConciergeBubble from '@assets/images/simple-illustrations/simple-illustration__concierge-bubble.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 EmptyShelves from '@assets/images/simple-illustrations/simple-illustration__empty-shelves.svg'; -import Encryption from '@assets/images/simple-illustrations/simple-illustration__encryption.svg'; -import EnvelopeReceipt from '@assets/images/simple-illustrations/simple-illustration__envelopereceipt.svg'; -import Filters from '@assets/images/simple-illustrations/simple-illustration__filters.svg'; -import Flash from '@assets/images/simple-illustrations/simple-illustration__flash.svg'; -import Gears from '@assets/images/simple-illustrations/simple-illustration__gears.svg'; -import HeadSet from '@assets/images/simple-illustrations/simple-illustration__headset.svg'; -import Hourglass from '@assets/images/simple-illustrations/simple-illustration__hourglass.svg'; -import House from '@assets/images/simple-illustrations/simple-illustration__house.svg'; -import Lightbulb from '@assets/images/simple-illustrations/simple-illustration__lightbulb.svg'; -import LockClosed from '@assets/images/simple-illustrations/simple-illustration__lockclosed.svg'; -import LockClosedOrange from '@assets/images/simple-illustrations/simple-illustration__lockclosed_orange.svg'; -import LockOpen from '@assets/images/simple-illustrations/simple-illustration__lockopen.svg'; -import Luggage from '@assets/images/simple-illustrations/simple-illustration__luggage.svg'; import MagnifyingGlassReceipt from '@assets/images/simple-illustrations/simple-illustration__magnifyingglass-receipt.svg'; -import Mailbox from '@assets/images/simple-illustrations/simple-illustration__mailbox.svg'; import ExpensifyMobileApp from '@assets/images/simple-illustrations/simple-illustration__mobileapp.svg'; import MoneyIntoWallet from '@assets/images/simple-illustrations/simple-illustration__moneyintowallet.svg'; import OpenSafe from '@assets/images/simple-illustrations/simple-illustration__opensafe.svg'; @@ -118,20 +88,14 @@ import TurtleInShell from '@assets/images/turtle-in-shell.svg'; export { Abracadabra, - Encryption, BrokenMagnifyingGlass, - ChatBubbles, - PinkCar, Computer, - EmailAddress, EmptyCardState, EmptyStateExpenses, - EnvelopeReceipt, ExpensifyCardImage, PaymentHands, MagicCode, MagnifyingGlassReceipt, - Mailbox, MushroomTopHat, RocketBlue, RocketDude, @@ -141,61 +105,39 @@ export { ToddInCar, ShieldYellow, BrokenCompanyCardBankConnection, - CreditCardsNewGreen, LaptopWithSecondScreenAndHourglass, LaptopWithSecondScreenSync, LaptopWithSecondScreenX, - LockOpen, - Luggage, MoneyIntoWallet, - ConciergeBubble, TreasureChest, ThumbsUpStars, Hands, - HeadSet, SmartScan, - Hourglass, - CommentBubbles, TrashCan, Profile, - Puzzle, PalmTree, - LockClosed, - Gears, QRCode, RealtimeReport, HoldExpense, ReceiptFairy, - Approval, PendingBank, ThreeLeggedLaptopWoman, - House, - Buildings, - Alert, TeachersUnite, - Abacus, - Binoculars, ReceiptUpload, SplitBill, PiggyBank, Pillow, - Car, Pencil, CarIce, ReceiptLocationMarker, - Lightbulb, Stopwatch, SubscriptionAnnual, SubscriptionPPU, ExpensifyApprovedLogo, SendMoney, - CheckmarkCircle, - CreditCardEyes, - LockClosedOrange, FolderWithPapers, VirtualCard, Tire, - Filters, RunningTurtle, CompanyCardsPendingState, VisaCompanyCardDetail, @@ -220,7 +162,6 @@ export { StripeCompanyCardDetailLarge, VisaCompanyCardDetailLarge, WellsFargoCompanyCardDetailLarge, - Flash, ExpensifyMobileApp, ModalHoldOrReject, ThumbsDown, @@ -229,7 +170,6 @@ export { ReceiptsStackedOnPin, PaperAirplane, CardReplacementSuccess, - EmptyShelves, BlueShield, OpenSafe, LaptopOnDeskWithCoffeeAndKey, diff --git a/src/components/Icon/chunks/illustrations.chunk.ts b/src/components/Icon/chunks/illustrations.chunk.ts index bb0851f18f1f..6e80127ba2d7 100644 --- a/src/components/Icon/chunks/illustrations.chunk.ts +++ b/src/components/Icon/chunks/illustrations.chunk.ts @@ -14,18 +14,48 @@ import LaptopWithSecondScreenX from '@assets/images/laptop-with-second-screen-x. import ModalHoldOrReject from '@assets/images/product-illustrations/modal-hold-or-reject.svg'; import TeleScope from '@assets/images/product-illustrations/telescope.svg'; import ToddBehindCloud from '@assets/images/product-illustrations/todd-behind-cloud.svg'; -// Simple Illustrations - Core ones that are actually used +// Simple Illustrations - Bucket 3 (Common) +import Puzzle from '@assets/images/simple-illustrations/emptystate__puzzlepieces.svg'; +import Abacus from '@assets/images/simple-illustrations/simple-illustration__abacus.svg'; +// Simple Illustrations - Original core ones import Accounting from '@assets/images/simple-illustrations/simple-illustration__accounting.svg'; +import Alert from '@assets/images/simple-illustrations/simple-illustration__alert.svg'; +import Approval from '@assets/images/simple-illustrations/simple-illustration__approval.svg'; +import Binoculars from '@assets/images/simple-illustrations/simple-illustration__binoculars.svg'; import BlueShield from '@assets/images/simple-illustrations/simple-illustration__blueshield.svg'; import Building from '@assets/images/simple-illustrations/simple-illustration__building.svg'; +import Buildings from '@assets/images/simple-illustrations/simple-illustration__buildings.svg'; import CarIce from '@assets/images/simple-illustrations/simple-illustration__car-ice.svg'; +import Car from '@assets/images/simple-illustrations/simple-illustration__car.svg'; +import PinkCar from '@assets/images/simple-illustrations/simple-illustration__car_pink.svg'; +import ChatBubbles from '@assets/images/simple-illustrations/simple-illustration__chatbubbles.svg'; +import CheckmarkCircle from '@assets/images/simple-illustrations/simple-illustration__checkmarkcircle.svg'; import Coins from '@assets/images/simple-illustrations/simple-illustration__coins.svg'; +import CommentBubbles from '@assets/images/simple-illustrations/simple-illustration__commentbubbles.svg'; +import ConciergeBubble from '@assets/images/simple-illustrations/simple-illustration__concierge-bubble.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 EmptyShelves from '@assets/images/simple-illustrations/simple-illustration__empty-shelves.svg'; +import Encryption from '@assets/images/simple-illustrations/simple-illustration__encryption.svg'; +import EnvelopeReceipt from '@assets/images/simple-illustrations/simple-illustration__envelopereceipt.svg'; +import Filters from '@assets/images/simple-illustrations/simple-illustration__filters.svg'; +import Flash from '@assets/images/simple-illustrations/simple-illustration__flash.svg'; import FolderOpen from '@assets/images/simple-illustrations/simple-illustration__folder-open.svg'; +import Gears from '@assets/images/simple-illustrations/simple-illustration__gears.svg'; import HandCard from '@assets/images/simple-illustrations/simple-illustration__handcard.svg'; +import HeadSet from '@assets/images/simple-illustrations/simple-illustration__headset.svg'; +import Hourglass from '@assets/images/simple-illustrations/simple-illustration__hourglass.svg'; +import House from '@assets/images/simple-illustrations/simple-illustration__house.svg'; import InvoiceBlue from '@assets/images/simple-illustrations/simple-illustration__invoice.svg'; +import Lightbulb from '@assets/images/simple-illustrations/simple-illustration__lightbulb.svg'; +import LockClosed from '@assets/images/simple-illustrations/simple-illustration__lockclosed.svg'; +import LockClosedOrange from '@assets/images/simple-illustrations/simple-illustration__lockclosed_orange.svg'; +import LockOpen from '@assets/images/simple-illustrations/simple-illustration__lockopen.svg'; import Luggage from '@assets/images/simple-illustrations/simple-illustration__luggage.svg'; import MagnifyingGlassMoney from '@assets/images/simple-illustrations/simple-illustration__magnifyingglass-money.svg'; +import Mailbox from '@assets/images/simple-illustrations/simple-illustration__mailbox.svg'; import MoneyReceipts from '@assets/images/simple-illustrations/simple-illustration__money-receipts.svg'; import MoneyWings from '@assets/images/simple-illustrations/simple-illustration__moneywings.svg'; import Pencil from '@assets/images/simple-illustrations/simple-illustration__pencil.svg'; @@ -34,6 +64,7 @@ import RealtimeReport from '@assets/images/simple-illustrations/simple-illustrat import ReceiptWrangler from '@assets/images/simple-illustrations/simple-illustration__receipt-wrangler.svg'; import ReportReceipt from '@assets/images/simple-illustrations/simple-illustration__report-receipt.svg'; import Rules from '@assets/images/simple-illustrations/simple-illustration__rules.svg'; +import ShieldYellow from '@assets/images/simple-illustrations/simple-illustration__shield.svg'; import Stopwatch from '@assets/images/simple-illustrations/simple-illustration__stopwatch.svg'; import Tag from '@assets/images/simple-illustrations/simple-illustration__tag.svg'; import ThumbsDown from '@assets/images/simple-illustrations/simple-illustration__thumbsdown.svg'; @@ -61,7 +92,7 @@ const Illustrations = { Telescope: TeleScope, // Alias for consistency ToddBehindCloud, - // Simple Illustrations + // Simple Illustrations - Original Accounting, Building, Coins, @@ -86,8 +117,38 @@ const Illustrations = { BlueShield, Pencil, Luggage, - // Legacy aliases for compatibility - Car: CompanyCard, // Fallback for Car illustration requests + + // Simple Illustrations - Bucket 3 (Common) + Puzzle, + Abacus, + Alert, + Approval, + Binoculars, + Buildings, + Car, + PinkCar, + ChatBubbles, + CheckmarkCircle, + CommentBubbles, + ConciergeBubble, + CreditCardEyes, + CreditCardsNewGreen, + EmailAddress, + EmptyShelves, + Encryption, + EnvelopeReceipt, + Filters, + Flash, + Gears, + HeadSet, + Hourglass, + House, + Lightbulb, + LockClosed, + LockClosedOrange, + LockOpen, + Mailbox, + ShieldYellow, }; /** diff --git a/src/components/OnboardingHelpDropdownButton.tsx b/src/components/OnboardingHelpDropdownButton.tsx index 74bb8ee16b08..c5f99dd05fb4 100644 --- a/src/components/OnboardingHelpDropdownButton.tsx +++ b/src/components/OnboardingHelpDropdownButton.tsx @@ -2,6 +2,7 @@ import {accountIDSelector} from '@selectors/Session'; import {addMinutes} from 'date-fns'; import React from 'react'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -17,7 +18,6 @@ import type {ReportNameValuePairs} from '@src/types/onyx'; import ButtonWithDropdownMenu from './ButtonWithDropdownMenu'; import type {DropdownOption, OnboardingHelpType} from './ButtonWithDropdownMenu/types'; import {CalendarSolid, Close, Monitor} from './Icon/Expensicons'; -import * as Illustrations from './Icon/Illustrations'; type OnboardingHelpButtonProps = { /** The ID of onboarding chat report */ @@ -51,6 +51,8 @@ function OnboardingHelpDropdownButton({reportID, shouldUseNarrowLayout, shouldSh const currentUserPersonalDetails = useCurrentUserPersonalDetails(); const userTimezone = currentUserPersonalDetails?.timezone?.selected ? currentUserPersonalDetails?.timezone.selected : CONST.DEFAULT_TIME_ZONE.selected; + const illustrations = useMemoizedLazyIllustrations(['HeadSet'] as const); + if (!reportID || !accountID) { return null; } @@ -84,7 +86,7 @@ function OnboardingHelpDropdownButton({reportID, shouldUseNarrowLayout, shouldSh )} ${DateUtils.getZoneAbbreviation(new Date(latestScheduledCall.eventTime), userTimezone)}`, descriptionTextStyle: [styles.themeTextColor, styles.ml2], displayInDefaultIconColor: true, - icon: Illustrations.HeadSet, + icon: illustrations.HeadSet, iconWidth: variables.avatarSizeLargeNormal, iconHeight: variables.avatarSizeLargeNormal, wrapperStyle: [styles.mb3, styles.pl4, styles.pr5, styles.pt3, styles.pb6, styles.borderBottom], diff --git a/src/libs/SubscriptionUtils.ts b/src/libs/SubscriptionUtils.ts index 2f940513152a..653229f5fc79 100644 --- a/src/libs/SubscriptionUtils.ts +++ b/src/libs/SubscriptionUtils.ts @@ -2,9 +2,7 @@ import {differenceInSeconds, fromUnixTime, isAfter, isBefore} from 'date-fns'; import {fromZonedTime} from 'date-fns-tz'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; -import type {SvgProps} from 'react-native-svg'; import type {ValueOf} from 'type-fest'; -import * as Illustrations from '@components/Icon/Illustrations'; import type {LocalizedTranslate} from '@components/LocaleContextProvider'; import type {PreferredCurrency} from '@hooks/usePreferredCurrency'; import type {PersonalPolicyTypeExcludedProps} from '@pages/settings/Subscription/SubscriptionPlan/SubscriptionPlanCard'; @@ -13,6 +11,7 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {BillingGraceEndPeriod, BillingStatus, Fund, FundList, IntroSelected, Policy, StripeCustomerID} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; +import type IconAsset from '@src/types/utils/IconAsset'; import {convertToShortDisplayString} from './CurrencyUtils'; import {getOwnedPaidPolicies, isPolicyOwner} from './PolicyUtils'; @@ -44,10 +43,15 @@ type SubscriptionPlanInfo = { subtitle: string; note: string | undefined; benefits: string[]; - src: React.FC; + src: IconAsset; description: string; }; +type SubscriptionPlanIllustrations = { + Mailbox: IconAsset; + ShieldYellow: IconAsset; +}; + let currentUserAccountID = -1; Onyx.connect({ key: ONYXKEYS.SESSION, @@ -555,6 +559,7 @@ function getSubscriptionPlanInfo( preferredCurrency: PreferredCurrency, isFromComparisonModal: boolean, hasTeam2025Pricing: boolean, + illustrations: Record<'Mailbox' | 'ShieldYellow', IconAsset>, ): SubscriptionPlanInfo { const priceValue = getSubscriptionPrice(subscriptionPlan, preferredCurrency, privateSubscriptionType, hasTeam2025Pricing); const price = convertToShortDisplayString(priceValue, preferredCurrency); @@ -587,7 +592,7 @@ function getSubscriptionPlanInfo( translate('subscription.yourPlan.collect.benefit7'), translate('subscription.yourPlan.collect.benefit8'), ], - src: Illustrations.Mailbox, + src: illustrations.Mailbox, description: translate('subscription.yourPlan.collect.description'), }; } @@ -606,7 +611,7 @@ function getSubscriptionPlanInfo( translate('subscription.yourPlan.control.benefit7'), translate('subscription.yourPlan.control.benefit8'), ], - src: Illustrations.ShieldYellow, + src: illustrations.ShieldYellow, description: translate('subscription.yourPlan.control.description'), }; } @@ -634,3 +639,5 @@ export { getSubscriptionPlanInfo, getSubscriptionPrice, }; + +export type {SubscriptionPlanIllustrations}; diff --git a/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx b/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx index 8ee9ab3f4047..79ec95623275 100644 --- a/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx +++ b/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx @@ -1,5 +1,5 @@ import {useIsFocused} from '@react-navigation/native'; -import React, {useCallback, useImperativeHandle, useRef} from 'react'; +import React, {useCallback, useImperativeHandle, useMemo, useRef} from 'react'; import {InteractionManager, View} from 'react-native'; import {ScrollView} from 'react-native-gesture-handler'; import FormHelpMessage from '@components/FormHelpMessage'; @@ -9,6 +9,7 @@ import type {MenuItemProps} from '@components/MenuItem'; import MenuItemList from '@components/MenuItemList'; import ScreenWrapper from '@components/ScreenWrapper'; import Text from '@components/Text'; +import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useOnboardingMessages from '@hooks/useOnboardingMessages'; import useOnyx from '@hooks/useOnyx'; @@ -39,17 +40,21 @@ function getOnboardingChoices(customChoices: OnboardingPurpose[]) { return selectableOnboardingChoices.filter((choice) => customChoices.includes(choice)); } -const menuIcons = { - [CONST.ONBOARDING_CHOICES.EMPLOYER]: Illustrations.ReceiptUpload, - [CONST.ONBOARDING_CHOICES.MANAGE_TEAM]: Illustrations.Abacus, - [CONST.ONBOARDING_CHOICES.PERSONAL_SPEND]: Illustrations.PiggyBank, - [CONST.ONBOARDING_CHOICES.CHAT_SPLIT]: Illustrations.SplitBill, - [CONST.ONBOARDING_CHOICES.LOOKING_AROUND]: Illustrations.Binoculars, -}; - function BaseOnboardingPurpose({shouldUseNativeStyles, shouldEnableMaxHeight, route}: BaseOnboardingPurposeProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); + const illustrations = useMemoizedLazyIllustrations(['Abacus', 'Binoculars'] as const); + + const menuIcons = useMemo( + () => ({ + [CONST.ONBOARDING_CHOICES.EMPLOYER]: Illustrations.ReceiptUpload, + [CONST.ONBOARDING_CHOICES.MANAGE_TEAM]: illustrations.Abacus, + [CONST.ONBOARDING_CHOICES.PERSONAL_SPEND]: Illustrations.PiggyBank, + [CONST.ONBOARDING_CHOICES.CHAT_SPLIT]: Illustrations.SplitBill, + [CONST.ONBOARDING_CHOICES.LOOKING_AROUND]: illustrations.Binoculars, + }), + [illustrations.Abacus, illustrations.Binoculars], + ); const {onboardingIsMediumOrLargerScreenWidth} = useResponsiveLayout(); const [account] = useOnyx(ONYXKEYS.ACCOUNT, {canBeMissing: true}); const {onboardingMessages} = useOnboardingMessages(); diff --git a/src/pages/OnboardingWorkEmail/BaseOnboardingWorkEmail.tsx b/src/pages/OnboardingWorkEmail/BaseOnboardingWorkEmail.tsx index ac9155fec631..880285c7b1f1 100644 --- a/src/pages/OnboardingWorkEmail/BaseOnboardingWorkEmail.tsx +++ b/src/pages/OnboardingWorkEmail/BaseOnboardingWorkEmail.tsx @@ -1,6 +1,6 @@ import {useIsFocused} from '@react-navigation/native'; import {PUBLIC_DOMAINS_SET, Str} from 'expensify-common'; -import React, {useCallback, useEffect, useState} from 'react'; +import React, {useCallback, useEffect, useMemo, useState} from 'react'; import {View} from 'react-native'; import AutoEmailLink from '@components/AutoEmailLink'; import Button from '@components/Button'; @@ -16,6 +16,7 @@ import ScreenWrapper from '@components/ScreenWrapper'; import Text from '@components/Text'; import TextInput from '@components/TextInput'; import useAutoFocusInput from '@hooks/useAutoFocusInput'; +import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useOnyx from '@hooks/useOnyx'; @@ -45,6 +46,7 @@ type Item = { function BaseOnboardingWorkEmail({shouldUseNativeStyles}: BaseOnboardingWorkEmailProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); + const illustrations = useMemoizedLazyIllustrations(['EnvelopeReceipt', 'Gears'] as const); const [onboardingValues] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {canBeMissing: true}); const [formValue] = useOnyx(ONYXKEYS.FORMS.ONBOARDING_WORK_EMAIL_FORM, {canBeMissing: true}); const workEmail = formValue?.[INPUT_IDS.ONBOARDING_WORK_EMAIL]; @@ -119,21 +121,24 @@ function BaseOnboardingWorkEmail({shouldUseNativeStyles}: BaseOnboardingWorkEmai return errors; }; - const section: Item[] = [ - { - icon: Illustrations.EnvelopeReceipt, - titleTranslationKey: 'onboarding.workEmail.explanationModal.descriptionOne', - shouldRenderEmail: true, - }, - { - icon: Illustrations.Profile, - titleTranslationKey: 'onboarding.workEmail.explanationModal.descriptionTwo', - }, - { - icon: Illustrations.Gears, - titleTranslationKey: 'onboarding.workEmail.explanationModal.descriptionThree', - }, - ]; + const section: Item[] = useMemo( + () => [ + { + icon: illustrations.EnvelopeReceipt, + titleTranslationKey: 'onboarding.workEmail.explanationModal.descriptionOne', + shouldRenderEmail: true, + }, + { + icon: Illustrations.Profile, + titleTranslationKey: 'onboarding.workEmail.explanationModal.descriptionTwo', + }, + { + icon: illustrations.Gears, + titleTranslationKey: 'onboarding.workEmail.explanationModal.descriptionThree', + }, + ], + [illustrations.EnvelopeReceipt, illustrations.Gears], + ); return (
diff --git a/src/pages/ReimbursementAccount/USD/ConnectBankAccount/components/FinishChatCard.tsx b/src/pages/ReimbursementAccount/USD/ConnectBankAccount/components/FinishChatCard.tsx index 840d0ef32d60..d1cb4aae99de 100644 --- a/src/pages/ReimbursementAccount/USD/ConnectBankAccount/components/FinishChatCard.tsx +++ b/src/pages/ReimbursementAccount/USD/ConnectBankAccount/components/FinishChatCard.tsx @@ -1,10 +1,10 @@ import React from 'react'; import {ChatBubble, Pencil, RotateLeft} from '@components/Icon/Expensicons'; -import {ConciergeBubble} from '@components/Icon/Illustrations'; import MenuItem from '@components/MenuItem'; import ScrollView from '@components/ScrollView'; import Section from '@components/Section'; import Text from '@components/Text'; +import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -34,11 +34,13 @@ function FinishChatCard({requiresTwoFactorAuth, reimbursementAccount, setUSDBank const shouldShowResetModal = reimbursementAccount?.shouldShowResetModal ?? false; const handleNavigateToConciergeChat = () => navigateToConciergeChat(true, undefined, undefined, reimbursementAccount?.achData?.ACHRequestReportActionID); + const illustrations = useMemoizedLazyIllustrations(['ConciergeBubble'] as const); + return (
diff --git a/src/pages/RequireTwoFactorAuthenticationPage.tsx b/src/pages/RequireTwoFactorAuthenticationPage.tsx index 973b2d26f2bd..b9d8c4e13f7a 100644 --- a/src/pages/RequireTwoFactorAuthenticationPage.tsx +++ b/src/pages/RequireTwoFactorAuthenticationPage.tsx @@ -4,9 +4,9 @@ import {View} from 'react-native'; import type {OnyxCollection} from 'react-native-onyx'; import Button from '@components/Button'; import Icon from '@components/Icon'; -import {Encryption} from '@components/Icon/Illustrations'; import ScreenWrapper from '@components/ScreenWrapper'; import Text from '@components/Text'; +import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -34,6 +34,7 @@ const is2FARequiredBecauseOfXeroSelector = (email?: string) => { }; function RequireTwoFactorAuthenticationPage() { + const illustrations = useMemoizedLazyIllustrations(['Encryption'] as const); const styles = useThemeStyles(); const {translate} = useLocalize(); const [isUserValidated = false] = useOnyx(ONYXKEYS.ACCOUNT, {selector: isUserValidatedSelector, canBeMissing: true}); @@ -53,7 +54,7 @@ function RequireTwoFactorAuthenticationPage() { diff --git a/src/pages/RestrictedAction/Workspace/WorkspaceAdminRestrictedAction.tsx b/src/pages/RestrictedAction/Workspace/WorkspaceAdminRestrictedAction.tsx index 8081a479bd9d..59912b9f0c80 100644 --- a/src/pages/RestrictedAction/Workspace/WorkspaceAdminRestrictedAction.tsx +++ b/src/pages/RestrictedAction/Workspace/WorkspaceAdminRestrictedAction.tsx @@ -2,16 +2,16 @@ import React, {useCallback} from 'react'; import {View} from 'react-native'; import Button from '@components/Button'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import * as Illustrations from '@components/Icon/Illustrations'; import ImageSVG from '@components/ImageSVG'; import ScreenWrapper from '@components/ScreenWrapper'; import ScrollView from '@components/ScrollView'; import Text from '@components/Text'; +import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import usePolicy from '@hooks/usePolicy'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; -import * as PolicyUtils from '@libs/PolicyUtils'; +import {getPolicy} from '@libs/PolicyUtils'; import variables from '@styles/variables'; import ROUTES from '@src/ROUTES'; @@ -20,6 +20,7 @@ type WorkspaceAdminRestrictedActionProps = { }; function WorkspaceAdminRestrictedAction({policyID}: WorkspaceAdminRestrictedActionProps) { + const illustrations = useMemoizedLazyIllustrations(['LockClosedOrange'] as const); const {translate} = useLocalize(); const policy = usePolicy(policyID); const styles = useThemeStyles(); @@ -27,7 +28,7 @@ function WorkspaceAdminRestrictedAction({policyID}: WorkspaceAdminRestrictedActi const openAdminsReport = useCallback(() => { // This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850 // eslint-disable-next-line @typescript-eslint/no-deprecated - const reportID = PolicyUtils.getPolicy(policyID)?.chatReportIDAdmins; + const reportID = getPolicy(policyID)?.chatReportIDAdmins; Navigation.closeRHPFlow(); Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(reportID ? String(reportID) : undefined)); }, [policyID]); @@ -47,7 +48,7 @@ function WorkspaceAdminRestrictedAction({policyID}: WorkspaceAdminRestrictedActi > diff --git a/src/pages/RestrictedAction/Workspace/WorkspaceOwnerRestrictedAction/index.native.tsx b/src/pages/RestrictedAction/Workspace/WorkspaceOwnerRestrictedAction/index.native.tsx index 02f0ced2c63e..26d056b92142 100644 --- a/src/pages/RestrictedAction/Workspace/WorkspaceOwnerRestrictedAction/index.native.tsx +++ b/src/pages/RestrictedAction/Workspace/WorkspaceOwnerRestrictedAction/index.native.tsx @@ -5,10 +5,10 @@ import Button from '@components/Button'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; -import * as Illustrations from '@components/Icon/Illustrations'; import ScreenWrapper from '@components/ScreenWrapper'; import ScrollView from '@components/ScrollView'; import Text from '@components/Text'; +import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; @@ -16,6 +16,7 @@ import variables from '@styles/variables'; import ROUTES from '@src/ROUTES'; function WorkspaceOwnerRestrictedAction() { + const illustrations = useMemoizedLazyIllustrations(['LockClosedOrange'] as const); const {translate} = useLocalize(); const styles = useThemeStyles(); @@ -38,7 +39,7 @@ function WorkspaceOwnerRestrictedAction() { diff --git a/src/pages/RestrictedAction/Workspace/WorkspaceOwnerRestrictedAction/index.tsx b/src/pages/RestrictedAction/Workspace/WorkspaceOwnerRestrictedAction/index.tsx index 94462c92f17c..a5e42736c27e 100644 --- a/src/pages/RestrictedAction/Workspace/WorkspaceOwnerRestrictedAction/index.tsx +++ b/src/pages/RestrictedAction/Workspace/WorkspaceOwnerRestrictedAction/index.tsx @@ -5,10 +5,10 @@ import Button from '@components/Button'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; -import * as Illustrations from '@components/Icon/Illustrations'; import ScreenWrapper from '@components/ScreenWrapper'; import ScrollView from '@components/ScrollView'; import Text from '@components/Text'; +import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; @@ -16,6 +16,7 @@ import variables from '@styles/variables'; import ROUTES from '@src/ROUTES'; function WorkspaceOwnerRestrictedAction() { + const illustrations = useMemoizedLazyIllustrations(['LockClosedOrange'] as const); const {translate} = useLocalize(); const styles = useThemeStyles(); @@ -37,7 +38,7 @@ function WorkspaceOwnerRestrictedAction() { diff --git a/src/pages/RestrictedAction/Workspace/WorkspaceUserRestrictedAction.tsx b/src/pages/RestrictedAction/Workspace/WorkspaceUserRestrictedAction.tsx index 01d1dda601aa..97940b4bd05a 100644 --- a/src/pages/RestrictedAction/Workspace/WorkspaceUserRestrictedAction.tsx +++ b/src/pages/RestrictedAction/Workspace/WorkspaceUserRestrictedAction.tsx @@ -2,16 +2,16 @@ import React, {useCallback} from 'react'; import {View} from 'react-native'; import Button from '@components/Button'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import * as Illustrations from '@components/Icon/Illustrations'; import ImageSVG from '@components/ImageSVG'; import ScreenWrapper from '@components/ScreenWrapper'; import ScrollView from '@components/ScrollView'; import Text from '@components/Text'; +import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import usePolicy from '@hooks/usePolicy'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; -import * as ReportUtils from '@libs/ReportUtils'; +import {findPolicyExpenseChatByPolicyID} from '@libs/ReportUtils'; import variables from '@styles/variables'; import ROUTES from '@src/ROUTES'; @@ -20,12 +20,14 @@ type WorkspaceUserRestrictedActionProps = { }; function WorkspaceUserRestrictedAction({policyID}: WorkspaceUserRestrictedActionProps) { + const illustrations = useMemoizedLazyIllustrations(['LockClosedOrange'] as const); const {translate} = useLocalize(); const policy = usePolicy(policyID); const styles = useThemeStyles(); const openPolicyExpenseReport = useCallback(() => { - const reportID = ReportUtils.findPolicyExpenseChatByPolicyID(policyID)?.reportID ?? '-1'; + // eslint-disable-next-line rulesdir/no-default-id-values + const reportID = findPolicyExpenseChatByPolicyID(policyID)?.reportID ?? '-1'; Navigation.closeRHPFlow(); Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(reportID)); }, [policyID]); @@ -45,7 +47,7 @@ function WorkspaceUserRestrictedAction({policyID}: WorkspaceUserRestrictedAction > diff --git a/src/pages/Search/EmptySearchView.tsx b/src/pages/Search/EmptySearchView.tsx index 36f2311e2f98..3227880162a5 100644 --- a/src/pages/Search/EmptySearchView.tsx +++ b/src/pages/Search/EmptySearchView.tsx @@ -11,7 +11,7 @@ import ConfirmModal from '@components/ConfirmModal'; import EmptyStateComponent from '@components/EmptyStateComponent'; import type {EmptyStateButton} from '@components/EmptyStateComponent/types'; import type {FeatureListItem} from '@components/FeatureList'; -import {Alert, PiggyBank} from '@components/Icon/Illustrations'; +import {PiggyBank} from '@components/Icon/Illustrations'; import LottieAnimations from '@components/LottieAnimations'; import type DotLottieAnimation from '@components/LottieAnimations/types'; import MenuItem from '@components/MenuItem'; @@ -24,6 +24,7 @@ import TextLink from '@components/TextLink'; import useCreateEmptyReportConfirmation from '@hooks/useCreateEmptyReportConfirmation'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useIsPaidPolicyAdmin from '@hooks/useIsPaidPolicyAdmin'; +import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import usePermissions from '@hooks/usePermissions'; @@ -81,17 +82,6 @@ type EmptySearchViewItem = { children?: React.ReactNode; }; -const tripsFeatures: FeatureListItem[] = [ - { - icon: PiggyBank, - translationKey: 'travel.features.saveMoney', - }, - { - icon: Alert, - translationKey: 'travel.features.alerts', - }, -]; - type ReportSummary = ReturnType[number]; function EmptySearchView({similarSearchHash, type, hasResults}: EmptySearchViewProps) { @@ -158,6 +148,21 @@ function EmptySearchViewContent({ const StyleUtils = useStyleUtils(); const {translate} = useLocalize(); const styles = useThemeStyles(); + const illustrations = useMemoizedLazyIllustrations(['Alert'] as const); + + const tripsFeatures: FeatureListItem[] = useMemo( + () => [ + { + icon: PiggyBank, + translationKey: 'travel.features.saveMoney', + }, + { + icon: illustrations.Alert, + translationKey: 'travel.features.alerts', + }, + ], + [illustrations.Alert], + ); const [contextMenuAnchor, setContextMenuAnchor] = useState(null); const handleContextMenuAnchorRef = useCallback((node: RNText | null) => { setContextMenuAnchor(node); diff --git a/src/pages/TeachersUnite/ImTeacherUpdateEmailPage.tsx b/src/pages/TeachersUnite/ImTeacherUpdateEmailPage.tsx index a8483b97c2aa..93df99409921 100644 --- a/src/pages/TeachersUnite/ImTeacherUpdateEmailPage.tsx +++ b/src/pages/TeachersUnite/ImTeacherUpdateEmailPage.tsx @@ -3,11 +3,11 @@ import BlockingView from '@components/BlockingViews/BlockingView'; import Button from '@components/Button'; import FixedFooter from '@components/FixedFooter'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import * as Illustrations from '@components/Icon/Illustrations'; import RenderHTML from '@components/RenderHTML'; import ScreenWrapper from '@components/ScreenWrapper'; import Text from '@components/Text'; import useEnvironment from '@hooks/useEnvironment'; +import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; @@ -15,6 +15,7 @@ import variables from '@styles/variables'; import ROUTES from '@src/ROUTES'; function ImTeacherUpdateEmailPage() { + const illustrations = useMemoizedLazyIllustrations(['EmailAddress'] as const); const styles = useThemeStyles(); const {translate} = useLocalize(); const {environmentURL} = useEnvironment(); @@ -29,7 +30,7 @@ function ImTeacherUpdateEmailPage() { diff --git a/src/pages/TransactionMerge/MergeTransactionsListContent.tsx b/src/pages/TransactionMerge/MergeTransactionsListContent.tsx index 5a5f51098bec..189dc707d17a 100644 --- a/src/pages/TransactionMerge/MergeTransactionsListContent.tsx +++ b/src/pages/TransactionMerge/MergeTransactionsListContent.tsx @@ -2,12 +2,12 @@ import React, {useCallback, useEffect, useMemo} from 'react'; import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import EmptyStateComponent from '@components/EmptyStateComponent'; -import {EmptyShelves} from '@components/Icon/Illustrations'; import RenderHTML from '@components/RenderHTML'; import ScrollView from '@components/ScrollView'; import SelectionList from '@components/SelectionListWithSections'; import type {ListItem} from '@components/SelectionListWithSections/types'; import MergeExpensesSkeleton from '@components/Skeletons/MergeExpensesSkeleton'; +import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useOnyx from '@hooks/useOnyx'; @@ -41,6 +41,7 @@ type MergeTransactionsListContentProps = { type MergeTransactionListItemType = Transaction & ListItem; function MergeTransactionsListContent({transactionID, mergeTransaction}: MergeTransactionsListContentProps) { + const illustrations = useMemoizedLazyIllustrations(['EmptyShelves'] as const); const {translate, localeCompare} = useLocalize(); const styles = useThemeStyles(); @@ -155,7 +156,7 @@ function MergeTransactionsListContent({transactionID, mergeTransaction}: MergeTr cardStyles={[styles.appBG]} cardContentStyles={[styles.p0]} headerMediaType={CONST.EMPTY_STATE_MEDIA.ILLUSTRATION} - headerMedia={EmptyShelves} + headerMedia={illustrations.EmptyShelves} title={translate('transactionMerge.listPage.noEligibleExpenseFound')} subtitleText={subTitleContent} headerStyles={[styles.emptyStateCardIllustrationContainer, styles.mb5]} diff --git a/src/pages/Travel/ManageTrips.tsx b/src/pages/Travel/ManageTrips.tsx index 8af395178ab5..2bd4e85556f9 100644 --- a/src/pages/Travel/ManageTrips.tsx +++ b/src/pages/Travel/ManageTrips.tsx @@ -1,4 +1,4 @@ -import React, {useCallback, useRef, useState} from 'react'; +import React, {useCallback, useMemo, useRef, useState} from 'react'; // eslint-disable-next-line no-restricted-imports import type {ScrollView as RNScrollView} from 'react-native'; import {Linking, View} from 'react-native'; @@ -9,28 +9,33 @@ import FeatureList from '@components/FeatureList'; import * as Illustrations from '@components/Icon/Illustrations'; import LottieAnimations from '@components/LottieAnimations'; import ScrollView from '@components/ScrollView'; +import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useThemeStyles from '@hooks/useThemeStyles'; import colors from '@styles/theme/colors'; import CONST from '@src/CONST'; -const tripsFeatures: FeatureListItem[] = [ - { - icon: Illustrations.PiggyBank, - translationKey: 'travel.features.saveMoney', - }, - { - icon: Illustrations.Alert, - translationKey: 'travel.features.alerts', - }, -]; - function ManageTrips() { const styles = useThemeStyles(); const {shouldUseNarrowLayout} = useResponsiveLayout(); const {translate} = useLocalize(); const [shouldScrollToBottom, setShouldScrollToBottom] = useState(false); + const illustrations = useMemoizedLazyIllustrations(['Alert'] as const); + + const tripsFeatures: FeatureListItem[] = useMemo( + () => [ + { + icon: Illustrations.PiggyBank, + translationKey: 'travel.features.saveMoney', + }, + { + icon: illustrations.Alert, + translationKey: 'travel.features.alerts', + }, + ], + [illustrations.Alert], + ); const navigateToBookTravelDemo = () => { Linking.openURL(CONST.BOOK_TRAVEL_DEMO_URL); diff --git a/src/pages/domain/DomainSamlPage.tsx b/src/pages/domain/DomainSamlPage.tsx index 81d2c3e34f8c..0719aede5242 100644 --- a/src/pages/domain/DomainSamlPage.tsx +++ b/src/pages/domain/DomainSamlPage.tsx @@ -1,14 +1,15 @@ import {Str} from 'expensify-common'; -import React from 'react'; +import React, {useMemo} from 'react'; import {View} from 'react-native'; import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; import type {FeatureListItem} from '@components/FeatureList'; import FeatureList from '@components/FeatureList'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import {LaptopOnDeskWithCoffeeAndKey, LockClosed, OpenSafe, ShieldYellow} from '@components/Icon/Illustrations'; +import {LaptopOnDeskWithCoffeeAndKey, OpenSafe, ShieldYellow} from '@components/Icon/Illustrations'; import RenderHTML from '@components/RenderHTML'; import ScreenWrapper from '@components/ScreenWrapper'; import ScrollViewWithContext from '@components/ScrollViewWithContext'; +import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; @@ -24,25 +25,29 @@ import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue'; type DomainSamlPageProps = PlatformStackScreenProps; -const samlFeatures: FeatureListItem[] = [ - { - icon: OpenSafe, - translationKey: 'domain.samlFeatureList.fasterAndEasierLogin', - }, - { - icon: ShieldYellow, - translationKey: 'domain.samlFeatureList.moreSecurityAndControl', - }, - { - icon: LockClosed, - translationKey: 'domain.samlFeatureList.onePasswordForAnything', - }, -]; - function DomainSamlPage({route}: DomainSamlPageProps) { const styles = useThemeStyles(); const {shouldUseNarrowLayout} = useResponsiveLayout(); const {translate} = useLocalize(); + const illustrations = useMemoizedLazyIllustrations(['LockClosed'] as const); + + const samlFeatures: FeatureListItem[] = useMemo( + () => [ + { + icon: OpenSafe, + translationKey: 'domain.samlFeatureList.fasterAndEasierLogin', + }, + { + icon: ShieldYellow, + translationKey: 'domain.samlFeatureList.moreSecurityAndControl', + }, + { + icon: illustrations.LockClosed, + translationKey: 'domain.samlFeatureList.onePasswordForAnything', + }, + ], + [illustrations.LockClosed], + ); const accountID = route.params.accountID; const [domain, domainResults] = useOnyx(`${ONYXKEYS.COLLECTION.DOMAIN}${accountID}`, {canBeMissing: true}); @@ -65,7 +70,7 @@ function DomainSamlPage({route}: DomainSamlPageProps) { diff --git a/src/pages/settings/Preferences/PreferencesPage.tsx b/src/pages/settings/Preferences/PreferencesPage.tsx index 5ecbe872dcb1..266e53e98480 100755 --- a/src/pages/settings/Preferences/PreferencesPage.tsx +++ b/src/pages/settings/Preferences/PreferencesPage.tsx @@ -1,7 +1,6 @@ import React from 'react'; import {View} from 'react-native'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import * as Illustrations from '@components/Icon/Illustrations'; import LottieAnimations from '@components/LottieAnimations'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import ScreenWrapper from '@components/ScreenWrapper'; @@ -9,6 +8,7 @@ import ScrollView from '@components/ScrollView'; import Section from '@components/Section'; import Switch from '@components/Switch'; import Text from '@components/Text'; +import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import usePolicy from '@hooks/usePolicy'; @@ -27,6 +27,7 @@ import ROUTES from '@src/ROUTES'; import {getEmptyObject} from '@src/types/utils/EmptyObject'; function PreferencesPage() { + const illustrations = useMemoizedLazyIllustrations(['Gears'] as const); const [priorityMode] = useOnyx(ONYXKEYS.NVP_PRIORITY_MODE, {canBeMissing: true}); const platform = getPlatform(true); @@ -52,7 +53,7 @@ function PreferencesPage() { > >(); const {environmentURL} = useEnvironment(); const {result, login, backTo} = params; + const illustrations = useMemoizedLazyIllustrations(['LockClosedOrange'] as const); const defaultResult = { heading: translate('mergeAccountsPage.mergeFailureGenericHeading'), buttonText: translate('common.buttonConfirm'), - illustration: Illustrations.LockClosedOrange, + illustration: illustrations.LockClosedOrange, }; const results: Record, ConfirmationPageProps> = useMemo(() => { @@ -68,7 +70,7 @@ function MergeResultPage() { ), onButtonPress: () => Navigation.goBack(ROUTES.SETTINGS_SECURITY), buttonText: translate('common.buttonConfirm'), - illustration: Illustrations.LockClosedOrange, + illustration: illustrations.LockClosedOrange, }, [CONST.MERGE_ACCOUNT_RESULTS.ERR_2FA]: { heading: translate('mergeAccountsPage.mergeFailureGenericHeading'), @@ -81,7 +83,7 @@ function MergeResultPage() { ctaStyle: {...styles.mt2, ...styles.textSupporting}, onButtonPress: () => Navigation.goBack(ROUTES.SETTINGS_SECURITY), buttonText: translate('common.buttonConfirm'), - illustration: Illustrations.LockClosedOrange, + illustration: illustrations.LockClosedOrange, }, [CONST.MERGE_ACCOUNT_RESULTS.ERR_SMART_SCANNER]: { heading: translate('mergeAccountsPage.mergeFailureGenericHeading'), @@ -91,7 +93,7 @@ function MergeResultPage() { ), buttonText: translate('common.buttonConfirm'), - illustration: Illustrations.LockClosedOrange, + illustration: illustrations.LockClosedOrange, onButtonPress: () => Navigation.goBack(ROUTES.SETTINGS_SECURITY), }, [CONST.MERGE_ACCOUNT_RESULTS.ERR_SAML_DOMAIN_CONTROL]: { @@ -103,7 +105,7 @@ function MergeResultPage() { ), buttonText: translate('common.buttonConfirm'), onButtonPress: () => Navigation.goBack(ROUTES.SETTINGS_SECURITY), - illustration: Illustrations.LockClosedOrange, + illustration: illustrations.LockClosedOrange, }, [CONST.MERGE_ACCOUNT_RESULTS.ERR_SAML_NOT_SUPPORTED]: { heading: translate('mergeAccountsPage.mergePendingSAML.weAreWorkingOnIt'), @@ -136,7 +138,7 @@ function MergeResultPage() { ), buttonText: translate('common.buttonConfirm'), onButtonPress: () => Navigation.goBack(ROUTES.SETTINGS_SECURITY), - illustration: Illustrations.LockClosedOrange, + illustration: illustrations.LockClosedOrange, }, [CONST.MERGE_ACCOUNT_RESULTS.ERR_ACCOUNT_LOCKED]: { heading: translate('mergeAccountsPage.mergeFailureGenericHeading'), @@ -147,7 +149,7 @@ function MergeResultPage() { ), buttonText: translate('common.buttonConfirm'), onButtonPress: () => Navigation.goBack(ROUTES.SETTINGS_SECURITY), - illustration: Illustrations.LockClosedOrange, + illustration: illustrations.LockClosedOrange, }, [CONST.MERGE_ACCOUNT_RESULTS.ERR_INVOICING]: { heading: translate('mergeAccountsPage.mergeFailureGenericHeading'), @@ -158,31 +160,31 @@ function MergeResultPage() { ), buttonText: translate('common.buttonConfirm'), onButtonPress: () => Navigation.goBack(ROUTES.SETTINGS_SECURITY), - illustration: Illustrations.LockClosedOrange, + illustration: illustrations.LockClosedOrange, }, [CONST.MERGE_ACCOUNT_RESULTS.TOO_MANY_ATTEMPTS]: { heading: translate('mergeAccountsPage.mergeFailureTooManyAttempts.heading'), description: translate('mergeAccountsPage.mergeFailureTooManyAttempts.description'), buttonText: translate('common.buttonConfirm'), onButtonPress: () => Navigation.goBack(ROUTES.SETTINGS_SECURITY), - illustration: Illustrations.LockClosedOrange, + illustration: illustrations.LockClosedOrange, }, [CONST.MERGE_ACCOUNT_RESULTS.ACCOUNT_UNVALIDATED]: { heading: translate('mergeAccountsPage.mergeFailureGenericHeading'), description: translate('mergeAccountsPage.mergeFailureUnvalidatedAccount.description'), buttonText: translate('common.buttonConfirm'), onButtonPress: () => Navigation.goBack(ROUTES.SETTINGS_SECURITY), - illustration: Illustrations.LockClosedOrange, + illustration: illustrations.LockClosedOrange, }, [CONST.MERGE_ACCOUNT_RESULTS.ERR_MERGE_SELF]: { heading: translate('mergeAccountsPage.mergeFailureGenericHeading'), description: translate('mergeAccountsPage.mergeFailureSelfMerge.description'), buttonText: translate('common.buttonConfirm'), onButtonPress: () => Navigation.goBack(ROUTES.SETTINGS_SECURITY), - illustration: Illustrations.LockClosedOrange, + illustration: illustrations.LockClosedOrange, }, }; - }, [login, translate, userEmailOrPhone, styles, environmentURL]); + }, [login, translate, userEmailOrPhone, styles, environmentURL, illustrations.LockClosedOrange]); useEffect(() => { /** diff --git a/src/pages/settings/Security/SecuritySettingsPage.tsx b/src/pages/settings/Security/SecuritySettingsPage.tsx index cde433a06868..2c8d46f526ea 100644 --- a/src/pages/settings/Security/SecuritySettingsPage.tsx +++ b/src/pages/settings/Security/SecuritySettingsPage.tsx @@ -8,7 +8,6 @@ import {DelegateNoAccessContext} from '@components/DelegateNoAccessModalProvider import HeaderWithBackButton from '@components/HeaderWithBackButton'; import * as Expensicons from '@components/Icon/Expensicons'; import {FallbackAvatar} from '@components/Icon/Expensicons'; -import * as Illustrations from '@components/Icon/Illustrations'; import {LockedAccountContext} from '@components/LockedAccountModalProvider'; import LottieAnimations from '@components/LottieAnimations'; import MenuItem from '@components/MenuItem'; @@ -23,6 +22,7 @@ import Section from '@components/Section'; import Text from '@components/Text'; import TextLink from '@components/TextLink'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import usePrivateSubscription from '@hooks/usePrivateSubscription'; @@ -55,6 +55,7 @@ type BaseMenuItemType = { }; function SecuritySettingsPage() { + const illustrations = useMemoizedLazyIllustrations(['LockClosed'] as const); const styles = useThemeStyles(); const {translate, formatPhoneNumber} = useLocalize(); const waitForNavigate = useWaitForNavigation(); @@ -346,7 +347,7 @@ function SecuritySettingsPage() { title={translate('initialSettingsPage.security')} shouldShowBackButton={shouldUseNarrowLayout} onBackButtonPress={Navigation.popToSidebar} - icon={Illustrations.LockClosed} + icon={illustrations.LockClosed} shouldUseHeadlineHeader shouldDisplaySearchRouter /> diff --git a/src/pages/settings/Security/TwoFactorAuth/DisabledPage.tsx b/src/pages/settings/Security/TwoFactorAuth/DisabledPage.tsx index 423581af2bac..c03a2c7b8f61 100644 --- a/src/pages/settings/Security/TwoFactorAuth/DisabledPage.tsx +++ b/src/pages/settings/Security/TwoFactorAuth/DisabledPage.tsx @@ -2,7 +2,7 @@ import React from 'react'; import BlockingView from '@components/BlockingViews/BlockingView'; import Button from '@components/Button'; import FixedFooter from '@components/FixedFooter'; -import * as Illustrations from '@components/Icon/Illustrations'; +import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import variables from '@styles/variables'; @@ -12,6 +12,7 @@ import ROUTES from '@src/ROUTES'; import TwoFactorAuthWrapper from './TwoFactorAuthWrapper'; function DisabledPage() { + const illustrations = useMemoizedLazyIllustrations(['LockOpen'] as const); const styles = useThemeStyles(); const {translate} = useLocalize(); @@ -21,7 +22,7 @@ function DisabledPage() { title={translate('twoFactorAuth.disableTwoFactorAuth')} > { diff --git a/src/pages/settings/Subscription/CardSection/utils.ts b/src/pages/settings/Subscription/CardSection/utils.ts index 12001745aeec..71d63bbfc447 100644 --- a/src/pages/settings/Subscription/CardSection/utils.ts +++ b/src/pages/settings/Subscription/CardSection/utils.ts @@ -1,7 +1,6 @@ import {addMonths, format, fromUnixTime, startOfMonth} from 'date-fns'; import type {OnyxEntry} from 'react-native-onyx'; import * as Expensicons from '@components/Icon/Expensicons'; -import * as Illustrations from '@components/Icon/Illustrations'; import type {LocaleContextProps} from '@components/LocaleContextProvider'; import {convertAmountToDisplayString} from '@libs/CurrencyUtils'; import DateUtils from '@libs/DateUtils'; @@ -32,6 +31,7 @@ type GetBillingStatusProps = { retryBillingSuccessful: OnyxEntry; billingDisputePending: number | undefined; retryBillingFailed: boolean | undefined; + creditCardEyesIcon?: IconAsset; }; function getBillingStatus({ @@ -42,6 +42,7 @@ function getBillingStatus({ retryBillingSuccessful, billingDisputePending, retryBillingFailed, + creditCardEyesIcon, }: GetBillingStatusProps): BillingStatusResult | undefined { const cardEnding = (accountData?.cardNumber ?? '')?.slice(-4); @@ -140,7 +141,7 @@ function getBillingStatus({ title: translate('subscription.billingBanner.cardExpireSoon.title'), subtitle: translate('subscription.billingBanner.cardExpireSoon.subtitle'), isError: false, - icon: Illustrations.CreditCardEyes, + icon: creditCardEyesIcon, }; case PAYMENT_STATUS.RETRY_BILLING_SUCCESS: diff --git a/src/pages/settings/Subscription/SubscriptionPlan/SubscriptionPlanCard.tsx b/src/pages/settings/Subscription/SubscriptionPlan/SubscriptionPlanCard.tsx index 6e215c94eaf9..e110eb329982 100644 --- a/src/pages/settings/Subscription/SubscriptionPlan/SubscriptionPlanCard.tsx +++ b/src/pages/settings/Subscription/SubscriptionPlan/SubscriptionPlanCard.tsx @@ -6,6 +6,7 @@ import * as Expensicons from '@components/Icon/Expensicons'; import SelectCircle from '@components/SelectCircle'; import Text from '@components/Text'; import useHasTeam2025Pricing from '@hooks/useHasTeam2025Pricing'; +import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import usePreferredCurrency from '@hooks/usePreferredCurrency'; import usePrivateSubscription from '@hooks/usePrivateSubscription'; @@ -40,6 +41,7 @@ function SubscriptionPlanCard({subscriptionPlan, isFromComparisonModal = false, const privateSubscription = usePrivateSubscription(); const preferredCurrency = usePreferredCurrency(); const hasTeam2025Pricing = useHasTeam2025Pricing(); + const lazyIllustrations = useMemoizedLazyIllustrations(['Mailbox', 'ShieldYellow'] as const); const {title, src, description, benefits, note, subtitle} = getSubscriptionPlanInfo( translate, subscriptionPlan, @@ -47,6 +49,7 @@ function SubscriptionPlanCard({subscriptionPlan, isFromComparisonModal = false, preferredCurrency, isFromComparisonModal, hasTeam2025Pricing, + lazyIllustrations, ); const isSelected = isFromComparisonModal && subscriptionPlan === currentSubscriptionPlan; const benefitsColumns = shouldUseNarrowLayout || isFromComparisonModal ? 1 : 2; diff --git a/src/pages/settings/Troubleshoot/TroubleshootPage.tsx b/src/pages/settings/Troubleshoot/TroubleshootPage.tsx index 1d73f4b49a49..de1be276542c 100644 --- a/src/pages/settings/Troubleshoot/TroubleshootPage.tsx +++ b/src/pages/settings/Troubleshoot/TroubleshootPage.tsx @@ -6,7 +6,6 @@ import ConfirmModal from '@components/ConfirmModal'; import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import * as Expensicons from '@components/Icon/Expensicons'; -import * as Illustrations from '@components/Icon/Illustrations'; import ImportOnyxState from '@components/ImportOnyxState'; import LottieAnimations from '@components/LottieAnimations'; import MenuItemList from '@components/MenuItemList'; @@ -21,6 +20,7 @@ import Switch from '@components/Switch'; import TestToolMenu from '@components/TestToolMenu'; import TestToolRow from '@components/TestToolRow'; import useEnvironment from '@hooks/useEnvironment'; +import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; @@ -46,6 +46,7 @@ type BaseMenuItem = { }; function TroubleshootPage() { + const illustrations = useMemoizedLazyIllustrations(['Lightbulb'] as const); const {translate} = useLocalize(); const styles = useThemeStyles(); const {isProduction} = useEnvironment(); @@ -154,7 +155,7 @@ function TroubleshootPage() { shouldShowBackButton={shouldUseNarrowLayout} shouldDisplaySearchRouter onBackButtonPress={Navigation.popToSidebar} - icon={Illustrations.Lightbulb} + icon={illustrations.Lightbulb} shouldUseHeadlineHeader /> {isLoading && } diff --git a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx index bca3dbf5ee89..9e983bc493fd 100644 --- a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx +++ b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx @@ -118,7 +118,20 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro const [quickAction] = useOnyx(ONYXKEYS.NVP_QUICK_ACTION_GLOBAL_CREATE, {canBeMissing: true}); - const illustrations = useMemoizedLazyIllustrations(['FolderOpen', 'Accounting', 'CompanyCard', 'Workflows', 'InvoiceBlue', 'Rules', 'Tag', 'PerDiem', 'HandCard', 'Coins'] as const); + const illustrations = useMemoizedLazyIllustrations([ + 'FolderOpen', + 'Accounting', + 'CompanyCard', + 'Workflows', + 'InvoiceBlue', + 'Rules', + 'Tag', + 'PerDiem', + 'HandCard', + 'Coins', + 'Car', + 'Gears', + ] as const); const onDisabledOrganizeSwitchPress = useCallback(() => { if (!hasAccountingConnection) { @@ -136,7 +149,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro const spendItems: Item[] = [ { - icon: Illustrations.Car, + icon: illustrations.Car, titleTranslationKey: 'workspace.moreFeatures.distanceRates.title', subtitleTranslationKey: 'workspace.moreFeatures.distanceRates.subtitle', isActive: policy?.areDistanceRatesEnabled ?? false, @@ -568,7 +581,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro shouldShowOfflineIndicatorInWideScreen > ; }; -const workspaceTypeIcon = (workspaceType: WorkspacesListRowProps['workspaceType']): IconAsset => { - switch (workspaceType) { - case CONST.POLICY.TYPE.CORPORATE: - return Illustrations.ShieldYellow; - case CONST.POLICY.TYPE.TEAM: - return Illustrations.Mailbox; - default: - return Illustrations.Mailbox; - } -}; - function BrickRoadIndicatorIcon({brickRoadIndicator}: BrickRoadIndicatorIconProps) { const theme = useTheme(); @@ -138,6 +128,21 @@ function WorkspacesListRow({ const {shouldUseNarrowLayout} = useResponsiveLayout(); const theme = useTheme(); const isNarrow = layoutWidth === CONST.LAYOUT_WIDTH.NARROW; + const illustrations = useMemoizedLazyIllustrations(['Mailbox'] as const); + + const workspaceTypeIcon = useCallback( + (type: WorkspacesListRowProps['workspaceType']): IconAsset => { + switch (type) { + case CONST.POLICY.TYPE.CORPORATE: + return Illustrations.ShieldYellow; + case CONST.POLICY.TYPE.TEAM: + return illustrations.Mailbox; + default: + return illustrations.Mailbox; + } + }, + [illustrations.Mailbox], + ); const ownerDetails = ownerAccountID && getPersonalDetailsByIDs({accountIDs: [ownerAccountID], currentUserAccountID: currentUserPersonalDetails.accountID}).at(0); const threeDotsMenuRef = useRef<{hidePopoverMenu: () => void; isPopupMenuVisible: boolean}>(null); diff --git a/src/pages/workspace/companyCards/WorkspaceCompanyCardExpensifyCardPromotionBanner.tsx b/src/pages/workspace/companyCards/WorkspaceCompanyCardExpensifyCardPromotionBanner.tsx index 0a4d73bb9e7e..58e0d03d3009 100644 --- a/src/pages/workspace/companyCards/WorkspaceCompanyCardExpensifyCardPromotionBanner.tsx +++ b/src/pages/workspace/companyCards/WorkspaceCompanyCardExpensifyCardPromotionBanner.tsx @@ -2,7 +2,7 @@ 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 {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useStyleUtils from '@hooks/useStyleUtils'; @@ -26,6 +26,8 @@ function WorkspaceCompanyCardExpensifyCardPromotionBanner({policy}: WorkspaceCom const policyID = policy?.id; const areExpensifyCardsEnabled = policy?.areExpensifyCardsEnabled; + const illustrations = useMemoizedLazyIllustrations(['CreditCardsNewGreen'] as const); + const handleLearnMore = useCallback(() => { if (!policyID) { return; @@ -56,7 +58,7 @@ function WorkspaceCompanyCardExpensifyCardPromotionBanner({policy}: WorkspaceCom return ( diff --git a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx index 8b198a4a8f8e..7fe3ea53285b 100644 --- a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx +++ b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx @@ -7,7 +7,6 @@ import DelegateNoAccessWrapper from '@components/DelegateNoAccessWrapper'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import getBankIcon from '@components/Icon/BankIcons'; import * as Expensicons from '@components/Icon/Expensicons'; -import * as Illustrations from '@components/Icon/Illustrations'; import LottieAnimations from '@components/LottieAnimations'; import MenuItem from '@components/MenuItem'; import ScreenWrapper from '@components/ScreenWrapper'; @@ -15,6 +14,7 @@ import Text from '@components/Text'; import useBottomSafeSafeAreaPaddingStyle from '@hooks/useBottomSafeSafeAreaPaddingStyle'; import useDefaultFundID from '@hooks/useDefaultFundID'; import useExpensifyCardUkEuSupported from '@hooks/useExpensifyCardUkEuSupported'; +import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import usePolicy from '@hooks/usePolicy'; @@ -45,6 +45,8 @@ function WorkspaceExpensifyCardBankAccounts({route}: WorkspaceExpensifyCardBankA const policyID = route?.params?.policyID; const policy = usePolicy(policyID); + const illustrations = useMemoizedLazyIllustrations(['Puzzle'] as const); + const isUkEuCurrencySupported = useExpensifyCardUkEuSupported(policyID); const defaultFundID = useDefaultFundID(policyID); @@ -134,7 +136,7 @@ function WorkspaceExpensifyCardBankAccounts({route}: WorkspaceExpensifyCardBankA { if (!policyID) { return; @@ -61,7 +63,7 @@ function WorkspaceReceiptPartnersPromotionBanner({policy, readOnly}: WorkspaceRe return ( { }); describe('CardSectionUtils', () => { + let creditCardEyesIcon: IconAsset; + afterEach(() => { jest.restoreAllMocks(); }); beforeAll(() => { + // Get illustrations using renderHook BEFORE fake timers to avoid timing issues + const {result} = renderHook(() => useMemoizedLazyIllustrations(['CreditCardEyes'] as const)); + creditCardEyesIcon = result.current.CreditCardEyes; + mockGetSubscriptionStatus.mockReturnValue(''); jest.useFakeTimers(); @@ -95,6 +103,7 @@ describe('CardSectionUtils', () => { retryBillingSuccessful: false, billingDisputePending: undefined, retryBillingFailed: undefined, + creditCardEyesIcon, }), ).toBeUndefined(); }); @@ -111,6 +120,7 @@ describe('CardSectionUtils', () => { retryBillingSuccessful: false, billingDisputePending: undefined, retryBillingFailed: undefined, + creditCardEyesIcon, }), ).toEqual({ title: 'subscription.billingBanner.policyOwnerAmountOwed.title', @@ -145,6 +155,7 @@ describe('CardSectionUtils', () => { retryBillingSuccessful: false, billingDisputePending: undefined, retryBillingFailed: undefined, + creditCardEyesIcon, }), ).toEqual({ title: 'subscription.billingBanner.policyOwnerAmountOwedOverdue.title', @@ -167,6 +178,7 @@ describe('CardSectionUtils', () => { retryBillingSuccessful: false, billingDisputePending: undefined, retryBillingFailed: undefined, + creditCardEyesIcon, }), ).toEqual({ title: 'subscription.billingBanner.policyOwnerAmountOwedOverdue.title', @@ -189,6 +201,7 @@ describe('CardSectionUtils', () => { retryBillingSuccessful: false, billingDisputePending: undefined, retryBillingFailed: undefined, + creditCardEyesIcon, }), ).toEqual({ title: 'subscription.billingBanner.policyOwnerUnderInvoicing.title', @@ -211,6 +224,7 @@ describe('CardSectionUtils', () => { retryBillingSuccessful: false, billingDisputePending: undefined, retryBillingFailed: undefined, + creditCardEyesIcon, }), ).toEqual({ title: 'subscription.billingBanner.policyOwnerUnderInvoicingOverdue.title', @@ -233,6 +247,7 @@ describe('CardSectionUtils', () => { retryBillingSuccessful: false, billingDisputePending: 1, retryBillingFailed: undefined, + creditCardEyesIcon, }), ).toEqual({ title: 'subscription.billingBanner.billingDisputePending.title', @@ -255,6 +270,7 @@ describe('CardSectionUtils', () => { retryBillingSuccessful: false, billingDisputePending: undefined, retryBillingFailed: undefined, + creditCardEyesIcon, }), ).toEqual({ title: 'subscription.billingBanner.cardAuthenticationRequired.title', @@ -277,6 +293,7 @@ describe('CardSectionUtils', () => { retryBillingSuccessful: false, billingDisputePending: undefined, retryBillingFailed: undefined, + creditCardEyesIcon, }), ).toEqual({ title: 'subscription.billingBanner.insufficientFunds.title', @@ -299,6 +316,7 @@ describe('CardSectionUtils', () => { retryBillingSuccessful: false, billingDisputePending: undefined, retryBillingFailed: undefined, + creditCardEyesIcon, }), ).toEqual({ title: 'subscription.billingBanner.cardExpired.title', @@ -315,6 +333,7 @@ describe('CardSectionUtils', () => { retryBillingSuccessful: false, billingDisputePending: undefined, retryBillingFailed: undefined, + creditCardEyesIcon, }), ).toEqual({ title: 'subscription.billingBanner.cardExpired.title', @@ -337,12 +356,13 @@ describe('CardSectionUtils', () => { retryBillingSuccessful: false, billingDisputePending: undefined, retryBillingFailed: true, + creditCardEyesIcon, }), ).toEqual({ title: 'subscription.billingBanner.cardExpireSoon.title', subtitle: 'subscription.billingBanner.cardExpireSoon.subtitle', isError: false, - icon: Illustrations.CreditCardEyes, + icon: creditCardEyesIcon, }); }); @@ -359,6 +379,7 @@ describe('CardSectionUtils', () => { retryBillingSuccessful: false, billingDisputePending: undefined, retryBillingFailed: undefined, + creditCardEyesIcon, }), ).toEqual({ title: 'subscription.billingBanner.retryBillingSuccess.title', @@ -381,6 +402,7 @@ describe('CardSectionUtils', () => { retryBillingSuccessful: false, billingDisputePending: undefined, retryBillingFailed: undefined, + creditCardEyesIcon, }), ).toEqual({ title: 'subscription.billingBanner.retryBillingError.title',