Skip to content

Commit

Permalink
george / WALL-431 / Demo: Input & selector stitching (#8794)
Browse files Browse the repository at this point in the history
* feat: ✨ account transfer component (demo)

* fix: transfer hint message

* fix: 🎨 apply comments

* refactor: 🎨 remove reducer, simplify transfer logic, improve readability (#34)

* fix: update padding of app-icon component (#33)

* style: improve styles for account list

* style: apply comments

* fix: apply comments, refactor account modal in desktop

* fix: 🎨 apply comments

* feat: add scrolling behaviour to account list in mobile view

* fix: apply comments, fix test

* refactor: 🔥 remove mobile dialog, refactor scrolling, remove redundant logic

* fix: apply comments, refactor tests

* test: 🚀 add tests for transfer related components

* style: fix style for merged icon

* fix: mock loginid

* fix: typo, demo icon, transition on closing, blinking icons

* perf: disable automatic opening of wallet modal

---------

Co-authored-by: Hamid <hamid@regentmarkets.com>
  • Loading branch information
heorhi-deriv and hamid-deriv committed Jun 13, 2023
1 parent a130318 commit a27d3e3
Show file tree
Hide file tree
Showing 30 changed files with 1,154 additions and 421 deletions.
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { render, screen, fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { BrowserRouter } from 'react-router-dom';
import WalletModalBody from '../wallet-modal-body';

jest.mock('Components/wallet-transfer', () => jest.fn(() => <div>WalletTransfer</div>));

describe('WalletModalBody', () => {
let mocked_props: React.ComponentProps<typeof WalletModalBody>;

beforeEach(() => {
mocked_props = {
active_tab_index: 0,
contentScrollHandler: jest.fn(),
is_dark: false,
is_demo: true,
is_mobile: false,
setActiveTabIndex: jest.fn(),
setIsWalletNameVisible: jest.fn(),
is_wallet_name_visible: true,
wallet_type: 'demo',
};
Expand All @@ -22,21 +27,39 @@ describe('WalletModalBody', () => {
render(<BrowserRouter>{component}</BrowserRouter>);
};

it('Should render proper tabs for demo wallet with proper content', () => {
it('Should render proper tabs for demo wallet', () => {
renderWithRouter(<WalletModalBody {...mocked_props} />);

expect(screen.getByText('Transfer')).toBeInTheDocument();
expect(screen.getByText('Transfer Demo')).toBeInTheDocument();
expect(screen.getByText('Transactions')).toBeInTheDocument();
expect(screen.getByText('Reset balance')).toBeInTheDocument();
});

it('Shoud trigger setActiveTabIndex callback when the user clicked on the tab', () => {
it('Should render proper content under the Transfer tab', () => {
mocked_props.active_tab_index = 1;
renderWithRouter(<WalletModalBody {...mocked_props} />);

const el_transfer_tab = screen.getByText('Transfer');
userEvent.click(el_transfer_tab);

expect(screen.getByText('WalletTransfer')).toBeInTheDocument();
});

it('Should trigger setActiveTabIndex callback when the user clicked on the tab', () => {
renderWithRouter(<WalletModalBody {...mocked_props} />);

const el_transactions_tab = screen.getByText('Transactions');
userEvent.click(el_transactions_tab);

expect(mocked_props.setActiveTabIndex).toHaveBeenCalledTimes(1);
});

it('Should trigger contentScrollHandler callback when the user scrolls the content', () => {
renderWithRouter(<WalletModalBody {...mocked_props} />);

const el_themed_scrollbars = screen.getByTestId('dt_themed_scrollbars');
fireEvent.scroll(el_themed_scrollbars);

expect(mocked_props.contentScrollHandler).toHaveBeenCalledTimes(1);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,10 @@ import { mockStore, StoreProvider } from '@deriv/stores';
import WalletModal from '../wallet-modal';

jest.mock('../wallet-modal-header', () => jest.fn(() => <div>WalletModalHeader</div>));
jest.mock('../wallet-modal-body', () => {
const { forwardRef } = jest.requireActual('react');
return {
__esModule: true,
default: forwardRef(() => <div>WalletModalBody</div>),
};
});
jest.mock('../wallet-modal-body', () => jest.fn(() => <div>WalletModalBody</div>));

describe('WalletModal', () => {
let modal_root_el;
let modal_root_el: HTMLDivElement;
beforeAll(() => {
modal_root_el = document.createElement('div');
modal_root_el.setAttribute('id', 'modal_root');
Expand Down
38 changes: 19 additions & 19 deletions packages/appstore/src/components/modals/wallet-modal/provider.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/no-empty-function */
import React from 'react';
import { localize } from '@deriv/translations';
import { isMobile } from '@deriv/shared';
import WalletTransfer from 'Components/wallet-transfer';

export type TWalletType = 'real' | 'demo' | 'p2p' | 'payment_agent';

Expand All @@ -13,8 +13,8 @@ export const getCashierOptions = (type: TWalletType) => {
icon: 'IcAdd',
label: localize('Deposit'),
//Remove Lorem ipsum text after QA testing (testing scroll behaviour)
content: (
<div style={{ padding: `${isMobile() ? '1.6rem 0' : '2.4rem 0'}`, textAlign: 'justify' }}>
content: () => (
<div style={{ textAlign: 'justify' }}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas euismod lectus odio, sed
pulvinar ex eleifend eu. Quisque elementum pellentesque felis. Maecenas elementum vitae
purus sed ullamcorper. In quis tempus diam, non posuere ipsum. Quisque viverra in mauris
Expand Down Expand Up @@ -70,82 +70,82 @@ export const getCashierOptions = (type: TWalletType) => {
</div>
),
},
{ icon: 'IcMinus', label: localize('Withdraw'), content: <p>Withdraw Real</p> },
{ icon: 'IcMinus', label: localize('Withdraw'), content: () => <p>Withdraw Real</p> },
{
icon: 'IcAccountTransfer',
label: localize('Transfer'),
content: <p>Transfer Real</p>,
content: () => <p>Transfer Real</p>,
},
{
icon: 'IcStatement',
label: localize('Transactions'),
content: <p>Transactions Real</p>,
content: () => <p>Transactions Real</p>,
},
];
case 'demo':
return [
{
icon: 'IcAccountTransfer',
label: localize('Transfer'),
content: <p>Transfer Demo</p>,
content: (props: React.ComponentProps<typeof WalletTransfer>) => <WalletTransfer {...props} />,
},
{
icon: 'IcStatement',
label: localize('Transactions'),
content: <p>Transactions Demo</p>,
content: () => <p>Transactions Demo</p>,
},
{
icon: 'IcAdd',
label: localize('Reset balance'),
content: <p>Reset balance</p>,
content: () => <p>Reset balance</p>,
},
];
case 'p2p':
return [
{
icon: 'IcAdd',
label: localize('Buy/Sell'),
content: <p>Buy/Sell</p>,
content: () => <p>Transfer Real</p>,
},
{
icon: 'IcStatement',
label: localize('Orders'),
content: <p>Orders P2P</p>,
content: () => <p>Transfer Real</p>,
},
{
icon: 'IcStatement',
label: localize('My ads'),
content: <p>My ads P2P</p>,
content: () => <p>Transfer Real</p>,
},
{
icon: 'IcStatement',
label: localize('My profile'),
content: <p>My profile P2P</p>,
content: () => <p>Transfer Real</p>,
},
{
icon: 'IcAccountTransfer',
label: localize('Transfer'),
content: <p>Transfer P2P</p>,
content: () => <p>Transfer Real</p>,
},
{
icon: 'IcStatement',
label: localize('Transactions'),
content: <p>Transactions P2P</p>,
content: () => <p>Transfer Real</p>,
},
];
case 'payment_agent':
return [
{ icon: 'IcAdd', label: localize('Deposit'), content: <p>Deposit PA</p> },
{ icon: 'IcMinus', label: localize('Withdraw'), content: <p>Withdraw PA</p> },
{ icon: 'IcAdd', label: localize('Deposit'), content: () => <p>Transfer Real</p> },
{ icon: 'IcMinus', label: localize('Withdraw'), content: () => <p>Transfer Real</p> },
{
icon: 'IcAccountTransfer',
label: localize('Transfer'),
content: <p>Transfer PA</p>,
content: () => <p>Transfer Real</p>,
},
{
icon: 'IcStatement',
label: localize('Transactions'),
content: <p>Transactions PA</p>,
content: () => <p>Transfer Real</p>,
},
];
default:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,38 @@
import React from 'react';
import classNames from 'classnames';
import { Tabs, ThemedScrollbars } from '@deriv/components';
import { Tabs, ThemedScrollbars, Div100vhContainer } from '@deriv/components';
import { getCashierOptions, TWalletType } from './provider';

type TWalletModalBodyProps = {
active_tab_index: number;
contentScrollHandler: React.UIEventHandler<HTMLDivElement>;
is_dark: boolean;
is_demo: boolean;
is_mobile: boolean;
setActiveTabIndex: (index: number) => void;
setIsWalletNameVisible: (value: boolean) => void;
is_wallet_name_visible: boolean;
wallet_type: TWalletType;
};

const WalletModalBody = ({
active_tab_index,
contentScrollHandler,
is_dark,
is_demo,
is_mobile,
is_wallet_name_visible,
setActiveTabIndex,
setIsWalletNameVisible,
is_wallet_name_visible,
wallet_type,
}: TWalletModalBodyProps) => {
const content_heigth = 'calc(100vh - 24.4rem)';
const max_content_width = '128rem';
const getHeightOffset = React.useCallback(() => {
const desktop_header_height = '24.4rem';
const mobile_header_height = '8.2rem';

return is_mobile ? mobile_header_height : desktop_header_height;
}, [is_mobile]);

return (
<Tabs
active_icon_color={is_dark ? 'var(--badge-white)' : ''}
Expand All @@ -36,6 +45,7 @@ const WalletModalBody = ({
header_fit_content
icon_size={16}
icon_color={is_demo ? 'var(--demo-text-color-1)' : ''}
is_scrollable={false}
onTabItemClick={(index: number) => {
setActiveTabIndex(index);
}}
Expand All @@ -44,12 +54,18 @@ const WalletModalBody = ({
return (
<div key={option.label} icon={option.icon} label={option.label}>
<ThemedScrollbars
is_bypassed={is_mobile}
is_scrollbar_hidden
height={content_heigth}
width={max_content_width}
className='dc-tabs--modal-body__tabs__themed-scrollbar'
is_scrollbar_hidden={is_mobile}
onScroll={contentScrollHandler}
>
{option.content}
<Div100vhContainer height_offset={getHeightOffset()}>
<div className='dc-tabs--modal-body__tabs__content-wrapper'>
{option.content({
is_wallet_name_visible,
setIsWalletNameVisible,
})}
</div>
</Div100vhContainer>
</ThemedScrollbars>
</div>
);
Expand All @@ -58,6 +74,4 @@ const WalletModalBody = ({
);
};

WalletModalBody.displayName = 'WalletModalBody';

export default WalletModalBody;
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ const WalletModalHeader = ({
{formatMoney(currency, balance, true)} {getCurrencyDisplayCode(currency)}
</Text>
</div>
{/* TODO: replace Icon with WalletIcon component */}
<div className={classNames(`${header_class_name}__currency-icon icon-visibility`)}>
<Icon {...getCurrencyIconProps()} data_testid='dt_currency_icon' />
</div>
Expand Down
Loading

0 comments on commit a27d3e3

Please sign in to comment.