Skip to content

Commit

Permalink
Merge pull request #50 from shafin-deriv/shafin/BOT-1862/chore-accoun…
Browse files Browse the repository at this point in the history
…t-switcher

chore: account switcher initial PR
  • Loading branch information
sandeep-deriv authored Sep 10, 2024
2 parents 19f320d + 782730c commit 74ff754
Show file tree
Hide file tree
Showing 49 changed files with 1,267 additions and 325 deletions.
1 change: 1 addition & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ const config: Config = {
'^@/components/(.*)$': '<rootDir>/src/components/$1',
'^@/constants/(.*)$': '<rootDir>/src/constants/$1',
'^@/hooks/(.*)$': '<rootDir>/src/hooks/$1',
'^@/stores/(.*)$': '<rootDir>/src/stores/$1',
},

// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
Expand Down
13 changes: 12 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
},
"dependencies": {
"@deriv-com/analytics": "^1.5.3",
"@deriv-com/api-hooks": "^1.1.1",
"@deriv-com/api-hooks": "^1.6.5",
"@deriv-com/translations": "^1.2.4",
"@deriv-com/ui": "^1.29.0",
"@deriv-com/utils": "latest",
Expand Down Expand Up @@ -97,6 +97,7 @@
"@types/react-dom": "^18.3.0",
"@types/react-router-dom": "^5.3.3",
"@types/react-transition-group": "^4.4.10",
"@types/react-virtualized": "^9.21.30",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.0.0",
"babel-core": "^7.0.0-bridge.0",
Expand Down Expand Up @@ -141,4 +142,4 @@
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.0.4"
}
}
}
1 change: 1 addition & 0 deletions rsbuild.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export default defineConfig({
'@/hooks': path.resolve(__dirname, './src/hooks'),
'@/utils': path.resolve(__dirname, './src/utils'),
'@/constants': path.resolve(__dirname, './src/constants'),
'@/stores': path.resolve(__dirname, './src/stores'),
},
},
output: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { render, screen } from '@testing-library/react';
import ContractCardRunningBot, { message_running_bot } from '../contract-card-running-bot';

jest.mock('@/external/bot-skeleton/scratch/dbot.js', () => ({}));

describe('ContractCardRunningBot', () => {
it('renders ContractCardRunningBot with the Icon component with correct props', () => {
const { container } = render(<ContractCardRunningBot />);
const svg = container.getElementsByTagName('svg')[0];
expect(svg).toBeInTheDocument();
expect(svg).toHaveAttribute('id', 'rotate-icon');
expect(svg).toHaveAttribute('height', '24');
expect(svg).toHaveAttribute('width', '16');
});

it('renders ContractCardRunningBot with the Text component with the correct text and styles', () => {
render(<ContractCardRunningBot />);
const text = screen.getByText(message_running_bot);
expect(text).toBeInTheDocument();
expect(text).toHaveClass('dc-contract-card-message');
});
});
60 changes: 35 additions & 25 deletions src/components/contract-card-loading/contract-card-loading.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,44 @@
import React from 'react';
import ContentLoader from 'react-content-loader';
import { contract_stages } from '@/constants/contract-stage';
import ContractCardRunningBot from './contract-card-running-bot';

type TContractCardLoader = {
speed?: number;
contract_stage?: number;
};

