Skip to content

Commit

Permalink
[TRAH] Sergei / TRAH-2591 / MT5 Trade Screen (binary-com#12793)
Browse files Browse the repository at this point in the history
* fix: delete export from ButtonGroup

* feat: add TradeModal

* feat: add some data

* feat: add test button

* feat: add images and some styles

* refactor: delete comments

* feat: add onClick for CFDs open modal button

* feat: almost done

* feat: almost done

* refactor: delete helper code from TradersHubRoute

* feat: implemet review suggestions

* feat: implement more comments

* feat: change mt5 to CFDPlatforms

* feat: implement comments 3

* feat: change Text size

* feat: implement comments #4
  • Loading branch information
sergei-deriv committed Jan 10, 2024
1 parent 6ff40ff commit 8820630
Show file tree
Hide file tree
Showing 18 changed files with 378 additions and 32 deletions.
1 change: 1 addition & 0 deletions packages/library/src/providers/CFDProvider/CFDProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { TMarketTypes, TPlatforms, THooks } from '../../types';

type TCFDState = {
// Add your CFD states here
accountId?: string;
marketType?: TMarketTypes.All;
platform?: TPlatforms.All;
selectedJurisdiction?: THooks.AvailableMT5Accounts['shortcode'];
Expand Down
8 changes: 4 additions & 4 deletions packages/tradershub/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import './index.scss';
const App = () => (
<APIProvider standalone>
<BreakpointProvider>
<Provider.ModalProvider>
<Provider.CFDProvider>
<Provider.CFDProvider>
<Provider.ModalProvider>
<ContentSwitcher>
<AppContent />
</ContentSwitcher>
</Provider.CFDProvider>
</Provider.ModalProvider>
</Provider.ModalProvider>
</Provider.CFDProvider>
</BreakpointProvider>
</APIProvider>
);
Expand Down
2 changes: 1 addition & 1 deletion packages/tradershub/src/components/Clipboard/Clipboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const Clipboard = ({ textCopy, tooltip }: TClipboardProps) => {
isVisible={isHovered && !isMobile}
message={isCopied ? 'Copied!' : 'Copy'}
>
<Button colorStyle='white' onClick={onClick} ref={hoverRef} size='sm'>
<Button colorStyle='white' onClick={onClick} ref={hoverRef} size='sm' variant='tertiary'>
{isCopied ? <CheckmarkCircle /> : <ClipboardIcon />}
</Button>
</Tooltip>
Expand Down
7 changes: 3 additions & 4 deletions packages/tradershub/src/components/Modal/Modal.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { ReactElement, ReactNode } from 'react';
import React, { PropsWithChildren, ReactElement } from 'react';
import { qtMerge } from '@deriv/quill-design';
import ModalContent from './ModalContent';
import ModalFooter from './ModalFooter';
Expand Down Expand Up @@ -33,10 +33,9 @@ type TModal = {
* @property {ReactNode} children - Children nodes
* @property {string} [className] - Optional CSS class name
*/
export type TModalComponents = {
children?: ReactNode;
export type TModalComponents = PropsWithChildren<{
className?: string;
};
}>;

/**
* Modal component
Expand Down
32 changes: 32 additions & 0 deletions packages/tradershub/src/features/cfd/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import FinancialMT5Icon from '../../public/images/cfd/mt5-financial.svg';
import SwapFreeMT5Icon from '../../public/images/cfd/mt5-swap-free.svg';
import CTraderLabelIcon from '../../public/images/ctrader-label.svg';
import DerivXLabelIcon from '../../public/images/derivx-label.svg';
import InstallationAppleIcon from '../../public/images/ic-installation-apple.svg';
import InstallationGoogleIcon from '../../public/images/ic-installation-google.svg';
import InstallationHuaweiIcon from '../../public/images/ic-installation-huawei.svg';
import LinuxIcon from '../../public/images/ic-linux-logo.svg';
import MacOSIcon from '../../public/images/ic-macos-logo.svg';
import MT5Icon from '../../public/images/ic-mt5.svg';
Expand Down Expand Up @@ -158,3 +161,32 @@ export const PlatformUrls: TPlatformUrls = {
live: 'https://dx.deriv.com',
},
};

export type TAppLinks = {
android: string;
huawei?: string;
ios: string;
};

export const LinksMapper: Record<TPlatforms.All, TAppLinks> = {
ctrader: {
android: 'https://play.google.com/store/apps/details?id=com.deriv.ct',
ios: 'https://apps.apple.com/cy/app/ctrader/id767428811',
},
dxtrade: {
android: 'https://play.google.com/store/apps/details?id=com.deriv.dx',
huawei: 'https://appgallery.huawei.com/app/C104633219',
ios: 'https://apps.apple.com/us/app/deriv-x/id1563337503',
},
mt5: {
android: 'https://download.mql5.com/cdn/mobile/mt5/android?server=Deriv-Demo,Deriv-Server,Deriv-Server-02',
huawei: 'https://appgallery.huawei.com/#/app/C102015329',
ios: 'https://download.mql5.com/cdn/mobile/mt5/ios?server=Deriv-Demo,Deriv-Server,Deriv-Server-02',
},
};

export const AppToIconMapper: Record<string, React.ComponentType<React.SVGAttributes<SVGElement>>> = {
android: InstallationGoogleIcon,
huawei: InstallationHuaweiIcon,
ios: InstallationAppleIcon,
};
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import React, { Fragment } from 'react';
import { useActiveTradingAccount, useCtraderAccountsList } from '@deriv/api';
import { Provider } from '@deriv/library';
import { Button, Text } from '@deriv/quill-design';
import { TradingAccountCard } from '../../../../../components';
import { getStaticUrl } from '../../../../../helpers/urls';
import CTrader from '../../../../../public/images/cfd/ctrader.svg';
import { PlatformDetails } from '../../../constants';
import { CFDPlatforms, PlatformDetails } from '../../../constants';
import { TradeModal } from '../../../modals/TradeModal';

const AddedCTraderAccountsList = () => {
const { data: cTraderAccounts } = useCtraderAccountsList();
const { data: activeTrading } = useActiveTradingAccount();
const { show } = Provider.useModal();
const account = cTraderAccounts?.find(account => account.is_virtual === activeTrading?.is_virtual);

const leading = () => (
<div
Expand Down Expand Up @@ -37,7 +41,21 @@ const AddedCTraderAccountsList = () => {
>
Transfer
</Button>
<Button className='rounded-200 px-800'>Open</Button>
<Button
className='rounded-200 px-800'
onClick={() =>
account &&
show(
<TradeModal
account={account}
marketType={account?.market_type}
platform={CFDPlatforms.CTRADER}
/>
)
}
>
Open
</Button>
</div>
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import React, { useMemo } from 'react';
import { useHistory } from 'react-router-dom';
import { useAuthorize, useJurisdictionStatus } from '@deriv/api';
import { useActiveTradingAccount, useJurisdictionStatus } from '@deriv/api';
import { Provider } from '@deriv/library';
import { Button, Text } from '@deriv/quill-design';
import { TradingAccountCard } from '../../../../../components/TradingAccountCard';
import { THooks } from '../../../../../types';
import { MarketTypeDetails } from '../../../constants';
import { CFDPlatforms, MarketTypeDetails } from '../../../constants';
import { TradeModal } from '../../../modals/TradeModal';
import { MT5AccountIcon } from '../MT5AccountIcon';

const AddedMT5AccountsList = ({ account }: { account: THooks.MT5AccountsList }) => {
const { data: activeWallet } = useAuthorize();
const { data: activeAccount } = useActiveTradingAccount();
const { show } = Provider.useModal();
const history = useHistory();
const { getVerificationStatus } = useJurisdictionStatus();
const jurisdictionStatus = useMemo(
Expand All @@ -27,7 +30,7 @@ const AddedMT5AccountsList = ({ account }: { account: THooks.MT5AccountsList })
colorStyle='black'
disabled={jurisdictionStatus.is_failed || jurisdictionStatus.is_pending}
onClick={() => {
history.push('/wallets/cashier/transfer');
history.push('/cashier/transfer');
}}
variant='secondary'
>
Expand All @@ -36,7 +39,15 @@ const AddedMT5AccountsList = ({ account }: { account: THooks.MT5AccountsList })
<Button
className='rounded-200 px-800'
disabled={jurisdictionStatus.is_failed || jurisdictionStatus.is_pending}
// onClick show MT5TradeModal
onClick={() =>
show(
<TradeModal
account={account}
marketType={account?.market_type}
platform={CFDPlatforms.MT5}
/>
)
}
>
Open
</Button>
Expand All @@ -46,7 +57,7 @@ const AddedMT5AccountsList = ({ account }: { account: THooks.MT5AccountsList })
<div className='flex-grow user-select-none'>
<div className='flex self-stretch flex-center gap-400'>
<Text size='sm'>{title}</Text>
{!activeWallet?.is_virtual && (
{!activeAccount?.is_virtual && (
<div className='flex items-center rounded-md h-1200 py-50 px-200 gap-200 bg-system-light-secondary-background'>
<Text bold size='xs'>
{account.landing_company_short?.toUpperCase()}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import React, { Fragment } from 'react';
import { useActiveTradingAccount, useDxtradeAccountsList } from '@deriv/api';
import { Provider } from '@deriv/library';
import { Button, Text } from '@deriv/quill-design';
import { TradingAccountCard } from '../../../../../../components';
import { getStaticUrl } from '../../../../../../helpers/urls';
import DerivX from '../../../../../../public/images/cfd/derivx.svg';
import { PlatformDetails } from '../../../../constants';
import { CFDPlatforms, PlatformDetails } from '../../../../constants';
import { TradeModal } from '../../../../modals/TradeModal';

const AddedDxtradeAccountsList = () => {
const { data: dxTradeAccounts } = useDxtradeAccountsList();
const { data: activeTrading } = useActiveTradingAccount();
const { show } = Provider.useModal();
const account = dxTradeAccounts?.find(account => account.is_virtual === activeTrading?.is_virtual);

const leading = () => (
<div
Expand Down Expand Up @@ -38,7 +42,21 @@ const AddedDxtradeAccountsList = () => {
>
Transfer
</Button>
<Button className='rounded-200 px-800'>Open</Button>
<Button
className='rounded-200 px-800'
onClick={() =>
account &&
show(
<TradeModal
account={account}
marketType={account?.market_type}
platform={CFDPlatforms.DXTRADE}
/>
)
}
>
Open
</Button>
</div>
);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React, { useEffect } from 'react';
import QRCode from 'qrcode.react';
import { Provider } from '@deriv/library';
import { Text, useBreakpoint } from '@deriv/quill-design';
import { Modal } from '../../../../components/Modal';
import { THooks, TMarketTypes, TPlatforms } from '../../../../types';
import { AppToIconMapper, CFDPlatforms, LinksMapper, PlatformDetails, TAppLinks } from '../../constants';
import { MT5TradeScreen } from '../../screens/MT5TradeScreen';

type TTradeModalProps = {
account?: THooks.CtraderAccountsList | THooks.DxtradeAccountsList | THooks.MT5AccountsList;
marketType?: TMarketTypes.All;
platform: TPlatforms.All;
};

const TradeModal = ({ account, marketType, platform }: TTradeModalProps) => {
const { isDesktop } = useBreakpoint();
const { setCfdState } = Provider.useCFDContext();

useEffect(() => {
setCfdState('marketType', marketType);
setCfdState('platform', platform);
if (platform === CFDPlatforms.MT5) setCfdState('accountId', (account as THooks.MT5AccountsList)?.loginid);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

const appOrder = ['ios', 'android', 'huawei'];

return (
<Modal>
<Modal.Header title='Trade' />
<Modal.Content>
<MT5TradeScreen account={account} />
</Modal.Content>
<Modal.Footer>
<div className='pt-50 min-h-[190px] flex justify-center items-center flex-col h-fit w-full gap-800'>
<Text align='center' size='sm' weight='bold'>
Download {PlatformDetails[platform].title} on your phone to trade with the{' '}
{PlatformDetails[platform].title} account
</Text>
<div className='flex gap-800'>
<div className='flex flex-col justify-center gap-400'>
{appOrder.map(app => {
const AppsLinkMapper = LinksMapper[platform][app as keyof TAppLinks];
if (AppsLinkMapper) {
const AppIcon = AppToIconMapper[app];
const appLink = AppsLinkMapper;
return (
<AppIcon
className='w-[137px] h-[40px] cursor-pointer'
key={app}
onClick={() => window.open(appLink)}
/>
);
}
return null;
})}
</div>
{isDesktop && (
<div className='border-75 border-system-light-hover-background rounded-200 flex flex-col justify-center items-center w-[150px] gap-[5px] p-400'>
<QRCode size={80} value={PlatformDetails[platform].link} />
<Text align='center' size='xs'>
Scan the QR code to download {PlatformDetails[platform].title}
</Text>
</div>
)}
</div>
</div>
</Modal.Footer>
</Modal>
);
};

export default TradeModal;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as TradeModal } from './TradeModal';
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import React, { FC, useRef } from 'react';
import { useHover } from 'usehooks-ts';
import { qtMerge, Text, useBreakpoint } from '@deriv/quill-design';
import { Button, qtMerge, Text, useBreakpoint } from '@deriv/quill-design';
import { Clipboard, Tooltip } from '../../../../../components';
import EditIcon from '../../../../../public/images/ic-edit.svg';

type TMT5TradeDetailsItemProps = {
className?: string;
label: string;
label?: string;
value: string;
variant: 'clipboard' | 'password';
variant?: 'clipboard' | 'info' | 'password';
};

const MT5TradeDetailsItem: FC<TMT5TradeDetailsItemProps> = ({ className, label, value, variant = 'clipboard' }) => {
Expand All @@ -25,15 +25,17 @@ const MT5TradeDetailsItem: FC<TMT5TradeDetailsItemProps> = ({ className, label,
<Text colorStyle='subtle' size='sm'>
{label}
</Text>
<div className='flex items-center space-x-400 pr-400'>
<Text bold size='sm'>
<div className='flex items-center gap-x-400'>
<Text bold={variant !== 'info'} size='sm'>
{value}
</Text>
{variant === 'clipboard' && <Clipboard textCopy={value} />}
{variant === 'password' && (
<Tooltip alignment='left' isVisible={isHovered && isDesktop} message='Change password'>
<div ref={hoverRef}>
<EditIcon className='cursor-pointer' />
<Button colorStyle='white' size='sm' variant='tertiary'>
<EditIcon className='cursor-pointer' />
</Button>
</div>
</Tooltip>
)}
Expand Down
Loading

0 comments on commit 8820630

Please sign in to comment.