diff --git a/packages/api-v2/src/hooks/__tests__/useSortedMT5Accounts.spec.ts b/packages/api-v2/src/hooks/__tests__/useSortedMT5Accounts.spec.ts
deleted file mode 100644
index c556c4b76780..000000000000
--- a/packages/api-v2/src/hooks/__tests__/useSortedMT5Accounts.spec.ts
+++ /dev/null
@@ -1,296 +0,0 @@
-import { renderHook } from '@testing-library/react-hooks';
-import useActiveAccount from '../useActiveAccount';
-import useAvailableMT5Accounts from '../useAvailableMT5Accounts';
-import useIsEuRegion from '../useIsEuRegion';
-import useMT5AccountsList from '../useMT5AccountsList';
-import useSortedMT5Accounts from '../useSortedMT5Accounts';
-import { cleanup } from '@testing-library/react';
-
-jest.mock('../useActiveAccount', () => jest.fn());
-jest.mock('../useAvailableMT5Accounts', () => jest.fn());
-jest.mock('../useIsEuRegion', () => jest.fn());
-jest.mock('../useMT5AccountsList', () => jest.fn());
-
-const mockMT5NonEUAvailableAccounts = [
- {
- is_default_jurisdiction: 'false',
- product: 'standard',
- shortcode: 'svg',
- },
- {
- is_default_jurisdiction: 'false',
- product: 'financial',
- shortcode: 'svg',
- },
- {
- is_default_jurisdiction: 'true',
- product: 'financial',
- shortcode: 'vanuatu',
- },
- {
- is_default_jurisdiction: 'true',
- product: 'stp',
- shortcode: 'vanuatu',
- },
- {
- is_default_jurisdiction: 'true',
- product: 'standard',
- shortcode: 'vanuatu',
- },
- {
- is_default_jurisdiction: 'true',
- product: 'zero_spread',
- shortcode: 'bvi',
- },
- {
- is_default_jurisdiction: 'true',
- product: 'swap_free',
- shortcode: 'svg',
- },
-];
-
-const mockMT5NonEUAddedAccounts = [
- {
- is_virtual: false,
- landing_company_short: 'vanuatu',
- product: 'standard',
- },
- {
- is_virtual: false,
- landing_company_short: 'vanuatu',
- product: 'financial',
- },
- {
- is_virtual: false,
- landing_company_short: 'bvi',
- product: 'zero_spread',
- },
-];
-
-const mockMT5EUAvailableAccounts = [
- {
- is_default_jurisdiction: 'true',
- product: 'financial',
- shortcode: 'maltainvest',
- },
-];
-
-const mockMT5EUAddedAccounts = [
- {
- is_virtual: false,
- landing_company_short: 'maltainvest',
- product: 'financial',
- },
-];
-
-describe('useSortedMT5Accounts', () => {
- beforeEach(() => {
- (useActiveAccount as jest.Mock).mockReturnValue({
- data: { is_virtual: false },
- });
- (useIsEuRegion as jest.Mock).mockReturnValue({
- isEUCountry: false,
- });
- });
- afterEach(cleanup);
-
- it('returns non-eu available accounts with default jurisdiction', () => {
- (useAvailableMT5Accounts as jest.Mock).mockReturnValue({
- data: mockMT5NonEUAvailableAccounts,
- });
- (useMT5AccountsList as jest.Mock).mockReturnValue({
- data: [],
- });
-
- const { result } = renderHook(() => useSortedMT5Accounts());
-
- expect(result.current.data).toEqual([
- {
- is_added: false,
- is_default_jurisdiction: 'true',
- product: 'standard',
- shortcode: 'vanuatu',
- },
- {
- is_added: false,
- is_default_jurisdiction: 'true',
- product: 'financial',
- shortcode: 'vanuatu',
- },
- {
- is_added: false,
- is_default_jurisdiction: 'true',
- product: 'swap_free',
- shortcode: 'svg',
- },
- {
- is_added: false,
- is_default_jurisdiction: 'true',
- product: 'zero_spread',
- shortcode: 'bvi',
- },
- ]);
- });
-
- it('returns eu available accounts with default jurisdiction', () => {
- (useAvailableMT5Accounts as jest.Mock).mockReturnValue({
- data: mockMT5EUAvailableAccounts,
- });
- (useMT5AccountsList as jest.Mock).mockReturnValue({
- data: [],
- });
-
- const { result } = renderHook(() => useSortedMT5Accounts());
-
- expect(result.current.data).toEqual([
- {
- is_added: false,
- is_default_jurisdiction: 'true',
- product: 'financial',
- shortcode: 'maltainvest',
- },
- ]);
- });
-
- it('returns list of non-eu added and available accounts after some accounts are created', () => {
- (useAvailableMT5Accounts as jest.Mock).mockReturnValue({
- data: mockMT5NonEUAvailableAccounts,
- });
- (useMT5AccountsList as jest.Mock).mockReturnValue({
- data: mockMT5NonEUAddedAccounts,
- });
-
- const { result } = renderHook(() => useSortedMT5Accounts());
-
- expect(result.current.data).toEqual([
- {
- is_added: true,
- is_virtual: false,
- landing_company_short: 'vanuatu',
- product: 'standard',
- },
- {
- is_added: true,
- is_virtual: false,
- landing_company_short: 'vanuatu',
- product: 'financial',
- },
- {
- is_added: false,
- is_default_jurisdiction: 'true',
- product: 'swap_free',
- shortcode: 'svg',
- },
- {
- is_added: true,
- is_virtual: false,
- landing_company_short: 'bvi',
- product: 'zero_spread',
- },
- ]);
- });
-
- it('returns list of eu added and available accounts after some accounts are created', () => {
- (useAvailableMT5Accounts as jest.Mock).mockReturnValue({
- data: mockMT5EUAvailableAccounts,
- });
- (useMT5AccountsList as jest.Mock).mockReturnValue({
- data: mockMT5EUAddedAccounts,
- });
- (useIsEuRegion as jest.Mock).mockReturnValue({
- isEUCountry: true,
- });
-
- const { result } = renderHook(() => useSortedMT5Accounts());
-
- expect(result.current.data).toEqual([
- {
- is_added: true,
- is_virtual: false,
- landing_company_short: 'maltainvest',
- product: 'financial',
- },
- ]);
- });
-
- it('returns sorted non-eu accounts list in the correct order', () => {
- (useAvailableMT5Accounts as jest.Mock).mockReturnValue({
- data: mockMT5NonEUAvailableAccounts,
- });
- (useMT5AccountsList as jest.Mock).mockReturnValue({
- data: [],
- });
-
- const { result } = renderHook(() => useSortedMT5Accounts());
-
- expect(result.current.data?.map(account => account.product)).toStrictEqual([
- 'standard',
- 'financial',
- 'swap_free',
- 'zero_spread',
- ]);
- });
-
- it('filters-out available MT5 financial stp account disabling clients to create it', () => {
- (useAvailableMT5Accounts as jest.Mock).mockReturnValue({
- data: mockMT5NonEUAvailableAccounts,
- });
- (useMT5AccountsList as jest.Mock).mockReturnValue({
- data: [],
- });
-
- const { result } = renderHook(() => useSortedMT5Accounts());
-
- expect(result.current.data).not.toContain({
- is_added: false,
- is_default_jurisdiction: 'true',
- product: 'stp',
- shortcode: 'vanuatu',
- });
- });
-
- it('all available MT5 accounts are created', () => {
- (useAvailableMT5Accounts as jest.Mock).mockReturnValue({
- data: mockMT5NonEUAvailableAccounts,
- });
- (useMT5AccountsList as jest.Mock).mockReturnValue({
- data: [
- ...mockMT5NonEUAddedAccounts,
- {
- is_virtual: false,
- landing_company_short: 'svg',
- product: 'swap_free',
- },
- ],
- });
-
- const { result } = renderHook(() => useSortedMT5Accounts());
-
- expect(result.current.data).toEqual([
- {
- is_added: true,
- is_virtual: false,
- landing_company_short: 'vanuatu',
- product: 'standard',
- },
- {
- is_added: true,
- is_virtual: false,
- landing_company_short: 'vanuatu',
- product: 'financial',
- },
- {
- is_added: true,
- is_virtual: false,
- landing_company_short: 'svg',
- product: 'swap_free',
- },
- {
- is_added: true,
- is_virtual: false,
- landing_company_short: 'bvi',
- product: 'zero_spread',
- },
- ]);
- });
-});
diff --git a/packages/api-v2/src/hooks/useSortedMT5Accounts.ts b/packages/api-v2/src/hooks/useSortedMT5Accounts.ts
index e85841d39c02..7db93f7d010f 100644
--- a/packages/api-v2/src/hooks/useSortedMT5Accounts.ts
+++ b/packages/api-v2/src/hooks/useSortedMT5Accounts.ts
@@ -28,42 +28,79 @@ const useSortedMT5Accounts = (regulation?: string) => {
: account.landing_company_short !== 'maltainvest')
);
- const available_accounts = filtered_available_accounts.filter(available => {
- return (
- !filtered_mt5_accounts.find(added => added.product === available.product) &&
- // @ts-expect-error type for is_default_jurisdiction is unavailable in mt5_login_list and trading_platform_available_accounts
- available.is_default_jurisdiction === 'true' &&
- /*
- TODO: remove this check to filter out the creation of `stp` accounts in phase 2 of default jurisdiction
- when this product type is separated from `financial` type.
- */
- // @ts-expect-error type `stp` is unavailable in the type for trading_platform_available_accounts
- available.product !== 'stp'
- );
- });
+ return filtered_available_accounts?.map(available_account => {
+ const created_account = filtered_mt5_accounts?.find(account => {
+ return (
+ available_account.market_type === account.market_type &&
+ available_account.shortcode === account.landing_company_short
+ );
+ });
- const combined_accounts = [
- ...available_accounts.map(account => ({ ...account, is_added: false })),
- ...filtered_mt5_accounts.map(account => ({ ...account, is_added: true })),
- ];
- return combined_accounts;
+ if (created_account)
+ return {
+ ...created_account,
+ /** Determine if the account is added or not */
+ is_added: true,
+ } as const;
+
+ return {
+ ...available_account,
+ /** Determine if the account is added or not */
+ is_added: false,
+ } as const;
+ });
}, [activeAccount?.is_virtual, all_available_mt5_accounts, isEU, mt5_accounts]);
+ // // Reduce out the added and non added accounts to make sure only one of each market_type is shown for not added
+ const filtered_data = useMemo(() => {
+ if (!modified_data) return;
+
+ const added_accounts = modified_data.filter(account => account.is_added);
+ const non_added_accounts = modified_data.filter(account => !account.is_added);
+
+ const filtered_non_added_accounts = non_added_accounts.reduce((acc, account) => {
+ const { market_type, product } = account;
+ const key = product === 'zero_spread' ? `${market_type}_${product}` : market_type;
+
+ const existing_account = acc.find(acc_account =>
+ acc_account.product === 'zero_spread'
+ ? `${acc_account.market_type}_${acc_account.product}` === key
+ : acc_account.market_type === key
+ );
+ const added_account = added_accounts.find(acc_account =>
+ acc_account.product === 'zero_spread'
+ ? `${acc_account.market_type}_${acc_account.product}` === key
+ : acc_account.market_type === key
+ );
+ if (existing_account || added_account) return acc;
+
+ return [...acc, account];
+ }, [] as typeof non_added_accounts);
+
+ return [...added_accounts, ...filtered_non_added_accounts];
+ }, [modified_data]);
+
+ // Sort the data by market_type and product to make sure the order is 'synthetic', 'financial', 'swap_free' and 'zero_spread'
const sorted_data = useMemo(() => {
- const sorting_order = ['standard', 'financial', 'stp', 'swap_free', 'zero_spread'];
+ const sorting_order = ['synthetic', 'financial', 'swap_free', 'zero_spread'];
- if (!modified_data) return;
+ if (!filtered_data) return;
const sorted_data = sorting_order.reduce((acc, sort_order) => {
- const accounts = modified_data.filter(account => account.product === sort_order);
+ const accounts = filtered_data.filter(account => {
+ if (account.market_type === 'all') {
+ return account.product === sort_order;
+ }
+ return account.market_type === sort_order;
+ });
if (!accounts.length) return acc;
return [...acc, ...accounts];
- }, [] as typeof modified_data);
+ }, [] as typeof filtered_data);
return sorted_data;
- }, [modified_data]);
+ }, [filtered_data]);
- const areAllAccountsCreated = modified_data?.length === all_available_mt5_accounts?.length;
+ const areAllAccountsCreated = sorted_data?.length === all_available_mt5_accounts?.length;
return {
data: sorted_data,
diff --git a/packages/wallets/src/features/cfd/components/CFDPasswordModalTnc/CFDPasswordModalTnc.scss b/packages/wallets/src/features/cfd/components/CFDPasswordModalTnc/CFDPasswordModalTnc.scss
new file mode 100644
index 000000000000..5f1047baca7e
--- /dev/null
+++ b/packages/wallets/src/features/cfd/components/CFDPasswordModalTnc/CFDPasswordModalTnc.scss
@@ -0,0 +1,9 @@
+.wallets-cfd-modal-tnc {
+ display: flex;
+ flex-direction: column;
+ gap: 1.6rem;
+
+ @include mobile-or-tablet-screen {
+ margin-top: auto;
+ }
+}
diff --git a/packages/wallets/src/features/cfd/components/CFDPasswordModalTnc/CFDPasswordModalTnc.tsx b/packages/wallets/src/features/cfd/components/CFDPasswordModalTnc/CFDPasswordModalTnc.tsx
new file mode 100644
index 000000000000..ed0ccb3c891c
--- /dev/null
+++ b/packages/wallets/src/features/cfd/components/CFDPasswordModalTnc/CFDPasswordModalTnc.tsx
@@ -0,0 +1,57 @@
+import React from 'react';
+import { Localize, useTranslations } from '@deriv-com/translations';
+import { Checkbox, InlineMessage, Text, useDevice } from '@deriv-com/ui';
+import { WalletLink } from '../../../../components/Base';
+import { useModal } from '../../../../components/ModalProvider';
+import { THooks, TPlatforms } from '../../../../types';
+import { companyNamesAndUrls, getMarketTypeDetails, PlatformDetails } from '../../constants';
+import './CFDPasswordModalTnc.scss';
+
+export type TCFDPasswordModalTncProps = {
+ checked: boolean;
+ onChange: () => void;
+ platform: TPlatforms.All;
+ product?: THooks.AvailableMT5Accounts['product'];
+};
+
+const CFDPasswordModalTnc = ({ checked, onChange, platform, product }: TCFDPasswordModalTncProps) => {
+ const { isDesktop } = useDevice();
+ const { getModalState } = useModal();
+ const { localize } = useTranslations();
+ const selectedJurisdiction = getModalState('selectedJurisdiction');
+ const selectedCompany = companyNamesAndUrls[selectedJurisdiction as keyof typeof companyNamesAndUrls];
+ const platformTitle = PlatformDetails[platform].title;
+ const productTitle = getMarketTypeDetails(localize, product).all.title;
+
+ return (
+
+
+
+
+
+
+
+ ]}
+ i18n_default_text='I confirm and accept {{company}}’s <0>terms and conditions0>'
+ values={{
+ company: selectedCompany.name,
+ }}
+ />
+
+ }
+ name='zerospread-checkbox'
+ onChange={onChange}
+ />
+
+ );
+};
+
+export default CFDPasswordModalTnc;
diff --git a/packages/wallets/src/features/cfd/screens/components/MT5PasswordModalTnc/__tests__/MT5PasswordModalTnc.spec.tsx b/packages/wallets/src/features/cfd/components/CFDPasswordModalTnc/__tests__/CFDPasswordModalTnc.spec.tsx
similarity index 54%
rename from packages/wallets/src/features/cfd/screens/components/MT5PasswordModalTnc/__tests__/MT5PasswordModalTnc.spec.tsx
rename to packages/wallets/src/features/cfd/components/CFDPasswordModalTnc/__tests__/CFDPasswordModalTnc.spec.tsx
index 35e05b9cb1ac..820b654032c3 100644
--- a/packages/wallets/src/features/cfd/screens/components/MT5PasswordModalTnc/__tests__/MT5PasswordModalTnc.spec.tsx
+++ b/packages/wallets/src/features/cfd/components/CFDPasswordModalTnc/__tests__/CFDPasswordModalTnc.spec.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { fireEvent, render, screen } from '@testing-library/react';
-import MT5PasswordModalTnc, { type TMT5PasswordModalTncProps } from '../MT5PasswordModalTnc';
+import CFDPasswordModalTnc, { type TCFDPasswordModalTncProps } from '../CFDPasswordModalTnc';
jest.mock('@deriv-com/ui', () => ({
Checkbox: jest.fn(({ checked, label, onChange }) => (
@@ -18,44 +18,53 @@ jest.mock('@deriv-com/ui', () => ({
useDevice: jest.fn(() => ({ isDesktop: true })),
}));
-jest.mock('../../../../../../components/ModalProvider', () => ({
+jest.mock('../../../../../components/ModalProvider', () => ({
useModal: jest.fn(() => ({
getModalState: jest.fn(() => 'bvi'),
})),
}));
-jest.mock('../../../../../../components/Base/WalletLink', () => ({
+jest.mock('../../../../../components/Base/WalletLink', () => ({
WalletLink: ({ children }: { children: React.ReactNode }) => {children},
}));
const mockOnChange = jest.fn();
-describe('MT5PasswordModalTnc', () => {
- const defaultProps: TMT5PasswordModalTncProps = {
+describe('CFDPasswordModalTnc', () => {
+ const defaultProps: TCFDPasswordModalTncProps = {
checked: false,
onChange: mockOnChange,
+ platform: 'mt5',
+ product: 'zero_spread',
};
it('renders correctly', () => {
- render();
- expect(screen.getByTestId('dt_wallets_mt5_tnc_checkbox')).toBeInTheDocument();
+ render();
+ expect(screen.getByTestId('dt_wallets_tnc_checkbox')).toBeInTheDocument();
+ expect(screen.getByTestId('dt_wallets_tnc_inline_message')).toBeInTheDocument();
});
it('displays correct text content', () => {
- render();
- expect(screen.getByText("I confirm and accept Deriv (BVI) Ltd's")).toBeInTheDocument();
+ render();
+ expect(screen.getByText(/You are adding your Deriv MT5/i)).toBeInTheDocument();
+ expect(screen.getByText(/I confirm and accept/i)).toBeInTheDocument();
});
it('handles checkbox change', () => {
- render();
- const checkbox = screen.getByTestId('dt_wallets_mt5_tnc_checkbox');
+ render();
+ const checkbox = screen.getByTestId('dt_wallets_tnc_checkbox');
fireEvent.click(checkbox);
expect(mockOnChange).toHaveBeenCalledTimes(1);
});
it('renders the terms and conditions link', () => {
- render();
+ render();
const link = screen.getByText('terms and conditions');
expect(link).toHaveAttribute('href', 'https://example.com');
});
+
+ it('uses the correct platform and product titles', () => {
+ render();
+ expect(screen.getByText(/MT5.*Zero Spread/)).toBeInTheDocument();
+ });
});
diff --git a/packages/wallets/src/features/cfd/components/CFDPasswordModalTnc/index.ts b/packages/wallets/src/features/cfd/components/CFDPasswordModalTnc/index.ts
new file mode 100644
index 000000000000..bea48cf4ec04
--- /dev/null
+++ b/packages/wallets/src/features/cfd/components/CFDPasswordModalTnc/index.ts
@@ -0,0 +1 @@
+export { default as CFDPasswordModalTnc } from './CFDPasswordModalTnc';
diff --git a/packages/wallets/src/features/cfd/components/CFDPlatformsListAccounts/CFDPlatformsListAccounts.tsx b/packages/wallets/src/features/cfd/components/CFDPlatformsListAccounts/CFDPlatformsListAccounts.tsx
index 0a3ea97a7b3c..68f97577d784 100644
--- a/packages/wallets/src/features/cfd/components/CFDPlatformsListAccounts/CFDPlatformsListAccounts.tsx
+++ b/packages/wallets/src/features/cfd/components/CFDPlatformsListAccounts/CFDPlatformsListAccounts.tsx
@@ -9,7 +9,6 @@ import {
AvailableDxtradeAccountsList,
AvailableMT5AccountsList,
} from '../../flows';
-import { TAddedMT5Account, TAvailableMT5Account } from '../../types';
import './CFDPlatformsListAccounts.scss';
const CFDPlatformsListAccounts: React.FC = () => {
@@ -56,18 +55,10 @@ const CFDPlatformsListAccounts: React.FC = () => {
{mt5AccountsList?.map((account, index) => {
if (account.is_added)
- return (
-
- );
+ return
;
return (
-
+
);
})}
{!isRestricted && (
diff --git a/packages/wallets/src/features/cfd/components/ClientVerificationBadge/ClientVerificationStatusBadge.scss b/packages/wallets/src/features/cfd/components/ClientVerificationBadge/ClientVerificationStatusBadge.scss
deleted file mode 100644
index 101e4280e4a1..000000000000
--- a/packages/wallets/src/features/cfd/components/ClientVerificationBadge/ClientVerificationStatusBadge.scss
+++ /dev/null
@@ -1,9 +0,0 @@
-.wallets-client-verification-badge {
- margin-inline-end: auto;
-
- &__content {
- &--underlined {
- text-decoration: underline;
- }
- }
-}
diff --git a/packages/wallets/src/features/cfd/components/ClientVerificationBadge/ClientVerificationStatusBadge.tsx b/packages/wallets/src/features/cfd/components/ClientVerificationBadge/ClientVerificationStatusBadge.tsx
deleted file mode 100644
index 6eea858836d2..000000000000
--- a/packages/wallets/src/features/cfd/components/ClientVerificationBadge/ClientVerificationStatusBadge.tsx
+++ /dev/null
@@ -1,76 +0,0 @@
-import React from 'react';
-import classNames from 'classnames';
-import {
- LabelPairedCircleCheckCaptionBoldIcon,
- LabelPairedCircleExclamationCaptionBoldIcon,
- LabelPairedClockThreeCaptionBoldIcon,
- LabelPairedTriangleExclamationCaptionBoldIcon,
-} from '@deriv/quill-icons';
-import { useTranslations } from '@deriv-com/translations';
-import { Badge, Text, useDevice } from '@deriv-com/ui';
-import { TTranslations } from '../../../../types';
-import './ClientVerificationStatusBadge.scss';
-
-type TBadgeColor = React.ComponentProps
['color'];
-
-const getBadgeVariations = (localize: TTranslations['localize']) => {
- return {
- failed: {
- color: 'danger-secondary',
- content: localize('Failed'),
- icon: ,
- },
- in_review: {
- color: 'warning-secondary',
- content: localize('In review'),
- icon: ,
- },
- needs_verification: {
- color: 'blue-secondary',
- content: localize('Needs verification'),
- icon: ,
- },
- verified: {
- color: 'success-secondary',
- content: localize('Verified'),
- icon: ,
- },
- };
-};
-
-type TClientVerificationBadgeProps = {
- onClick?: VoidFunction;
- variant: keyof ReturnType;
-};
-
-const ClientVerificationStatusBadge: React.FC = ({ onClick, variant }) => {
- const { localize } = useTranslations();
- const { isDesktop } = useDevice();
- const { color, content, icon } = getBadgeVariations(localize)[variant];
- return (
- {
- if (onClick) {
- e.stopPropagation();
- onClick();
- }
- }}
- >
-
- {content}
-
-
- );
-};
-
-export default ClientVerificationStatusBadge;
diff --git a/packages/wallets/src/features/cfd/components/ClientVerificationBadge/index.ts b/packages/wallets/src/features/cfd/components/ClientVerificationBadge/index.ts
deleted file mode 100644
index 7c8dfffb6e93..000000000000
--- a/packages/wallets/src/features/cfd/components/ClientVerificationBadge/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { default as ClientVerificationStatusBadge } from './ClientVerificationStatusBadge';
diff --git a/packages/wallets/src/features/cfd/components/PlatformStatusBadge/PlatformStatusBadge.tsx b/packages/wallets/src/features/cfd/components/PlatformStatusBadge/PlatformStatusBadge.tsx
index eabf13023033..61faecd6b7b0 100644
--- a/packages/wallets/src/features/cfd/components/PlatformStatusBadge/PlatformStatusBadge.tsx
+++ b/packages/wallets/src/features/cfd/components/PlatformStatusBadge/PlatformStatusBadge.tsx
@@ -3,15 +3,15 @@ import { useTradingPlatformStatus } from '@deriv/api-v2';
import { LegacyWarningIcon } from '@deriv/quill-icons';
import { useTranslations } from '@deriv-com/translations';
import { Badge, Text } from '@deriv-com/ui';
+import { THooks } from '../../../../types';
import type { TAccount } from '../../../cashier/modules/Transfer/types';
import { MT5_ACCOUNT_STATUS, TRADING_PLATFORM_STATUS } from '../../constants';
-import { TAddedMT5Account } from '../../types';
type TProps = {
badgeSize: ComponentProps['badgeSize'];
cashierAccount?: TAccount;
className?: ComponentProps['className'];
- mt5Account?: TAddedMT5Account;
+ mt5Account?: THooks.MT5AccountsList;
};
const PlatformStatusBadge: React.FC = ({ badgeSize, cashierAccount, className, mt5Account }) => {
diff --git a/packages/wallets/src/features/cfd/components/index.ts b/packages/wallets/src/features/cfd/components/index.ts
index 04b24a2fe7fc..ac62e79079c5 100644
--- a/packages/wallets/src/features/cfd/components/index.ts
+++ b/packages/wallets/src/features/cfd/components/index.ts
@@ -1,5 +1,4 @@
export * from './CFDPlatformsListAccounts';
-export * from './ClientVerificationBadge';
export * from './CompareAccountsCarousel';
export * from './ModalTradeWrapper';
export * from './PlatformStatusBadge';
diff --git a/packages/wallets/src/features/cfd/constants.tsx b/packages/wallets/src/features/cfd/constants.tsx
index 07a36a720225..bd51f9972fba 100644
--- a/packages/wallets/src/features/cfd/constants.tsx
+++ b/packages/wallets/src/features/cfd/constants.tsx
@@ -185,24 +185,12 @@ export const MT5_ACCOUNT_STATUS = {
FAILED: 'failed',
MIGRATED_WITH_POSITION: 'migrated_with_position',
MIGRATED_WITHOUT_POSITION: 'migrated_without_position',
- PENDING: 'pending',
- UNAVAILABLE: 'unavailable',
- UNDER_MAINTENANCE: 'under_maintenance',
- // TODO: remove all the statuses below once the KYC statuses are consolidated by BE
- // eslint-disable-next-line sort-keys
- POA_FAILED: 'poa_failed',
- POA_OUTDATED: 'poa_outdated',
- PROOF_FAILED: 'proof_failed',
-
- // eslint-disable-next-line sort-keys
NEEDS_VERIFICATION: 'needs_verification',
- POA_REQUIRED: 'poa_required',
-
- // eslint-disable-next-line sort-keys
+ PENDING: 'pending',
POA_PENDING: 'poa_pending',
- VERIFICATION_PENDING: 'verification_pending',
- // eslint-disable-next-line sort-keys
POA_VERIFIED: 'poa_verified',
+ UNAVAILABLE: 'unavailable',
+ UNDER_MAINTENANCE: 'under_maintenance',
} as const;
/**
diff --git a/packages/wallets/src/features/cfd/flows/MT5/AddedMT5AccountsList/AddedMT5AccountsList.scss b/packages/wallets/src/features/cfd/flows/MT5/AddedMT5AccountsList/AddedMT5AccountsList.scss
index 80a851dae2be..b2a54c389c1a 100644
--- a/packages/wallets/src/features/cfd/flows/MT5/AddedMT5AccountsList/AddedMT5AccountsList.scss
+++ b/packages/wallets/src/features/cfd/flows/MT5/AddedMT5AccountsList/AddedMT5AccountsList.scss
@@ -94,8 +94,5 @@
&--pending {
opacity: 0.5;
}
- &--disabled {
- opacity: 0.48;
- }
}
}
diff --git a/packages/wallets/src/features/cfd/flows/MT5/AddedMT5AccountsList/AddedMT5AccountsList.tsx b/packages/wallets/src/features/cfd/flows/MT5/AddedMT5AccountsList/AddedMT5AccountsList.tsx
index dab700346633..d6d4f84ae9ba 100644
--- a/packages/wallets/src/features/cfd/flows/MT5/AddedMT5AccountsList/AddedMT5AccountsList.tsx
+++ b/packages/wallets/src/features/cfd/flows/MT5/AddedMT5AccountsList/AddedMT5AccountsList.tsx
@@ -1,67 +1,161 @@
-import React, { useState } from 'react';
+import React, { useMemo, useState } from 'react';
import classNames from 'classnames';
+import { useJurisdictionStatus, useTradingPlatformStatus } from '@deriv/api-v2';
import {
LabelPairedChevronLeftCaptionRegularIcon,
LabelPairedChevronRightCaptionRegularIcon,
+ LabelPairedCircleExclamationLgBoldIcon,
+ LabelPairedTriangleExclamationMdBoldIcon,
} from '@deriv/quill-icons';
-import { useTranslations } from '@deriv-com/translations';
-import { Text } from '@deriv-com/ui';
+import { Localize, useTranslations } from '@deriv-com/translations';
+import { InlineMessage, Text } from '@deriv-com/ui';
import { WalletDisabledAccountModal, WalletStatusBadge } from '../../../../../components';
import { useModal } from '../../../../../components/ModalProvider';
import { TradingAccountCard } from '../../../../../components/TradingAccountCard';
import useIsRtl from '../../../../../hooks/useIsRtl';
-import { ClientVerificationStatusBadge, PlatformStatusBadge } from '../../../components';
-import { MARKET_TYPE, PlatformDetails } from '../../../constants';
-import { ClientVerificationModal, MT5TradeModal, TradingPlatformStatusModal } from '../../../modals';
-import { TAddedMT5Account } from '../../../types';
-import { useAddedMT5Account } from './hooks';
+import { THooks } from '../../../../../types';
+import { PlatformStatusBadge } from '../../../components/PlatformStatusBadge';
+import {
+ getMarketTypeDetails,
+ JURISDICTION,
+ MARKET_TYPE,
+ MT5_ACCOUNT_STATUS,
+ PlatformDetails,
+ TRADING_PLATFORM_STATUS,
+} from '../../../constants';
+import { MT5TradeModal, TradingPlatformStatusModal, VerificationFailedModal } from '../../../modals';
import './AddedMT5AccountsList.scss';
type TProps = {
- account: TAddedMT5Account;
+ account: THooks.MT5AccountsList;
+};
+
+type TTradingAccountJurisdictionStatusInfoProps = {
+ isAccountDisabled?: boolean;
+ isJurisdictionFailure?: boolean;
+ isJurisdictionPending?: boolean;
+ selectedJurisdiction: THooks.MT5AccountsList['landing_company_short'];
+};
+
+const TradingAccountJurisdictionStatusInfo: React.FC = ({
+ isAccountDisabled,
+ isJurisdictionFailure,
+ isJurisdictionPending,
+ selectedJurisdiction,
+}) => {
+ const { show } = useModal();
+ if (isAccountDisabled) {
+ return ;
+ }
+ if (isJurisdictionPending) {
+ return (
+
+ }
+ >
+
+
+
+
+ );
+ }
+
+ if (isJurisdictionFailure) {
+ return (
+
+ }
+ >
+
+
+ show(, {
+ defaultRootId: 'wallets_modal_root',
+ })
+ }
+ />,
+ ]}
+ i18n_default_text='Verification failed <0>Why?0>'
+ />
+
+
+ );
+ }
+
+ return null;
};
const AddedMT5AccountsList: React.FC = ({ account }) => {
+ const [shouldShowDisabledAccountModal, setShouldShowDisabledAccountModal] = useState(false);
+ const { getVerificationStatus } = useJurisdictionStatus();
const { localize } = useTranslations();
const isRtl = useIsRtl();
- const { accountDetails, isAccountDisabled, isServerMaintenance, kycStatus, showMT5TradeModal, showPlatformStatus } =
- useAddedMT5Account(account);
-
+ const jurisdictionStatus = useMemo(
+ () => getVerificationStatus(account.landing_company_short || JURISDICTION.SVG, account.status),
+ [account.landing_company_short, account.status, getVerificationStatus]
+ );
+ const { title } = getMarketTypeDetails(localize, account.product)[account.market_type ?? MARKET_TYPE.ALL];
const { show } = useModal();
- const [showDisabledAccountModal, setShowDisabledAccountModal] = useState(false);
+ const { getPlatformStatus } = useTradingPlatformStatus();
+ const platformStatus = getPlatformStatus(account.platform);
+
+ const hasPlatformStatus =
+ account.status === TRADING_PLATFORM_STATUS.UNAVAILABLE ||
+ account.status === MT5_ACCOUNT_STATUS.UNDER_MAINTENANCE ||
+ platformStatus === TRADING_PLATFORM_STATUS.MAINTENANCE;
+
+ const isServerMaintenance =
+ platformStatus === TRADING_PLATFORM_STATUS.MAINTENANCE ||
+ account.status === MT5_ACCOUNT_STATUS.UNDER_MAINTENANCE;
+ const showPlatformStatus = hasPlatformStatus && !(jurisdictionStatus.is_pending || jurisdictionStatus.is_failed);
+ // @ts-expect-error The enabled property exists, but the api-types are invalid
+ const isAccountDisabled = !account?.rights?.enabled;
+ const shouldShowBalance = !(jurisdictionStatus.is_failed || jurisdictionStatus.is_pending) && !isAccountDisabled;
return (
<>
{
if (isAccountDisabled) {
- setShowDisabledAccountModal(true);
- return;
+ return setShouldShowDisabledAccountModal(true);
}
-
- if (showPlatformStatus) {
+ if (hasPlatformStatus)
return show(, {
defaultRootId: 'wallets_modal_root',
});
- }
-
- if (showMT5TradeModal) {
- return show(
- ,
- { defaultRootId: 'wallets_modal_root' }
- );
+ if (platformStatus === TRADING_PLATFORM_STATUS.ACTIVE) {
+ return jurisdictionStatus.is_failed
+ ? show(, {
+ defaultRootId: 'wallets_modal_root',
+ })
+ : show(
+
+ );
}
}}
>
- {accountDetails.icon}
+ {getMarketTypeDetails(localize, account.product)[account.market_type || MARKET_TYPE.ALL].icon}
= ({ account }) => {
})}
>
- {accountDetails.title}
+ {title}
- {!isAccountDisabled && !kycStatus && (
+ {shouldShowBalance && (
{account.display_balance}
)}
+
{account.display_login}
- {!isAccountDisabled && kycStatus && (
-
- show(, {
- defaultRootId: 'wallets_modal_root',
- })
- }
- variant={kycStatus}
- />
- )}
- {isAccountDisabled && }
+
{showPlatformStatus ? (
@@ -105,7 +194,7 @@ const AddedMT5AccountsList: React.FC = ({ account }) => {
mt5Account={account}
/>
) : (
-
+
{isRtl ? (
) : (
@@ -118,8 +207,8 @@ const AddedMT5AccountsList: React.FC
= ({ account }) => {
setShowDisabledAccountModal(false)}
+ isVisible={shouldShowDisabledAccountModal}
+ onClose={() => setShouldShowDisabledAccountModal(false)}
/>
>
);
diff --git a/packages/wallets/src/features/cfd/flows/MT5/AddedMT5AccountsList/__tests__/AddedMT5AccountsList.spec.tsx b/packages/wallets/src/features/cfd/flows/MT5/AddedMT5AccountsList/__tests__/AddedMT5AccountsList.spec.tsx
index 1b5f66f84d52..7157576d8451 100644
--- a/packages/wallets/src/features/cfd/flows/MT5/AddedMT5AccountsList/__tests__/AddedMT5AccountsList.spec.tsx
+++ b/packages/wallets/src/features/cfd/flows/MT5/AddedMT5AccountsList/__tests__/AddedMT5AccountsList.spec.tsx
@@ -1,220 +1,160 @@
import React from 'react';
+import { useJurisdictionStatus, useTradingPlatformStatus } from '@deriv/api-v2';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import { ModalProvider } from '../../../../../../components/ModalProvider';
-import { PlatformDetails } from '../../../../constants';
+import { useModal } from '../../../../../../components/ModalProvider';
+import { MT5TradeModal, TradingPlatformStatusModal, VerificationFailedModal } from '../../../../modals';
import AddedMT5AccountsList from '../AddedMT5AccountsList';
-import { useAddedMT5Account } from '../hooks';
-// mock function to check if correct props are passed to the modal components
-const mockPropsFn = jest.fn();
-
-jest.mock('../hooks', () => ({
- useAddedMT5Account: jest.fn(),
-}));
-
-jest.mock('react-router-dom', () => ({
- ...jest.requireActual('react-router-dom'),
- useHistory: jest.fn(() => ({
- push: jest.fn(),
- })),
-}));
-
-jest.mock('../../../../components', () => ({
- ...jest.requireActual('../../../../components'),
- ClientVerificationStatusBadge: jest.fn(props => {
- mockPropsFn(props.variant);
- return (
- {
- e.stopPropagation();
- props.onClick();
- }}
- >
- ClientVerificationStatusBadge
-
- );
- }),
- PlatformStatusBadge: jest.fn(props => {
- mockPropsFn(props);
- return PlatformStatusBadge
;
- }),
-}));
-
-jest.mock('../../../../modals', () => ({
- ...jest.requireActual('../../../../modals'),
- ClientVerificationModal: jest.fn(props => {
- mockPropsFn(props);
- return ClientVerificationModal
;
- }),
- MT5TradeModal: jest.fn(props => {
- mockPropsFn(props);
- return MT5TradeModal
;
- }),
- TradingPlatformStatusModal: jest.fn(props => {
- mockPropsFn(props);
- return TradingPlatformStatusModal
;
- }),
+jest.mock('@deriv/api-v2', () => ({
+ useJurisdictionStatus: jest.fn(),
+ useTradingPlatformStatus: jest.fn(),
}));
-jest.mock('../../../../../../components', () => ({
- ...jest.requireActual('../../../../../../components'),
- WalletDisabledAccountModal: jest.fn(props => {
- mockPropsFn(props);
- return WalletDisabledAccountModal
;
- }),
- WalletStatusBadge: jest.fn(props => {
- mockPropsFn(props);
- return WalletStatusBadge
;
- }),
+jest.mock('../../../../../../components/ModalProvider', () => ({
+ useModal: jest.fn(),
}));
-const mockAccount = {
- display_balance: 'USD 1000.00',
- display_login: '12345678',
- landing_company_short: 'svg',
- market_type: 'financial',
- platform: 'mt5',
- product: 'financial',
- status: 'active',
-};
-
-const mockUseAddedMT5AccountData = {
- accountDetails: {
- icon: (
- <>
- icon-{mockAccount.platform}-{mockAccount.product}
- >
- ),
- title: 'Financial',
- },
- isServerMaintenance: false,
- showClientVerificationModal: false,
- showMT5TradeModal: true,
- showPlatformStatus: false,
-};
-
-const wrapper: React.FC = ({ children }) => (
- <>
- {children}
- >
-);
-
describe('AddedMT5AccountsList', () => {
- // const mockShow = jest.fn();
+ const mockAccount = {
+ display_balance: 'USD 1000.00',
+ display_login: '12345678',
+ landing_company_short: 'svg',
+ market_type: 'financial',
+ platform: 'mt5',
+ product: 'standard',
+ rights: { enabled: true },
+ status: 'active',
+ };
+
+ const mockShow = jest.fn();
- beforeAll(() => {
- const modalRoot = document.createElement('div');
- modalRoot.setAttribute('id', 'wallets_modal_root');
- document.body.appendChild(modalRoot);
- });
beforeEach(() => {
- (useAddedMT5Account as jest.Mock).mockReturnValue(mockUseAddedMT5AccountData);
+ (useJurisdictionStatus as jest.Mock).mockReturnValue({
+ getVerificationStatus: jest.fn().mockReturnValue({ is_failed: false, is_pending: false }),
+ });
+ (useTradingPlatformStatus as jest.Mock).mockReturnValue({
+ getPlatformStatus: jest.fn().mockReturnValue('active'),
+ });
+ (useModal as jest.Mock).mockReturnValue({ show: mockShow });
});
- it('displays added mt5 account with correct account details', () => {
+ it('renders added mt5 accounts list with correct account details', () => {
// @ts-expect-error - since this is a mock, we only need partial properties of the account
- render(, { wrapper });
+ render();
- expect(screen.getByText('icon-mt5-financial')).toBeInTheDocument();
expect(screen.getByText('Financial')).toBeInTheDocument();
expect(screen.getByText('USD 1000.00')).toBeInTheDocument();
expect(screen.getByText('12345678')).toBeInTheDocument();
});
- it('displays correct variant of ClientVerificationStatusBadge and renders modal with ClientVerificationModal when clicked on it', async () => {
- (useAddedMT5Account as jest.Mock).mockReturnValue({
- ...mockUseAddedMT5AccountData,
- kycStatus: 'mockKycStatus',
- });
-
+ it('shows MT5TradeModal when list is clicked and status is active', async () => {
// @ts-expect-error - since this is a mock, we only need partial properties of the account
- render(, { wrapper });
-
- const badge = screen.getByText('ClientVerificationStatusBadge');
+ render();
- expect(badge).toBeInTheDocument();
- expect(mockPropsFn).toBeCalledWith('mockKycStatus');
-
- userEvent.click(badge);
+ userEvent.click(screen.getByTestId('dt_wallets_trading_account_card'));
await waitFor(() => {
- expect(screen.getByText('ClientVerificationModal')).toBeInTheDocument();
+ expect(mockShow).toHaveBeenCalledWith(
+ // @ts-expect-error - since this is a mock, we only need partial properties of the account
+
+ );
});
});
- it('shows the disabled badge when the account MT5 account is disabled', () => {
- (useAddedMT5Account as jest.Mock).mockReturnValue({
- ...mockUseAddedMT5AccountData,
- isAccountDisabled: true,
- isServerMaintenance: true,
- showPlatformStatus: true,
+ it('shows TradingPlatformStatusModal when platform is under maintenance', async () => {
+ (useTradingPlatformStatus as jest.Mock).mockReturnValue({
+ getPlatformStatus: jest.fn().mockReturnValue('maintenance'),
});
// @ts-expect-error - since this is a mock, we only need partial properties of the account
- render(, { wrapper });
+ render();
- expect(screen.getByText('WalletStatusBadge')).toBeInTheDocument();
- expect(mockPropsFn).toBeCalledWith({
- badgeSize: 'md',
- padding: 'tight',
- status: 'disabled',
+ userEvent.click(screen.getByTestId('dt_wallets_trading_account_card'));
+
+ await waitFor(() => {
+ expect(mockShow).toHaveBeenCalledWith(, {
+ defaultRootId: 'wallets_modal_root',
+ });
});
});
- it('shows MT5TradeModal when list is clicked and status is active', async () => {
+ it('shows VerificationFailedModal when verification has failed', async () => {
+ (useJurisdictionStatus as jest.Mock).mockReturnValue({
+ getVerificationStatus: jest.fn().mockReturnValue({ is_failed: true, is_pending: false }),
+ });
// @ts-expect-error - since this is a mock, we only need partial properties of the account
- render(, { wrapper });
+ render();
userEvent.click(screen.getByTestId('dt_wallets_trading_account_card'));
await waitFor(() => {
- expect(screen.getByText('MT5TradeModal')).toBeInTheDocument();
- expect(mockPropsFn).toBeCalledWith({
- marketType: mockAccount.market_type,
- mt5Account: mockAccount,
- platform: PlatformDetails.mt5.platform,
+ expect(mockShow).toHaveBeenCalledWith(, {
+ defaultRootId: 'wallets_modal_root',
});
});
});
- it('shows TradingPlatformStatusModal when platform is under maintenance', async () => {
- (useAddedMT5Account as jest.Mock).mockReturnValue({
- ...mockUseAddedMT5AccountData,
- isServerMaintenance: true,
- showPlatformStatus: true,
+ it('displays pending verification message when status is pending', () => {
+ (useJurisdictionStatus as jest.Mock).mockReturnValue({
+ getVerificationStatus: jest.fn().mockReturnValue({ is_failed: false, is_pending: true }),
});
// @ts-expect-error - since this is a mock, we only need partial properties of the account
- render(, { wrapper });
+ render();
- userEvent.click(screen.getByTestId('dt_wallets_trading_account_card'));
+ expect(screen.getByText('Pending verification')).toBeInTheDocument();
+ });
- await waitFor(() => {
- expect(screen.getByText('TradingPlatformStatusModal')).toBeInTheDocument();
- expect(mockPropsFn).toBeCalledWith({
- isServerMaintenance: true,
- });
+ it('displays verification failed message when verification has failed', () => {
+ (useJurisdictionStatus as jest.Mock).mockReturnValue({
+ getVerificationStatus: jest.fn().mockReturnValue({ is_failed: true, is_pending: false }),
});
+ // @ts-expect-error - since this is a mock, we only need partial properties of the account
+ render();
+
+ expect(screen.getByText('Verification failed')).toBeInTheDocument();
+ expect(screen.getByText('Why?')).toBeInTheDocument();
});
- it('shows the WalletDisabledAccountModal when a disabled account MT5 account is clicked', async () => {
- (useAddedMT5Account as jest.Mock).mockReturnValue({
- ...mockUseAddedMT5AccountData,
- isAccountDisabled: true,
- isServerMaintenance: true,
- showPlatformStatus: true,
+ it('displays VerificationFailedModal when "Why?" link is clicked', async () => {
+ (useJurisdictionStatus as jest.Mock).mockReturnValue({
+ getVerificationStatus: jest.fn().mockReturnValue({ is_failed: true, is_pending: false }),
});
// @ts-expect-error - since this is a mock, we only need partial properties of the account
- render(, { wrapper });
+ render();
- await waitFor(() => {
- userEvent.click(screen.getByText('WalletStatusBadge'));
- });
+ const link = screen.getByText('Why?');
+ userEvent.click(link);
await waitFor(() => {
- expect(screen.getByText('WalletDisabledAccountModal')).toBeInTheDocument();
+ expect(mockShow).toHaveBeenCalledWith(, {
+ defaultRootId: 'wallets_modal_root',
+ });
});
});
+
+ it('shows WalletStatusBadge when account is disabled', () => {
+ // @ts-expect-error - since this is a mock, we only need partial properties of the account
+ render();
+
+ expect(screen.getByText('Disabled')).toBeInTheDocument();
+ });
+
+ it('opens WalletDisabledAccountModal when disabled account card is clicked', async () => {
+ // @ts-expect-error - since this is a mock, we only need partial properties of the account
+ render();
+
+ const card = screen.getByTestId('dt_wallets_trading_account_card');
+ await userEvent.click(card);
+
+ expect(screen.getByText('Contact us via live chat for more details.')).toBeInTheDocument();
+
+ const closeButton = screen.getByTestId('dt-close-icon');
+ expect(closeButton).toBeInTheDocument();
+ await userEvent.click(closeButton);
+
+ expect(screen.queryByText('Contact us via live chat for more details.')).not.toBeInTheDocument();
+ });
});
diff --git a/packages/wallets/src/features/cfd/flows/MT5/AddedMT5AccountsList/hooks/__tests__/useAddedMT5Account.spec.ts b/packages/wallets/src/features/cfd/flows/MT5/AddedMT5AccountsList/hooks/__tests__/useAddedMT5Account.spec.ts
deleted file mode 100644
index 0d7af35c6215..000000000000
--- a/packages/wallets/src/features/cfd/flows/MT5/AddedMT5AccountsList/hooks/__tests__/useAddedMT5Account.spec.ts
+++ /dev/null
@@ -1,111 +0,0 @@
-import { useTradingPlatformStatus } from '@deriv/api-v2';
-import { cleanup } from '@testing-library/react';
-import { renderHook } from '@testing-library/react-hooks';
-import { getMarketTypeDetails } from '../../../../../constants';
-import { TAddedMT5Account } from '../../../../../types';
-import useAddedMT5Account from '../useAddedMT5Account';
-
-jest.mock('@deriv/api-v2', () => ({
- ...jest.requireActual('@deriv/api-v2'),
- useTradingPlatformStatus: jest.fn(),
-}));
-
-jest.mock('../../../../../constants', () => ({
- ...jest.requireActual('../../../../../constants'),
- getMarketTypeDetails: jest.fn(),
-}));
-
-const mockAccount = {
- market_type: 'financial',
- product: 'financial',
- status: '',
-} as TAddedMT5Account;
-
-describe('useAddedMT5Account', () => {
- beforeEach(() => {
- (useTradingPlatformStatus as jest.Mock).mockReturnValue({
- getPlatformStatus: jest.fn(),
- });
- });
- afterEach(cleanup);
-
- it('provides correct account details based on the market type', () => {
- (getMarketTypeDetails as jest.Mock).mockReturnValue({ financial: 'mock-account-details' });
-
- const { result } = renderHook(() => useAddedMT5Account(mockAccount));
-
- expect(result.current.accountDetails).toEqual('mock-account-details');
- });
-
- it('isServerMaintenance is `true` when trading platform status is `maintenance`', () => {
- (useTradingPlatformStatus as jest.Mock).mockReturnValue({
- getPlatformStatus: jest.fn(() => 'maintenance'),
- });
-
- const { result } = renderHook(() => useAddedMT5Account(mockAccount));
-
- expect(result.current.isServerMaintenance).toEqual(true);
- });
-
- it('isServerMaintenance is `true` when account status is `under_maintenance`', () => {
- const { result } = renderHook(() => useAddedMT5Account({ ...mockAccount, status: 'under_maintenance' }));
-
- expect(result.current.isServerMaintenance).toEqual(true);
- });
-
- it('kycStatus is `failed` when status received for account is `proof_failed`', () => {
- const { result } = renderHook(() => useAddedMT5Account({ ...mockAccount, status: 'proof_failed' }));
-
- expect(result.current.kycStatus).toEqual('failed');
- });
-
- it('kycStatus is `failed` when status received for account is `poa_failed`', () => {
- const { result } = renderHook(() => useAddedMT5Account({ ...mockAccount, status: 'poa_failed' }));
-
- expect(result.current.kycStatus).toEqual('failed');
- });
-
- it('kycStatus is `in_review` when status received for account is `verification_pending`', () => {
- const { result } = renderHook(() => useAddedMT5Account({ ...mockAccount, status: 'verification_pending' }));
-
- expect(result.current.kycStatus).toEqual('in_review');
- });
-
- it('kycStatus is `needs_verification` when status received for account is `needs_verification`', () => {
- const { result } = renderHook(() => useAddedMT5Account({ ...mockAccount, status: 'needs_verification' }));
-
- expect(result.current.kycStatus).toEqual('needs_verification');
- });
-
- it('showMT5TradeModal is `true` when platform status is `active`', () => {
- (useTradingPlatformStatus as jest.Mock).mockReturnValue({
- getPlatformStatus: jest.fn(() => 'active'),
- });
-
- const { result } = renderHook(() => useAddedMT5Account(mockAccount));
-
- expect(result.current.showMT5TradeModal).toEqual(true);
- });
-
- it('showPlatformStatus is `true` when account status is `unavailable`', () => {
- const { result } = renderHook(() => useAddedMT5Account({ ...mockAccount, status: 'unavailable' }));
-
- expect(result.current.showPlatformStatus).toEqual(true);
- });
-
- it('showPlatformStatus is `true` when account status is `under_maintenance`', () => {
- const { result } = renderHook(() => useAddedMT5Account({ ...mockAccount, status: 'under_maintenance' }));
-
- expect(result.current.showPlatformStatus).toEqual(true);
- });
-
- it('showPlatformStatus is `true` when trading platform status is `maintenance`', () => {
- (useTradingPlatformStatus as jest.Mock).mockReturnValue({
- getPlatformStatus: jest.fn(() => 'maintenance'),
- });
-
- const { result } = renderHook(() => useAddedMT5Account(mockAccount));
-
- expect(result.current.showPlatformStatus).toEqual(true);
- });
-});
diff --git a/packages/wallets/src/features/cfd/flows/MT5/AddedMT5AccountsList/hooks/index.ts b/packages/wallets/src/features/cfd/flows/MT5/AddedMT5AccountsList/hooks/index.ts
deleted file mode 100644
index 1ac54db629bf..000000000000
--- a/packages/wallets/src/features/cfd/flows/MT5/AddedMT5AccountsList/hooks/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { default as useAddedMT5Account } from './useAddedMT5Account';
diff --git a/packages/wallets/src/features/cfd/flows/MT5/AddedMT5AccountsList/hooks/useAddedMT5Account.ts b/packages/wallets/src/features/cfd/flows/MT5/AddedMT5AccountsList/hooks/useAddedMT5Account.ts
deleted file mode 100644
index e02189eab358..000000000000
--- a/packages/wallets/src/features/cfd/flows/MT5/AddedMT5AccountsList/hooks/useAddedMT5Account.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import React, { useMemo } from 'react';
-import { useTradingPlatformStatus } from '@deriv/api-v2';
-import { useTranslations } from '@deriv-com/translations';
-import { ClientVerificationStatusBadge } from '../../../../components';
-import { getMarketTypeDetails, MARKET_TYPE, MT5_ACCOUNT_STATUS, TRADING_PLATFORM_STATUS } from '../../../../constants';
-import { TAddedMT5Account } from '../../../../types';
-
-type TBadgeVariations = Partial['variant']> | undefined;
-
-const getClientKycStatus = (status: TAddedMT5Account['status']): TBadgeVariations => {
- switch (status) {
- case MT5_ACCOUNT_STATUS.POA_FAILED:
- case MT5_ACCOUNT_STATUS.PROOF_FAILED:
- return 'failed';
- case MT5_ACCOUNT_STATUS.VERIFICATION_PENDING:
- case MT5_ACCOUNT_STATUS.POA_PENDING:
- return 'in_review';
- case MT5_ACCOUNT_STATUS.NEEDS_VERIFICATION:
- case MT5_ACCOUNT_STATUS.POA_REQUIRED:
- return 'needs_verification';
- default:
- }
-};
-
-const useAddedMT5Account = (account: TAddedMT5Account) => {
- const { localize } = useTranslations();
-
- // @ts-expect-error The enabled property exists, but the api-types are invalid
- const isAccountDisabled = !account.rights?.enabled;
-
- const accountDetails = useMemo(
- () => getMarketTypeDetails(localize, account.product)[account.market_type ?? MARKET_TYPE.ALL],
- [account.market_type, account.product, localize]
- );
-
- const { getPlatformStatus } = useTradingPlatformStatus();
- const platformStatus = getPlatformStatus(account.platform);
- const kycStatus = getClientKycStatus(account.status);
-
- const isServerMaintenance =
- platformStatus === TRADING_PLATFORM_STATUS.MAINTENANCE ||
- account.status === MT5_ACCOUNT_STATUS.UNDER_MAINTENANCE;
-
- const showPlatformStatus =
- account.status === MT5_ACCOUNT_STATUS.UNAVAILABLE ||
- account.status === MT5_ACCOUNT_STATUS.UNDER_MAINTENANCE ||
- platformStatus === TRADING_PLATFORM_STATUS.MAINTENANCE;
-
- const showMT5TradeModal = platformStatus === TRADING_PLATFORM_STATUS.ACTIVE;
-
- return {
- accountDetails,
- isAccountDisabled,
- isServerMaintenance,
- kycStatus,
- showMT5TradeModal,
- showPlatformStatus,
- };
-};
-
-export default useAddedMT5Account;
diff --git a/packages/wallets/src/features/cfd/flows/MT5/AvailableMT5AccountsList/AvailableMT5AccountsList.tsx b/packages/wallets/src/features/cfd/flows/MT5/AvailableMT5AccountsList/AvailableMT5AccountsList.tsx
index 3d6c53ed996e..310168f8c1a3 100644
--- a/packages/wallets/src/features/cfd/flows/MT5/AvailableMT5AccountsList/AvailableMT5AccountsList.tsx
+++ b/packages/wallets/src/features/cfd/flows/MT5/AvailableMT5AccountsList/AvailableMT5AccountsList.tsx
@@ -1,22 +1,25 @@
-import React, { useCallback } from 'react';
+import React, { lazy, Suspense, useCallback, useEffect, useState } from 'react';
import { useActiveWalletAccount, useMT5AccountsList, useTradingPlatformStatus } from '@deriv/api-v2';
import {
LabelPairedChevronLeftCaptionRegularIcon,
LabelPairedChevronRightCaptionRegularIcon,
} from '@deriv/quill-icons';
import { Localize, useTranslations } from '@deriv-com/translations';
-import { Text } from '@deriv-com/ui';
+import { Loader, Text } from '@deriv-com/ui';
import { TradingAccountCard } from '../../../../../components';
import { useModal } from '../../../../../components/ModalProvider';
import useIsRtl from '../../../../../hooks/useIsRtl';
+import { THooks } from '../../../../../types';
import { getMarketTypeDetails, MARKET_TYPE, PRODUCT, TRADING_PLATFORM_STATUS } from '../../../constants';
-import { ClientVerificationModal, MT5PasswordModal, TradingPlatformStatusModal } from '../../../modals';
-import { TAvailableMT5Account } from '../../../types';
-import { getClientVerification } from '../../../utils';
+import { JurisdictionModal, MT5PasswordModal, TradingPlatformStatusModal } from '../../../modals';
import './AvailableMT5AccountsList.scss';
+const LazyVerification = lazy(
+ () => import(/* webpackChunkName: "wallets-client-verification" */ '../../ClientVerification/ClientVerification')
+);
+
type TProps = {
- account: TAvailableMT5Account;
+ account: THooks.AvailableMT5Accounts;
};
const AvailableMT5AccountsList: React.FC = ({ account }) => {
@@ -28,11 +31,10 @@ const AvailableMT5AccountsList: React.FC = ({ account }) => {
const { description, title } = getMarketTypeDetails(localize, account.product)[
account.market_type || MARKET_TYPE.ALL
];
+ const [showMt5PasswordModal, setShowMt5PasswordModal] = useState(false);
const { data: mt5Accounts } = useMT5AccountsList();
const platformStatus = getPlatformStatus(account.platform);
const hasUnavailableAccount = mt5Accounts?.some(account => account.status === 'unavailable');
- const isVirtual = activeWallet?.is_virtual;
- const { hasClientKycStatus } = getClientVerification(account);
const onButtonClick = useCallback(() => {
if (hasUnavailableAccount) return show();
@@ -44,16 +46,58 @@ const AvailableMT5AccountsList: React.FC = ({ account }) => {
return show();
case TRADING_PLATFORM_STATUS.ACTIVE:
default:
- if (!isVirtual && hasClientKycStatus) {
- show();
+ if (activeWallet?.is_virtual || account.product === PRODUCT.SWAPFREE) {
+ show(
+
+ );
+ } else if (account.product === PRODUCT.ZEROSPREAD) {
+ show(
+ }>
+ {
+ setShowMt5PasswordModal(true);
+ }}
+ selectedJurisdiction={account.shortcode}
+ />
+
+ );
} else {
- show();
+ show();
}
setModalState('marketType', account.market_type);
setModalState('selectedJurisdiction', account.shortcode);
break;
}
- }, [hasUnavailableAccount, show, platformStatus, isVirtual, hasClientKycStatus, setModalState, account]);
+ }, [
+ hasUnavailableAccount,
+ show,
+ platformStatus,
+ account.platform,
+ account.market_type,
+ account.product,
+ account.shortcode,
+ activeWallet?.is_virtual,
+ setModalState,
+ ]);
+
+ useEffect(() => {
+ if (showMt5PasswordModal) {
+ show(
+
+ );
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [showMt5PasswordModal]);
return (
diff --git a/packages/wallets/src/features/cfd/flows/MT5/AvailableMT5AccountsList/__test__/AvailableMT5AcountsList.spec.tsx b/packages/wallets/src/features/cfd/flows/MT5/AvailableMT5AccountsList/__test__/AvailableMT5AcountsList.spec.tsx
index 8b6ef7708732..c9756151deeb 100644
--- a/packages/wallets/src/features/cfd/flows/MT5/AvailableMT5AccountsList/__test__/AvailableMT5AcountsList.spec.tsx
+++ b/packages/wallets/src/features/cfd/flows/MT5/AvailableMT5AccountsList/__test__/AvailableMT5AcountsList.spec.tsx
@@ -1,9 +1,9 @@
import React from 'react';
import { useActiveWalletAccount, useMT5AccountsList, useTradingPlatformStatus } from '@deriv/api-v2';
-import { render, screen } from '@testing-library/react';
+import { act, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { useModal } from '../../../../../../components/ModalProvider';
-import { ClientVerificationModal, MT5PasswordModal, TradingPlatformStatusModal } from '../../../../modals';
+import { JurisdictionModal, MT5PasswordModal, TradingPlatformStatusModal } from '../../../../modals';
import AvailableMT5AccountsList from '../AvailableMT5AccountsList';
jest.mock('@deriv/api-v2', () => ({
@@ -42,38 +42,16 @@ describe('AvailableMT5AccountsList', () => {
});
});
- const nonRegulatedAccount = {
+ const defaultAccount = {
market_type: 'synthetic',
platform: 'mt5',
product: 'swap_free',
shortcode: 'svg',
};
- const regulatedVerifiedAccount = {
- client_kyc_status: {
- poi_status: 'verified',
- valid_tin: 1,
- },
- market_type: 'synthetic',
- platform: 'mt5',
- product: 'swap_free',
- shortcode: 'svg',
- };
-
- const regulatedUnverifiedAccount = {
- client_kyc_status: {
- poi_status: 'none',
- valid_tin: 0,
- },
- market_type: 'synthetic',
- platform: 'mt5',
- product: 'financial',
- shortcode: 'bvi',
- };
-
it('renders default content for available mt5 account', () => {
// @ts-expect-error - since this is a mock, we only need partial properties of the account
- render();
+ render();
expect(screen.getByTestId('dt_wallets_trading_account_card')).toBeInTheDocument();
expect(screen.getByText('Standard')).toBeInTheDocument();
@@ -81,13 +59,14 @@ describe('AvailableMT5AccountsList', () => {
it('handles button click when platform status is active for real wallet account', () => {
// @ts-expect-error - since this is a mock, we only need partial properties of the account
- render();
+ render();
const button = screen.getByTestId('dt_wallets_trading_account_card');
userEvent.click(button);
- // @ts-expect-error - since this is a mock, we only need partial properties of the account
- expect(mockShow).toHaveBeenCalledWith();
+ expect(mockShow).toHaveBeenCalledWith(
+
+ );
expect(mockSetModalState).toHaveBeenCalledWith('marketType', 'synthetic');
expect(mockSetModalState).toHaveBeenCalledWith('selectedJurisdiction', 'svg');
});
@@ -98,7 +77,7 @@ describe('AvailableMT5AccountsList', () => {
});
// @ts-expect-error - since this is a mock, we only need partial properties of the account
- render();
+ render();
const button = screen.getByTestId('dt_wallets_trading_account_card');
userEvent.click(button);
@@ -111,7 +90,7 @@ describe('AvailableMT5AccountsList', () => {
getPlatformStatus: jest.fn(() => 'unavailable'),
});
// @ts-expect-error - since this is a mock, we only need partial properties of the account
- render();
+ render();
const button = screen.getByTestId('dt_wallets_trading_account_card');
userEvent.click(button);
@@ -119,12 +98,25 @@ describe('AvailableMT5AccountsList', () => {
expect(mockShow).toHaveBeenCalledWith();
});
+ it('shows JurisdictionModal by default when account is undefined', () => {
+ (useActiveWalletAccount as jest.Mock).mockReturnValue({
+ data: undefined,
+ });
+ // @ts-expect-error - since this is a mock, we only need partial properties of the account
+ render();
+
+ const button = screen.getByTestId('dt_wallets_trading_account_card');
+ userEvent.click(button);
+
+ expect(mockShow).toHaveBeenCalledWith();
+ });
+
it('shows TradingPlatformStatusModal with isServerMaintenance when platform status is maintenance', () => {
(useTradingPlatformStatus as jest.Mock).mockReturnValue({
getPlatformStatus: jest.fn(() => 'maintenance'),
});
// @ts-expect-error - since this is a mock, we only need partial properties of the account
- render();
+ render();
const button = screen.getByTestId('dt_wallets_trading_account_card');
userEvent.click(button);
@@ -132,49 +124,70 @@ describe('AvailableMT5AccountsList', () => {
expect(mockShow).toHaveBeenCalledWith();
});
- it('shows MT5PasswordModal for non-regulated real accounts if client is verified', () => {
- (useActiveWalletAccount as jest.Mock).mockReturnValue({
- data: undefined,
- });
+ it('shows JurisdictionModal when product is neither swap-free nor zero-spread', () => {
+ const nonSwapAccount = { ...defaultAccount, product: 'ctrader' };
// @ts-expect-error - since this is a mock, we only need partial properties of the account
- render();
+ render();
const button = screen.getByTestId('dt_wallets_trading_account_card');
userEvent.click(button);
- // @ts-expect-error - since this is a mock, we only need partial properties of the account
- expect(mockShow).toHaveBeenCalledWith();
+ expect(mockShow).toHaveBeenCalledWith();
});
- it('shows ClientVerificationModal for regulated real accounts if client is unverified', () => {
- (useActiveWalletAccount as jest.Mock).mockReturnValue({
- data: {
- is_virtual: false,
- },
- });
+ it('shows ClientVerification when product is zero-spread', async () => {
+ const zeroSpreadAccount = { ...defaultAccount, product: 'zero_spread' };
// @ts-expect-error - since this is a mock, we only need partial properties of the account
- render();
+ render();
+ expect(screen.getByText('NEW')).toBeInTheDocument();
const button = screen.getByTestId('dt_wallets_trading_account_card');
userEvent.click(button);
- // @ts-expect-error - since this is a mock, we only need partial properties of the account
- expect(mockShow).toHaveBeenCalledWith();
+ await waitFor(() => {
+ expect(mockShow).toHaveBeenCalled();
+ });
});
- it('shows MT5PasswordModal for demo accounts for verified clients', () => {
+ it('handles virtual wallet accounts correctly', () => {
(useActiveWalletAccount as jest.Mock).mockReturnValue({
- data: {
- is_virtual: true,
- },
+ data: { is_virtual: true },
});
// @ts-expect-error - since this is a mock, we only need partial properties of the account
- render();
+ render();
const button = screen.getByTestId('dt_wallets_trading_account_card');
userEvent.click(button);
+ expect(mockShow).toHaveBeenCalledWith(
+
+ );
+ });
+
+ it('shows MT5PasswordModal after ClientVerification completion', async () => {
+ const zeroSpreadAccount = { ...defaultAccount, product: 'zero_spread' };
// @ts-expect-error - since this is a mock, we only need partial properties of the account
- expect(mockShow).toHaveBeenCalledWith();
+ render();
+
+ const button = screen.getByTestId('dt_wallets_trading_account_card');
+ userEvent.click(button);
+
+ await waitFor(() => {
+ expect(mockShow).toHaveBeenCalled();
+ });
+
+ const lastCall = mockShow.mock.calls[mockShow.mock.calls.length - 1][0];
+ // eslint-disable-next-line testing-library/no-node-access
+ const { onCompletion } = lastCall.props.children.props; //required to access the function of lazy-loaded ClientVerification
+
+ act(() => {
+ onCompletion();
+ });
+
+ await waitFor(() => {
+ expect(mockShow).toHaveBeenCalledWith(
+
+ );
+ });
});
});
diff --git a/packages/wallets/src/features/cfd/modals/ClientVerificationModal/ClientVerificationModal.scss b/packages/wallets/src/features/cfd/modals/ClientVerificationModal/ClientVerificationModal.scss
deleted file mode 100644
index 305e021bca3e..000000000000
--- a/packages/wallets/src/features/cfd/modals/ClientVerificationModal/ClientVerificationModal.scss
+++ /dev/null
@@ -1,22 +0,0 @@
-.wallets-client-verification-modal {
- width: 100%;
- min-width: 44rem;
- height: 100%;
- padding: 2.4rem;
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 2.4rem;
-
- &__description {
- max-width: 36rem;
-
- @include mobile-or-tablet-screen {
- max-width: 100%;
- }
- }
-
- @include mobile-or-tablet-screen {
- min-width: 100%;
- }
-}
diff --git a/packages/wallets/src/features/cfd/modals/ClientVerificationModal/ClientVerificationModal.tsx b/packages/wallets/src/features/cfd/modals/ClientVerificationModal/ClientVerificationModal.tsx
deleted file mode 100644
index 856da8dee040..000000000000
--- a/packages/wallets/src/features/cfd/modals/ClientVerificationModal/ClientVerificationModal.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import React from 'react';
-import { DerivLightUploadPoiIcon } from '@deriv/quill-icons';
-import { Localize, useTranslations } from '@deriv-com/translations';
-import { Text, useDevice } from '@deriv-com/ui';
-import { ModalStepWrapper } from '../../../../components';
-import { getMarketTypeDetails, MARKET_TYPE } from '../../constants';
-import { TModifiedMT5Account } from '../../types';
-import { DocumentsList } from './components';
-import './ClientVerificationModal.scss';
-
-type TClientVerificationModal = {
- account: TModifiedMT5Account;
-};
-
-const ClientVerificationModal: React.FC = ({ account }) => {
- const { localize } = useTranslations();
- const { isMobile } = useDevice();
- const { title } = getMarketTypeDetails(localize, account.product)[account.market_type || MARKET_TYPE.ALL];
-
- return (
-
-
-
-
- {account.is_added ? (
-
- ) : (
-
- )}
-
-
-
-
- );
-};
-
-export default ClientVerificationModal;
diff --git a/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/DocumentsList/DocumentsList.scss b/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/DocumentsList/DocumentsList.scss
deleted file mode 100644
index 264c1f00b394..000000000000
--- a/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/DocumentsList/DocumentsList.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-.wallets-documents-list {
- width: 100%;
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 1.6rem;
-}
diff --git a/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/DocumentsList/DocumentsList.tsx b/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/DocumentsList/DocumentsList.tsx
deleted file mode 100644
index 44d2f2f4cf98..000000000000
--- a/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/DocumentsList/DocumentsList.tsx
+++ /dev/null
@@ -1,62 +0,0 @@
-import React from 'react';
-import { useHistory } from 'react-router-dom';
-import { TModifiedMT5Account } from 'src/features/cfd/types';
-import { useTranslations } from '@deriv-com/translations';
-import { ClientVerificationStatusBadge } from '../../../../components';
-import { getClientVerification } from '../../../../utils';
-import { DocumentTile } from './components';
-import './DocumentsList.scss';
-
-type TDocumentsListProps = {
- account: TModifiedMT5Account;
-};
-
-type TStatusBadgeProps = Record;
-
-const statusBadge: TStatusBadgeProps = {
- expired: ,
- none: <>>,
- pending: ,
- rejected: ,
- suspected: ,
- verified: ,
-};
-
-const DocumentsList: React.FC = ({ account }) => {
- const history = useHistory();
- const { localize } = useTranslations();
- const { hasPoaStatus, hasPoiStatus, hasTinStatus, isPoaRequired, isPoiRequired, isTinRequired, statuses } =
- getClientVerification(account);
-
- return (
-
- {hasPoiStatus && (
- history.push('/account/proof-of-identity')}
- title={localize('Proof of identity')}
- />
- )}
- {hasPoaStatus && (
- history.push('/account/proof-of-address')}
- title={localize('Proof of address')}
- />
- )}
- {hasTinStatus && isTinRequired && (
- history.push('/account/personal-details')}
- title={localize('Personal details')}
- />
- )}
-
- );
-};
-
-export default DocumentsList;
diff --git a/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/DocumentsList/__tests__/DocumentsList.spec.tsx b/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/DocumentsList/__tests__/DocumentsList.spec.tsx
deleted file mode 100644
index cec52fd1c3f7..000000000000
--- a/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/DocumentsList/__tests__/DocumentsList.spec.tsx
+++ /dev/null
@@ -1,172 +0,0 @@
-import React from 'react';
-import { render, screen, waitFor, within } from '@testing-library/react';
-import userEvent from '@testing-library/user-event';
-import DocumentsList from '../DocumentsList';
-
-const mockHistoryPush = jest.fn();
-
-jest.mock('react-router-dom', () => ({
- ...jest.requireActual('react-router-dom'),
- useHistory: jest.fn(() => ({
- push: mockHistoryPush,
- })),
-}));
-
-jest.mock('../../../../../components', () => ({
- ...jest.requireActual('../../../../../components'),
- ClientVerificationStatusBadge: jest.fn(({ variant }) => variant),
-}));
-
-jest.mock('../components', () => ({
- ...jest.requireActual('../components'),
- DocumentTile: jest.fn(({ badge, isDisabled, onClick, title }) => (
-
- )),
-}));
-
-describe('', () => {
- it('poi tile is not rendered', () => {
- render(
-
- );
-
- expect(screen.queryByText('Proof of identity')).not.toBeInTheDocument();
- });
-
- it('poi tile is not rendered', () => {
- render(
-
- );
-
- expect(screen.queryByText('Proof of address')).not.toBeInTheDocument();
- });
-
- it('personal details tile is not rendered', () => {
- render(
-
- );
-
- expect(screen.queryByText('Personal details')).not.toBeInTheDocument();
- });
-
- it('on click poi tile redirects to correct page', async () => {
- render(
-
- );
-
- const poiTile = screen.getByText('Proof of identity');
- userEvent.click(poiTile);
-
- await waitFor(() => {
- expect(mockHistoryPush).toBeCalledWith('/account/proof-of-identity');
- });
- });
-
- it('on click poa tile redirects to correct page', async () => {
- render(
-
- );
-
- const poaTile = screen.getByText('Proof of address');
- userEvent.click(poaTile);
-
- await waitFor(() => {
- expect(mockHistoryPush).toBeCalledWith('/account/proof-of-address');
- });
- });
-
- it('on click personal details tile redirects to correct page', async () => {
- render(
-
- );
-
- const personalDetailsTile = screen.getByText('Personal details');
- userEvent.click(personalDetailsTile);
-
- await waitFor(() => {
- expect(mockHistoryPush).toBeCalledWith('/account/personal-details');
- });
- });
-
- it('renders poi tile with correct badge', () => {
- render(
-
- );
-
- const poiTile = screen.getByText('Proof of identity');
-
- expect(within(poiTile).getByText('verified')).toBeInTheDocument;
- });
-
- it('renders poa tile with correct badge', () => {
- render(
-
- );
-
- const poaTile = screen.getByText('Proof of address');
-
- expect(within(poaTile).getByText('verified')).toBeInTheDocument;
- });
-});
diff --git a/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/DocumentsList/components/DocumentTile/DocumentTile.scss b/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/DocumentsList/components/DocumentTile/DocumentTile.scss
deleted file mode 100644
index e1b8aab8fd48..000000000000
--- a/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/DocumentsList/components/DocumentTile/DocumentTile.scss
+++ /dev/null
@@ -1,28 +0,0 @@
-.wallets-document-tile {
- width: 100%;
- height: 5.6rem;
- padding-inline: 1.6rem;
- border: none;
- border-radius: 8px;
- background: #f6f7f8;
- display: flex;
- align-items: center;
- justify-content: space-between;
- cursor: pointer;
-
- &:disabled {
- cursor: not-allowed;
- }
-
- &__status {
- display: flex;
- align-items: center;
- gap: 0.8rem;
- }
-
- &__chevron {
- &--disabled {
- fill: #d6d6d6;
- }
- }
-}
diff --git a/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/DocumentsList/components/DocumentTile/DocumentTile.tsx b/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/DocumentsList/components/DocumentTile/DocumentTile.tsx
deleted file mode 100644
index 1a3395392faf..000000000000
--- a/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/DocumentsList/components/DocumentTile/DocumentTile.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import React from 'react';
-import classNames from 'classnames';
-import { LabelPairedChevronRightMdRegularIcon } from '@deriv/quill-icons';
-import { Text } from '@deriv-com/ui';
-import './DocumentTile.scss';
-
-type TDocumentTileProps = {
- badge?: JSX.Element;
- disabled?: boolean;
- onClick: VoidFunction;
- title: string;
-};
-
-const DocumentTile: React.FC = ({ badge, disabled, onClick, title }) => {
- return (
-
- );
-};
-
-export default DocumentTile;
diff --git a/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/DocumentsList/components/DocumentTile/index.ts b/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/DocumentsList/components/DocumentTile/index.ts
deleted file mode 100644
index e6b33e8515a5..000000000000
--- a/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/DocumentsList/components/DocumentTile/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { default as DocumentTile } from './DocumentTile';
diff --git a/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/DocumentsList/components/index.ts b/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/DocumentsList/components/index.ts
deleted file mode 100644
index 76c67643d998..000000000000
--- a/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/DocumentsList/components/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './DocumentTile';
diff --git a/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/DocumentsList/index.ts b/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/DocumentsList/index.ts
deleted file mode 100644
index d23ca16a13b6..000000000000
--- a/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/DocumentsList/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { default as DocumentsList } from './DocumentsList';
diff --git a/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/index.ts b/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/index.ts
deleted file mode 100644
index a711e93c8860..000000000000
--- a/packages/wallets/src/features/cfd/modals/ClientVerificationModal/components/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './DocumentsList';
diff --git a/packages/wallets/src/features/cfd/modals/ClientVerificationModal/index.ts b/packages/wallets/src/features/cfd/modals/ClientVerificationModal/index.ts
deleted file mode 100644
index 7625bdeff6b4..000000000000
--- a/packages/wallets/src/features/cfd/modals/ClientVerificationModal/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { default as ClientVerificationModal } from './ClientVerificationModal';
diff --git a/packages/wallets/src/features/cfd/modals/JurisdictionModal/JurisdictionModal.tsx b/packages/wallets/src/features/cfd/modals/JurisdictionModal/JurisdictionModal.tsx
index 1698de810892..e32bbbd5f544 100644
--- a/packages/wallets/src/features/cfd/modals/JurisdictionModal/JurisdictionModal.tsx
+++ b/packages/wallets/src/features/cfd/modals/JurisdictionModal/JurisdictionModal.tsx
@@ -5,8 +5,10 @@ import { Button, Loader, useDevice } from '@deriv-com/ui';
import { ModalStepWrapper } from '../../../../components/Base';
import { useModal } from '../../../../components/ModalProvider';
import { DynamicLeverageContext } from '../../components/DynamicLeverageContext';
+import { PlatformDetails } from '../../constants';
import { DynamicLeverageScreen, DynamicLeverageTitle } from '../../screens/DynamicLeverage';
import { JurisdictionScreen } from '../../screens/Jurisdiction';
+import { MT5PasswordModal } from '..';
import './JurisdictionModal.scss';
const LazyVerification = lazy(
@@ -21,19 +23,32 @@ const JurisdictionModal = () => {
const [isDynamicLeverageVisible, setIsDynamicLeverageVisible] = useState(false);
const [isCheckBoxChecked, setIsCheckBoxChecked] = useState(false);
- const { setModalState, show } = useModal();
+ const { getModalState, setModalState, show } = useModal();
const { isLoading } = useAvailableMT5Accounts();
const { isDesktop } = useDevice();
const { localize } = useTranslations();
+ const marketType = getModalState('marketType') ?? 'all';
+ const platform = getModalState('platform') ?? PlatformDetails.mt5.platform;
+
const toggleDynamicLeverage = useCallback(() => {
setIsDynamicLeverageVisible(!isDynamicLeverageVisible);
}, [isDynamicLeverageVisible, setIsDynamicLeverageVisible]);
const JurisdictionFlow = () => {
+ const [showMt5PasswordModal, setShowMt5PasswordModal] = useState(false);
+ if (selectedJurisdiction === 'svg' || showMt5PasswordModal) {
+ return ;
+ }
+
return (
}>
-
+ {
+ setShowMt5PasswordModal(true);
+ }}
+ selectedJurisdiction={selectedJurisdiction}
+ />
);
};
diff --git a/packages/wallets/src/features/cfd/modals/MT5AccountAdded/MT5AccountAdded.tsx b/packages/wallets/src/features/cfd/modals/MT5AccountAdded/MT5AccountAdded.tsx
index 2552375f2083..076b42a78b02 100644
--- a/packages/wallets/src/features/cfd/modals/MT5AccountAdded/MT5AccountAdded.tsx
+++ b/packages/wallets/src/features/cfd/modals/MT5AccountAdded/MT5AccountAdded.tsx
@@ -31,8 +31,8 @@ const MT5AccountAdded: FC = ({ account, marketType, platform, product })
const history = useHistory();
const { isDesktop } = useDevice();
- const { localize } = useTranslations();
const { getModalState, hide } = useModal();
+ const { localize } = useTranslations();
const addedAccount = mt5Accounts?.find(acc => acc.login === account?.login);
@@ -97,7 +97,7 @@ const MT5AccountAdded: FC = ({ account, marketType, platform, product })
);
},
- [hide, buttonSize, history, addedAccount?.loginid]
+ [hide, isDesktop, history, addedAccount?.loginid]
);
const renderSuccessDescription = useMemo(() => {
diff --git a/packages/wallets/src/features/cfd/modals/MT5PasswordModal/MT5PasswordModal.tsx b/packages/wallets/src/features/cfd/modals/MT5PasswordModal/MT5PasswordModal.tsx
index 25cdb52233fd..1624b1d04d7d 100644
--- a/packages/wallets/src/features/cfd/modals/MT5PasswordModal/MT5PasswordModal.tsx
+++ b/packages/wallets/src/features/cfd/modals/MT5PasswordModal/MT5PasswordModal.tsx
@@ -1,6 +1,7 @@
import React, { useCallback, useMemo, useState } from 'react';
import {
useAccountStatus,
+ useActiveWalletAccount,
useAvailableMT5Accounts,
useCreateMT5Account,
useMT5AccountsList,
@@ -9,23 +10,25 @@ import {
useVerifyEmail,
} from '@deriv/api-v2';
import { Localize, useTranslations } from '@deriv-com/translations';
-import { Button, Loader, useDevice } from '@deriv-com/ui';
+import { Button, useDevice, Loader } from '@deriv-com/ui';
import { SentEmailContent, WalletError } from '../../../../components';
import { ModalStepWrapper, ModalWrapper } from '../../../../components/Base';
import { useModal } from '../../../../components/ModalProvider';
+import { THooks, TMarketTypes, TPlatforms } from '../../../../types';
import { platformPasswordResetRedirectLink } from '../../../../utils/cfd';
import { validPassword, validPasswordMT5 } from '../../../../utils/password-validation';
-import { CFD_PLATFORMS, JURISDICTION, MARKET_TYPE, PlatformDetails } from '../../constants';
+import { CFD_PLATFORMS, JURISDICTION, MARKET_TYPE, PlatformDetails, PRODUCT } from '../../constants';
import { CreatePassword, CreatePasswordMT5, EnterPassword, MT5ResetPasswordModal } from '../../screens';
-import { TAvailableMT5Account } from '../../types';
import MT5AccountAdded from '../MT5AccountAdded/MT5AccountAdded';
import { PasswordLimitExceededModal } from '../PasswordLimitExceededModal';
import { MT5PasswordModalFooter, SuccessModalFooter } from './MT5PasswordModalFooters';
import './MT5PasswordModal.scss';
type TProps = {
- account: TAvailableMT5Account;
isVirtual?: boolean;
+ marketType: TMarketTypes.SortedMT5Accounts;
+ platform: TPlatforms.All;
+ product?: THooks.AvailableMT5Accounts['product'];
};
export type TPlatformPasswordChange = {
@@ -33,11 +36,8 @@ export type TPlatformPasswordChange = {
newPassword: string;
};
-const MT5PasswordModal: React.FC
= ({ account, isVirtual = false }) => {
- const [isTncChecked, setIsTncChecked] = useState(
- // tnc is automatically checked for real SVG accounts and all demo accounts
- (account as TAvailableMT5Account).shortcode === JURISDICTION.SVG || isVirtual
- );
+const MT5PasswordModal: React.FC = ({ isVirtual, marketType, platform, product }) => {
+ const [isTncChecked, setIsTncChecked] = useState(!(product === PRODUCT.ZEROSPREAD && !isVirtual));
const {
data: createMT5AccountData,
error: createMT5AccountError,
@@ -52,6 +52,7 @@ const MT5PasswordModal: React.FC = ({ account, isVirtual = false }) => {
mutateAsync: tradingPasswordChangeMutateAsync,
} = useTradingPlatformPasswordChange();
const { data: accountStatusData, isLoading: accountStatusLoading } = useAccountStatus();
+ const { data: activeWalletData } = useActiveWalletAccount();
const { data: availableMT5AccountsData } = useAvailableMT5Accounts();
const {
error: emailVerificationError,
@@ -68,14 +69,11 @@ const MT5PasswordModal: React.FC = ({ account, isVirtual = false }) => {
const [password, setPassword] = useState('');
- const marketType = account.market_type ?? 'synthetic';
- const platform = account.platform;
- const product = account.product;
-
const isMT5PasswordNotSet = accountStatusData?.is_mt5_password_not_set;
const hasMT5Account = mt5AccountsData?.find(account => account.login);
+ const isDemo = activeWalletData?.is_virtual;
const { platform: mt5Platform, title: mt5Title } = PlatformDetails.mt5;
- const selectedJurisdiction = isVirtual ? JURISDICTION.SVG : getModalState('selectedJurisdiction');
+ const selectedJurisdiction = isDemo ? JURISDICTION.SVG : getModalState('selectedJurisdiction');
const isLoading = accountStatusLoading || createMT5AccountLoading || tradingPlatformPasswordChangeLoading;
@@ -91,7 +89,7 @@ const MT5PasswordModal: React.FC = ({ account, isVirtual = false }) => {
// =================================
const accountType = marketType === MARKET_TYPE.SYNTHETIC ? 'gaming' : marketType;
- const categoryAccountType = isVirtual ? 'demo' : accountType;
+ const categoryAccountType = isDemo ? 'demo' : accountType;
if (isMT5PasswordNotSet) {
await tradingPasswordChangeMutateAsync({
@@ -109,7 +107,7 @@ const MT5PasswordModal: React.FC = ({ account, isVirtual = false }) => {
email: settingsData?.email ?? '',
leverage: availableMT5AccountsData?.find(acc => acc.market_type === marketType)?.leverage ?? 500,
mainPassword: password,
- ...(selectedJurisdiction && !isVirtual ? { company: selectedJurisdiction } : {}),
+ ...(selectedJurisdiction && !isDemo ? { company: selectedJurisdiction } : {}),
...(marketType === MARKET_TYPE.FINANCIAL && { mt5_account_type: MARKET_TYPE.FINANCIAL }),
...(selectedJurisdiction &&
(selectedJurisdiction !== JURISDICTION.LABUAN
@@ -133,7 +131,7 @@ const MT5PasswordModal: React.FC = ({ account, isVirtual = false }) => {
}, [
availableMT5AccountsData,
createMT5AccountMutate,
- isVirtual,
+ isDemo,
isMT5PasswordNotSet,
marketType,
mt5Platform,
@@ -156,12 +154,12 @@ const MT5PasswordModal: React.FC = ({ account, isVirtual = false }) => {
emailVerificationMutate({
type: 'trading_platform_mt5_password_reset',
url_parameters: {
- redirect_to: platformPasswordResetRedirectLink(CFD_PLATFORMS.MT5, isVirtual),
+ redirect_to: platformPasswordResetRedirectLink(CFD_PLATFORMS.MT5, activeWalletData?.is_virtual),
},
verify_email: email,
});
}
- }, [email, emailVerificationMutate, isVirtual]);
+ }, [activeWalletData?.is_virtual, email, emailVerificationMutate]);
const onSubmitPasswordChange = useCallback(
({ currentPassword, newPassword }: TPlatformPasswordChange) => {
@@ -177,7 +175,7 @@ const MT5PasswordModal: React.FC = ({ account, isVirtual = false }) => {
const renderTitle = useCallback(() => {
const accountAction = hasMT5Account ? localize('Add') : localize('Create');
- const accountType = isVirtual ? localize('demo') : localize('real');
+ const accountType = isDemo ? localize('demo') : localize('real');
return updateMT5Password
? localize('{{mt5Title}} latest password requirements', { mt5Title })
@@ -186,13 +184,13 @@ const MT5PasswordModal: React.FC = ({ account, isVirtual = false }) => {
accountType,
mt5Title,
});
- }, [hasMT5Account, isVirtual, localize, mt5Title, updateMT5Password]);
+ }, [hasMT5Account, isDemo, localize, mt5Title, updateMT5Password]);
const renderFooter = useCallback(() => {
if (createMT5AccountSuccess)
return (
-
+
);
@@ -237,7 +235,7 @@ const MT5PasswordModal: React.FC = ({ account, isVirtual = false }) => {
}, [
createMT5AccountLoading,
createMT5AccountSuccess,
- isVirtual,
+ isDemo,
isDesktop,
isMT5PasswordNotSet,
mt5Title,
@@ -265,7 +263,6 @@ const MT5PasswordModal: React.FC = ({ account, isVirtual = false }) => {
if (isMT5PasswordNotSet && platform === CFD_PLATFORMS.MT5)
return (
= ({ account, isVirtual = false }) => {
}}
password={password}
platform={mt5Platform}
+ product={product}
/>
);
@@ -291,10 +289,9 @@ const MT5PasswordModal: React.FC = ({ account, isVirtual = false }) => {
return (
setPassword(e.target.value)}
@@ -310,18 +307,18 @@ const MT5PasswordModal: React.FC = ({ account, isVirtual = false }) => {
);
}, [
isMT5PasswordNotSet,
- platform,
tradingPlatformPasswordChangeLoading,
createMT5AccountLoading,
+ isTncChecked,
onSubmit,
password,
mt5Platform,
- account,
- isTncChecked,
- isVirtual,
- product,
updateMT5Password,
tradingPasswordChangeError,
+ platform,
+ isVirtual,
+ product,
+ activeWalletData?.is_virtual,
onSubmitPasswordChange,
marketType,
localize,
@@ -331,10 +328,6 @@ const MT5PasswordModal: React.FC = ({ account, isVirtual = false }) => {
isLoading,
]);
- if (accountStatusLoading) {
- return ;
- }
-
if (emailVerificationStatus === 'error') {
return (
= ({ account, isVirtual = false }) => {
);
}
- if (createMT5AccountSuccess) {
+ if (createMT5AccountSuccess && !isMT5PasswordNotSet) {
return (
void;
password: string;
platform: TPlatforms.All;
+ product?: THooks.AvailableMT5Accounts['product'];
};
const CreatePasswordMT5: React.FC = ({
- account,
isLoading,
isTncChecked,
isVirtual,
@@ -32,6 +30,7 @@ const CreatePasswordMT5: React.FC = ({
onTncChange,
password,
platform,
+ product,
}) => {
const { isDesktop } = useDevice();
const { localize } = useTranslations();
@@ -62,9 +61,13 @@ const CreatePasswordMT5: React.FC = ({
onChange={onPasswordChange}
password={password}
/>
- {!isVirtual && }
- {!isVirtual && account.shortcode !== 'svg' && (
-
+ {product === PRODUCT.ZEROSPREAD && !isVirtual && (
+
)}
diff --git a/packages/wallets/src/features/cfd/screens/EnterPassword/EnterPassword.tsx b/packages/wallets/src/features/cfd/screens/EnterPassword/EnterPassword.tsx
index 2c270fbd048d..d48df9ae70e7 100644
--- a/packages/wallets/src/features/cfd/screens/EnterPassword/EnterPassword.tsx
+++ b/packages/wallets/src/features/cfd/screens/EnterPassword/EnterPassword.tsx
@@ -5,14 +5,11 @@ import { Button, Text, useDevice } from '@deriv-com/ui';
import { WalletPasswordFieldLazy } from '../../../../components/Base';
import { THooks, TMarketTypes, TPlatforms } from '../../../../types';
import { validPassword, validPasswordMT5 } from '../../../../utils/password-validation';
-import { CFD_PLATFORMS, getMarketTypeDetails, JURISDICTION, PlatformDetails } from '../../constants';
-import { TAvailableMT5Account } from '../../types';
-import { MT5LicenceMessage, MT5PasswordModalTnc } from '../components';
+import { CFDPasswordModalTnc } from '../../components/CFDPasswordModalTnc';
+import { CFD_PLATFORMS, getMarketTypeDetails, PlatformDetails, PRODUCT } from '../../constants';
import './EnterPassword.scss';
-// Note: this component requires a proper refactor to remove props for keys available under the `account` prop
type TProps = {
- account?: TAvailableMT5Account;
isForgotPasswordLoading?: boolean;
isLoading?: boolean;
isTncChecked?: boolean;
@@ -31,7 +28,6 @@ type TProps = {
};
const EnterPassword: React.FC = ({
- account,
isForgotPasswordLoading,
isLoading,
isTncChecked = true,
@@ -104,9 +100,13 @@ const EnterPassword: React.FC = ({
{passwordErrorHints}
)}
- {account && !isVirtual && }
- {account && account.shortcode !== JURISDICTION.SVG && platform === CFD_PLATFORMS.MT5 && !isVirtual && (
- onTncChange?.()} />
+ {product === PRODUCT.ZEROSPREAD && !isVirtual && (
+ onTncChange?.()}
+ platform={platform}
+ product={product}
+ />
)}
{isDesktop && (
diff --git a/packages/wallets/src/features/cfd/screens/EnterPassword/__test__/EnterPassword.spec.tsx b/packages/wallets/src/features/cfd/screens/EnterPassword/__test__/EnterPassword.spec.tsx
index c5fe094d0dda..fbdb92674752 100644
--- a/packages/wallets/src/features/cfd/screens/EnterPassword/__test__/EnterPassword.spec.tsx
+++ b/packages/wallets/src/features/cfd/screens/EnterPassword/__test__/EnterPassword.spec.tsx
@@ -1,18 +1,12 @@
import React from 'react';
import { useActiveWalletAccount } from '@deriv/api-v2';
-import { cleanup, render, screen } from '@testing-library/react';
+import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { MARKET_TYPE, PlatformDetails } from '../../../constants';
import EnterPassword from '../EnterPassword';
jest.mock('@deriv/api-v2');
-jest.mock('../../components', () => ({
- ...jest.requireActual('../../components'),
- MT5LicenceMessage: jest.fn(() => MT5LicenceMessage
),
- MT5PasswordModalTnc: jest.fn(() => MT5PasswordModalTnc
),
-}));
-
describe('EnterPassword', () => {
const mockUseActiveWalletAccount = useActiveWalletAccount as jest.Mock;
@@ -20,8 +14,6 @@ describe('EnterPassword', () => {
mockUseActiveWalletAccount.mockReturnValue({ data: { is_virtual: false } });
});
- afterEach(cleanup);
-
const title = `Enter your ${PlatformDetails.mt5.title} password`;
const shortPassword = 'abcd';
const validPassword = 'Abcd1234!';
@@ -90,12 +82,6 @@ describe('EnterPassword', () => {
expect(addAccountButton).toBeDisabled();
});
- it('disables the "Add account" button when tnc is not checked', () => {
- renderComponent({ isTncChecked: false });
- const addAccountButton = screen.getByRole('button', { name: 'Add account' });
- expect(addAccountButton).toBeDisabled();
- });
-
it('shows password error hints when passwordError is true', () => {
renderComponent({ passwordError: true });
expect(
@@ -104,29 +90,4 @@ describe('EnterPassword', () => {
)
).toBeInTheDocument();
});
-
- it('shows the mt5 licence message component for real MT5 accounts', () => {
- renderComponent({ account: { shortcode: 'svg' } });
-
- expect(screen.getByText('MT5LicenceMessage')).toBeInTheDocument();
- });
-
- it('hides the mt5 licence message for virtual accounts', () => {
- mockUseActiveWalletAccount.mockReturnValue({ data: { is_virtual: true } });
- renderComponent();
-
- expect(screen.queryByText('MT5LicenceMessage')).not.toBeInTheDocument();
- });
-
- it('shows the mt5 tnc checkbox for regulated real accounts', () => {
- renderComponent({ account: { shortcode: 'bvi' } });
-
- expect(screen.getByText('MT5PasswordModalTnc')).toBeInTheDocument();
- });
-
- it('hides the mt5 tnc checkbox for non-regulated real accounts', () => {
- renderComponent({ account: { shortcode: 'svg' } });
-
- expect(screen.queryByText('MT5PasswordModalTnc')).not.toBeInTheDocument();
- });
});
diff --git a/packages/wallets/src/features/cfd/screens/MT5TradeScreen/MT5TradeScreen.tsx b/packages/wallets/src/features/cfd/screens/MT5TradeScreen/MT5TradeScreen.tsx
index f5efb6cc09e9..9c03bccd69c2 100644
--- a/packages/wallets/src/features/cfd/screens/MT5TradeScreen/MT5TradeScreen.tsx
+++ b/packages/wallets/src/features/cfd/screens/MT5TradeScreen/MT5TradeScreen.tsx
@@ -8,7 +8,6 @@ import { WalletBadge, WalletListCardBadge } from '../../../../components';
import { useModal } from '../../../../components/ModalProvider';
import { THooks } from '../../../../types';
import { CFD_PLATFORMS, getMarketTypeDetails, getServiceMaintenanceMessages, PlatformDetails } from '../../constants';
-import { TAddedMT5Account } from '../../types';
import MT5DesktopRedirectOption from './MT5TradeLink/MT5DesktopRedirectOption';
import MT5MobileRedirectOption from './MT5TradeLink/MT5MobileRedirectOption';
import { MT5TradeDetailsItem } from './MT5TradeDetailsItem';
@@ -16,7 +15,7 @@ import { MT5TradeLink } from './MT5TradeLink';
import './MT5TradeScreen.scss';
type MT5TradeScreenProps = {
- mt5Account?: TAddedMT5Account;
+ mt5Account?: THooks.MT5AccountsList;
};
const MT5TradeScreen: FC = ({ mt5Account }) => {
diff --git a/packages/wallets/src/features/cfd/screens/components/MT5LicenceMessage/MT5LicenceMessage.scss b/packages/wallets/src/features/cfd/screens/components/MT5LicenceMessage/MT5LicenceMessage.scss
deleted file mode 100644
index 10eefbe6dcd5..000000000000
--- a/packages/wallets/src/features/cfd/screens/components/MT5LicenceMessage/MT5LicenceMessage.scss
+++ /dev/null
@@ -1,5 +0,0 @@
-.wallets-mt5-licence-message {
- @include mobile-or-tablet-screen {
- margin-top: auto;
- }
-}
diff --git a/packages/wallets/src/features/cfd/screens/components/MT5LicenceMessage/MT5LicenceMessage.tsx b/packages/wallets/src/features/cfd/screens/components/MT5LicenceMessage/MT5LicenceMessage.tsx
deleted file mode 100644
index 8b68d3233535..000000000000
--- a/packages/wallets/src/features/cfd/screens/components/MT5LicenceMessage/MT5LicenceMessage.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import React from 'react';
-import { Localize, useTranslations } from '@deriv-com/translations';
-import { InlineMessage, Text, useDevice } from '@deriv-com/ui';
-import { getMarketTypeDetails, JURISDICTION, MARKET_TYPE, PlatformDetails } from '../../../constants';
-import { TAvailableMT5Account } from '../../../types';
-import './MT5LicenceMessage.scss';
-
-type TMT5LicenseMessageProps = {
- account: TAvailableMT5Account;
-};
-
-const MT5LicenseMessage: React.FC = ({ account }) => {
- const { isDesktop } = useDevice();
- const { localize } = useTranslations();
- const isSvg = account.shortcode === JURISDICTION.SVG;
-
- return (
-
-
- {isSvg ? (
- // TODO: remove this hardcoded logic for the company number for SVG once BE provides company_number key for non-regulated accounts
-
- ) : (
-
- )}
-
-
- );
-};
-
-export default MT5LicenseMessage;
diff --git a/packages/wallets/src/features/cfd/screens/components/MT5LicenceMessage/__tests__/MT5LicenceMessage.spec.tsx b/packages/wallets/src/features/cfd/screens/components/MT5LicenceMessage/__tests__/MT5LicenceMessage.spec.tsx
deleted file mode 100644
index d0d40201f9ca..000000000000
--- a/packages/wallets/src/features/cfd/screens/components/MT5LicenceMessage/__tests__/MT5LicenceMessage.spec.tsx
+++ /dev/null
@@ -1,48 +0,0 @@
-import React from 'react';
-import { render, screen } from '@testing-library/react';
-import MT5LicenseMessage from '../MT5LicenceMessage';
-
-jest.mock('@deriv-com/ui', () => ({
- ...jest.requireActual('@deriv-com/ui'),
- useDevice: jest.fn(() => ({ isDesktop: false })),
-}));
-
-const mockRegulatedAccount = {
- licence_number: 'mock_licence_number',
- market_type: 'financial',
- name: 'mock_company_name',
- product: 'financial',
- regulatory_authority: 'mock_regulatory_authority',
- shortcode: 'bvi',
-};
-
-const mockNonRegulatedAccount = {
- market_type: 'all',
- name: 'mock_company_name',
- product: 'swap_free',
- shortcode: 'svg',
-};
-
-describe('', () => {
- it('displays correct message for regulated account', () => {
- // @ts-expect-error - since this is a mock, we only need partial properties of the account
- render();
-
- expect(
- screen.getByText(
- 'You are adding your Deriv MT5 Financial account under mock_company_name, regulated by the mock_regulatory_authority (licence no. mock_licence_number).'
- )
- );
- });
-
- it('displays correct message for non-regulated account', () => {
- // @ts-expect-error - since this is a mock, we only need partial properties of the account
- render();
-
- expect(
- screen.getByText(
- 'You are adding your Deriv MT5 Swap-Free account under mock_company_name (company no. 273 LLC 2020).'
- )
- );
- });
-});
diff --git a/packages/wallets/src/features/cfd/screens/components/MT5LicenceMessage/index.ts b/packages/wallets/src/features/cfd/screens/components/MT5LicenceMessage/index.ts
deleted file mode 100644
index c939c664e13b..000000000000
--- a/packages/wallets/src/features/cfd/screens/components/MT5LicenceMessage/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { default as MT5LicenceMessage } from './MT5LicenceMessage';
diff --git a/packages/wallets/src/features/cfd/screens/components/MT5PasswordModalTnc/MT5PasswordModalTnc.scss b/packages/wallets/src/features/cfd/screens/components/MT5PasswordModalTnc/MT5PasswordModalTnc.scss
deleted file mode 100644
index b6fb09376e7e..000000000000
--- a/packages/wallets/src/features/cfd/screens/components/MT5PasswordModalTnc/MT5PasswordModalTnc.scss
+++ /dev/null
@@ -1,5 +0,0 @@
-.wallets-mt5-modal-tnc {
- display: flex;
- flex-direction: column;
- gap: 1.6rem;
-}
diff --git a/packages/wallets/src/features/cfd/screens/components/MT5PasswordModalTnc/MT5PasswordModalTnc.tsx b/packages/wallets/src/features/cfd/screens/components/MT5PasswordModalTnc/MT5PasswordModalTnc.tsx
deleted file mode 100644
index 507b9bb26e54..000000000000
--- a/packages/wallets/src/features/cfd/screens/components/MT5PasswordModalTnc/MT5PasswordModalTnc.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-import React from 'react';
-import { Localize } from '@deriv-com/translations';
-import { Checkbox, Text, useDevice } from '@deriv-com/ui';
-import { WalletLink } from '../../../../../components/Base';
-import { useModal } from '../../../../../components/ModalProvider';
-import { companyNamesAndUrls } from '../../../constants';
-import './MT5PasswordModalTnc.scss';
-
-export type TMT5PasswordModalTncProps = {
- checked: boolean;
- onChange: () => void;
-};
-
-const MT5PasswordModalTnc = ({ checked, onChange }: TMT5PasswordModalTncProps) => {
- const { isDesktop } = useDevice();
- const { getModalState } = useModal();
- const selectedJurisdiction = getModalState('selectedJurisdiction');
- // TODO: replace the company name with the information provided by the trading_platform_account_available API's BE response
- const selectedCompany = companyNamesAndUrls[selectedJurisdiction as keyof typeof companyNamesAndUrls];
-
- return (
-
-
- ]}
- i18n_default_text="I confirm and accept {{company}}'s <0>terms and conditions0>"
- values={{
- company: selectedCompany.name,
- }}
- />
-
- }
- name='mt5-tnc-checkbox'
- onChange={onChange}
- />
-
- );
-};
-
-export default MT5PasswordModalTnc;
diff --git a/packages/wallets/src/features/cfd/screens/components/MT5PasswordModalTnc/index.ts b/packages/wallets/src/features/cfd/screens/components/MT5PasswordModalTnc/index.ts
deleted file mode 100644
index fe47194df6f4..000000000000
--- a/packages/wallets/src/features/cfd/screens/components/MT5PasswordModalTnc/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { default as MT5PasswordModalTnc } from './MT5PasswordModalTnc';
diff --git a/packages/wallets/src/features/cfd/screens/components/index.ts b/packages/wallets/src/features/cfd/screens/components/index.ts
deleted file mode 100644
index 14f20a9a7f16..000000000000
--- a/packages/wallets/src/features/cfd/screens/components/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from './MT5LicenceMessage';
-export * from './MT5PasswordModalTnc';
diff --git a/packages/wallets/src/features/cfd/types.ts b/packages/wallets/src/features/cfd/types.ts
deleted file mode 100644
index 32aaf0d18d0d..000000000000
--- a/packages/wallets/src/features/cfd/types.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/* eslint-disable camelcase */
-/*
- TODO: Remove these types once API types for client_kyc_status is available for mt5_login_list and trading_platform_available_accounts from BE
-*/
-import { THooks } from '../../types';
-
-type TStatuses = 'expired' | 'none' | 'pending' | 'rejected' | 'suspected' | 'verified';
-
-export type TModifiedMT5Account = THooks.SortedMT5Accounts & {
- client_kyc_status: {
- poa_status: TStatuses;
- poi_status: TStatuses;
- valid_tin: 0 | 1;
- };
- licence_number: string;
- regulatory_authority: string;
-};
-
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-type ObjectWithKeyInUnion = T extends any ? (K extends keyof T ? T : never) : never;
-
-export type TAvailableMT5Account = ObjectWithKeyInUnion;
-export type TAddedMT5Account = ObjectWithKeyInUnion;
diff --git a/packages/wallets/src/features/cfd/utils/index.ts b/packages/wallets/src/features/cfd/utils/index.ts
deleted file mode 100644
index 04bca77e0dec..000000000000
--- a/packages/wallets/src/features/cfd/utils/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './utils';
diff --git a/packages/wallets/src/features/cfd/utils/utils.ts b/packages/wallets/src/features/cfd/utils/utils.ts
deleted file mode 100644
index e650e20011e0..000000000000
--- a/packages/wallets/src/features/cfd/utils/utils.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { TAddedMT5Account, TAvailableMT5Account } from '../types';
-
-const requiredDocumentStatuses = ['expired', 'none', 'rejected', 'suspected'];
-
-export const getClientVerification = (account: TAddedMT5Account | TAvailableMT5Account) => {
- const hasClientKycStatus = 'client_kyc_status' in account;
- const documentStatuses = account.client_kyc_status;
-
- const hasPoiStatus = hasClientKycStatus && 'poi_status' in documentStatuses;
- const hasPoaStatus = hasClientKycStatus && 'poa_status' in documentStatuses;
- const hasTinStatus = hasClientKycStatus && 'valid_tin' in documentStatuses;
-
- const isPoiRequired = hasPoiStatus && requiredDocumentStatuses.includes(documentStatuses.poi_status);
- const isPoaRequired = hasPoaStatus && requiredDocumentStatuses.includes(documentStatuses.poa_status);
- const isTinRequired = hasTinStatus && !documentStatuses.valid_tin;
-
- return {
- hasClientKycStatus,
- hasPoaStatus,
- hasPoiStatus,
- hasTinStatus,
- isPoaRequired,
- isPoiRequired,
- isTinRequired,
- isVerificationRequired: isPoiRequired || isPoaRequired || isTinRequired,
- statuses: documentStatuses,
- };
-};