diff --git a/__mocks__/globals.js b/__mocks__/globals.js index fb9470c7a3f2..e1a0f88cb921 100644 --- a/__mocks__/globals.js +++ b/__mocks__/globals.js @@ -8,6 +8,7 @@ jest.mock('@deriv/analytics', () => ({ trackEvent: jest.fn(), pageView: jest.fn(), reset: jest.fn(), + setAttributes: jest.fn(), }, })); diff --git a/package-lock.json b/package-lock.json index c597141cc2bc..11ef438b46ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@contentpass/zxcvbn": "^4.4.3", "@datadog/browser-logs": "^4.36.0", "@datadog/browser-rum": "^4.37.0", - "@deriv/analytics": "^1.3.8", + "@deriv/analytics": "^1.4.1", "@deriv/api-types": "^1.0.118", "@deriv/deriv-api": "^1.0.13", "@deriv/deriv-charts": "1.4.1", @@ -2885,9 +2885,9 @@ } }, "node_modules/@deriv/analytics": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/@deriv/analytics/-/analytics-1.3.8.tgz", - "integrity": "sha512-kYAqarwwpF1r4WziJs3ovgj2jF80B1uetOkmRtgB7m5imTX37IQbL3rnIY54V3D6J5c7BhYnBPy/8OV8bvApag==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@deriv/analytics/-/analytics-1.4.1.tgz", + "integrity": "sha512-FuaVu+uFT7mstQFUwPBOIMYW+eI+Q/ufyFYmxz8/wCzA6HM/Wc9ttjXdWh6R1Gwgh1KX8ZbU/nrJ93QKpWVy7Q==", "dependencies": { "@growthbook/growthbook": "^0.29.0", "rudder-sdk-js": "^2.35.0" @@ -51075,8 +51075,8 @@ } }, "@deriv/analytics": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/@deriv/analytics/-/analytics-1.3.8.tgz", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@deriv/analytics/-/analytics-1.4.1.tgz", "integrity": "sha512-kYAqarwwpF1r4WziJs3ovgj2jF80B1uetOkmRtgB7m5imTX37IQbL3rnIY54V3D6J5c7BhYnBPy/8OV8bvApag==", "requires": { "@growthbook/growthbook": "^0.29.0", diff --git a/package.json b/package.json index 96cf914677ad..986121cb056c 100644 --- a/package.json +++ b/package.json @@ -92,7 +92,7 @@ }, "dependencies": { "@babel/preset-typescript": "^7.16.5", - "@deriv/analytics": "^1.3.8", + "@deriv/analytics": "^1.4.1", "@sendbird/chat": "^4.9.7", "@types/react-transition-group": "^4.4.4", "babel-jest": "^27.3.1", diff --git a/packages/appstore/jest.config.js b/packages/appstore/jest.config.js index 9e8d3890b4d8..1ec8c6bd0270 100644 --- a/packages/appstore/jest.config.js +++ b/packages/appstore/jest.config.js @@ -10,6 +10,7 @@ module.exports = { '^Constants/(.*)$': '/src/constants/$1', '^Services/(.*)$': '/src/services/$1', '^Stores/(.*)$': '/src/stores/$1', + '^Hooks/(.*)$': '/src/hooks/$1', '^Types/(.*)$': '/src/types/$1', '^Utils/(.*)$': '/src/utils/$1', }, diff --git a/packages/appstore/src/components/wallet-cards-carousel/cards-slider-swiper.tsx b/packages/appstore/src/components/wallet-cards-carousel/cards-slider-swiper.tsx index dfa33194257d..5e494418e376 100644 --- a/packages/appstore/src/components/wallet-cards-carousel/cards-slider-swiper.tsx +++ b/packages/appstore/src/components/wallet-cards-carousel/cards-slider-swiper.tsx @@ -77,7 +77,12 @@ const CardsSliderSwiper = observer(() => {
{slider}
- +
); diff --git a/packages/appstore/src/hooks/index.ts b/packages/appstore/src/hooks/index.ts new file mode 100644 index 000000000000..561dc7ddcaba --- /dev/null +++ b/packages/appstore/src/hooks/index.ts @@ -0,0 +1 @@ +export * from './use-tradershub-tracking'; diff --git a/packages/appstore/src/hooks/use-tradershub-tracking.ts b/packages/appstore/src/hooks/use-tradershub-tracking.ts new file mode 100644 index 000000000000..a19d71d8a0e7 --- /dev/null +++ b/packages/appstore/src/hooks/use-tradershub-tracking.ts @@ -0,0 +1,113 @@ +import { Analytics } from '@deriv/analytics'; +import { useStore } from '@deriv/stores'; +import { useCallback, useEffect, useMemo } from 'react'; + +// This hook is used to track the onboarding form in TradersHub +export const useTradersHubTracking = () => { + const { traders_hub, ui, client } = useStore(); + + const { is_mobile } = ui; + + const { loginid } = client; + + const { is_first_time_visit } = traders_hub; + + const form_source = useMemo( + () => (is_first_time_visit ? 'tradershub_first_entrance' : 'tradershub_dashboard_form'), + [is_first_time_visit] + ); + + const event_name = 'ce_tradershub_onboarding_form'; + + useEffect(() => { + Analytics.setAttributes({ + device_type: is_mobile ? 'mobile' : 'desktop', + account_type: loginid?.slice(0, 2), + }); + }, [is_mobile, loginid]); + + const trackDotNavigation = useCallback( + (step: number) => { + Analytics.trackEvent(event_name, { + action: 'choose_step_navigation', + form_source, + step_num: step, + step_codename: `${step}_step`, + }); + }, + [form_source] + ); + + const trackLastStep = useCallback(() => { + Analytics.trackEvent(event_name, { + action: 'close', + form_source, + step_num: 7, + step_codename: '7_step', + }); + }, [form_source]); + + const trackStepBack = useCallback( + (new_step: number) => { + Analytics.trackEvent(event_name, { + action: 'step_back', + form_source, + step_num: new_step, + step_codename: `${new_step}_step`, + }); + }, + [form_source] + ); + + const trackStepForward = useCallback( + (new_step: number) => { + Analytics.trackEvent(event_name, { + action: 'step_passed', + form_source, + step_num: new_step, + step_codename: `${new_step}_step`, + }); + }, + [form_source] + ); + + const trackOnboardingClose = useCallback( + (current_step: number) => { + Analytics.trackEvent(event_name, { + action: 'close', + form_source, + step_num: current_step, + step_codename: `${current_step}_step`, + }); + }, + [form_source] + ); + + const trackOnboardingRestart = useCallback(() => { + Analytics.trackEvent(event_name, { + action: 'open', + form_source: 'repeat_tour', + step_num: 7, + step_codename: `7_step`, + }); + }, []); + + const trackOnboardingOpen = useCallback(() => { + Analytics.trackEvent(event_name, { + action: 'open', + form_source, + step_num: 1, + step_codename: '1_step', + }); + }, [form_source]); + + return { + trackDotNavigation, + trackLastStep, + trackStepBack, + trackStepForward, + trackOnboardingClose, + trackOnboardingOpen, + trackOnboardingRestart, + }; +}; diff --git a/packages/appstore/src/modules/onboarding/onboarding.tsx b/packages/appstore/src/modules/onboarding/onboarding.tsx index 783e23e65f8b..e34634974957 100644 --- a/packages/appstore/src/modules/onboarding/onboarding.tsx +++ b/packages/appstore/src/modules/onboarding/onboarding.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import { localize } from '@deriv/translations'; import { isDesktop, routes, ContentFlag } from '@deriv/shared'; import { Button, Text, Icon, ProgressBarTracker } from '@deriv/components'; @@ -7,6 +7,7 @@ import { getTradingHubContents } from 'Constants/trading-hub-content'; import { useHistory } from 'react-router-dom'; import EmptyOnboarding from './empty-onboarding'; import { useStore, observer } from '@deriv/stores'; +import { useTradersHubTracking } from 'Hooks/index'; type TOnboardingProps = { contents: Record< @@ -32,13 +33,23 @@ const Onboarding = observer(({ contents = getTradingHubContents() }: TOnboarding const { content_flag, is_demo_low_risk, selectAccountType, toggleIsTourOpen } = traders_hub; const [step, setStep] = React.useState(1); + const { trackOnboardingOpen, trackStepBack, trackStepForward, trackOnboardingClose, trackDotNavigation } = + useTradersHubTracking(); + const prevStep = () => { - if (step > 1) setStep(step - 1); + if (step > 1) { + trackStepBack(step); + setStep(step - 1); + } }; const nextStep = () => { - if (step < steps_list.length) setStep(step + 1); + if (step < steps_list.length) { + setStep(step + 1); + trackStepForward(step); + } if (step === steps_list.length) { + trackStepForward(step); toggleIsTourOpen(true); history.push(routes.traders_hub); if (is_demo_low_risk) { @@ -49,11 +60,18 @@ const Onboarding = observer(({ contents = getTradingHubContents() }: TOnboarding }; const handleCloseButton = async () => { + trackOnboardingClose(step); + toggleIsTourOpen(false); history.push(routes.traders_hub); await selectAccountType(prev_account_type); }; + const handleOnboardingStepChange = (step_num: number) => { + setStep(step_num); + trackDotNavigation(step_num); + }; + const eu_user = content_flag === ContentFlag.LOW_RISK_CR_EU || content_flag === ContentFlag.EU_REAL || @@ -72,6 +90,12 @@ const Onboarding = observer(({ contents = getTradingHubContents() }: TOnboarding const footer_description = is_eu_user ? eu_footer_text : footer_text; + useEffect(() => { + if (is_logged_in && is_landing_company_loaded) { + trackOnboardingOpen(); + } + }, [is_logged_in, is_landing_company_loaded, trackOnboardingOpen]); + if (!is_logged_in || !is_landing_company_loaded) { return ; } @@ -118,7 +142,11 @@ const Onboarding = observer(({ contents = getTradingHubContents() }: TOnboarding - +