Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WALL] Lubega / WALL-5262 / Wallets P2P standalone redirection banner #17903

Closed
38 changes: 22 additions & 16 deletions packages/wallets/src/components/AccountsList/AccountsList.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React, { FC, useCallback } from 'react';
import { useIsEuRegion } from '@deriv/api-v2';
import { useActiveWalletAccount, useIsEuRegion } from '@deriv/api-v2';
import { useTranslations } from '@deriv-com/translations';
import { Divider, Tab, Tabs, useDevice } from '@deriv-com/ui';
import { CFDPlatformsList } from '../../features';
import { OptionsAndMultipliersListing } from '../OptionsAndMultipliersListing';
import { WalletsTabsLoader } from '../SkeletonLoader';
import { WalletsP2PRedirectionBanner } from '../WalletsP2PRedirectionBanner';
import './AccountsList.scss';

type TProps = {
Expand All @@ -16,6 +17,7 @@ const AccountsList: FC<TProps> = ({ accountsActiveTabIndex, onTabClickHandler })
const { isDesktop } = useDevice();
const { localize } = useTranslations();
const { data: isEuRegion, isLoading: isEuRegionLoading } = useIsEuRegion();
const { data: activeWallet } = useActiveWalletAccount();

const optionsAndMultipliersTabTitle = isEuRegion ? localize('Multipliers') : localize('Options');

Expand All @@ -28,6 +30,7 @@ const AccountsList: FC<TProps> = ({ accountsActiveTabIndex, onTabClickHandler })
<div className='wallets-accounts-list' data-testid='dt_desktop_accounts_list'>
<div className='wallets-accounts-list__content'>
<Divider color='var(--border-divider)' height={2} />
{activeWallet?.account_type === 'doughflow' && <WalletsP2PRedirectionBanner />}
<CFDPlatformsList />
<Divider color='var(--border-divider)' height={2} />
<OptionsAndMultipliersListing />
Expand All @@ -44,21 +47,24 @@ const AccountsList: FC<TProps> = ({ accountsActiveTabIndex, onTabClickHandler })
}

