From 4f4fe7583bb4ce64136e72d65634d017968d1d8b Mon Sep 17 00:00:00 2001 From: amir ali <129206554+amir-deriv@users.noreply.github.com> Date: Wed, 21 Feb 2024 10:59:17 +0800 Subject: [PATCH] [CRO] Amir/cro 333/ab test for onboarding toggle (#13545) * chore: add ab test for skip onboarding flow * chore: add test case for feature flag hook * chore: add mock of analytics package on onboarding * chore: resolve review comments * chore: update package version to 1.4.11 * chore: change var name * fix: show onboarding as normal after login * fix: onboarding ab test flow issue on normal scenario * chore: fix eslint error * chore: downgrade package version to 1.4.10 * chore: update lock --- __mocks__/globals.js | 8 ++ package-lock.json | 108 +++++++++--------- .../src/modules/onboarding/onboarding.tsx | 6 +- .../account-signup-modal.jsx | 14 +++ packages/hooks/package.json | 1 + .../useGrowthbookFeatureFlag.spec.tsx | 31 +++++ packages/hooks/src/index.ts | 1 + .../hooks/src/useGrowthbookFeatureFlag.ts | 27 +++++ 8 files changed, 140 insertions(+), 56 deletions(-) create mode 100644 packages/hooks/src/__tests__/useGrowthbookFeatureFlag.spec.tsx create mode 100644 packages/hooks/src/useGrowthbookFeatureFlag.ts diff --git a/__mocks__/globals.js b/__mocks__/globals.js index 097188c93e5e..8fa59529a33e 100644 --- a/__mocks__/globals.js +++ b/__mocks__/globals.js @@ -9,6 +9,14 @@ jest.mock('@deriv-com/analytics', () => ({ pageView: jest.fn(), reset: jest.fn(), setAttributes: jest.fn(), + getFeatureValue: jest.fn(), + getInstances: jest.fn().mockReturnValue({ + ab: { + GrowthBook: { + setRenderer: jest.fn(), + }, + }, + }), }, })); diff --git a/package-lock.json b/package-lock.json index f80738b6cb6b..d99f2a111074 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9754,9 +9754,9 @@ "integrity": "sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w==" }, "node_modules/@storybook/builder-webpack4/node_modules/@types/node": { - "version": "16.18.82", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz", - "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q==" + "version": "16.18.79", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz", + "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ==" }, "node_modules/@storybook/builder-webpack4/node_modules/@types/webpack": { "version": "4.41.38", @@ -11083,9 +11083,9 @@ } }, "node_modules/@storybook/builder-webpack5/node_modules/@types/node": { - "version": "16.18.82", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz", - "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q==" + "version": "16.18.79", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz", + "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ==" }, "node_modules/@storybook/builder-webpack5/node_modules/colorette": { "version": "1.4.0", @@ -11510,9 +11510,9 @@ } }, "node_modules/@storybook/core-common/node_modules/@types/node": { - "version": "16.18.82", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz", - "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q==" + "version": "16.18.79", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz", + "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ==" }, "node_modules/@storybook/core-common/node_modules/@webassemblyjs/ast": { "version": "1.9.0", @@ -12334,9 +12334,9 @@ } }, "node_modules/@storybook/core-server/node_modules/@types/node": { - "version": "16.18.82", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz", - "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q==" + "version": "16.18.79", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz", + "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ==" }, "node_modules/@storybook/core-server/node_modules/@types/webpack": { "version": "4.41.38", @@ -13270,9 +13270,9 @@ "integrity": "sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w==" }, "node_modules/@storybook/manager-webpack4/node_modules/@types/node": { - "version": "16.18.82", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz", - "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q==" + "version": "16.18.79", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz", + "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ==" }, "node_modules/@storybook/manager-webpack4/node_modules/@types/webpack": { "version": "4.41.38", @@ -14563,9 +14563,9 @@ } }, "node_modules/@storybook/manager-webpack5/node_modules/@types/node": { - "version": "16.18.82", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz", - "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q==" + "version": "16.18.79", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz", + "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ==" }, "node_modules/@storybook/manager-webpack5/node_modules/ansi-styles": { "version": "4.3.0", @@ -15077,9 +15077,9 @@ "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==" }, "node_modules/@storybook/react/node_modules/@types/node": { - "version": "16.18.82", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz", - "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q==" + "version": "16.18.79", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz", + "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ==" }, "node_modules/@storybook/react/node_modules/acorn": { "version": "7.4.1", @@ -41086,9 +41086,9 @@ } }, "node_modules/react-focus-lock": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.11.0.tgz", - "integrity": "sha512-y6Amxjo3T67R/7tYPSS2HMUEjW4IIfDAnpc6sBZ3Nm8gkFhgEGwTP7Zw/vkYOyvOZly0EwT9oc5ZM2XmknTGgw==", + "version": "2.9.7", + "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.9.7.tgz", + "integrity": "sha512-EfhX040SELLqnQ9JftqsmQCG49iByg8F5X5m19Er+n371OaETZ35dlNPZrLOOTlnnwD4c2Zv0KDgabDTc7dPHw==", "dependencies": { "@babel/runtime": "^7.0.0", "focus-lock": "^1.2.0", @@ -41108,9 +41108,9 @@ } }, "node_modules/react-focus-lock/node_modules/focus-lock": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-1.3.0.tgz", - "integrity": "sha512-J5/QDEBUXkELMuWyRSsXBRG1JZ156tBvTS+sv3Ks5xBNyKCQ6qFZAfT3ZEPL3JfFEOS5SB+bT/0Ha3zS07yfEw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-1.3.2.tgz", + "integrity": "sha512-kFI92jZVqa8rP4Yer2sLNlUDcOdEFxYum2tIIr4eCH0XF+pOmlg0xiY4tkbDmHJXt3phtbJoWs1L6PgUVk97rA==", "dependencies": { "tslib": "^2.0.3" }, @@ -57118,9 +57118,9 @@ "integrity": "sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w==" }, "@types/node": { - "version": "16.18.82", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz", - "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q==" + "version": "16.18.79", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz", + "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ==" }, "@types/webpack": { "version": "4.41.38", @@ -58168,9 +58168,9 @@ }, "dependencies": { "@types/node": { - "version": "16.18.82", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz", - "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q==" + "version": "16.18.79", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz", + "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ==" }, "colorette": { "version": "1.4.0", @@ -58466,9 +58466,9 @@ } }, "@types/node": { - "version": "16.18.82", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz", - "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q==" + "version": "16.18.79", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz", + "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ==" }, "@webassemblyjs/ast": { "version": "1.9.0", @@ -59141,9 +59141,9 @@ }, "dependencies": { "@types/node": { - "version": "16.18.82", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz", - "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q==" + "version": "16.18.79", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz", + "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ==" }, "@types/webpack": { "version": "4.41.38", @@ -59911,9 +59911,9 @@ "integrity": "sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w==" }, "@types/node": { - "version": "16.18.82", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz", - "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q==" + "version": "16.18.79", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz", + "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ==" }, "@types/webpack": { "version": "4.41.38", @@ -60936,9 +60936,9 @@ }, "dependencies": { "@types/node": { - "version": "16.18.82", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz", - "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q==" + "version": "16.18.79", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz", + "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ==" }, "ansi-styles": { "version": "4.3.0", @@ -61269,9 +61269,9 @@ "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==" }, "@types/node": { - "version": "16.18.82", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz", - "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q==" + "version": "16.18.79", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz", + "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ==" }, "acorn": { "version": "7.4.1", @@ -79599,9 +79599,9 @@ } }, "react-focus-lock": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.11.0.tgz", - "integrity": "sha512-y6Amxjo3T67R/7tYPSS2HMUEjW4IIfDAnpc6sBZ3Nm8gkFhgEGwTP7Zw/vkYOyvOZly0EwT9oc5ZM2XmknTGgw==", + "version": "2.9.7", + "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.9.7.tgz", + "integrity": "sha512-EfhX040SELLqnQ9JftqsmQCG49iByg8F5X5m19Er+n371OaETZ35dlNPZrLOOTlnnwD4c2Zv0KDgabDTc7dPHw==", "requires": { "@babel/runtime": "^7.0.0", "focus-lock": "^1.2.0", @@ -79612,9 +79612,9 @@ }, "dependencies": { "focus-lock": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-1.3.0.tgz", - "integrity": "sha512-J5/QDEBUXkELMuWyRSsXBRG1JZ156tBvTS+sv3Ks5xBNyKCQ6qFZAfT3ZEPL3JfFEOS5SB+bT/0Ha3zS07yfEw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-1.3.2.tgz", + "integrity": "sha512-kFI92jZVqa8rP4Yer2sLNlUDcOdEFxYum2tIIr4eCH0XF+pOmlg0xiY4tkbDmHJXt3phtbJoWs1L6PgUVk97rA==", "requires": { "tslib": "^2.0.3" } diff --git a/packages/appstore/src/modules/onboarding/onboarding.tsx b/packages/appstore/src/modules/onboarding/onboarding.tsx index d9eebba857c3..d8e8f71c3428 100644 --- a/packages/appstore/src/modules/onboarding/onboarding.tsx +++ b/packages/appstore/src/modules/onboarding/onboarding.tsx @@ -9,7 +9,6 @@ import { getTradingHubContents } from 'Constants/trading-hub-content'; import EmptyOnboarding from './empty-onboarding'; import { useStore, observer } from '@deriv/stores'; import { useTradersHubTracking } from 'Hooks/index'; -import { Analytics } from '@deriv-com/analytics'; type TOnboardingProps = { contents: Record< @@ -45,6 +44,9 @@ const Onboarding = observer(({ contents = getTradingHubContents() }: TOnboarding const has_active_real_account = useHasActiveRealAccount(); const steps_list = Object.keys(contents).filter(key => is_mt5_allowed || key !== 'step3'); + const url_params = new URLSearchParams(window.location.search); + const skip_onboarding_flow = url_params.get('skip-onboarding-flow') === 'true'; + const { trackOnboardingOpen, trackStepBack, trackStepForward, trackOnboardingClose, trackDotNavigation } = useTradersHubTracking(); @@ -130,7 +132,7 @@ const Onboarding = observer(({ contents = getTradingHubContents() }: TOnboarding return ; } - if (is_logged_in && is_from_signup_account && is_eu_user) { + if ((is_logged_in && is_from_signup_account && is_eu_user) || skip_onboarding_flow) { history.push(routes.traders_hub); } diff --git a/packages/core/src/App/Containers/AccountSignupModal/account-signup-modal.jsx b/packages/core/src/App/Containers/AccountSignupModal/account-signup-modal.jsx index 537aa6dcf4c4..2aba95cbd513 100644 --- a/packages/core/src/App/Containers/AccountSignupModal/account-signup-modal.jsx +++ b/packages/core/src/App/Containers/AccountSignupModal/account-signup-modal.jsx @@ -18,6 +18,7 @@ import ResidenceForm from '../SetResidenceModal/set-residence-form.jsx'; import validateSignupFields from './validate-signup-fields.jsx'; import 'Sass/app/modules/account-signup.scss'; +import { useGrowthbookFeatureFlag } from '@deriv/hooks'; const AccountSignup = ({ enableApp, @@ -41,6 +42,12 @@ const AccountSignup = ({ const [modded_state, setModdedState] = React.useState({}); const language = getLanguage(); + // Growthbook ab/test experiment with onboarding flow + const growthbook_ab_test_skip_onboarding_flow = useGrowthbookFeatureFlag({ + featureFlag: 'skip-onboarding-flow', + defaultValue: false, + }); + const checkResidenceIsBrazil = selected_country => selected_country && residence_list[indexOfSelection(selected_country)]?.value?.toLowerCase() === 'br'; @@ -126,6 +133,13 @@ const AccountSignup = ({ error_message: error, }); } else { + // ======== Growthbook ab/test experiment with onboarding flow ======== + const searchParams = new URLSearchParams(window.location.search); + searchParams.set('skip-onboarding-flow', growthbook_ab_test_skip_onboarding_flow); + + window.history.pushState(null, '', `${window.location.pathname}?${searchParams.toString()}`); + // ==================================================================== + isModalVisible(false); setIsFromSignupAccount(true); SessionStore.remove('signup_query_param'); diff --git a/packages/hooks/package.json b/packages/hooks/package.json index 06f2fdbdb49c..55c906c6b243 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -5,6 +5,7 @@ "main": "src/index.ts", "dependencies": { "@binary-com/binary-document-uploader": "^2.4.8", + "@deriv-com/analytics": "1.4.10", "@deriv/api": "^1.0.0", "@deriv/stores": "^1.0.0", "@deriv/utils": "^1.0.0", diff --git a/packages/hooks/src/__tests__/useGrowthbookFeatureFlag.spec.tsx b/packages/hooks/src/__tests__/useGrowthbookFeatureFlag.spec.tsx new file mode 100644 index 000000000000..109538c5199b --- /dev/null +++ b/packages/hooks/src/__tests__/useGrowthbookFeatureFlag.spec.tsx @@ -0,0 +1,31 @@ +import { renderHook } from '@testing-library/react-hooks'; +import useGrowthbookFeatureFlag from '../useGrowthbookFeatureFlag'; +import { Analytics } from '@deriv-com/analytics'; + +describe('useGrowthbookFeatureFlag', () => { + test('Should call getFeatureValue from the package', async () => { + const { result } = renderHook(() => + useGrowthbookFeatureFlag({ + defaultValue: false, + featureFlag: 'dummy-feature-flag', + }) + ); + + expect(result.current).toBe(false); + expect(Analytics.getFeatureValue).toHaveBeenCalled(); + expect(Analytics.getFeatureValue).toHaveBeenCalledWith('dummy-feature-flag', false); + }); + + test('The default value for the feature flag must be sent correctly to the package', async () => { + const { result } = renderHook(() => + useGrowthbookFeatureFlag({ + defaultValue: true, + featureFlag: 'dummy-feature-flag-1', + }) + ); + + expect(result.current).toBe(true); + expect(Analytics.getFeatureValue).toHaveBeenCalled(); + expect(Analytics.getFeatureValue).toHaveBeenCalledWith('dummy-feature-flag-1', true); + }); +}); diff --git a/packages/hooks/src/index.ts b/packages/hooks/src/index.ts index 9c869e414d54..8bb02b6544ed 100644 --- a/packages/hooks/src/index.ts +++ b/packages/hooks/src/index.ts @@ -76,3 +76,4 @@ export { default as useWalletMigration } from './useWalletMigration'; export { default as useWalletTransactions } from './useWalletTransactions'; export { default as useWalletTransfer } from './useWalletTransfer'; export { default as useWalletsList } from './useWalletsList'; +export { default as useGrowthbookFeatureFlag } from './useGrowthbookFeatureFlag'; diff --git a/packages/hooks/src/useGrowthbookFeatureFlag.ts b/packages/hooks/src/useGrowthbookFeatureFlag.ts new file mode 100644 index 000000000000..2aee50d87f56 --- /dev/null +++ b/packages/hooks/src/useGrowthbookFeatureFlag.ts @@ -0,0 +1,27 @@ +import { useState, useEffect } from 'react'; +import { Analytics } from '@deriv-com/analytics'; + +interface UseGrowthbookFeatureFlagArgs { + featureFlag: string; + defaultValue: T; +} + +const useGrowthbookFeatureFlag = ({ featureFlag, defaultValue }: UseGrowthbookFeatureFlagArgs) => { + const [featureFlagValue, setFeatureFlagValue] = useState(defaultValue); + + useEffect(() => { + const value = (Analytics?.getFeatureValue(featureFlag, defaultValue) || defaultValue) as T; + setFeatureFlagValue(value); + + // Set the renderer for GrowthBook to update the value when the feature flag changes + Analytics.getInstances()?.ab?.GrowthBook?.setRenderer(() => { + const value = (Analytics?.getFeatureValue(featureFlag, defaultValue) || defaultValue) as T; + + setFeatureFlagValue(value); + }); + }, [featureFlag, defaultValue]); + + return featureFlagValue; +}; + +export default useGrowthbookFeatureFlag;