diff --git a/packages/account/src/Components/forms/__tests__/personal-details-form.spec.tsx b/packages/account/src/Components/forms/__tests__/personal-details-form.spec.tsx index 32c2a1008774..bf9bd8494465 100644 --- a/packages/account/src/Components/forms/__tests__/personal-details-form.spec.tsx +++ b/packages/account/src/Components/forms/__tests__/personal-details-form.spec.tsx @@ -5,12 +5,18 @@ import userEvent from '@testing-library/user-event'; import PersonalDetailsForm from '../personal-details-form'; import { APIProvider } from '@deriv/api'; +import { useGetPhoneNumberList } from '@deriv/hooks'; jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), Link: () =>
Mocked Link Component
, })); +jest.mock('@deriv/hooks', () => ({ + ...jest.requireActual('@deriv/hooks'), + useGetPhoneNumberList: jest.fn(), +})); + describe('PersonalDetailsForm', () => { const mock_props = { editable_fields: ['salutation'], @@ -20,6 +26,14 @@ describe('PersonalDetailsForm', () => { ], }; + beforeEach(() => { + (useGetPhoneNumberList as jest.Mock).mockReturnValue({ + legacy_core_countries_list: [ + { text: 'United States (+1)', value: '+1', id: '1_US', carriers: [], disabled: false }, + ], + }); + }); + const renderComponent = () => { render( @@ -37,7 +51,7 @@ describe('PersonalDetailsForm', () => { expect(screen.getByRole('radio', { name: 'Ms' })).toBeInTheDocument(); }); - it('should select the respective salutation when radio button is clicked', () => { + it('should select the respective salutation when radio button is clicked', async () => { renderComponent(); const mr_radio_input = screen.getByRole('radio', { name: 'Mr' }); @@ -46,11 +60,11 @@ describe('PersonalDetailsForm', () => { expect(mr_radio_input).not.toBeChecked(); expect(ms_radio_input).not.toBeChecked(); - userEvent.click(mr_radio_input); + await userEvent.click(mr_radio_input); expect(mr_radio_input).toBeChecked(); expect(ms_radio_input).not.toBeChecked(); - userEvent.click(ms_radio_input); + await userEvent.click(ms_radio_input); expect(mr_radio_input).not.toBeChecked(); expect(ms_radio_input).toBeChecked(); }); diff --git a/packages/account/src/Components/forms/form-fields/form-input-field.tsx b/packages/account/src/Components/forms/form-fields/form-input-field.tsx index 5571054ccf8e..74e1f2f8882e 100644 --- a/packages/account/src/Components/forms/form-fields/form-input-field.tsx +++ b/packages/account/src/Components/forms/form-fields/form-input-field.tsx @@ -33,10 +33,13 @@ const FormInputField = ({ name, warn, ...rest }: FormInputFieldProps) => ( autoComplete='off' error={touched[field.name] && errors[field.name] ? errors[field.name] : undefined} warn={warn} - onChange={(e: React.ChangeEvent) => { - !touched[field.name] && setFieldTouched(field.name); - field.onChange(e); - }} + onChange={ + rest.onChange || + ((e: React.ChangeEvent) => { + !touched[field.name] && setFieldTouched(field.name); + field.onChange(e); + }) + } /> ); }} diff --git a/packages/account/src/Components/forms/personal-details-form.jsx b/packages/account/src/Components/forms/personal-details-form.jsx index a0172b31607b..2b816accd8ea 100644 --- a/packages/account/src/Components/forms/personal-details-form.jsx +++ b/packages/account/src/Components/forms/personal-details-form.jsx @@ -2,17 +2,20 @@ import React from 'react'; import { Link } from 'react-router-dom'; import clsx from 'clsx'; import { Field, useFormikContext } from 'formik'; + import { Autocomplete, Checkbox, InlineMessage, RadioGroup, SelectNative, Text } from '@deriv/components'; +import { useGetPhoneNumberList, useGrowthbookGetFeatureValue, useResidenceList } from '@deriv/hooks'; import { routes, validPhone } from '@deriv/shared'; import { Localize, localize } from '@deriv/translations'; +import { useDevice } from '@deriv-com/ui'; + import { isFieldImmutable, verifyFields } from '../../Helpers/utils'; import FormBodySection from '../form-body-section'; -import { DateOfBirthField, FormInputField } from './form-fields'; import FormSubHeader from '../form-sub-header'; import InlineNoteWithIcon from '../inline-note-with-icon'; -import { useResidenceList } from '@deriv/hooks'; -import { useDevice } from '@deriv-com/ui'; + import AccountOpeningReasonField from './form-fields/account-opening-reason'; +import { DateOfBirthField, FormInputField } from './form-fields'; const PersonalDetailsForm = props => { const { isDesktop } = useDevice(); @@ -40,10 +43,16 @@ const PersonalDetailsForm = props => { // need to put this check related to DIEL clients const is_svg_only = is_svg && !is_eu_user; + const [isCountryCodeDropdownEnabled, isCountryCodeLoaded] = useGrowthbookGetFeatureValue({ + featureFlag: 'enable_country_code_dropdown', + }); + const { errors, touched, values, setFieldValue, handleChange, handleBlur } = useFormikContext(); const { data: residence_list } = useResidenceList(); + const { legacy_core_countries_list } = useGetPhoneNumberList(); + const getNameAndDobLabels = () => { const is_asterisk_needed = is_svg || is_eu_user || is_rendered_for_onfido || is_rendered_for_idv; const first_name_label = is_asterisk_needed ? localize('First name*') : localize('First name'); @@ -381,6 +390,10 @@ const PersonalDetailsForm = props => { )} {!is_svg_only && 'phone' in values && ( { {'phone' in values && ( { export default PersonalDetailsForm; -const PhoneField = ({ value, editable_fields, has_real_account, required }) => ( - = 9 && value?.length <= 35) - } - maxLength={50} - data-testid='phone' - /> +const PhoneField = ({ + handleChange, + setFieldValue, + country_code_list, + value, + editable_fields, + has_real_account, + required, + is_country_code_dropdown_enabled, +}) => ( + +
+ {is_country_code_dropdown_enabled && ( + = 9 && value?.length <= 35) + } + country_code_list={country_code_list} + required + /> + )} + = 9 && value?.length <= 35) + } + {...(is_country_code_dropdown_enabled && { + onChange: e => { + const phone_number = e.target.value.replace(/\D/g, ''); + setFieldValue('phone', phone_number, true); + }, + })} + maxLength={50} + data-testid='phone' + /> +
+
); +const CountryCodeDropdown = ({ handleChange, setFieldValue, disabled, country_code_list, required }) => { + const { isDesktop } = useDevice(); + return ( + + {({ field, meta }) => ( + + {isDesktop ? ( + { + setFieldValue('calling_country_code', country_list.value, true); + }} + required + data-testid='calling_country_code' + /> + ) : ( + { + handleChange(e); + setFieldValue('calling_country_code', e.target.value, true); + }} + {...field} + list_portal_id='modal_root' + required + is_country_code_dropdown + should_hide_disabled_options={false} + data_testid='calling_country_code_mobile' + /> + )} + + )} + + ); +}; + const PlaceOfBirthField = ({ handleChange, setFieldValue, disabled, residence_list, required }) => { const { isDesktop } = useDevice(); return ( diff --git a/packages/account/src/Components/personal-details/__tests__/personal-details.spec.tsx b/packages/account/src/Components/personal-details/__tests__/personal-details.spec.tsx index e997a07d0422..4669730c2e2c 100644 --- a/packages/account/src/Components/personal-details/__tests__/personal-details.spec.tsx +++ b/packages/account/src/Components/personal-details/__tests__/personal-details.spec.tsx @@ -10,6 +10,7 @@ import { FormikErrors } from 'formik'; import { getIDVFormValidationSchema } from '../../../Configs/kyc-validation-config'; import { useDevice } from '@deriv-com/ui'; import { APIProvider } from '@deriv/api'; +import { useGrowthbookGetFeatureValue } from '@deriv/hooks'; jest.mock('@deriv-com/ui', () => ({ ...jest.requireActual('@deriv-com/ui'), @@ -44,6 +45,11 @@ jest.mock('@deriv-com/analytics', () => ({ }, })); +jest.mock('@deriv/hooks', () => ({ + ...jest.requireActual('@deriv/hooks'), + useGrowthbookGetFeatureValue: jest.fn(), +})); + type TPersonalDetailsSectionForm = ComponentProps['value']; const mock_warnings = {}; @@ -266,6 +272,10 @@ describe('', () => { real_account_signup_target: '', }; + beforeEach(() => { + (useGrowthbookGetFeatureValue as jest.Mock).mockReturnValue([false, false]); + }); + afterEach(() => { jest.clearAllMocks(); }); @@ -440,6 +450,19 @@ describe('', () => { expect(mrs_radio_btn).not.toBeChecked(); }); + it('should display country code dropdown when isCountryCodeDropdownEnabled is true ', () => { + (useGrowthbookGetFeatureValue as jest.Mock).mockReturnValue([true, true]); + renderwithRouter({}); + + expect(screen.getByText(/code\*/i)).toBeInTheDocument(); + }); + + it('should not display country code dropdown when isCountryCodeDropdownEnabled is false ', () => { + renderwithRouter({}); + + expect(screen.queryByText(/code\*/i)).not.toBeInTheDocument(); + }); + it('should display the correct field details ', () => { renderwithRouter({}); diff --git a/packages/account/src/Components/personal-details/personal-details.tsx b/packages/account/src/Components/personal-details/personal-details.tsx index 93a02aa4d8c3..123c8969fe34 100644 --- a/packages/account/src/Components/personal-details/personal-details.tsx +++ b/packages/account/src/Components/personal-details/personal-details.tsx @@ -17,6 +17,7 @@ import { TIDVFormValues, TListItem, TPersonalDetailsBaseForm } from '../../Types import { GetAccountStatus, GetSettings, ResidenceList } from '@deriv/api-types'; import { getPersonalDetailsBaseValidationSchema } from '../../Configs/user-profile-validation-config'; import { getIDVFormValidationSchema } from '../../Configs/kyc-validation-config'; +import { useGrowthbookGetFeatureValue } from '@deriv/hooks'; type TPersonalDetailsSectionForm = Partial & { confirmation_checkbox?: boolean; @@ -79,6 +80,9 @@ const PersonalDetails = observer( } = useStore(); const { account_status, account_settings, residence, real_account_signup_target } = props; + const [isCountryCodeDropdownEnabled, isCountryCodeLoaded] = useGrowthbookGetFeatureValue({ + featureFlag: 'enable_country_code_dropdown', + }); const { isDesktop } = useDevice(); const handleCancel = (values: TPersonalDetailsSectionForm) => { const current_step = getCurrentStep() - 1; @@ -124,11 +128,15 @@ const PersonalDetails = observer( const schema = useMemo( () => is_rendered_for_idv - ? getPersonalDetailsBaseValidationSchema(real_account_signup_target).concat( - getIDVFormValidationSchema() - ) - : getPersonalDetailsBaseValidationSchema(real_account_signup_target), - [is_rendered_for_idv, real_account_signup_target] + ? getPersonalDetailsBaseValidationSchema( + real_account_signup_target, + isCountryCodeLoaded && isCountryCodeDropdownEnabled + ).concat(getIDVFormValidationSchema()) + : getPersonalDetailsBaseValidationSchema( + real_account_signup_target, + isCountryCodeLoaded && isCountryCodeDropdownEnabled + ), + [is_rendered_for_idv, real_account_signup_target, isCountryCodeLoaded, isCountryCodeDropdownEnabled] ); /* diff --git a/packages/account/src/Components/poi/poi-confirm-with-example-form-container/__tests__/poi-confirm-with-example-form-container.spec.tsx b/packages/account/src/Components/poi/poi-confirm-with-example-form-container/__tests__/poi-confirm-with-example-form-container.spec.tsx index 0b50d02ebc77..44c601e51a5b 100644 --- a/packages/account/src/Components/poi/poi-confirm-with-example-form-container/__tests__/poi-confirm-with-example-form-container.spec.tsx +++ b/packages/account/src/Components/poi/poi-confirm-with-example-form-container/__tests__/poi-confirm-with-example-form-container.spec.tsx @@ -4,12 +4,18 @@ import { act, render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import PoiConfirmWithExampleFormContainer from '../poi-confirm-with-example-form-container'; import { APIProvider } from '@deriv/api'; +import { useGetPhoneNumberList } from '@deriv/hooks'; jest.mock('@deriv/quill-icons', () => ({ ...jest.requireActual('@deriv/quill-icons'), DerivLightNameDobPoiIcon: () => 'DerivLightNameDobPoiIcon', })); +jest.mock('@deriv/hooks', () => ({ + ...jest.requireActual('@deriv/hooks'), + useGetPhoneNumberList: jest.fn(), +})); + jest.mock('@deriv/shared', () => ({ ...jest.requireActual('@deriv/shared'), isDesktop: jest.fn(() => true), @@ -46,6 +52,11 @@ jest.mock('@deriv/shared', () => ({ describe('', () => { beforeAll(() => { (ReactDOM.createPortal as jest.Mock) = jest.fn(element => element); + (useGetPhoneNumberList as jest.Mock).mockReturnValue({ + legacy_core_countries_list: [ + { text: 'United States (+1)', value: '+1', id: '1_US', carriers: [], disabled: false }, + ], + }); }); afterEach(() => { (ReactDOM.createPortal as jest.Mock).mockClear(); @@ -71,7 +82,7 @@ describe('', () => { expect(await screen.findByText('DerivLightNameDobPoiIcon')).toBeInTheDocument(); expect(screen.getByText(clarification_message)).toBeInTheDocument(); const checkbox_el: HTMLInputElement = screen.getByRole('checkbox'); - expect(checkbox_el.checked).toBeFalsy(); + expect(checkbox_el).not.toBeChecked(); const input_fields: HTMLInputElement[] = screen.getAllByRole('textbox'); expect(input_fields).toHaveLength(3); @@ -84,21 +95,21 @@ describe('', () => { renderComponent({}); const checkbox_el: HTMLInputElement = await screen.findByRole('checkbox'); - expect(checkbox_el.checked).toBeFalsy(); + expect(checkbox_el).not.toBeChecked(); const input_fields: HTMLInputElement[] = screen.getAllByRole('textbox'); const first_name_input = input_fields[0]; const last_name_input = input_fields[1]; const dob_input = input_fields[2]; - expect(first_name_input.value).toBe('test first name'); - expect(last_name_input.value).toBe('test last name'); - expect(dob_input.value).toBe('2003-08-02'); + expect(first_name_input).toHaveValue('test first name'); + expect(last_name_input).toHaveValue('test last name'); + expect(dob_input).toHaveValue('2003-08-02'); - userEvent.clear(first_name_input); - userEvent.clear(last_name_input); - userEvent.type(first_name_input, 'new test first name'); - userEvent.type(last_name_input, 'new test last name'); + await userEvent.clear(first_name_input); + await userEvent.clear(last_name_input); + await userEvent.type(first_name_input, 'new test first name'); + await userEvent.type(last_name_input, 'new test last name'); await waitFor(() => { expect(first_name_input.value).toBe('new test first name'); @@ -106,7 +117,7 @@ describe('', () => { }); const button_el = screen.getByRole('button'); - userEvent.click(button_el); + await userEvent.click(button_el); await userEvent.click(button_el); act(() => { jest.advanceTimersByTime(500); diff --git a/packages/account/src/Configs/personal-details-config.ts b/packages/account/src/Configs/personal-details-config.ts index 80d3f3cfe20e..a7a0a1a2d88a 100644 --- a/packages/account/src/Configs/personal-details-config.ts +++ b/packages/account/src/Configs/personal-details-config.ts @@ -13,12 +13,14 @@ type TPersonalDetailsConfig = { }; residence: string; account_status: GetAccountStatus; + selected_phone_code: string; }; export const personal_details_config = ({ residence_list, account_settings, real_account_signup_target, + selected_phone_code, }: TPersonalDetailsConfig): TSchema => { if (!residence_list || !account_settings) { return {}; @@ -61,6 +63,10 @@ export const personal_details_config = ({ residence_list.find(item => item.value === account_settings.citizen)?.text) || '', }, + calling_country_code: { + supported_in: ['svg', 'maltainvest'], + default_value: selected_phone_code ?? account_settings?.calling_country_code, + }, phone: { supported_in: ['svg', 'maltainvest'], default_value: account_settings.phone ?? '', @@ -102,6 +108,7 @@ const personalDetailsConfig = ( residence_list, account_settings, account_status, + selected_phone_code, residence, }: TPersonalDetailsConfig, PersonalDetails: T @@ -112,6 +119,7 @@ const personalDetailsConfig = ( real_account_signup_target, residence, account_status, + selected_phone_code, }); const disabled_items = account_settings.immutable_fields; return { diff --git a/packages/core/src/App/Containers/RealAccountSignup/__tests__/account-wizard.spec.tsx b/packages/core/src/App/Containers/RealAccountSignup/__tests__/account-wizard.spec.tsx index 1503d1c9fbfa..f63d86747849 100644 --- a/packages/core/src/App/Containers/RealAccountSignup/__tests__/account-wizard.spec.tsx +++ b/packages/core/src/App/Containers/RealAccountSignup/__tests__/account-wizard.spec.tsx @@ -1,12 +1,13 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; -import { useIsClientHighRiskForMT5 } from '@deriv/hooks'; +import { useGetPhoneNumberList, useIsClientHighRiskForMT5 } from '@deriv/hooks'; import { StoreProvider, mockStore } from '@deriv/stores'; import AccountWizard from '../account-wizard'; jest.mock('@deriv/hooks', () => ({ ...jest.requireActual('@deriv/hooks'), useIsClientHighRiskForMT5: jest.fn(), + useGetPhoneNumberList: jest.fn(), })); const mockUseIsClientHighRiskForMT5 = useIsClientHighRiskForMT5 as jest.MockedFunction< @@ -69,6 +70,11 @@ jest.mock('../account-wizard-form', () => ({ describe('', () => { beforeEach(() => { mockUseIsClientHighRiskForMT5.mockReturnValue(false); + (useGetPhoneNumberList as jest.Mock).mockReturnValue({ + legacy_core_countries_list: [ + { text: 'United States (+1)', value: '+1', id: '1_US', carriers: [], disabled: false }, + ], + }); }); const store = mockStore({ diff --git a/packages/core/src/App/Containers/RealAccountSignup/account-wizard.jsx b/packages/core/src/App/Containers/RealAccountSignup/account-wizard.jsx index 92147389375a..0744091ebaf8 100644 --- a/packages/core/src/App/Containers/RealAccountSignup/account-wizard.jsx +++ b/packages/core/src/App/Containers/RealAccountSignup/account-wizard.jsx @@ -10,7 +10,7 @@ import { observer, useStore } from '@deriv/stores'; import AcceptRiskForm from './accept-risk-form.jsx'; import LoadingModal from './real-account-signup-loader.jsx'; import { getItems } from './account-wizard-form'; -import { useResidenceSelfDeclaration, useGrowthbookGetFeatureValue } from '@deriv/hooks'; +import { useResidenceSelfDeclaration, useGrowthbookGetFeatureValue, useGetPhoneNumberList } from '@deriv/hooks'; import 'Sass/details-form.scss'; import { Analytics } from '@deriv-com/analytics'; @@ -57,11 +57,21 @@ const StepperHeader = ({ has_target, has_real_account, items, getCurrentStep, ge const AccountWizard = observer(props => { const { client, notifications, ui, traders_hub } = useStore(); + const [isCountryCodeDropdownEnabled, isCountryCodeLoaded] = useGrowthbookGetFeatureValue({ + featureFlag: 'enable_country_code_dropdown', + }); + const { selected_phone_code } = useGetPhoneNumberList(); + + const is_phone_number_required = client.account_settings.immutable_fields.includes('phone'); + const { is_eu_user } = traders_hub; const modifiedProps = { ...props, - account_settings: client.account_settings, + account_settings: { + ...client.account_settings, + ...(isCountryCodeLoaded && isCountryCodeDropdownEnabled && { calling_country_code: '' }), + }, account_status: client.account_status, fetchAccountSettings: client.fetchAccountSettings, fetchResidenceList: client.fetchResidenceList, @@ -146,7 +156,15 @@ const AccountWizard = observer(props => { const get_items_props = { ...modifiedProps, + selected_phone_code, }; + React.useEffect(() => { + if (selected_phone_code && isCountryCodeLoaded && isCountryCodeDropdownEnabled) { + const updated_items = getItems(get_items_props); + setStateItems(updated_items); + setRealAccountSignupFormData(updated_items); + } + }, [selected_phone_code, setRealAccountSignupFormData, isCountryCodeLoaded, isCountryCodeDropdownEnabled]); React.useEffect(() => { setIsTradingAssessmentForNewUserEnabled(true); @@ -179,7 +197,7 @@ const AccountWizard = observer(props => { React.useEffect(() => { if (residence_list.length) { - const setDefaultPhone = country_code => { + const setDefaultPhone = () => { let items; if (state_items.length) { items = state_items; @@ -187,15 +205,15 @@ const AccountWizard = observer(props => { items = getItems(get_items_props); } - if (items.length > 1 && 'phone' in items[1]?.form_value) { - items[1].form_value.phone = items[1].form_value.phone || country_code || ''; + if (items.length > 1 && 'phone' in items[1]?.form_value && !isCountryCodeDropdownEnabled) { + items[1].form_value.phone = items[1].form_value.phone || ''; setStateItems(items); setRealAccountSignupFormData(items); } }; getCountryCode(residence_list).then(setDefaultPhone); } - }, [residence_list, setRealAccountSignupFormData]); + }, [residence_list, setRealAccountSignupFormData, isCountryCodeDropdownEnabled]); const fetchFromStorage = () => { const stored_items = localStorage.getItem('real_account_signup_wizard'); @@ -227,6 +245,9 @@ const AccountWizard = observer(props => { : original_form_values[current]; return acc; }, {}); + if (values.calling_country_code && values.phone) { + values.phone = values.calling_country_code + values.phone; + } if (values.date_of_birth) { values.date_of_birth = toMoment(values.date_of_birth).format('YYYY-MM-DD'); } @@ -301,6 +322,11 @@ const AccountWizard = observer(props => { delete clone?.tax_identification_confirm; delete clone?.agreed_tos; delete clone?.confirmation_checkbox; + delete clone?.calling_country_code; + + if (is_phone_number_required && clone?.phone) { + delete clone.phone; + } if (is_residence_self_declaration_required && clone?.resident_self_declaration) clone.resident_self_declaration = 1; @@ -390,6 +416,7 @@ const AccountWizard = observer(props => { const createRealAccount = (payload = undefined) => { setLoading(true); const form_data = { ...form_values() }; + delete form_data?.calling_country_code; /** * Remove document_type from payload if it is not present (For Non IDV supporting countries) */ diff --git a/packages/core/src/sass/app/_common/components/account-common.scss b/packages/core/src/sass/app/_common/components/account-common.scss index 07da40141b3f..185623909839 100644 --- a/packages/core/src/sass/app/_common/components/account-common.scss +++ b/packages/core/src/sass/app/_common/components/account-common.scss @@ -83,7 +83,9 @@ &__status-message { background-color: var(--transparent-correct-message); justify-content: flex-start; - transition: transform 0.35s ease, opacity 0.35s linear; + transition: + transform 0.35s ease, + opacity 0.35s linear; transform-origin: top; opacity: 1; width: 98%; @@ -160,7 +162,9 @@ } &_wrapper { - transition: transform 0.35s ease, opacity 0.35s linear; + transition: + transform 0.35s ease, + opacity 0.35s linear; transform-origin: top; opacity: 1; padding: 1.6rem; @@ -244,6 +248,35 @@ margin-top: 2rem; } + &__phone-container { + display: flex; + .dc-autocomplete { + width: 40%; + .dc-input__container { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + } + + @include mobile-or-tablet-screen { + .dc-select-native { + width: 40%; + + &__container { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + } + } + + &--input { + .dc-input__container { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + } + } + &__section { display: grid; diff --git a/packages/hooks/src/useGetPhoneNumberList.ts b/packages/hooks/src/useGetPhoneNumberList.ts index 057e5f8cff5f..bbf1828d6756 100644 --- a/packages/hooks/src/useGetPhoneNumberList.ts +++ b/packages/hooks/src/useGetPhoneNumberList.ts @@ -1,4 +1,4 @@ -import { useCallback } from 'react'; +import { useCallback, useMemo } from 'react'; import { useQuery } from '@deriv/api'; import { useStore } from '@deriv/stores'; @@ -57,13 +57,17 @@ const useGetPhoneNumberList = () => { carriers: country.carriers, })); - const legacy_core_countries_list = countries?.map(country => ({ - text: `${country.display_name} (${country.calling_country_code})`, - value: country.calling_country_code, - id: `${country.calling_country_code}_${country.country_code}`, - carriers: country.carriers, - disabled: false, - })); + const legacy_core_countries_list = useMemo( + () => + countries?.map(country => ({ + text: `${country.display_name} (${country.calling_country_code})`, + value: country.calling_country_code, + id: `${country.calling_country_code}_${country.country_code}`, + carriers: country.carriers, + disabled: false, + })), + [countries] + ); //@ts-expect-error will remove this once the account_settings is updated const selected_phone_code = account_settings?.calling_country_code || getSelectedPhoneCode();