diff --git a/packages/core/src/App/AppContent.tsx b/packages/core/src/App/AppContent.tsx index 89eee7d3fc94..2b3b46ee4979 100644 --- a/packages/core/src/App/AppContent.tsx +++ b/packages/core/src/App/AppContent.tsx @@ -6,6 +6,7 @@ import { useGrowthbookGetFeatureValue, useGrowthbookIsOn, useIntercom, + useIsHubRedirectionEnabled, useLiveChat, useOauth2, useSilentLoginAndLogout, @@ -62,6 +63,9 @@ const AppContent: React.FC<{ passthrough: unknown }> = observer(({ passthrough } await logout(); }, }); + const { isChangingToHubAppId } = useIsHubRedirectionEnabled(); + + const is_app_id_set = localStorage.getItem('config.app_id'); const [isWebPasskeysFFEnabled, isGBLoaded] = useGrowthbookIsOn({ featureFlag: 'web_passkeys', @@ -108,6 +112,13 @@ const AppContent: React.FC<{ passthrough: unknown }> = observer(({ passthrough } useFreshChat(token); useIntercom(token); + React.useEffect(() => { + if (isChangingToHubAppId && !is_app_id_set) { + const app_id = process.env.NODE_ENV === 'production' ? 61554 : 53503; + localStorage.setItem('config.app_id', app_id.toString()); + } + }, [isChangingToHubAppId, is_app_id_set]); + React.useEffect(() => { switchLanguage(current_language); }, [current_language, switchLanguage]); diff --git a/packages/core/src/App/app.jsx b/packages/core/src/App/app.jsx index 9afd1ed62fca..400ddc2dfeb4 100644 --- a/packages/core/src/App/app.jsx +++ b/packages/core/src/App/app.jsx @@ -1,28 +1,33 @@ import React from 'react'; -import WS from 'Services/ws-methods'; -import PropTypes from 'prop-types'; +import { useTranslation, withTranslation } from 'react-i18next'; import { BrowserRouter as Router } from 'react-router-dom'; -import { Analytics } from '@deriv-com/analytics'; -import { BreakpointProvider } from '@deriv-com/quill-ui'; +import PropTypes from 'prop-types'; + import { APIProvider } from '@deriv/api'; import { CashierStore } from '@deriv/cashier'; import { CFDStore } from '@deriv/cfd'; import { Loading } from '@deriv/components'; import { - POIProvider, initFormErrorMessages, + POIProvider, setSharedCFDText, setUrlLanguage, setWebsocket, useOnLoadTranslation, } from '@deriv/shared'; -import { StoreProvider, P2PSettingsProvider } from '@deriv/stores'; +import { P2PSettingsProvider, StoreProvider } from '@deriv/stores'; import { getLanguage, initializeTranslations } from '@deriv/translations'; -import { withTranslation, useTranslation } from 'react-i18next'; -import { initializeI18n, TranslationProvider, getInitialLanguage } from '@deriv-com/translations'; +import { Analytics } from '@deriv-com/analytics'; +import { BreakpointProvider } from '@deriv-com/quill-ui'; +import { getInitialLanguage, initializeI18n, TranslationProvider } from '@deriv-com/translations'; + +import WS from 'Services/ws-methods'; + import { CFD_TEXT } from '../Constants/cfd-text'; import { FORM_ERROR_MESSAGES } from '../Constants/form-error-messages'; + import AppContent from './AppContent'; + import 'Sass/app.scss'; const AppWithoutTranslation = ({ root_store }) => { diff --git a/packages/hooks/src/__tests__/useIsHubRedirectionEnabled.spec.tsx b/packages/hooks/src/__tests__/useIsHubRedirectionEnabled.spec.tsx new file mode 100644 index 000000000000..5f2859afcb41 --- /dev/null +++ b/packages/hooks/src/__tests__/useIsHubRedirectionEnabled.spec.tsx @@ -0,0 +1,64 @@ +import { useClientCountry, useSettings } from '@deriv/api'; +import { renderHook } from '@testing-library/react-hooks'; + +import useGrowthbookGetFeatureValue from '../useGrowthbookGetFeatureValue'; +import useIsHubRedirectionEnabled from '../useIsHubRedirectionEnabled'; + +jest.mock('@deriv/api', () => ({ + ...jest.requireActual('@deriv/api'), + useClientCountry: jest.fn(() => ({ data: 'US' })), + useSettings: jest.fn(() => ({ data: { citizen: 'US' } })), +})); + +jest.mock('../useGrowthbookGetFeatureValue', () => + jest.fn(() => [ + { + hub_enabled_country_list: [''], + }, + ]) +); + +describe('useIsHubRedirectionEnabled', () => { + it('should return initial state correctly', () => { + const { result } = renderHook(() => useIsHubRedirectionEnabled()); + + expect(result.current.isHubRedirectionEnabled).toBe(false); + expect(result.current.isChangingToHubAppId).toBe(false); + }); + + it('should return false if client country is not in the hub enabled list', () => { + (useClientCountry as jest.Mock).mockReturnValue({ data: 'UK' }); + (useSettings as jest.Mock).mockReturnValue({ data: { citizen: 'UK' } }); + (useGrowthbookGetFeatureValue as jest.Mock).mockReturnValue([ + { + hub_enabled_country_list: ['US', 'AU'], + }, + ]); + const { result } = renderHook(() => useIsHubRedirectionEnabled()); + expect(result.current.isHubRedirectionEnabled).toBe(false); + }); + + it('should return true if client country is in the hub enabled list', () => { + (useClientCountry as jest.Mock).mockReturnValue({ data: 'UK' }); + (useSettings as jest.Mock).mockReturnValue({ data: { citizen: 'UK' } }); + (useGrowthbookGetFeatureValue as jest.Mock).mockReturnValue([ + { + hub_enabled_country_list: ['US', 'AU', 'UK'], + }, + ]); + const { result } = renderHook(() => useIsHubRedirectionEnabled()); + expect(result.current.isHubRedirectionEnabled).toBe(true); + }); + + it('should return isChangingToHubAppId true if client country is in the hub enabled list but not in the citizen list', () => { + (useClientCountry as jest.Mock).mockReturnValue({ data: 'UK' }); + (useSettings as jest.Mock).mockReturnValue({ data: { citizen: 'MY' } }); + (useGrowthbookGetFeatureValue as jest.Mock).mockReturnValue([ + { + hub_enabled_country_list: ['US', 'AU', 'UK'], + }, + ]); + const { result } = renderHook(() => useIsHubRedirectionEnabled()); + expect(result.current.isChangingToHubAppId).toBe(true); + }); +}); diff --git a/packages/hooks/src/index.ts b/packages/hooks/src/index.ts index 329c45cf7c40..5defd2e84bdf 100644 --- a/packages/hooks/src/index.ts +++ b/packages/hooks/src/index.ts @@ -39,6 +39,7 @@ export { default as useInputATMFormatter } from './useInputATMFormatter'; export { default as useInputDecimalFormatter } from './useInputDecimalFormatter'; export { default as useIsAccountStatusPresent } from './useIsAccountStatusPresent'; export { default as useIsClientHighRiskForMT5 } from './useIsClientHighRiskForMT5'; +export { default as useIsHubRedirectionEnabled } from './useIsHubRedirectionEnabled'; export { default as useIsP2PEnabled } from './useIsP2PEnabled'; export { default as useIsRealAccountNeededForCashier } from './useIsRealAccountNeededForCashier'; export { default as useIsRtl } from './useIsRtl'; diff --git a/packages/hooks/src/useIsHubRedirectionEnabled.ts b/packages/hooks/src/useIsHubRedirectionEnabled.ts new file mode 100644 index 000000000000..d9bd376825ea --- /dev/null +++ b/packages/hooks/src/useIsHubRedirectionEnabled.ts @@ -0,0 +1,34 @@ +import { useClientCountry, useSettings } from '@deriv/api'; + +import useGrowthbookGetFeatureValue from './useGrowthbookGetFeatureValue'; + +type THubEnabledCountryList = { + hub_enabled_country_list: string[]; +}; + +const useIsHubRedirectionEnabled = () => { + const [hubEnabledCountryList] = useGrowthbookGetFeatureValue({ + featureFlag: 'hub_enabled_country_list', + }); + const { data: clientCountry } = useClientCountry(); + const { data: accountSettings } = useSettings(); + const { citizen } = accountSettings; + + const isHubRedirectionEnabled = + typeof hubEnabledCountryList === 'object' && + hubEnabledCountryList !== null && + Array.isArray((hubEnabledCountryList as THubEnabledCountryList).hub_enabled_country_list) && + citizen && + (hubEnabledCountryList as THubEnabledCountryList).hub_enabled_country_list.includes(citizen); + + const isChangingToHubAppId = + typeof hubEnabledCountryList === 'object' && + hubEnabledCountryList !== null && + Array.isArray((hubEnabledCountryList as THubEnabledCountryList).hub_enabled_country_list) && + clientCountry && + (hubEnabledCountryList as THubEnabledCountryList).hub_enabled_country_list.includes(clientCountry); + + return { isHubRedirectionEnabled, isChangingToHubAppId }; +}; + +export default useIsHubRedirectionEnabled;