From 1695fa23d0036d22360cad9d1fcb908f62fb534d Mon Sep 17 00:00:00 2001 From: ameerul-deriv Date: Mon, 11 Nov 2024 11:20:05 +0800 Subject: [PATCH 01/11] chore: added Funds Banner and Modal --- src/components/FundsBanner/FundsBanner.scss | 21 ++++++++ src/components/FundsBanner/FundsBanner.tsx | 37 ++++++++++++++ src/components/FundsBanner/index.tsx | 1 + .../Modals/FundsModal/FundsModal.scss | 32 +++++++++++++ .../Modals/FundsModal/FundsModal.tsx | 48 +++++++++++++++++++ src/components/Modals/FundsModal/index.tsx | 1 + src/components/Modals/index.ts | 1 + src/components/index.ts | 1 + .../components/GuideTooltip/GuideTooltip.scss | 2 +- src/routes/AppContent/index.tsx | 4 ++ 10 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 src/components/FundsBanner/FundsBanner.scss create mode 100644 src/components/FundsBanner/FundsBanner.tsx create mode 100644 src/components/FundsBanner/index.tsx create mode 100644 src/components/Modals/FundsModal/FundsModal.scss create mode 100644 src/components/Modals/FundsModal/FundsModal.tsx create mode 100644 src/components/Modals/FundsModal/index.tsx diff --git a/src/components/FundsBanner/FundsBanner.scss b/src/components/FundsBanner/FundsBanner.scss new file mode 100644 index 00000000..3873742c --- /dev/null +++ b/src/components/FundsBanner/FundsBanner.scss @@ -0,0 +1,21 @@ +.funds-banner { + @include mobile-or-tablet-screen { + padding: 1.6rem 1.6rem 0.8rem; + } + + &__inline-message { + background-color: rgba(44, 154, 255, 0.08); + border-radius: 1.6rem; + padding: 1.6rem; + margin-bottom: 1.5rem; + + @include mobile-or-tablet-screen { + margin-bottom: 0; + } + } + + .deriv-inline-message__icon { + width: 24px; + height: 24px; + } +} diff --git a/src/components/FundsBanner/FundsBanner.tsx b/src/components/FundsBanner/FundsBanner.tsx new file mode 100644 index 00000000..bf6604c9 --- /dev/null +++ b/src/components/FundsBanner/FundsBanner.tsx @@ -0,0 +1,37 @@ +import { FundsModal } from '@/components/Modals'; +import { useModalManager } from '@/hooks/custom-hooks'; +import { LabelPairedCircleInfoLgBoldIcon } from '@deriv/quill-icons'; +import { Localize } from '@deriv-com/translations'; +import { InlineMessage, Text, useDevice } from '@deriv-com/ui'; +import './FundsBanner.scss'; + +const FundsBanner = () => { + const { isDesktop } = useDevice(); + const { hideModal, isModalOpenFor, showModal } = useModalManager(); + + return ( +
+ } + iconPosition='center' + > + + showModal('FundsModal')} + />, + ]} + i18n_default_text='Your P2P funds are accessible through your Options trading account. <0>Learn more' + /> + + + {!!isModalOpenFor('FundsModal') && } +
+ ); +}; + +export default FundsBanner; diff --git a/src/components/FundsBanner/index.tsx b/src/components/FundsBanner/index.tsx new file mode 100644 index 00000000..84379dad --- /dev/null +++ b/src/components/FundsBanner/index.tsx @@ -0,0 +1 @@ +export { default as FundsBanner } from './FundsBanner'; diff --git a/src/components/Modals/FundsModal/FundsModal.scss b/src/components/Modals/FundsModal/FundsModal.scss new file mode 100644 index 00000000..c3849de6 --- /dev/null +++ b/src/components/Modals/FundsModal/FundsModal.scss @@ -0,0 +1,32 @@ +.funds-modal { + @include default-modal; + + &__header { + padding-top: 1rem !important; + + @include mobile-or-tablet-screen { + padding-top: 0 !important; + padding-left: 1.6rem; + } + } + + &__body { + display: flex; + flex-direction: column; + padding: 1rem 2.4rem; + gap: 2.4rem; + + @include mobile-or-tablet-screen { + padding: 0 1.6rem; + } + } + + &__footer { + padding-bottom: 2.4rem; + gap: 0.8rem; + + @include mobile-or-tablet-screen { + padding-bottom: 1.6rem; + } + } +} diff --git a/src/components/Modals/FundsModal/FundsModal.tsx b/src/components/Modals/FundsModal/FundsModal.tsx new file mode 100644 index 00000000..dfa58d1f --- /dev/null +++ b/src/components/Modals/FundsModal/FundsModal.tsx @@ -0,0 +1,48 @@ +import { Localize } from '@deriv-com/translations'; +import { Button, Modal, Text } from '@deriv-com/ui'; +import './FundsModal.scss'; + +type TFundsModalProps = { + isModalOpen: boolean; + onRequestClose: () => void; +}; + +const FundsModal = ({ isModalOpen, onRequestClose }: TFundsModalProps) => { + return ( + + + + + + + +
+ + + + + + +
+
+ + + + + + + + + +
+
+ + + +
+ ); +}; + +export default FundsModal; diff --git a/src/components/Modals/FundsModal/index.tsx b/src/components/Modals/FundsModal/index.tsx new file mode 100644 index 00000000..25c3cab2 --- /dev/null +++ b/src/components/Modals/FundsModal/index.tsx @@ -0,0 +1 @@ +export { default as FundsModal } from './FundsModal'; diff --git a/src/components/Modals/index.ts b/src/components/Modals/index.ts index feef7047..8eb55e72 100644 --- a/src/components/Modals/index.ts +++ b/src/components/Modals/index.ts @@ -19,6 +19,7 @@ export * from './EmailVerificationModal'; export * from './ErrorModal'; export * from './FallbackErrorModal'; export * from './FilterModal'; +export * from './FundsModal'; export * from './InvalidVerificationLinkModal'; export * from './LeaveFilterModal'; export * from './LoadingModal'; diff --git a/src/components/index.ts b/src/components/index.ts index d7b98ee8..4f9aabbe 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -14,6 +14,7 @@ export * from './FileDropzone'; export * from './FloatingRate'; export * from './FormProgress'; export * from './FullPageMobileWrapper'; +export * from './FundsBanner'; export * from './LightDivider'; export * from './MobileTabs'; export * from './OnboardingTooltip'; diff --git a/src/pages/guide/components/GuideTooltip/GuideTooltip.scss b/src/pages/guide/components/GuideTooltip/GuideTooltip.scss index 5ebd4117..5f710577 100644 --- a/src/pages/guide/components/GuideTooltip/GuideTooltip.scss +++ b/src/pages/guide/components/GuideTooltip/GuideTooltip.scss @@ -9,7 +9,7 @@ position: absolute; top: 0; right: 0; - margin-top: 1rem; + margin-top: 8.2rem; &:hover { cursor: pointer; diff --git a/src/routes/AppContent/index.tsx b/src/routes/AppContent/index.tsx index 4365b982..31b6eee1 100644 --- a/src/routes/AppContent/index.tsx +++ b/src/routes/AppContent/index.tsx @@ -1,5 +1,6 @@ import { useEffect, useRef, useState } from 'react'; import { useHistory, useLocation } from 'react-router-dom'; +import { FundsBanner } from '@/components'; import { BlockedScenarios } from '@/components/BlockedScenarios'; import { BUY_SELL_URL, ERROR_CODES } from '@/constants'; import { api, useIsP2PBlocked, useLiveChat, useOAuth } from '@/hooks'; @@ -59,6 +60,8 @@ const AppContent = () => { } = api.advertiser.useGetInfo(); const isPermissionDenied = error?.code === ERROR_CODES.PERMISSION_DENIED; const isEndpointRoute = getCurrentRoute() === 'endpoint'; + const isAdvertiserPage = getCurrentRoute() === 'advertiser'; + const isP2PGuide = getCurrentRoute() === 'guide'; useEffect(() => { initLiveChat(); @@ -113,6 +116,7 @@ const AppContent = () => { } else if ((isFetched && activeAccountData) || isEndpointRoute) { return (
+ {!isEndpointRoute && !isAdvertiserPage && !isP2PGuide && } Date: Mon, 11 Nov 2024 11:55:03 +0800 Subject: [PATCH 02/11] chore: added test cases for FundsBanner and FundsModal --- src/components/FundsBanner/FundsBanner.scss | 14 +++++ src/components/FundsBanner/FundsBanner.tsx | 30 +++++---- .../__tests__/FundsBanner.spec.tsx | 61 +++++++++++++++++++ 3 files changed, 92 insertions(+), 13 deletions(-) create mode 100644 src/components/FundsBanner/__tests__/FundsBanner.spec.tsx diff --git a/src/components/FundsBanner/FundsBanner.scss b/src/components/FundsBanner/FundsBanner.scss index 3873742c..cf7ebbca 100644 --- a/src/components/FundsBanner/FundsBanner.scss +++ b/src/components/FundsBanner/FundsBanner.scss @@ -12,6 +12,20 @@ @include mobile-or-tablet-screen { margin-bottom: 0; } + + &__button { + padding: 0; + text-decoration: underline; + cursor: pointer; + + &:hover { + background-color: transparent !important; + + & > span { + color: #0e0e0e !important; + } + } + } } .deriv-inline-message__icon { diff --git a/src/components/FundsBanner/FundsBanner.tsx b/src/components/FundsBanner/FundsBanner.tsx index bf6604c9..7396a6bd 100644 --- a/src/components/FundsBanner/FundsBanner.tsx +++ b/src/components/FundsBanner/FundsBanner.tsx @@ -2,12 +2,13 @@ import { FundsModal } from '@/components/Modals'; import { useModalManager } from '@/hooks/custom-hooks'; import { LabelPairedCircleInfoLgBoldIcon } from '@deriv/quill-icons'; import { Localize } from '@deriv-com/translations'; -import { InlineMessage, Text, useDevice } from '@deriv-com/ui'; +import { Button, InlineMessage, Text, useDevice } from '@deriv-com/ui'; import './FundsBanner.scss'; const FundsBanner = () => { const { isDesktop } = useDevice(); const { hideModal, isModalOpenFor, showModal } = useModalManager(); + const textSize = isDesktop ? 'sm' : 'md'; return (
@@ -16,18 +17,21 @@ const FundsBanner = () => { icon={} iconPosition='center' > - - showModal('FundsModal')} - />, - ]} - i18n_default_text='Your P2P funds are accessible through your Options trading account. <0>Learn more' - /> - +
+ + + + +
{!!isModalOpenFor('FundsModal') && }
diff --git a/src/components/FundsBanner/__tests__/FundsBanner.spec.tsx b/src/components/FundsBanner/__tests__/FundsBanner.spec.tsx new file mode 100644 index 00000000..70ad285e --- /dev/null +++ b/src/components/FundsBanner/__tests__/FundsBanner.spec.tsx @@ -0,0 +1,61 @@ +import { fireEvent, render, screen } from '@testing-library/react'; +import FundsBanner from '../FundsBanner'; + +const mockModalManager = { + hideModal: jest.fn(), + isModalOpenFor: jest.fn().mockReturnValue(false), + showModal: jest.fn(), +}; + +jest.mock('@deriv-com/ui', () => ({ + ...jest.requireActual('@deriv-com/ui'), + useDevice: jest.fn().mockReturnValue({ + isMobile: false, + }), +})); + +jest.mock('@/hooks/custom-hooks', () => ({ + useModalManager: jest.fn(() => mockModalManager), +})); + +describe('', () => { + it('should render the FundsBanner', () => { + render(); + + expect( + screen.getByText(/Your P2P funds are accessible through your Options trading account./) + ).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /Learn more/ })).toBeInTheDocument(); + }); + + it('should call showModal when the Learn more button is clicked and show the FundsModal', () => { + render(); + fireEvent.click(screen.getByRole('button', { name: /Learn more/ })); + + expect(mockModalManager.showModal).toHaveBeenCalledWith('FundsModal'); + }); + + it('should render the FundsModal if it is open', () => { + mockModalManager.isModalOpenFor.mockImplementation((modalName: string) => modalName === 'FundsModal'); + render(); + + expect(screen.getByText('How to fund your trades?')).toBeInTheDocument(); + expect(screen.getByText('For Options trading:')).toBeInTheDocument(); + expect(screen.getByText('Trade directly with funds from your Options trading account.')).toBeInTheDocument(); + expect(screen.getByText('For CFDs trading:')).toBeInTheDocument(); + expect( + screen.getByText('1. Transfer funds from your Options trading account to your USD Wallet.') + ).toBeInTheDocument(); + expect( + screen.getByText('2. Then, move the funds from your USD Wallet to your CFDs account.') + ).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'OK' })).toBeInTheDocument(); + }); + + it('should call hideModal when the OK button is clicked', () => { + render(); + + fireEvent.click(screen.getByRole('button', { name: 'OK' })); + expect(mockModalManager.hideModal).toHaveBeenCalled(); + }); +}); From 59a0be6441840ebc875ced7dee568d6cf02933e9 Mon Sep 17 00:00:00 2001 From: ameerul-deriv Date: Mon, 11 Nov 2024 15:11:08 +0800 Subject: [PATCH 03/11] fix: show Banner in Buy/Sell page only --- .../CurrencyDropdown/CurrencyDropdown.tsx | 17 ++++++++++++---- .../__tests__/CurrencyDropdown.spec.tsx | 6 ++++++ src/routes/AppContent/index.tsx | 20 +++++++++++++++---- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/pages/buy-sell/components/CurrencyDropdown/CurrencyDropdown.tsx b/src/pages/buy-sell/components/CurrencyDropdown/CurrencyDropdown.tsx index 2ff1c6b0..365667f3 100644 --- a/src/pages/buy-sell/components/CurrencyDropdown/CurrencyDropdown.tsx +++ b/src/pages/buy-sell/components/CurrencyDropdown/CurrencyDropdown.tsx @@ -3,7 +3,7 @@ import clsx from 'clsx'; import { TCurrencyListItem } from 'types'; import { useOnClickOutside } from 'usehooks-ts'; import { FullPageMobileWrapper } from '@/components'; -import { api } from '@/hooks'; +import { api, useQueryString } from '@/hooks'; import { LabelPairedChevronDownMdRegularIcon } from '@deriv/quill-icons'; import { Localize } from '@deriv-com/translations'; import { Text, useDevice } from '@deriv-com/ui'; @@ -19,6 +19,15 @@ const CurrencyDropdown = ({ selectedCurrency, setSelectedCurrency }: TCurrencyDr const { data } = api.settings.useSettings(); const { isDesktop, isMobile } = useDevice(); const [showCurrencySelector, setShowCurrencySelector] = useState(false); + const { deleteQueryString, setQueryString } = useQueryString(); + + const onToggleCurrencyDropdown = (shouldShow: boolean) => { + setShowCurrencySelector(shouldShow); + if (!isDesktop) { + if (shouldShow) setQueryString({ modal: 'CurrencyFilterModal' }); + else deleteQueryString('modal'); + } + }; const currencySelectorRef = useRef(null); useOnClickOutside(currencySelectorRef, () => { @@ -39,7 +48,7 @@ const CurrencyDropdown = ({ selectedCurrency, setSelectedCurrency }: TCurrencyDr }, [data?.currencyList, selectedCurrency]) ?? []; const onSelectItem = (currency: string) => { - setShowCurrencySelector(false); + onToggleCurrencyDropdown(false); setSelectedCurrency(currency); }; @@ -48,7 +57,7 @@ const CurrencyDropdown = ({ selectedCurrency, setSelectedCurrency }: TCurrencyDr { - setShowCurrencySelector(false); + onToggleCurrencyDropdown(false); }} renderHeader={() => ( @@ -70,7 +79,7 @@ const CurrencyDropdown = ({ selectedCurrency, setSelectedCurrency }: TCurrencyDr className={clsx('currency-dropdown__dropdown', { 'currency-dropdown__dropdown--active': showCurrencySelector, })} - onClick={() => setShowCurrencySelector(prev => !prev)} + onClick={() => onToggleCurrencyDropdown(!showCurrencySelector)} > diff --git a/src/pages/buy-sell/components/CurrencyDropdown/__tests__/CurrencyDropdown.spec.tsx b/src/pages/buy-sell/components/CurrencyDropdown/__tests__/CurrencyDropdown.spec.tsx index 9be55633..d0c08c0c 100644 --- a/src/pages/buy-sell/components/CurrencyDropdown/__tests__/CurrencyDropdown.spec.tsx +++ b/src/pages/buy-sell/components/CurrencyDropdown/__tests__/CurrencyDropdown.spec.tsx @@ -45,6 +45,12 @@ jest.mock('@/hooks', () => ({ }, })); +jest.mock('@/hooks/custom-hooks', () => ({ + ...jest.requireActual('@/hooks/custom-hooks'), + useQueryString: jest + .fn() + .mockReturnValue({ deleteQueryString: jest.fn(), queryString: { modal: '' }, setQueryString: jest.fn() }), +})); let mockIsDesktop = true; jest.mock('@deriv-com/ui', () => ({ diff --git a/src/routes/AppContent/index.tsx b/src/routes/AppContent/index.tsx index 31b6eee1..4cb1e105 100644 --- a/src/routes/AppContent/index.tsx +++ b/src/routes/AppContent/index.tsx @@ -3,7 +3,7 @@ import { useHistory, useLocation } from 'react-router-dom'; import { FundsBanner } from '@/components'; import { BlockedScenarios } from '@/components/BlockedScenarios'; import { BUY_SELL_URL, ERROR_CODES } from '@/constants'; -import { api, useIsP2PBlocked, useLiveChat, useOAuth } from '@/hooks'; +import { api, useIsP2PBlocked, useLiveChat, useOAuth, useQueryString } from '@/hooks'; import { GuideTooltip } from '@/pages/guide/components'; import { AdvertiserInfoStateProvider } from '@/providers/AdvertiserInfoStateProvider'; import { getCurrentRoute } from '@/utils'; @@ -44,6 +44,7 @@ const AppContent = () => { const [activeTab, setActiveTab] = useState(() => getActiveTab(location.pathname)); const [hasCreatedAdvertiser, setHasCreatedAdvertiser] = useState(false); + const [showFundsBanner, setShowFundsBanner] = useState(false); const { error: p2pSettingsError, isActive, @@ -60,8 +61,8 @@ const AppContent = () => { } = api.advertiser.useGetInfo(); const isPermissionDenied = error?.code === ERROR_CODES.PERMISSION_DENIED; const isEndpointRoute = getCurrentRoute() === 'endpoint'; - const isAdvertiserPage = getCurrentRoute() === 'advertiser'; - const isP2PGuide = getCurrentRoute() === 'guide'; + const isBuySellPage = getCurrentRoute() === 'buy-sell'; + const { queryString } = useQueryString(); useEffect(() => { initLiveChat(); @@ -104,6 +105,17 @@ const AppContent = () => { } }, []); + useEffect(() => { + if ( + isBuySellPage && + ((!isDesktop && (queryString.modal === 'RadioGroupFilterModal' || !queryString.modal)) || isDesktop) + ) { + setShowFundsBanner(true); + } else { + setShowFundsBanner(false); + } + }, [isBuySellPage, isDesktop, location, queryString]); + const getComponent = () => { if ((isP2PSettingsLoading || isLoadingActiveAccount || !isFetched || !activeAccountData) && !isEndpointRoute) { return ; @@ -116,7 +128,7 @@ const AppContent = () => { } else if ((isFetched && activeAccountData) || isEndpointRoute) { return (
- {!isEndpointRoute && !isAdvertiserPage && !isP2PGuide && } + {showFundsBanner && } Date: Mon, 11 Nov 2024 16:06:36 +0800 Subject: [PATCH 04/11] chore: show banner if user is an advertiser --- src/pages/buy-sell/screens/BuySell/BuySell.scss | 12 +++++++++++- src/pages/buy-sell/screens/BuySell/BuySell.tsx | 4 +++- .../screens/BuySell/__tests__/BuySell.spec.tsx | 1 + .../guide/components/GuideTooltip/GuideTooltip.scss | 4 ++++ .../guide/components/GuideTooltip/GuideTooltip.tsx | 5 ++++- .../GuideTooltip/__tests__/GuideTooltip.spec.tsx | 5 +++++ src/routes/AppContent/index.tsx | 6 ++++-- 7 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/pages/buy-sell/screens/BuySell/BuySell.scss b/src/pages/buy-sell/screens/BuySell/BuySell.scss index 4ded954b..f94e7a9d 100644 --- a/src/pages/buy-sell/screens/BuySell/BuySell.scss +++ b/src/pages/buy-sell/screens/BuySell/BuySell.scss @@ -8,7 +8,7 @@ & .buy-sell-table { & .table { @include mobile-or-tablet-screen { - height: calc(100% - 26rem); + height: calc(100% - 37rem); } } } @@ -30,6 +30,16 @@ } } + &--not-advertiser { + & .buy-sell-table { + & .table { + @include mobile-or-tablet-screen { + height: calc(100% - 26rem); + } + } + } + } + &--outside-hours { & .mobile-wrapper { top: -8.5rem; diff --git a/src/pages/buy-sell/screens/BuySell/BuySell.tsx b/src/pages/buy-sell/screens/BuySell/BuySell.tsx index 509dac76..7b4e0e07 100644 --- a/src/pages/buy-sell/screens/BuySell/BuySell.tsx +++ b/src/pages/buy-sell/screens/BuySell/BuySell.tsx @@ -2,7 +2,7 @@ import clsx from 'clsx'; import { useHistory, useLocation } from 'react-router-dom'; import { OutsideBusinessHoursHint, PageReturn, TemporarilyBarredHint, Verification } from '@/components'; import { BUY_SELL_URL } from '@/constants'; -import { useGetBusinessHours, useIsAdvertiserBarred } from '@/hooks/custom-hooks'; +import { useGetBusinessHours, useIsAdvertiser, useIsAdvertiserBarred } from '@/hooks/custom-hooks'; import { useTranslations } from '@deriv-com/translations'; import { BuySellTable } from '../BuySellTable'; import './BuySell.scss'; @@ -14,6 +14,7 @@ const BuySell = () => { const history = useHistory(); const location = useLocation(); const poiPoaVerified = new URLSearchParams(location.search).get('poi_poa_verified'); + const isAdvertiser = useIsAdvertiser(); if (poiPoaVerified === 'false') { return ( @@ -32,6 +33,7 @@ const BuySell = () => {
diff --git a/src/pages/buy-sell/screens/BuySell/__tests__/BuySell.spec.tsx b/src/pages/buy-sell/screens/BuySell/__tests__/BuySell.spec.tsx index afcd6348..f7d6a9e8 100644 --- a/src/pages/buy-sell/screens/BuySell/__tests__/BuySell.spec.tsx +++ b/src/pages/buy-sell/screens/BuySell/__tests__/BuySell.spec.tsx @@ -27,6 +27,7 @@ jest.mock('@/hooks/custom-hooks', () => ({ useGetBusinessHours: jest.fn().mockReturnValue({ isScheduleAvailable: true, }), + useIsAdvertiser: jest.fn().mockReturnValue(true), useIsAdvertiserBarred: jest.fn().mockReturnValue(false), })); diff --git a/src/pages/guide/components/GuideTooltip/GuideTooltip.scss b/src/pages/guide/components/GuideTooltip/GuideTooltip.scss index 5f710577..9878d2b7 100644 --- a/src/pages/guide/components/GuideTooltip/GuideTooltip.scss +++ b/src/pages/guide/components/GuideTooltip/GuideTooltip.scss @@ -14,6 +14,10 @@ &:hover { cursor: pointer; } + + &--not-advertiser { + margin-top: 1rem; + } } @include mobile-or-tablet-screen { diff --git a/src/pages/guide/components/GuideTooltip/GuideTooltip.tsx b/src/pages/guide/components/GuideTooltip/GuideTooltip.tsx index 1937326b..59520860 100644 --- a/src/pages/guide/components/GuideTooltip/GuideTooltip.tsx +++ b/src/pages/guide/components/GuideTooltip/GuideTooltip.tsx @@ -1,6 +1,8 @@ +import clsx from 'clsx'; import { useHistory } from 'react-router-dom'; import { OnboardingTooltip } from '@/components'; import { GUIDE_URL } from '@/constants'; +import { useIsAdvertiser } from '@/hooks/custom-hooks'; import { getCurrentRoute } from '@/utils'; import { LabelPairedBookCircleQuestionLgRegularIcon } from '@deriv/quill-icons'; import { Localize } from '@deriv-com/translations'; @@ -10,11 +12,12 @@ import './GuideTooltip.scss'; const GuideTooltip = () => { const history = useHistory(); const currentRoute = getCurrentRoute(); + const isAdvertiser = useIsAdvertiser(); return ( } - className='guide-tooltip__icon' + className={clsx('guide-tooltip__icon', { 'guide-tooltip__icon--not-advertiser': !isAdvertiser })} description={ } diff --git a/src/pages/guide/components/GuideTooltip/__tests__/GuideTooltip.spec.tsx b/src/pages/guide/components/GuideTooltip/__tests__/GuideTooltip.spec.tsx index 78b00120..3826ebba 100644 --- a/src/pages/guide/components/GuideTooltip/__tests__/GuideTooltip.spec.tsx +++ b/src/pages/guide/components/GuideTooltip/__tests__/GuideTooltip.spec.tsx @@ -1,6 +1,11 @@ import { render, screen } from '@testing-library/react'; import GuideTooltip from '../GuideTooltip'; +jest.mock('@/hooks/custom-hooks', () => ({ + ...jest.requireActual('@/hooks/custom-hooks'), + useIsAdvertiser: jest.fn().mockReturnValue(true), +})); + describe('GuideTooltip', () => { it('should render the GuideTooltip component', () => { render(); diff --git a/src/routes/AppContent/index.tsx b/src/routes/AppContent/index.tsx index 4cb1e105..6efbaddd 100644 --- a/src/routes/AppContent/index.tsx +++ b/src/routes/AppContent/index.tsx @@ -3,7 +3,7 @@ import { useHistory, useLocation } from 'react-router-dom'; import { FundsBanner } from '@/components'; import { BlockedScenarios } from '@/components/BlockedScenarios'; import { BUY_SELL_URL, ERROR_CODES } from '@/constants'; -import { api, useIsP2PBlocked, useLiveChat, useOAuth, useQueryString } from '@/hooks'; +import { api, useIsAdvertiser, useIsP2PBlocked, useLiveChat, useOAuth, useQueryString } from '@/hooks'; import { GuideTooltip } from '@/pages/guide/components'; import { AdvertiserInfoStateProvider } from '@/providers/AdvertiserInfoStateProvider'; import { getCurrentRoute } from '@/utils'; @@ -62,6 +62,7 @@ const AppContent = () => { const isPermissionDenied = error?.code === ERROR_CODES.PERMISSION_DENIED; const isEndpointRoute = getCurrentRoute() === 'endpoint'; const isBuySellPage = getCurrentRoute() === 'buy-sell'; + const isAdvertiser = useIsAdvertiser(); const { queryString } = useQueryString(); useEffect(() => { @@ -107,6 +108,7 @@ const AppContent = () => { useEffect(() => { if ( + isAdvertiser && isBuySellPage && ((!isDesktop && (queryString.modal === 'RadioGroupFilterModal' || !queryString.modal)) || isDesktop) ) { @@ -114,7 +116,7 @@ const AppContent = () => { } else { setShowFundsBanner(false); } - }, [isBuySellPage, isDesktop, location, queryString]); + }, [isAdvertiser, isBuySellPage, isDesktop, location, queryString]); const getComponent = () => { if ((isP2PSettingsLoading || isLoadingActiveAccount || !isFetched || !activeAccountData) && !isEndpointRoute) { From f122debf615f3f0f646d852afb7ccce03efa41e1 Mon Sep 17 00:00:00 2001 From: ameerul-deriv Date: Mon, 11 Nov 2024 16:19:04 +0800 Subject: [PATCH 05/11] fix: dont hide the banner if FundsModal isShowing --- src/routes/AppContent/index.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/routes/AppContent/index.tsx b/src/routes/AppContent/index.tsx index 6efbaddd..f3ffb473 100644 --- a/src/routes/AppContent/index.tsx +++ b/src/routes/AppContent/index.tsx @@ -110,7 +110,11 @@ const AppContent = () => { if ( isAdvertiser && isBuySellPage && - ((!isDesktop && (queryString.modal === 'RadioGroupFilterModal' || !queryString.modal)) || isDesktop) + ((!isDesktop && + (queryString.modal === 'RadioGroupFilterModal' || + queryString.modal === 'FundsModal' || + !queryString.modal)) || + isDesktop) ) { setShowFundsBanner(true); } else { From 7464cc4ae3a1d5d3bff9cf1e91e1dac91543808f Mon Sep 17 00:00:00 2001 From: ameerul-deriv Date: Mon, 11 Nov 2024 16:36:05 +0800 Subject: [PATCH 06/11] chore: fix BuySellheader failing test cases --- .../screens/BuySellHeader/__tests__/BuySellHeader.spec.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/buy-sell/screens/BuySellHeader/__tests__/BuySellHeader.spec.tsx b/src/pages/buy-sell/screens/BuySellHeader/__tests__/BuySellHeader.spec.tsx index 1358311b..c7f6f3b5 100644 --- a/src/pages/buy-sell/screens/BuySellHeader/__tests__/BuySellHeader.spec.tsx +++ b/src/pages/buy-sell/screens/BuySellHeader/__tests__/BuySellHeader.spec.tsx @@ -61,6 +61,7 @@ const mockUseQueryString = { jest.mock('@/hooks/custom-hooks', () => ({ ...jest.requireActual('@/hooks/custom-hooks'), + useIsAdvertiser: jest.fn().mockReturnValue(true), useModalManager: jest.fn(() => mockUseModalManager), useQueryString: jest.fn(() => mockUseQueryString), })); From 6ecd646aa6f8a554f1695abdd326bdf47cd3ca93 Mon Sep 17 00:00:00 2001 From: ameerul-deriv Date: Wed, 13 Nov 2024 09:41:52 +0800 Subject: [PATCH 07/11] chore: removed important and targeted header --- src/components/Modals/FundsModal/FundsModal.scss | 7 +++---- src/components/Modals/FundsModal/FundsModal.tsx | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/components/Modals/FundsModal/FundsModal.scss b/src/components/Modals/FundsModal/FundsModal.scss index c3849de6..b0368bf6 100644 --- a/src/components/Modals/FundsModal/FundsModal.scss +++ b/src/components/Modals/FundsModal/FundsModal.scss @@ -1,8 +1,7 @@ .funds-modal { @include default-modal; - - &__header { - padding-top: 1rem !important; + .deriv-modal__header { + padding-top: 1rem; @include mobile-or-tablet-screen { padding-top: 0 !important; @@ -26,7 +25,7 @@ gap: 0.8rem; @include mobile-or-tablet-screen { - padding-bottom: 1.6rem; + padding: 1.6rem; } } } diff --git a/src/components/Modals/FundsModal/FundsModal.tsx b/src/components/Modals/FundsModal/FundsModal.tsx index dfa58d1f..b6559036 100644 --- a/src/components/Modals/FundsModal/FundsModal.tsx +++ b/src/components/Modals/FundsModal/FundsModal.tsx @@ -10,7 +10,7 @@ type TFundsModalProps = { const FundsModal = ({ isModalOpen, onRequestClose }: TFundsModalProps) => { return ( - + From 816426ed9e0d9e7e7dd32ef7b1bd7dd6537d13af Mon Sep 17 00:00:00 2001 From: ameerul-deriv Date: Mon, 18 Nov 2024 16:46:40 +0800 Subject: [PATCH 08/11] chore: fix position of p2p guide icon --- src/pages/guide/components/GuideTooltip/GuideTooltip.scss | 5 ++++- src/pages/guide/components/GuideTooltip/GuideTooltip.tsx | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/pages/guide/components/GuideTooltip/GuideTooltip.scss b/src/pages/guide/components/GuideTooltip/GuideTooltip.scss index 9878d2b7..54570e41 100644 --- a/src/pages/guide/components/GuideTooltip/GuideTooltip.scss +++ b/src/pages/guide/components/GuideTooltip/GuideTooltip.scss @@ -9,7 +9,6 @@ position: absolute; top: 0; right: 0; - margin-top: 8.2rem; &:hover { cursor: pointer; @@ -18,6 +17,10 @@ &--not-advertiser { margin-top: 1rem; } + + &--is-buy-sell { + margin-top: 8.2rem; + } } @include mobile-or-tablet-screen { diff --git a/src/pages/guide/components/GuideTooltip/GuideTooltip.tsx b/src/pages/guide/components/GuideTooltip/GuideTooltip.tsx index 59520860..8c677702 100644 --- a/src/pages/guide/components/GuideTooltip/GuideTooltip.tsx +++ b/src/pages/guide/components/GuideTooltip/GuideTooltip.tsx @@ -17,7 +17,10 @@ const GuideTooltip = () => { return ( } - className={clsx('guide-tooltip__icon', { 'guide-tooltip__icon--not-advertiser': !isAdvertiser })} + className={clsx('guide-tooltip__icon', { + 'guide-tooltip__icon--is-buy-sell': currentRoute === 'buy-sell', + 'guide-tooltip__icon--not-advertiser': !isAdvertiser, + })} description={ } From bd0c7081ed2238de9886f27b7817320231d11a94 Mon Sep 17 00:00:00 2001 From: ameerul-deriv Date: Mon, 18 Nov 2024 17:49:58 +0800 Subject: [PATCH 09/11] fix: guide icon position for non advertisers --- src/pages/guide/components/GuideTooltip/GuideTooltip.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/guide/components/GuideTooltip/GuideTooltip.tsx b/src/pages/guide/components/GuideTooltip/GuideTooltip.tsx index 8c677702..75e7ba2c 100644 --- a/src/pages/guide/components/GuideTooltip/GuideTooltip.tsx +++ b/src/pages/guide/components/GuideTooltip/GuideTooltip.tsx @@ -18,7 +18,7 @@ const GuideTooltip = () => { } className={clsx('guide-tooltip__icon', { - 'guide-tooltip__icon--is-buy-sell': currentRoute === 'buy-sell', + 'guide-tooltip__icon--is-buy-sell': currentRoute === 'buy-sell' && isAdvertiser, 'guide-tooltip__icon--not-advertiser': !isAdvertiser, })} description={ From 2760fd765121ddfbe34d9a1d2749884729f51826 Mon Sep 17 00:00:00 2001 From: ameerul-deriv Date: Tue, 24 Dec 2024 15:37:44 +0800 Subject: [PATCH 10/11] chore: added logic to check if user has migrated to wallets --- .../api/account/__tests__/useActiveAccount.spec.ts | 14 ++++++++++++++ src/hooks/api/account/useActiveAccount.ts | 1 + .../BuySellHeader/__tests__/BuySellHeader.spec.tsx | 3 +++ .../BuySellTable/__tests__/BuySellTable.spec.tsx | 3 +++ .../guide/components/GuideTooltip/GuideTooltip.tsx | 5 ++++- .../GuideTooltip/__tests__/GuideTooltip.spec.tsx | 11 +++++++++++ src/routes/AppContent/index.tsx | 5 +++-- 7 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/hooks/api/account/__tests__/useActiveAccount.spec.ts b/src/hooks/api/account/__tests__/useActiveAccount.spec.ts index 13b93081..76065d47 100644 --- a/src/hooks/api/account/__tests__/useActiveAccount.spec.ts +++ b/src/hooks/api/account/__tests__/useActiveAccount.spec.ts @@ -116,6 +116,7 @@ describe('useActiveAccount', () => { created_at: 1718953961, currency: 'USD', currency_type: 'fiat', + hasMigratedToWallets: false, is_disabled: 0, is_virtual: 0, landing_company_name: 'name', @@ -139,6 +140,7 @@ describe('useActiveAccount', () => { created_at: 1718953961, currency: 'USD', currency_type: 'fiat', + hasMigratedToWallets: false, is_disabled: 0, is_virtual: 0, landing_company_name: 'name', @@ -146,4 +148,16 @@ describe('useActiveAccount', () => { loginid: 'CR00001', }); }); + + it('should return hasMigratedToWallets as true if the account is linked to dwallet', () => { + // @ts-expect-error mockAccountList is not typed with platform + mockAccountList[0].linked_to = [{ platform: 'dwallet' }]; + mockUseAccountList.mockReturnValue({ data: mockAccountList }); + mockUseAuthData.mockReturnValue({ activeLoginid: 'CR00001' }); + mockUseBalance.mockReturnValue({ data: mockBalanceData }); + + const { result } = renderHook(() => useActiveAccount()); + + expect(result.current.data?.hasMigratedToWallets).toBe(true); + }); }); diff --git a/src/hooks/api/account/useActiveAccount.ts b/src/hooks/api/account/useActiveAccount.ts index 1e46b165..0454a195 100644 --- a/src/hooks/api/account/useActiveAccount.ts +++ b/src/hooks/api/account/useActiveAccount.ts @@ -17,6 +17,7 @@ const useActiveAccount = () => { ? { ...activeAccount, balance: balanceData?.accounts?.[activeAccount?.loginid]?.balance ?? 0, + hasMigratedToWallets: activeAccount?.linked_to.some(item => item.platform === 'dwallet'), } : undefined; }, [activeAccount, balanceData]); diff --git a/src/pages/buy-sell/screens/BuySellHeader/__tests__/BuySellHeader.spec.tsx b/src/pages/buy-sell/screens/BuySellHeader/__tests__/BuySellHeader.spec.tsx index c7f6f3b5..7c59c9c0 100644 --- a/src/pages/buy-sell/screens/BuySellHeader/__tests__/BuySellHeader.spec.tsx +++ b/src/pages/buy-sell/screens/BuySellHeader/__tests__/BuySellHeader.spec.tsx @@ -19,6 +19,9 @@ jest.mock('@deriv-com/ui', () => ({ jest.mock('@/hooks', () => ({ ...jest.requireActual('@/hooks'), api: { + account: { + useActiveAccount: jest.fn().mockReturnValue({ data: { hasMigratedToWallets: false } }), + }, settings: { useGetSettings: () => ({ data: {}, diff --git a/src/pages/buy-sell/screens/BuySellTable/__tests__/BuySellTable.spec.tsx b/src/pages/buy-sell/screens/BuySellTable/__tests__/BuySellTable.spec.tsx index 8d9070f8..e6c0fc66 100644 --- a/src/pages/buy-sell/screens/BuySellTable/__tests__/BuySellTable.spec.tsx +++ b/src/pages/buy-sell/screens/BuySellTable/__tests__/BuySellTable.spec.tsx @@ -49,6 +49,9 @@ jest.mock('@/components/Modals', () => ({ jest.mock('@/hooks', () => ({ ...jest.requireActual('@/hooks'), api: { + account: { + useActiveAccount: jest.fn().mockReturnValue({ data: { hasMigratedToWallets: false } }), + }, advert: { useGetList: jest.fn(() => mockAdvertiserListData), }, diff --git a/src/pages/guide/components/GuideTooltip/GuideTooltip.tsx b/src/pages/guide/components/GuideTooltip/GuideTooltip.tsx index 75e7ba2c..92430f1c 100644 --- a/src/pages/guide/components/GuideTooltip/GuideTooltip.tsx +++ b/src/pages/guide/components/GuideTooltip/GuideTooltip.tsx @@ -2,6 +2,7 @@ import clsx from 'clsx'; import { useHistory } from 'react-router-dom'; import { OnboardingTooltip } from '@/components'; import { GUIDE_URL } from '@/constants'; +import { api } from '@/hooks'; import { useIsAdvertiser } from '@/hooks/custom-hooks'; import { getCurrentRoute } from '@/utils'; import { LabelPairedBookCircleQuestionLgRegularIcon } from '@deriv/quill-icons'; @@ -13,12 +14,14 @@ const GuideTooltip = () => { const history = useHistory(); const currentRoute = getCurrentRoute(); const isAdvertiser = useIsAdvertiser(); + const { data: activeAccountData } = api.account.useActiveAccount(); return ( } className={clsx('guide-tooltip__icon', { - 'guide-tooltip__icon--is-buy-sell': currentRoute === 'buy-sell' && isAdvertiser, + 'guide-tooltip__icon--is-buy-sell': + currentRoute === 'buy-sell' && isAdvertiser && activeAccountData?.hasMigratedToWallets, 'guide-tooltip__icon--not-advertiser': !isAdvertiser, })} description={ diff --git a/src/pages/guide/components/GuideTooltip/__tests__/GuideTooltip.spec.tsx b/src/pages/guide/components/GuideTooltip/__tests__/GuideTooltip.spec.tsx index 3826ebba..c4095f30 100644 --- a/src/pages/guide/components/GuideTooltip/__tests__/GuideTooltip.spec.tsx +++ b/src/pages/guide/components/GuideTooltip/__tests__/GuideTooltip.spec.tsx @@ -1,6 +1,17 @@ import { render, screen } from '@testing-library/react'; import GuideTooltip from '../GuideTooltip'; +jest.mock('@/hooks', () => ({ + ...jest.requireActual('@/hooks'), + api: { + ...jest.requireActual('@/hooks/api'), + account: { + ...jest.requireActual('@/hooks/api/account'), + useActiveAccount: jest.fn().mockReturnValue({ data: { hasMigratedToWallets: false } }), + }, + }, +})); + jest.mock('@/hooks/custom-hooks', () => ({ ...jest.requireActual('@/hooks/custom-hooks'), useIsAdvertiser: jest.fn().mockReturnValue(true), diff --git a/src/routes/AppContent/index.tsx b/src/routes/AppContent/index.tsx index f3ffb473..29a9d7c0 100644 --- a/src/routes/AppContent/index.tsx +++ b/src/routes/AppContent/index.tsx @@ -114,13 +114,14 @@ const AppContent = () => { (queryString.modal === 'RadioGroupFilterModal' || queryString.modal === 'FundsModal' || !queryString.modal)) || - isDesktop) + isDesktop) && + activeAccountData?.hasMigratedToWallets ) { setShowFundsBanner(true); } else { setShowFundsBanner(false); } - }, [isAdvertiser, isBuySellPage, isDesktop, location, queryString]); + }, [activeAccountData?.hasMigratedToWallets, isAdvertiser, isBuySellPage, isDesktop, location, queryString]); const getComponent = () => { if ((isP2PSettingsLoading || isLoadingActiveAccount || !isFetched || !activeAccountData) && !isEndpointRoute) { From d030c3db205aac9a92082753a434a5e648518313 Mon Sep 17 00:00:00 2001 From: ameerul-deriv Date: Thu, 26 Dec 2024 15:21:50 +0800 Subject: [PATCH 11/11] fix: hide cashier tab if user has migrated to wallets --- .../AppHeader/MenuItems/MenuItems.tsx | 7 +++++- .../AppHeader/MobileMenu/MenuContent.tsx | 8 ++++++- .../MobileMenu/__tests__/MenuContent.spec.tsx | 24 +++++++++++++++++++ .../MobileMenu/__tests__/MobileMenu.spec.tsx | 5 ++++ .../AppHeader/__tests__/AppHeader.spec.tsx | 18 ++++++++++++++ 5 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/components/AppHeader/MenuItems/MenuItems.tsx b/src/components/AppHeader/MenuItems/MenuItems.tsx index b9ebe325..b35ec79d 100644 --- a/src/components/AppHeader/MenuItems/MenuItems.tsx +++ b/src/components/AppHeader/MenuItems/MenuItems.tsx @@ -1,3 +1,4 @@ +import { api } from '@/hooks'; import { useTranslations } from '@deriv-com/translations'; import { MenuItem, Text, useDevice } from '@deriv-com/ui'; import { getMenuItems } from '../HeaderConfig'; @@ -6,7 +7,11 @@ import './MenuItems.scss'; const MenuItems = () => { const { localize } = useTranslations(); const { isDesktop } = useDevice(); - const items = getMenuItems(localize); + const { data: activeAccountData } = api.account.useActiveAccount(); + const menuItems = getMenuItems(localize); + const items = activeAccountData?.hasMigratedToWallets + ? menuItems.filter(item => !item.label.includes(localize('Cashier'))) + : menuItems; return ( <> diff --git a/src/components/AppHeader/MobileMenu/MenuContent.tsx b/src/components/AppHeader/MobileMenu/MenuContent.tsx index 21550992..1315af5f 100644 --- a/src/components/AppHeader/MobileMenu/MenuContent.tsx +++ b/src/components/AppHeader/MobileMenu/MenuContent.tsx @@ -1,11 +1,15 @@ import clsx from 'clsx'; +import { api } from '@/hooks'; +import { useTranslations } from '@deriv-com/translations'; import { MenuItem, Text, useDevice } from '@deriv-com/ui'; import { PlatformSwitcher } from '../PlatformSwitcher'; import { MobileMenuConfig } from './MobileMenuConfig'; export const MenuContent = () => { + const { localize } = useTranslations(); const { isDesktop } = useDevice(); const textSize = isDesktop ? 'sm' : 'md'; + const { data: activeAccountData } = api.account.useActiveAccount(); return (
@@ -15,7 +19,6 @@ export const MenuContent = () => {
{MobileMenuConfig().map((item, index) => { const removeBorderBottom = item.find(({ removeBorderBottom }) => removeBorderBottom); - return (
{ key={index} > {item.map(({ LeftComponent, RightComponent, as, href, label, onClick, target }) => { + if (activeAccountData?.hasMigratedToWallets && label === localize('Cashier')) { + return null; + } if (as === 'a') { return ( ({ ...jest.requireActual('@deriv-com/ui'), @@ -16,6 +17,16 @@ jest.mock('@deriv-com/api-hooks', () => ({ }), })); +jest.mock('@/hooks', () => ({ + api: { + account: { + useActiveAccount: jest.fn(() => ({ + data: mockActiveAccountData, + })), + }, + }, +})); + jest.mock('../../PlatformSwitcher', () => ({ PlatformSwitcher: () =>
PlatformSwitcher
, })); @@ -30,6 +41,13 @@ jest.mock('../MobileMenuConfig', () => ({ LeftComponent: () => Home Icon, removeBorderBottom: false, }, + { + as: 'a', + href: '/cashier', + label: 'Cashier', + LeftComponent: () => Cashier Icon, + removeBorderBottom: false, + }, ], [ { @@ -102,4 +120,10 @@ describe('MenuContent Component', () => { expect(screen.getAllByTestId('dt_menu_item')[0]).toHaveClass('border-b'); expect(screen.getAllByTestId('dt_menu_item')[1]).not.toHaveClass('border-b'); }); + + it('does not render Cashier menu item when hasMigratedToWallets is true', () => { + mockActiveAccountData.hasMigratedToWallets = true; + render(); + expect(screen.queryByText('Cashier')).not.toBeInTheDocument(); + }); }); diff --git a/src/components/AppHeader/MobileMenu/__tests__/MobileMenu.spec.tsx b/src/components/AppHeader/MobileMenu/__tests__/MobileMenu.spec.tsx index e3499e3f..28052684 100644 --- a/src/components/AppHeader/MobileMenu/__tests__/MobileMenu.spec.tsx +++ b/src/components/AppHeader/MobileMenu/__tests__/MobileMenu.spec.tsx @@ -8,6 +8,11 @@ import userEvent from '@testing-library/user-event'; import MobileMenu from '../MobileMenu'; jest.mock('@/hooks', () => ({ + api: { + account: { + useActiveAccount: jest.fn().mockReturnValue({ data: { hasMigratedToWallets: false } }), + }, + }, useModalManager: jest.fn().mockReturnValue({ hideModal: jest.fn(), isModalOpenFor: jest.fn().mockReturnValue(false), diff --git a/src/components/AppHeader/__tests__/AppHeader.spec.tsx b/src/components/AppHeader/__tests__/AppHeader.spec.tsx index da7b2901..25f23c2f 100644 --- a/src/components/AppHeader/__tests__/AppHeader.spec.tsx +++ b/src/components/AppHeader/__tests__/AppHeader.spec.tsx @@ -116,6 +116,7 @@ describe('', () => { mockUseAuthData.mockReturnValue({ activeLoginid: '12345', logout: jest.fn() }); mockUseActiveAccountValues.data = { currency: 'USD', + hasMigratedToWallets: false, is_virtual: 0, } as ReturnType['data']; @@ -152,4 +153,21 @@ describe('', () => { await userEvent.click(logoutButton); expect(logout).toHaveBeenCalled(); }); + + it('should not render Cashier menu item when hasMigratedToWallets is true', () => { + mockUseAuthData.mockReturnValue({ activeLoginid: '12345', logout: jest.fn() }); + mockUseActiveAccountValues.data = { + currency: 'USD', + hasMigratedToWallets: true, + is_virtual: 0, + } as ReturnType['data']; + render( + + + + + + ); + expect(screen.queryByText('Cashier')).not.toBeInTheDocument(); + }); });