-
-
-
-
-
+
+
+
-
-
-
+
{!is_from_derivgo && (
);
-};
-
-DerivPassword.propTypes = {
- email: PropTypes.string,
- is_dark_mode_on: PropTypes.bool,
- is_eu_user: PropTypes.bool,
- financial_restricted_countries: PropTypes.bool,
- is_social_signup: PropTypes.bool,
- social_identity_provider: PropTypes.string,
-};
+});
export default DerivPassword;
diff --git a/packages/account/src/Sections/Security/Passwords/index.js b/packages/account/src/Sections/Security/Passwords/index.js
deleted file mode 100644
index 0c13bc42a994..000000000000
--- a/packages/account/src/Sections/Security/Passwords/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Passwords from './passwords.jsx';
-
-export default Passwords;
diff --git a/packages/account/src/Sections/Security/Passwords/index.ts b/packages/account/src/Sections/Security/Passwords/index.ts
new file mode 100644
index 000000000000..04e64f927ceb
--- /dev/null
+++ b/packages/account/src/Sections/Security/Passwords/index.ts
@@ -0,0 +1,3 @@
+import Passwords from './passwords';
+
+export default Passwords;
diff --git a/packages/account/src/Sections/Security/Passwords/passwords-platform.jsx b/packages/account/src/Sections/Security/Passwords/passwords-platform.jsx
deleted file mode 100644
index 400884fb9178..000000000000
--- a/packages/account/src/Sections/Security/Passwords/passwords-platform.jsx
+++ /dev/null
@@ -1,111 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { Button, Icon, Popover, Text } from '@deriv/components';
-import { CFD_PLATFORMS, WS, getPlatformSettings } from '@deriv/shared';
-import { localize, Localize } from '@deriv/translations';
-import FormSubHeader from 'Components/form-sub-header';
-import SentEmailModal from 'Components/sent-email-modal';
-
-const PasswordsPlatform = ({ email, has_dxtrade_accounts, has_mt5_accounts }) => {
- const [identifier, setIdenifier] = React.useState('');
- const [is_sent_email_modal_open, setIsSentEmailModalOpen] = React.useState(false);
-
- const platform_name_dxtrade = getPlatformSettings('dxtrade').name;
-
- const getPlatformTitle = () => {
- let title = '';
- if (has_mt5_accounts) {
- title = localize('Deriv MT5 Password');
- } else if (has_dxtrade_accounts) {
- title = localize('{{platform_name_dxtrade}} Password', { platform_name_dxtrade });
- }
- return title;
- };
-
- const onClickSendEmail = cfd_platform => {
- const password_reset_code =
- cfd_platform === CFD_PLATFORMS.MT5
- ? 'trading_platform_mt5_password_reset'
- : 'trading_platform_dxtrade_password_reset';
-
- WS.verifyEmail(email, password_reset_code, {
- url_parameters: {
- redirect_to: 3,
- },
- });
- setIdenifier(cfd_platform);
- setIsSentEmailModalOpen(true);
- };
-
- return (
-
-
-
- {has_mt5_accounts && (
-
-
-
-
-
-
-
-
-
-
- )}
- {has_dxtrade_accounts && (
-
-
-
-
-
-
-
-
-
-
- )}
-
setIsSentEmailModalOpen(false)}
- onClickSendEmail={onClickSendEmail}
- is_modal_when_mobile
- />
- {/*
- setIsSuccessDialogOpen(false)}
- /> */}
-
-
- );
-};
-
-PasswordsPlatform.propTypes = {
- email: PropTypes.string,
- has_dxtrade_accounts: PropTypes.bool,
- has_mt5_accounts: PropTypes.bool,
-};
-
-export default PasswordsPlatform;
diff --git a/packages/account/src/Sections/Security/Passwords/passwords-platform.tsx b/packages/account/src/Sections/Security/Passwords/passwords-platform.tsx
new file mode 100644
index 000000000000..a26e5f06b57b
--- /dev/null
+++ b/packages/account/src/Sections/Security/Passwords/passwords-platform.tsx
@@ -0,0 +1,100 @@
+import React from 'react';
+import { useMutation } from '@deriv/api';
+import { CFD_PLATFORMS, getPlatformSettings } from '@deriv/shared';
+import { observer, useStore } from '@deriv/stores';
+import { Localize, localize } from '@deriv/translations';
+import FormSubHeader from 'Components/form-sub-header';
+import SentEmailModal from 'Components/sent-email-modal';
+import PlatformPartials from './platform-partials';
+
+type TPasswordsPlatformProps = {
+ has_dxtrade_accounts?: boolean;
+ has_mt5_accounts?: boolean;
+};
+
+/**
+ * Displays a change password instructions for MT5 and/or DXTrade.
+ * @name PasswordsPlatform
+ * @param [has_dxtrade_accounts=false] - Whether the user has DXTrade accounts.
+ * @param [has_mt5_accounts=false] - Whether the user has MT5 accounts.
+ * @returns React.ReactNode
+ */
+const PasswordsPlatform = observer(
+ ({ has_dxtrade_accounts = false, has_mt5_accounts = false }: TPasswordsPlatformProps) => {
+ const { mutate } = useMutation('verify_email');
+
+ const {
+ client: { email },
+ } = useStore();
+
+ const [identifier, setIdentifier] = React.useState('');
+ const [is_sent_email_modal_open, setIsSentEmailModalOpen] = React.useState(false);
+
+ const platform_name_dxtrade = getPlatformSettings('dxtrade').name;
+
+ const getPlatformTitle = () => {
+ let title = '';
+ if (has_mt5_accounts) {
+ title = localize('Deriv MT5 Password');
+ } else if (has_dxtrade_accounts) {
+ title = localize('{{platform_name_dxtrade}} Password', { platform_name_dxtrade });
+ }
+ return title;
+ };
+
+ const onClickSendEmail = (cfd_platform?: string) => {
+ const password_reset_code =
+ cfd_platform === CFD_PLATFORMS.MT5
+ ? 'trading_platform_mt5_password_reset'
+ : 'trading_platform_dxtrade_password_reset';
+
+ mutate({
+ payload: {
+ verify_email: email,
+ type: password_reset_code,
+
+ url_parameters: {
+ redirect_to: 3,
+ },
+ },
+ });
+
+ setIdentifier(cfd_platform ?? '');
+ setIsSentEmailModalOpen(true);
+ };
+
+ return (
+
+
+
+ {has_mt5_accounts && (
+
+ }
+ />
+ )}
+ {has_dxtrade_accounts && (
+
+ }
+ />
+ )}
+
setIsSentEmailModalOpen(false)}
+ onClickSendEmail={onClickSendEmail}
+ is_modal_when_mobile
+ />
+
+
+ );
+ }
+);
+export default PasswordsPlatform;
diff --git a/packages/account/src/Sections/Security/Passwords/passwords.jsx b/packages/account/src/Sections/Security/Passwords/passwords.jsx
deleted file mode 100644
index 719d784a160c..000000000000
--- a/packages/account/src/Sections/Security/Passwords/passwords.jsx
+++ /dev/null
@@ -1,70 +0,0 @@
-import React from 'react';
-import { Loading } from '@deriv/components';
-import { observer, useStore } from '@deriv/stores';
-import DerivPassword from './deriv-password.jsx';
-import DerivEmail from './deriv-email.jsx';
-import PasswordsPlatform from './passwords-platform.jsx';
-
-const Passwords = observer(() => {
- const [is_loading, setIsLoading] = React.useState(true);
- const { client, ui, common, traders_hub } = useStore();
- const {
- is_populating_mt5_account_list,
- is_populating_dxtrade_account_list,
- is_social_signup,
- email,
- social_identity_provider,
- mt5_login_list,
- is_mt5_password_not_set,
- dxtrade_accounts_list,
- is_dxtrade_password_not_set,
- } = client;
- const { is_from_derivgo } = common;
- const { is_eu_user, financial_restricted_countries } = traders_hub;
- const { is_dark_mode_on } = ui;
- React.useEffect(() => {
- if (
- is_populating_mt5_account_list === false &&
- is_populating_dxtrade_account_list === false &&
- is_social_signup !== undefined
- ) {
- setIsLoading(false);
- }
- }, [is_populating_mt5_account_list, is_populating_dxtrade_account_list, is_social_signup]);
-
- if (is_loading) {
- return
;
- }
-
- return (
-
-
-
- {!is_from_derivgo && (mt5_login_list?.length > 0 || !is_mt5_password_not_set) && (
-
0 || !is_mt5_password_not_set}
- />
- )}
- {!is_from_derivgo && (dxtrade_accounts_list?.length > 0 || !is_dxtrade_password_not_set) && (
- 0 || !is_dxtrade_password_not_set}
- />
- )}
-
- );
-});
-
-export default Passwords;
diff --git a/packages/account/src/Sections/Security/Passwords/passwords.tsx b/packages/account/src/Sections/Security/Passwords/passwords.tsx
new file mode 100644
index 000000000000..59a4dfde3931
--- /dev/null
+++ b/packages/account/src/Sections/Security/Passwords/passwords.tsx
@@ -0,0 +1,56 @@
+import React from 'react';
+import { Loading } from '@deriv/components';
+import { observer, useStore } from '@deriv/stores';
+import DerivPassword from './deriv-password';
+import DerivEmail from './deriv-email';
+import PasswordsPlatform from './passwords-platform';
+
+/**
+ * Displays the Email, Password, section under Account settings.
+ * @name Passwords
+ * @returns {React.ReactNode}
+ */
+const Passwords = observer(() => {
+ const { client, common } = useStore();
+ const {
+ is_populating_mt5_account_list,
+ is_populating_dxtrade_account_list,
+ is_social_signup,
+ mt5_login_list,
+ is_mt5_password_not_set,
+ dxtrade_accounts_list,
+ is_dxtrade_password_not_set,
+ } = client;
+ const { is_from_derivgo } = common;
+
+ const [is_loading, setIsLoading] = React.useState(true);
+ const has_mt5_accounts = mt5_login_list?.length > 0 || !is_mt5_password_not_set;
+ const has_dxtrade_accounts = dxtrade_accounts_list?.length > 0 || !is_dxtrade_password_not_set;
+
+ React.useEffect(() => {
+ if (
+ is_populating_mt5_account_list === false &&
+ is_populating_dxtrade_account_list === false &&
+ is_social_signup !== undefined
+ ) {
+ setIsLoading(false);
+ }
+ }, [is_populating_mt5_account_list, is_populating_dxtrade_account_list, is_social_signup]);
+
+ if (is_loading) {
+ return
;
+ }
+
+ return (
+
+
+
+ {!is_from_derivgo && has_mt5_accounts &&
}
+ {!is_from_derivgo && has_dxtrade_accounts && (
+
+ )}
+
+ );
+});
+
+export default Passwords;
diff --git a/packages/account/src/Sections/Security/Passwords/platform-description.tsx b/packages/account/src/Sections/Security/Passwords/platform-description.tsx
new file mode 100644
index 000000000000..ecbfbff8dad2
--- /dev/null
+++ b/packages/account/src/Sections/Security/Passwords/platform-description.tsx
@@ -0,0 +1,85 @@
+import React from 'react';
+import { Localize } from '@deriv/translations';
+
+type TPlatformDescription = {
+ brand_website_name: string;
+ platform_values: {
+ platform_name_trader: string;
+ platform_name_dbot: string;
+ platform_name_smarttrader: string;
+ platform_name_go: string;
+ platform_name_ctrader: string;
+ };
+ is_eu_user: boolean;
+ financial_restricted_countries: boolean;
+};
+
+/**
+ * Renders description for the platforms.
+ * @name PlatformDescription
+ * @param brand_website_name - Name of the website
+ * @param platform_values - Object containing platform names
+ * @param is_eu_user - Boolean value to check if user is from EU
+ * @param financial_restricted_countries - Boolean value to check if user is from a restricted country
+ * @returns Returns a react node
+ */
+const PlatformDescription = ({
+ brand_website_name,
+ platform_values,
+ is_eu_user,
+ financial_restricted_countries,
+}: TPlatformDescription) => {
+ const {
+ platform_name_trader,
+ platform_name_dbot,
+ platform_name_smarttrader,
+ platform_name_go,
+ platform_name_ctrader,
+ } = platform_values;
+ if (is_eu_user) {
+ return (
+
Deriv password0> to log in to {{brand_website_name}} and {{platform_name_trader}}.'
+ }
+ components={[]}
+ values={{
+ brand_website_name,
+ platform_name_trader,
+ }}
+ />
+ );
+ } else if (financial_restricted_countries) {
+ return (
+ Deriv password0> to log in to {{brand_website_name}}, {{platform_name_trader}} and {{platform_name_go}}.'
+ }
+ components={[]}
+ values={{
+ brand_website_name,
+ platform_name_trader,
+ platform_name_go,
+ }}
+ />
+ );
+ }
+ return (
+ Deriv password0> to log in to {{brand_website_name}}, {{platform_name_go}}, {{platform_name_trader}}, {{platform_name_smarttrader}}, {{platform_name_dbot}} and {{platform_name_ctrader}}.'
+ }
+ components={[]}
+ values={{
+ brand_website_name,
+ platform_name_trader,
+ platform_name_dbot,
+ platform_name_smarttrader,
+ platform_name_go,
+ platform_name_ctrader,
+ }}
+ />
+ );
+};
+
+export default PlatformDescription;
diff --git a/packages/account/src/Sections/Security/Passwords/platform-partials.tsx b/packages/account/src/Sections/Security/Passwords/platform-partials.tsx
new file mode 100644
index 000000000000..92e03a2f108c
--- /dev/null
+++ b/packages/account/src/Sections/Security/Passwords/platform-partials.tsx
@@ -0,0 +1,45 @@
+import React from 'react';
+import { Button, Icon, Popover, Text } from '@deriv/components';
+import { getPlatformSettings, CFD_PLATFORMS } from '@deriv/shared';
+import { localize } from '@deriv/translations';
+
+type TPlatformPartialsProps = {
+ description: JSX.Element;
+ type: typeof CFD_PLATFORMS[keyof typeof CFD_PLATFORMS];
+ handleClick: (type: typeof CFD_PLATFORMS[keyof typeof CFD_PLATFORMS]) => void;
+};
+
+/**
+ * Component for displaying a change password instructions for a platform
+ * @name PlatformPartials
+ * @param description - The description of the platform
+ * @param type - The type of the platform
+ * @param handleClick - The function to call when the button is clicked
+ * @returns React.ReactNode
+ */
+const PlatformPartials = ({ description, type, handleClick }: TPlatformPartialsProps) => {
+ const platform_config = getPlatformSettings(type);
+
+ return (
+
+
+ {description}
+
+
+
+
+
+
+
+ );
+};
+
+export default PlatformPartials;
diff --git a/packages/account/src/Types/common.type.ts b/packages/account/src/Types/common.type.ts
index eb813d8eb788..dcf351c133a4 100644
--- a/packages/account/src/Types/common.type.ts
+++ b/packages/account/src/Types/common.type.ts
@@ -1,7 +1,7 @@
/** Add types that are shared between components */
import React from 'react';
-import { Authorize, IdentityVerificationAddDocumentResponse } from '@deriv/api-types';
import { Redirect } from 'react-router-dom';
+import { Authorize, IdentityVerificationAddDocumentResponse } from '@deriv/api-types';
import { Platforms } from '@deriv/shared';
export type TToken = {
@@ -104,15 +104,6 @@ type TIdentity = {
};
};
-export type TResidenseList = {
- identity: TIdentity;
- phone_idd: string;
- tin_format: string[];
- disabled: string;
- text: string;
- value: string;
-};
-
export type TFile = {
path: string;
lastModified: number;
diff --git a/packages/api/src/hooks/index.ts b/packages/api/src/hooks/index.ts
index 676110c7fc2a..db9c782955b0 100644
--- a/packages/api/src/hooks/index.ts
+++ b/packages/api/src/hooks/index.ts
@@ -35,3 +35,4 @@ export { default as useTradingPlatformPasswordChange } from './useTradingPlatfor
export { default as useTransactions } from './useTransactions';
export { default as useTransferBetweenAccounts } from './useTransferBetweenAccounts';
export { default as useWalletAccountsList } from './useWalletAccountsList';
+export { default as useVerifyEmail } from './useVerifyEmail';
diff --git a/packages/components/src/components/date-picker/date-picker.tsx b/packages/components/src/components/date-picker/date-picker.tsx
index f3934fad7ec6..48f18e94678e 100644
--- a/packages/components/src/components/date-picker/date-picker.tsx
+++ b/packages/components/src/components/date-picker/date-picker.tsx
@@ -7,12 +7,8 @@ import MobileWrapper from '../mobile-wrapper';
import DesktopWrapper from '../desktop-wrapper';
import { useOnClickOutside } from '../../hooks/use-onclickoutside';
import { MomentInput } from 'moment';
+import { TDatePickerOnChangeEvent } from '../types';
-type TDatePickerOnChangeEvent = {
- date?: string;
- duration?: number | null | string;
- target?: { name: string; value: number | string | moment.Moment | null };
-};
type TDatePicker = Omit<
React.ComponentProps & React.ComponentProps & React.ComponentProps,
'value' | 'onSelect' | 'is_datepicker_visible' | 'placement' | 'style' | 'calendar_el_ref' | 'parent_ref'
diff --git a/packages/components/src/components/date-picker/index.ts b/packages/components/src/components/date-picker/index.ts
index e1fd3c52ef90..adfc2a303a54 100644
--- a/packages/components/src/components/date-picker/index.ts
+++ b/packages/components/src/components/date-picker/index.ts
@@ -1,4 +1,3 @@
import DatePicker from './date-picker';
import './date-picker.scss';
-
export default DatePicker;
diff --git a/packages/components/src/components/send-email-template/send-email-template.tsx b/packages/components/src/components/send-email-template/send-email-template.tsx
index 955916de4707..e3273b37337d 100644
--- a/packages/components/src/components/send-email-template/send-email-template.tsx
+++ b/packages/components/src/components/send-email-template/send-email-template.tsx
@@ -11,8 +11,8 @@ type TSendEmailTemplate = {
live_chat?: React.ReactNode;
onClickSendEmail: () => void;
resend_timeout?: number;
- subtitle?: string;
- title: string;
+ subtitle?: React.ReactNode;
+ title: React.ReactNode;
txt_resend_in: string;
txt_resend: string;
};
diff --git a/packages/components/src/components/types/common.types.ts b/packages/components/src/components/types/common.types.ts
index 65048a670689..df3b6a82b70a 100644
--- a/packages/components/src/components/types/common.types.ts
+++ b/packages/components/src/components/types/common.types.ts
@@ -23,3 +23,9 @@ export type TTableRowItem =
export type TRow = { [key: string]: any };
export type TPassThrough = { isTopUp: (item: TRow) => boolean };
+
+export type TDatePickerOnChangeEvent = {
+ date?: string;
+ duration?: number | null | string;
+ target?: { name?: string; value?: number | string | moment.Moment | null };
+};
diff --git a/packages/components/src/components/types/index.ts b/packages/components/src/components/types/index.ts
index 7911e1a631d9..98187945e4e1 100644
--- a/packages/components/src/components/types/index.ts
+++ b/packages/components/src/components/types/index.ts
@@ -2,7 +2,7 @@ import { TIconsManifest, TIconProps } from './icons.types';
import { TAccordionProps, TAccordionItem } from './accordion.types';
import { TMultiStepProps, TMultiStepRefProps } from './multi-step.types';
import { TPopoverProps } from './popover.types';
-import { TGetCardLables, TGetContractTypeDisplay } from './common.types';
+import { TGetCardLables, TGetContractTypeDisplay, TDatePickerOnChangeEvent } from './common.types';
import { TErrorMessages, TGetContractPath, TToastConfig } from './contract.types';
export type {
@@ -18,4 +18,5 @@ export type {
TGetContractPath,
TToastConfig,
TGetContractTypeDisplay,
+ TDatePickerOnChangeEvent,
};
diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts
index c2e7729236ed..56937ff875a7 100644
--- a/packages/components/src/index.ts
+++ b/packages/components/src/index.ts
@@ -114,3 +114,4 @@ export { default as UnhandledErrorModal } from './components/unhandled-error-mod
export { default as VerticalTab } from './components/vertical-tab';
export { default as Wizard } from './components/wizard';
export * from './hooks';
+export * from './components/types';
diff --git a/packages/core/src/App/Containers/RealAccountSignup/account-wizard-form.js b/packages/core/src/App/Containers/RealAccountSignup/account-wizard-form.js
index 7fb55cf09287..c412cda01bd2 100644
--- a/packages/core/src/App/Containers/RealAccountSignup/account-wizard-form.js
+++ b/packages/core/src/App/Containers/RealAccountSignup/account-wizard-form.js
@@ -1,4 +1,5 @@
import {
+ FinancialDetails,
PersonalDetails,
TermsOfUse,
TradingAssessmentNewUser,
@@ -10,18 +11,15 @@ import {
tradingAssessmentConfig,
} from '@deriv/account';
-import AddressDetails from './address-details';
-import CurrencySelector from './currency-selector.jsx';
-import FinancialDetails from './financial-details.jsx';
+import AddressDetails from '@deriv/account/src/Components/address-details';
+import CurrencySelector from '@deriv/account/src/Components/currency-selector';
const isMaltaAccount = ({ real_account_signup_target }) => real_account_signup_target === 'maltainvest';
-const shouldShowPersonalAndAddressDetailsAndCurrency = ({ real_account_signup_target }) =>
- real_account_signup_target !== 'samoa';
export const getItems = props => [
- ...(shouldShowPersonalAndAddressDetailsAndCurrency(props) ? [currencySelectorConfig(props, CurrencySelector)] : []),
- ...(shouldShowPersonalAndAddressDetailsAndCurrency(props) ? [personalDetailsConfig(props, PersonalDetails)] : []),
- ...(shouldShowPersonalAndAddressDetailsAndCurrency(props) ? [addressDetailsConfig(props, AddressDetails)] : []),
+ currencySelectorConfig(props, CurrencySelector),
+ personalDetailsConfig(props, PersonalDetails),
+ addressDetailsConfig(props, AddressDetails),
...(isMaltaAccount(props) ? [tradingAssessmentConfig(props, TradingAssessmentNewUser)] : []),
...(isMaltaAccount(props) ? [financialDetailsConfig(props, FinancialDetails)] : []),
termsOfUseConfig(props, TermsOfUse),
diff --git a/packages/core/src/App/Containers/RealAccountSignup/address-details.jsx b/packages/core/src/App/Containers/RealAccountSignup/address-details.jsx
deleted file mode 100644
index 7b91511c5fe6..000000000000
--- a/packages/core/src/App/Containers/RealAccountSignup/address-details.jsx
+++ /dev/null
@@ -1,8 +0,0 @@
-import { AddressDetails } from '@deriv/account';
-import { connect } from 'Stores/connect';
-
-export default connect(({ client }) => ({
- is_gb_residence: client.residence === 'gb',
- fetchStatesList: client.fetchStatesList,
- states_list: client.states_list,
-}))(AddressDetails);
diff --git a/packages/core/src/App/Containers/RealAccountSignup/currency-selector.jsx b/packages/core/src/App/Containers/RealAccountSignup/currency-selector.jsx
deleted file mode 100644
index a8f23d58b27d..000000000000
--- a/packages/core/src/App/Containers/RealAccountSignup/currency-selector.jsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import { CurrencySelector } from '@deriv/account';
-import { connect } from 'Stores/connect';
-import './currency-selector.scss';
-
-export default connect(({ client, ui }) => ({
- currencies: client.currencies_list,
- has_currency: !!client.currency,
- has_real_account: client.has_active_real_account,
- legal_allowed_currencies: client.upgradeable_currencies,
- real_account_signup: ui.real_account_signup,
- resetRealAccountSignupParams: ui.resetRealAccountSignupParams,
- selectable_currencies: client.selectable_currencies,
- available_crypto_currencies: client.available_crypto_currencies,
- real_account_signup_target: ui.real_account_signup_target,
- is_dxtrade_allowed: client.is_dxtrade_allowed,
- is_mt5_allowed: client.is_mt5_allowed,
- has_fiat: client.has_fiat,
- accounts: client.accounts,
- is_eu: client.is_eu,
-}))(CurrencySelector);
diff --git a/packages/core/src/App/Containers/RealAccountSignup/financial-details.jsx b/packages/core/src/App/Containers/RealAccountSignup/financial-details.jsx
deleted file mode 100644
index 274cfa2e9824..000000000000
--- a/packages/core/src/App/Containers/RealAccountSignup/financial-details.jsx
+++ /dev/null
@@ -1,8 +0,0 @@
-import { FinancialDetails } from '@deriv/account';
-import { connect } from 'Stores/connect';
-
-export default connect(({ client }) => ({
- is_gb_residence: client.residence === 'gb',
- fetchStatesList: client.fetchStatesList,
- states_list: client.states_list,
-}))(FinancialDetails);
diff --git a/packages/core/src/App/Containers/RealAccountSignup/set-currency.jsx b/packages/core/src/App/Containers/RealAccountSignup/set-currency.jsx
index 93367176e2c1..08a2fef65240 100644
--- a/packages/core/src/App/Containers/RealAccountSignup/set-currency.jsx
+++ b/packages/core/src/App/Containers/RealAccountSignup/set-currency.jsx
@@ -5,7 +5,7 @@ import { currencySelectorConfig } from '@deriv/account';
import { website_name, generateValidationFunction } from '@deriv/shared';
import { Text } from '@deriv/components';
import { connect } from 'Stores/connect';
-import CurrencySelector from './currency-selector';
+import CurrencySelector from '@deriv/account/src/Components/currency-selector';
import LoadingModal from './real-account-signup-loader.jsx';
import 'Sass/set-currency.scss';
import 'Sass/change-account.scss';
diff --git a/packages/core/src/Stores/ui-store.js b/packages/core/src/Stores/ui-store.js
index 37cf48411a20..0944dcd95815 100644
--- a/packages/core/src/Stores/ui-store.js
+++ b/packages/core/src/Stores/ui-store.js
@@ -303,6 +303,7 @@ export default class UIStore extends BaseStore {
init: action.bound,
installWithDeferredPrompt: action.bound,
is_account_switcher_disabled: computed,
+ is_desktop: computed,
is_mobile: computed,
is_tablet: computed,
is_warning_scam_message_modal_visible: computed,
@@ -479,6 +480,11 @@ export default class UIStore extends BaseStore {
return MAX_MOBILE_WIDTH < this.screen_width && this.screen_width <= MAX_TABLET_WIDTH;
}
+ get is_desktop() {
+ // TODO: remove tablet once there is a design for the specific size.
+ return this.is_tablet || this.screen_width > MAX_TABLET_WIDTH;
+ }
+
get is_account_switcher_disabled() {
return !!this.account_switcher_disabled_message;
}
diff --git a/packages/hooks/src/__tests__/useIsAccountStatusPresent.spec.tsx b/packages/hooks/src/__tests__/useIsAccountStatusPresent.spec.tsx
index eeffe186e82a..05153b421de5 100644
--- a/packages/hooks/src/__tests__/useIsAccountStatusPresent.spec.tsx
+++ b/packages/hooks/src/__tests__/useIsAccountStatusPresent.spec.tsx
@@ -1,7 +1,7 @@
import * as React from 'react';
-import { mockStore, StoreProvider } from '@deriv/stores';
import { renderHook } from '@testing-library/react-hooks';
-import { useIsAccountStatusPresent } from '../useIsAccountStatusPresent';
+import { mockStore, StoreProvider } from '@deriv/stores';
+import useIsAccountStatusPresent from '../useIsAccountStatusPresent';
describe('useIsAccountStatusPresent', () => {
it('should return false when the status is not present', () => {
diff --git a/packages/hooks/src/__tests__/useStatesList.spec.tsx b/packages/hooks/src/__tests__/useStatesList.spec.tsx
new file mode 100644
index 000000000000..6d174de438ba
--- /dev/null
+++ b/packages/hooks/src/__tests__/useStatesList.spec.tsx
@@ -0,0 +1,49 @@
+import * as React from 'react';
+import { renderHook } from '@testing-library/react-hooks';
+import { APIProvider, useFetch } from '@deriv/api';
+import { StoreProvider, mockStore } from '@deriv/stores';
+import useStatesList from '../useStatesList';
+
+jest.mock('@deriv/api', () => ({
+ ...jest.requireActual('@deriv/api'),
+ useFetch: jest.fn(),
+}));
+
+const mockUseFetch = useFetch as jest.MockedFunction>;
+
+describe('useStatesList', () => {
+ const mock = mockStore({});
+
+ const wrapper = ({ children }: { children: JSX.Element }) => (
+
+ {children}
+
+ );
+
+ it('should return an empty array when the store is not ready', () => {
+ // @ts-expect-error need to come up with a way to mock the return type of useFetch
+ mockUseFetch.mockReturnValue({
+ data: {
+ states_list: [],
+ },
+ });
+ const { result } = renderHook(() => useStatesList('in'), { wrapper });
+
+ expect(result.current.data).toHaveLength(0);
+ });
+
+ it('should return data fetched along with correct status', () => {
+ // @ts-expect-error need to come up with a way to mock the return type of useFetch
+ mockUseFetch.mockReturnValue({
+ data: {
+ states_list: [
+ { text: 'state 1', value: 's1' },
+ { text: 'state 2', value: 's2' },
+ ],
+ },
+ isFetched: true,
+ });
+ const { result } = renderHook(() => useStatesList('in'), { wrapper });
+ expect(result.current.isFetched).toBeTruthy();
+ });
+});
diff --git a/packages/hooks/src/index.ts b/packages/hooks/src/index.ts
index 4b22cbce43d4..fd9e68b0f16c 100644
--- a/packages/hooks/src/index.ts
+++ b/packages/hooks/src/index.ts
@@ -46,7 +46,8 @@ export { default as usePlatformRealAccounts } from './usePlatformRealAccounts';
export { default as useRealSTPAccount } from './useRealSTPAccount';
export { default as useTotalAccountBalance } from './useTotalAccountBalance';
export { default as useVerifyEmail } from './useVerifyEmail';
-export { useIsAccountStatusPresent } from './useIsAccountStatusPresent';
+export { default as useIsAccountStatusPresent } from './useIsAccountStatusPresent';
+export { default as useStatesList } from './useStatesList';
export { default as useP2PConfig } from './useP2PConfig';
export { default as useIsClientHighRiskForMT5 } from './useIsClientHighRiskForMT5';
export { default as useCFDCanGetMoreMT5Accounts } from './useCFDCanGetMoreMT5Accounts';
diff --git a/packages/hooks/src/useIsAccountStatusPresent.ts b/packages/hooks/src/useIsAccountStatusPresent.ts
index f6b467cd0089..db9144b6e058 100644
--- a/packages/hooks/src/useIsAccountStatusPresent.ts
+++ b/packages/hooks/src/useIsAccountStatusPresent.ts
@@ -48,7 +48,13 @@ const AccountStatusList = [
type TAccountStatus = typeof AccountStatusList[number];
-export const useIsAccountStatusPresent = (status: TAccountStatus) => {
+/**
+ * Custom hook to check if a particular account status is present.
+ * @name useIsAccountStatusPresent
+ * @param status of the account to check
+ * @returns boolean
+ */
+const useIsAccountStatusPresent = (status: TAccountStatus) => {
const {
client: { account_status },
} = useStore();
@@ -57,3 +63,5 @@ export const useIsAccountStatusPresent = (status: TAccountStatus) => {
return React.useMemo(() => status_list?.includes(status) ?? false, [status_list, status]);
};
+
+export default useIsAccountStatusPresent;
diff --git a/packages/hooks/src/useStatesList.ts b/packages/hooks/src/useStatesList.ts
new file mode 100644
index 000000000000..ad5086745a1c
--- /dev/null
+++ b/packages/hooks/src/useStatesList.ts
@@ -0,0 +1,16 @@
+import { useFetch } from '@deriv/api';
+/**
+ * Custom hook to get states list for a particular country.
+ * @returns an object with the states list and the options to manage API response.
+ */
+const useStatesList = (country: string) => {
+ const { data, ...rest } = useFetch('states_list', {
+ // @ts-expect-error The `states_list` type from `@deriv/api-types` is not correct.
+ // The type should be `string`, but it's an alias to string type.
+ payload: { states_list: country },
+ });
+
+ return { ...rest, data: data?.states_list ?? [] };
+};
+
+export default useStatesList;
diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts
index 963f4e3419bb..2faa767f9621 100644
--- a/packages/shared/src/index.ts
+++ b/packages/shared/src/index.ts
@@ -35,3 +35,4 @@ export * from './services';
export * from './utils/helpers';
export * from './utils/constants';
export * from './utils/loader-handler';
+export * from './utils/types';
diff --git a/packages/shared/src/utils/config/adapters.ts b/packages/shared/src/utils/config/adapters.ts
index 0b962cb0d005..7ec4efc3e265 100644
--- a/packages/shared/src/utils/config/adapters.ts
+++ b/packages/shared/src/utils/config/adapters.ts
@@ -21,6 +21,7 @@ type TIDVFormValues = {
/**
* Formats the IDV form values to be sent to the API
+ * @name formatIDVFormValues
* @param idv_form_value - Formik values of the IDV form
* @param country_code - Country code of the user
* @returns IDV form values
diff --git a/packages/shared/src/utils/currency/currency.ts b/packages/shared/src/utils/currency/currency.ts
index d26b7eb207e8..6bf986764e61 100644
--- a/packages/shared/src/utils/currency/currency.ts
+++ b/packages/shared/src/utils/currency/currency.ts
@@ -42,7 +42,7 @@ const crypto_currencies_display_order = [
'USDK',
];
-export const reorderCurrencies = (list: Array<{ value: string; type: string }>, type = 'fiat') => {
+export const reorderCurrencies = (list: Array, type = 'fiat') => {
const new_order = type === 'fiat' ? fiat_currencies_display_order : crypto_currencies_display_order;
return list.sort((a, b) => {
diff --git a/packages/shared/src/utils/types.ts b/packages/shared/src/utils/types.ts
new file mode 100644
index 000000000000..51ebd1123f8f
--- /dev/null
+++ b/packages/shared/src/utils/types.ts
@@ -0,0 +1,3 @@
+import { Jurisdiction } from './constants';
+
+export type TBrokerCodes = typeof Jurisdiction[keyof typeof Jurisdiction];
diff --git a/packages/stores/src/mockStore.ts b/packages/stores/src/mockStore.ts
index be3884422813..546f4bc0984b 100644
--- a/packages/stores/src/mockStore.ts
+++ b/packages/stores/src/mockStore.ts
@@ -19,7 +19,6 @@ const mock = (): TStores & { is_mock: boolean } => {
account_settings: {},
account_type: 'virtual',
accounts: {},
- is_social_signup: false,
active_account_landing_company: '',
trading_platform_available_accounts: [],
account_limits: {},
@@ -125,6 +124,7 @@ const mock = (): TStores & { is_mock: boolean } => {
setCFDScore: jest.fn(),
getLimits: jest.fn(),
has_active_real_account: false,
+ has_fiat: false,
has_logged_out: false,
has_maltainvest_account: false,
has_restricted_mt5_account: false,
@@ -133,6 +133,7 @@ const mock = (): TStores & { is_mock: boolean } => {
is_authorize: false,
is_deposit_lock: false,
is_dxtrade_allowed: false,
+ is_dxtrade_password_not_set: false,
is_eu: false,
is_eu_country: false,
has_residence: false,
@@ -144,7 +145,10 @@ const mock = (): TStores & { is_mock: boolean } => {
is_landing_company_loaded: false,
is_logged_in: false,
is_logging_in: false,
+ is_mt5_password_not_set: false,
is_pending_proof_of_ownership: false,
+ is_populating_dxtrade_account_list: false,
+ is_social_signup: false,
is_single_currency: false,
is_switching: false,
is_tnc_needed: false,
@@ -206,6 +210,7 @@ const mock = (): TStores & { is_mock: boolean } => {
setVisibilityRealityCheck: jest.fn(),
setP2pAdvertiserInfo: jest.fn(),
setPreSwitchAccount: jest.fn(),
+ social_identity_provider: '',
switched: false,
switch_broadcast: false,
switchEndSignal: jest.fn(),
@@ -224,6 +229,7 @@ const mock = (): TStores & { is_mock: boolean } => {
is_populating_mt5_account_list: false,
landing_companies: {},
landing_company: {},
+ upgradeable_currencies: [],
getChangeableFields: jest.fn(),
isAccountOfTypeDisabled: jest.fn(),
is_mt5_allowed: false,
@@ -307,9 +313,13 @@ const mock = (): TStores & { is_mock: boolean } => {
is_closing_create_real_account_modal: false,
is_dark_mode_on: false,
is_language_settings_modal_on: false,
+ is_desktop: false,
+ is_app_disabled: false,
+ has_only_forward_starting_contracts: false,
header_extension: null,
is_link_expired_modal_visible: false,
is_mobile: false,
+ is_tablet: false,
is_mobile_language_menu_open: false,
is_positions_drawer_on: false,
is_reports_visible: false,
@@ -324,8 +334,16 @@ const mock = (): TStores & { is_mock: boolean } => {
toggleCashier: jest.fn(),
setDarkMode: jest.fn(),
setReportsTabIndex: jest.fn(),
- has_only_forward_starting_contracts: false,
has_real_account_signup_ended: false,
+ real_account_signup_target: '',
+ real_account_signup: {
+ active_modal_index: -1,
+ previous_currency: '',
+ current_currency: '',
+ success_message: '',
+ error_message: '',
+ },
+ resetRealAccountSignupParams: jest.fn(),
notification_messages_ui: jest.fn(),
openPositionsDrawer: jest.fn(),
openRealAccountSignup: jest.fn(),
@@ -352,7 +370,6 @@ const mock = (): TStores & { is_mock: boolean } => {
setSubSectionIndex: jest.fn(),
sub_section_index: 0,
toggleReadyToDepositModal: jest.fn(),
- is_tablet: false,
is_ready_to_deposit_modal_visible: false,
is_real_acc_signup_on: false,
is_need_real_account_for_cashier_modal_visible: false,
diff --git a/packages/stores/types.ts b/packages/stores/types.ts
index 7d3d8555799d..3b4c60be66d5 100644
--- a/packages/stores/types.ts
+++ b/packages/stores/types.ts
@@ -14,6 +14,7 @@ import type {
SetFinancialAssessmentRequest,
SetFinancialAssessmentResponse,
StatesList,
+ WebsiteStatus,
ContractUpdateHistory,
Transaction,
ActiveSymbols,
@@ -242,6 +243,15 @@ type TDXTraderStatusServerType = Record<'all' | 'demo' | 'real', number>;
type TMt5StatusServer = Record<'demo' | 'real', TMt5StatusServerType[]>;
+type RealAccountSignupSettings = {
+ active_modal_index: number;
+ current_currency: string;
+ error_code?: string;
+ error_details?: string | Record;
+ error_message: string;
+ previous_currency: string;
+ success_message: string;
+};
type TCountryStandpoint = {
is_belgium: boolean;
is_france: boolean;
@@ -264,7 +274,7 @@ type TClientStore = {
};
account_list: TAccountsList;
account_status: GetAccountStatus;
- available_crypto_currencies: string[];
+ available_crypto_currencies: Array;
balance?: string | number;
can_change_fiat_currency: boolean;
clients_country: string;
@@ -293,6 +303,7 @@ type TClientStore = {
is_social_signup: boolean;
has_residence: boolean;
is_authorize: boolean;
+ is_dxtrade_password_not_set: boolean;
is_financial_account: boolean;
is_financial_assessment_needed: boolean;
is_financial_information_incomplete: boolean;
@@ -301,7 +312,9 @@ type TClientStore = {
is_logged_in: boolean;
is_logging_in: boolean;
is_low_risk: boolean;
+ is_mt5_password_not_set: boolean;
is_pending_proof_of_ownership: boolean;
+ is_populating_dxtrade_account_list: boolean;
is_switching: boolean;
is_tnc_needed: boolean;
is_trading_experience_incomplete: boolean;
@@ -336,9 +349,11 @@ type TClientStore = {
setP2pAdvertiserInfo: () => void;
setPreSwitchAccount: (status?: boolean) => void;
switchAccount: (value?: string) => Promise;
+ social_identity_provider: string;
switched: boolean;
switch_broadcast: boolean;
switchEndSignal: () => void;
+ upgradeable_currencies: Array;
verification_code: {
payment_agent_withdraw: string;
payment_withdraw: string;
@@ -392,6 +407,7 @@ type TClientStore = {
has_account_error_in_mt5_demo_list: boolean;
has_account_error_in_dxtrade_real_list: boolean;
has_account_error_in_dxtrade_demo_list: boolean;
+ has_fiat: boolean;
is_fully_authenticated: boolean;
states_list: StatesList;
/** @deprecated Use `useCurrencyConfig` or `useCurrentCurrencyConfig` from `@deriv/hooks` package instead. */
@@ -478,8 +494,11 @@ type TUiStore = {
is_reports_visible: boolean;
is_route_modal_on: boolean;
is_language_settings_modal_on: boolean;
+ is_desktop: boolean;
+ is_app_disabled: boolean;
is_link_expired_modal_visible: boolean;
is_mobile: boolean;
+ is_tablet: boolean;
is_mobile_language_menu_open: boolean;
is_positions_drawer_on: boolean;
is_services_error_visible: boolean;
@@ -523,7 +542,6 @@ type TUiStore = {
toggleServicesErrorModal: (is_visible: boolean) => void;
toggleSetCurrencyModal: () => void;
toggleShouldShowRealAccountsList: (value: boolean) => void;
- is_tablet: boolean;
removeToast: (key: string) => void;
is_ready_to_deposit_modal_visible: boolean;
reports_route_tab_index: number;
@@ -540,6 +558,7 @@ type TUiStore = {
is_top_up_virtual_open: boolean;
is_top_up_virtual_in_progress: boolean;
is_top_up_virtual_success: boolean;
+ real_account_signup_target: string;
closeSuccessTopUpModal: () => void;
closeTopUpModal: () => void;
is_cfd_reset_password_modal_enabled: boolean;
@@ -548,6 +567,8 @@ type TUiStore = {
is_accounts_switcher_on: boolean;
openTopUpModal: () => void;
is_reset_trading_password_modal_visible: boolean;
+ real_account_signup: RealAccountSignupSettings;
+ resetRealAccountSignupParams: () => void;
setResetTradingPasswordModalOpen: () => void;
populateHeaderExtensions: (header_items: JSX.Element | null) => void;
populateSettingsExtensions: (menu_items: Array | null) => void;