const ContractCardLoader = ({ speed = 3 }: TContractCardLoader) => (
<ContentLoader
height={153}
width={334}
speed={speed}
backgroundColor={'var(--general-section-2)'}
foregroundColor={'var(--general-hover)'}
data-testid='contract-card-loader'
>
<rect x='12' y='15' rx='0' ry='0' width='41' height='25' />
<rect x='61' y='24' rx='0' ry='0' width='91' height='8' />
<rect x='180' y='15' rx='0' ry='0' width='41' height='25' />
<rect x='229' y='24' rx='0' ry='0' width='91' height='8' />
<rect x='12' y='48' rx='0' ry='0' width='60' height='8' />
<rect x='12' y='64' rx='0' ry='0' width='308' height='8' />
<rect x='12' y='80' rx='0' ry='0' width='308' height='1' />
<rect x='12' y='89' rx='0' ry='0' width='140' height='8' />
<rect x='12' y='105' rx='0' ry='0' width='60' height='8' />
<rect x='12' y='121' rx='0' ry='0' width='140' height='8' />
<rect x='12' y='137' rx='0' ry='0' width='60' height='8' />
<rect x='180' y='89' rx='0' ry='0' width='140' height='8' />
<rect x='180' y='105' rx='0' ry='0' width='60' height='8' />
<rect x='180' y='121' rx='0' ry='0' width='140' height='8' />
<rect x='180' y='137' rx='0' ry='0' width='60' height='8' />
</ContentLoader>
const ContractCardLoader = ({ speed = 3, contract_stage }: TContractCardLoader) => (
<>
{contract_stage === contract_stages.RUNNING ? (
<ContractCardRunningBot />
) : (
<ContentLoader
height={153}
width={334}
speed={speed}
backgroundColor={'var(--general-section-2)'}
foregroundColor={'var(--general-hover)'}
data-testid='contract-card-loader'
>
<rect x='12' y='15' rx='0' ry='0' width='41' height='25' />
<rect x='61' y='24' rx='0' ry='0' width='91' height='8' />
<rect x='180' y='15' rx='0' ry='0' width='41' height='25' />
<rect x='229' y='24' rx='0' ry='0' width='91' height='8' />
<rect x='12' y='48' rx='0' ry='0' width='60' height='8' />
<rect x='12' y='64' rx='0' ry='0' width='308' height='8' />
<rect x='12' y='80' rx='0' ry='0' width='308' height='1' />
<rect x='12' y='89' rx='0' ry='0' width='140' height='8' />
<rect x='12' y='105' rx='0' ry='0' width='60' height='8' />
<rect x='12' y='121' rx='0' ry='0' width='140' height='8' />
<rect x='12' y='137' rx='0' ry='0' width='60' height='8' />
<rect x='180' y='89' rx='0' ry='0' width='140' height='8' />
<rect x='180' y='105' rx='0' ry='0' width='60' height='8' />
<rect x='180' y='121' rx='0' ry='0' width='140' height='8' />
<rect x='180' y='137' rx='0' ry='0' width='60' height='8' />
</ContentLoader>
)}
</>
);

export default ContractCardLoader;
24 changes: 24 additions & 0 deletions src/components/contract-card-loading/contract-card-running-bot.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react';
import { LabelPairedLoaderMdBoldIcon } from '@deriv/quill-icons';
import { localize } from '@deriv-com/translations';
import { Text } from '@deriv-com/ui';

export const message_running_bot = localize('Your bot is running and waiting for a signal to buy a contract.');

const ContractCardRunningBot = () => (
<>
<LabelPairedLoaderMdBoldIcon id='rotate-icon' fontSize={16} />
<Text
color='less-prominent'
line_height='xs'
size='xs'
weight='bold'
align='center'
className='dc-contract-card-message'
>
{message_running_bot}
</Text>
</>
);

export default ContractCardRunningBot;
67 changes: 67 additions & 0 deletions src/components/currency/currency-icon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { lazy, Suspense } from 'react';

const CURRENCY_ICONS = {
aud: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyAudIcon }))),
bch: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyBchIcon }))),
btc: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyBtcIcon }))),
busd: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyBusdIcon }))),
dai: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyDaiIcon }))),
eth: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyEthIcon }))),
eur: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyEurIcon }))),
'eur-check': lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyEurIcon }))),
eurs: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyEursIcon }))),
eusdt: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyUsdtIcon }))),
gbp: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyGbpIcon }))),
idk: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyIdkIcon }))),
ltc: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyLtcIcon }))),
pax: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyPaxIcon }))),
tusd: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyTusdIcon }))),
tusdt: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyUsdtIcon }))),
unknown: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyPlaceholderIcon }))),
usd: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyUsdIcon }))),
usdc: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyUsdcIcon }))),
usdk: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyUsdkIcon }))),
ust: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyUsdtIcon }))),
virtual: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyDemoIcon }))),
xrp: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyXrpIcon }))),
algo: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyAlgoIcon }))),
avax: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyAvaxIcon }))),
bat: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyBatIcon }))),
bnb: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyBnbIcon }))),
dash: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyDashIcon }))),
doge: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyDogeIcon }))),
dot: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyDotIcon }))),
eos: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyEosIcon }))),
etc: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyEtcIcon }))),
fil: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyFilIcon }))),
iota: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyIotaIcon }))),
link: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyLinkIcon }))),
matic: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyMaticIcon }))),
mkr: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyMkrIcon }))),
mcd: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyMultiCollateralDaiIcon }))),
neo: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyNeoIcon }))),
none: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyNoneIcon }))),
omg: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyOmgIcon }))),
p2p: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyP2PIcon }))),
scd: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencySingleCollateralDaiIcon }))),
sol: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencySolIcon }))),
terra: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyTerraIcon }))),
trx: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyTrxIcon }))),
uni: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyUniIcon }))),
xlm: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyXlmIcon }))),
xmr: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyXmrIcon }))),
xtz: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyXtzIcon }))),
zec: lazy(() => import('@deriv/quill-icons').then(module => ({ default: module.CurrencyZecIcon }))),
};