return (
<Tabs
activeTab={tabs[accountsActiveTabIndex ?? 0]}
className='wallets-accounts-list__tabs'
onChange={onChangeTabHandler}
wrapperClassName='wallets-accounts-list'
>
<Tab className='wallets-accounts-list__tab' title={localize('CFDs')}>
<CFDPlatformsList />
<Divider className='wallets-accounts-list__divider' color='var(--wallets-banner-border-color)' />
</Tab>
<Tab className='wallets-accounts-list__tab' title={optionsAndMultipliersTabTitle}>
<OptionsAndMultipliersListing />
<Divider className='wallets-accounts-list__divider' color='var(--wallets-banner-border-color)' />
</Tab>
</Tabs>
<>
{activeWallet?.account_type === 'doughflow' && <WalletsP2PRedirectionBanner />}
<Tabs
activeTab={tabs[accountsActiveTabIndex ?? 0]}
className='wallets-accounts-list__tabs'
onChange={onChangeTabHandler}
wrapperClassName='wallets-accounts-list'
>
<Tab className='wallets-accounts-list__tab' title={localize('CFDs')}>
<CFDPlatformsList />
<Divider className='wallets-accounts-list__divider' color='var(--wallets-banner-border-color)' />
</Tab>
<Tab className='wallets-accounts-list__tab' title={optionsAndMultipliersTabTitle}>
<OptionsAndMultipliersListing />
<Divider className='wallets-accounts-list__divider' color='var(--wallets-banner-border-color)' />
</Tab>
</Tabs>
</>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { ComponentProps, PropsWithChildren } from 'react';
import { WalletTourGuide } from 'src/components/WalletTourGuide';
import { APIProvider, useIsEuRegion } from '@deriv/api-v2';
import { APIProvider, useActiveWalletAccount, useIsEuRegion } from '@deriv/api-v2';
import { useDevice } from '@deriv-com/ui';
import { render, screen } from '@testing-library/react';
import WalletsAuthProvider from '../../../AuthProvider';
Expand Down Expand Up @@ -28,6 +28,7 @@ jest.mock(

jest.mock('@deriv/api-v2', () => ({
...jest.requireActual('@deriv/api-v2'),
useActiveWalletAccount: jest.fn(),
useIsEuRegion: jest.fn(),
}));

Expand All @@ -41,6 +42,15 @@ const wrapper = ({ children }: PropsWithChildren) => (

describe('AccountsList', () => {
beforeEach(() => {
(useActiveWalletAccount as jest.Mock).mockReturnValue({
data: {
account_type: 'doughflow',
currency_config: { display_code: 'USD', fractional_digits: 2 },
is_virtual: false,
loginid: 'CRW1234',
wallet_currency_type: 'USD',
},
});
(useDevice as jest.Mock).mockReturnValue({ isDesktop: true });
(useIsEuRegion as jest.Mock).mockReturnValue({
data: false,
Expand Down Expand Up @@ -137,6 +147,19 @@ describe('AccountsList', () => {
expect(screen.getAllByText('Options')[0]).toBeInTheDocument();
});

it('renders P2P redirection banner in desktop view', () => {
render(<AccountsList />, { wrapper });

expect(screen.getByText('Easily exchange USD with local currency using Deriv P2P.')).toBeInTheDocument();
});

it('renders P2P redirection banner in mobile view', () => {
(useDevice as jest.Mock).mockReturnValue({ isMobile: true });
render(<AccountsList />, { wrapper });

expect(screen.getByText('Easily exchange USD with local currency using Deriv P2P.')).toBeInTheDocument();
});

it('renders wallet tour guide in mobile view with isWalletSettled set to false', () => {
(useDevice as jest.Mock).mockReturnValue({ isMobile: true });

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.wallets-p2p-redirection-banner {
display: flex;
align-items: center;
justify-content: space-between;
background-color: #f8f9fa;
border-radius: 0.8rem;
margin: 2.4rem 0 0;
padding: 1.6rem;
gap: 1.6rem;

@include mobile-or-tablet-screen {
margin: 1.6rem 1.6rem 0;
}

&:hover {
background-color: var(--du-general-hover, #e6e9e9);
cursor: pointer;
}

&__description {
flex: 1;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';
import {
CurrencyP2PIcon,
LabelPairedChevronLeftCaptionRegularIcon,
LabelPairedChevronRightCaptionRegularIcon,
} from '@deriv/quill-icons';
import { Localize } from '@deriv-com/translations';
import { Text } from '@deriv-com/ui';
import { redirectToStandaloneP2P } from '../../helpers/urls';
import useIsRtl from '../../hooks/useIsRtl';
import './WalletsP2PRedirectionBanner.scss';

const WalletsP2PRedirectionBanner: React.FC = () => {
const isRtl = useIsRtl();

return (
<div
className='wallets-p2p-redirection-banner'
data-testid='dt_wallets_p2p_redirection_banner'
onClick={() => redirectToStandaloneP2P()}
onKeyDown={() => redirectToStandaloneP2P()}
>
<CurrencyP2PIcon />
<Text align='start' className='wallets-p2p-redirection-banner__description' size='sm'>
<Localize i18n_default_text='Easily exchange USD with local currency using Deriv P2P.' />
</Text>
{isRtl ? <LabelPairedChevronLeftCaptionRegularIcon /> : <LabelPairedChevronRightCaptionRegularIcon />}
</div>
);
};

export default WalletsP2PRedirectionBanner;
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React from 'react';
import { fireEvent, render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { redirectToStandaloneP2P } from '../../../helpers/urls';
import useIsRtl from '../../../hooks/useIsRtl';
import WalletsP2PRedirectionBanner from '../WalletsP2PRedirectionBanner';

jest.mock('@deriv/quill-icons', () => ({
CurrencyP2PIcon: () => <div data-testid='dt_currency_p2p_icon' />,
LabelPairedChevronLeftCaptionRegularIcon: () => <div data-testid='dt_chevron_left_icon' />,
LabelPairedChevronRightCaptionRegularIcon: () => <div data-testid='dt_chevron_right_icon' />,
}));

jest.mock('../../../helpers/urls', () => ({
redirectToStandaloneP2P: jest.fn(),
}));

jest.mock('../../../hooks/useIsRtl', () => jest.fn());

describe('WalletsP2PRedirectionBanner', () => {
beforeEach(() => {
(useIsRtl as jest.Mock).mockReturnValue(false);
});

afterEach(() => {
jest.clearAllMocks();
});

it('renders the banner with default elements', () => {
render(<WalletsP2PRedirectionBanner />);

expect(screen.getByTestId('dt_currency_p2p_icon')).toBeInTheDocument();
expect(screen.getByText('Easily exchange USD with local currency using Deriv P2P.')).toBeInTheDocument();
expect(screen.getByTestId('dt_chevron_right_icon')).toBeInTheDocument();
});

it('renders the chevron left icon in RTL mode', () => {
(useIsRtl as jest.Mock).mockReturnValue(true);

render(<WalletsP2PRedirectionBanner />);

expect(screen.getByTestId('dt_chevron_left_icon')).toBeInTheDocument();
expect(screen.queryByTestId('dt_chevron_right_icon')).not.toBeInTheDocument();
});

it('calls redirectToStandaloneP2P on click', async () => {
render(<WalletsP2PRedirectionBanner />);

const banner = screen.getByTestId('dt_wallets_p2p_redirection_banner');
await userEvent.click(banner);

expect(redirectToStandaloneP2P).toHaveBeenCalledTimes(1);
});

it('calls redirectToStandaloneP2P on keydown', () => {
render(<WalletsP2PRedirectionBanner />);

const banner = screen.getByTestId('dt_wallets_p2p_redirection_banner');
fireEvent.keyDown(banner);

expect(redirectToStandaloneP2P).toHaveBeenCalledTimes(1);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as WalletsP2PRedirectionBanner } from './WalletsP2PRedirectionBanner';
1 change: 1 addition & 0 deletions packages/wallets/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export * from './WalletsContainer';
export * from './WalletsDisabledAccountsBanner';
export * from './WalletsDisclaimerBanner';
export * from './WalletsErrorScreen';
export * from './WalletsP2PRedirectionBanner';
export * from './WalletsPercentageSelector';
export * from './WalletsResetMT5Password';
export * from './WalletStatusBadge';
Expand Down
9 changes: 9 additions & 0 deletions packages/wallets/src/helpers/urls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export const derivUrls = Object.freeze({
DERIV_COM_PRODUCTION_EU: `https://eu.${domainUrl}`,
DERIV_COM_STAGING: `https://staging.${domainUrl}`,
DERIV_HOST_NAME: domainUrl,
DERIV_P2P_PRODUCTION: `https://p2p.${domainUrl}`,
DERIV_P2P_STAGING: `https://staging-p2p.${domainUrl}`,
SMARTTRADER_PRODUCTION: `https://smarttrader.${domainUrl}`,
SMARTTRADER_STAGING: `https://staging-smarttrader.${domainUrl}`,
});
Expand Down Expand Up @@ -155,3 +157,10 @@ export const redirectToOutSystems = (currency = '') => {
return (window.location.href = redirectURL.toString());
}
};

export const redirectToStandaloneP2P = () => {
const baseUrl = isProduction() ? derivUrls.DERIV_P2P_PRODUCTION : derivUrls.DERIV_P2P_STAGING;

const redirectURL = new URL(baseUrl);
return (window.location.href = redirectURL.toString());
lubega-deriv marked this conversation as resolved.
Show resolved Hide resolved
lubega-deriv marked this conversation as resolved.
Show resolved Hide resolved
};
Loading