export const CurrencyIcon = ({ currency, isVirtual }: { currency?: string; isVirtual?: boolean }) => {
const Icon = isVirtual
? CURRENCY_ICONS.virtual
: CURRENCY_ICONS[currency?.toLowerCase() as keyof typeof CURRENCY_ICONS] || CURRENCY_ICONS.unknown;

return (
<Suspense fallback={null}>
<Icon iconSize='sm' />
</Suspense>
);
};
81 changes: 81 additions & 0 deletions src/components/data-list/data-list-cell.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import React from 'react';
import classNames from 'classnames';
import { isTurbosContract, isVanillaContract } from '../shared';
import { TPassThrough, TRow } from '../types/common.types';

export type TColIndex =
| 'type'
| 'reference'
| 'currency'
| 'purchase'
| 'payout'
| 'profit'
| 'indicative'
| 'id'
| 'multiplier'
| 'buy_price'
| 'cancellation'
| 'limit_order'
| 'bid_price'
| 'action';

export type TRenderCellContent = {
cell_value: string;
is_footer?: boolean;
passthrough?: TPassThrough;
row_obj: TRow;
is_turbos?: boolean;
is_vanilla?: boolean;
};
export type THeaderProps = {
title?: React.ReactNode;
is_vanilla?: boolean;
};

export type TDataListCell = {
className?: string;
column?: {
key?: string;
title?: string;
col_index?: TColIndex;
renderCellContent?: (props: TRenderCellContent) => React.ReactNode;
renderHeader?: (prop: renderHeaderType) => React.ReactNode;
};
is_footer?: boolean;
passthrough?: TPassThrough;
row?: TRow;
};

type renderHeaderType = { title?: string; is_vanilla?: boolean };

const DataListCell = ({ className, column, is_footer, passthrough, row }: TDataListCell) => {
if (!column) return null;
const { col_index, title } = column;
const cell_value = row?.[col_index as TColIndex];
const is_turbos = isTurbosContract(row?.contract_info?.contract_type);
const is_vanilla = isVanillaContract(row?.contract_info?.contract_type);

return (
<div className={classNames(className, column.col_index)}>
{!is_footer && (
<div className={classNames(`${column.col_index}__row-title`, 'data-list__row-title')}>
{column.renderHeader ? column.renderHeader({ title, is_vanilla }) : title}
</div>
)}
<div className='data-list__row-content'>
{column.renderCellContent
? column.renderCellContent({
cell_value,
is_footer,
passthrough,
row_obj: row as TRow,
is_vanilla,
is_turbos,
})
: cell_value}
</div>
</div>
);
};

export default React.memo(DataListCell);
Loading

0 comments on commit 74ff754

Please sign in to comment.