diff --git a/packages/cashier/package.json b/packages/cashier/package.json index 12402ee5f6fa..1f053f99647f 100644 --- a/packages/cashier/package.json +++ b/packages/cashier/package.json @@ -37,6 +37,7 @@ "url": "https://github.com/binary-com/deriv-app/issues" }, "dependencies": { + "@deriv-com/analytics": "1.11.0", "@deriv/api": "^1.0.0", "@deriv/api-types": "1.0.172", "@deriv/components": "^1.0.0", diff --git a/packages/cashier/src/components/deposit-sub-page-analytics-event-tracker/deposit-sub-page-analytics-event-tracker.tsx b/packages/cashier/src/components/deposit-sub-page-analytics-event-tracker/deposit-sub-page-analytics-event-tracker.tsx new file mode 100644 index 000000000000..15c7eb4387a1 --- /dev/null +++ b/packages/cashier/src/components/deposit-sub-page-analytics-event-tracker/deposit-sub-page-analytics-event-tracker.tsx @@ -0,0 +1,24 @@ +import React, { useEffect } from 'react'; +import { Analytics } from '@deriv-com/analytics'; +import { useStore } from '@deriv/stores'; + +type TProps = { deposit_category: 'crypto' | 'fiat' | 'fiat_onramp' | 'payment_agent' | 'p2p' }; + +const DepositSubPageAnalyticsEventTracker: React.FC = ({ deposit_category }) => { + const { client } = useStore(); + const { currency, loginid } = client; + + useEffect(() => { + Analytics.trackEvent('ce_cashier_deposit_onboarding_form', { + action: 'open_deposit_subpage', + form_name: 'ce_cashier_deposit_onboarding_form', + currency, + deposit_category, + login_id: loginid, + }); + }, [currency, deposit_category, loginid]); + + return null; +}; + +export default DepositSubPageAnalyticsEventTracker; diff --git a/packages/cashier/src/components/deposit-sub-page-analytics-event-tracker/index.ts b/packages/cashier/src/components/deposit-sub-page-analytics-event-tracker/index.ts new file mode 100644 index 000000000000..b914207bb670 --- /dev/null +++ b/packages/cashier/src/components/deposit-sub-page-analytics-event-tracker/index.ts @@ -0,0 +1 @@ +export { default as DepositSubPageAnalyticsEventTracker } from './deposit-sub-page-analytics-event-tracker'; diff --git a/packages/cashier/src/containers/cashier/__tests__/cashier.spec.tsx b/packages/cashier/src/containers/cashier/__tests__/cashier.spec.tsx index b7b7a4e02f70..5bbc605a7275 100644 --- a/packages/cashier/src/containers/cashier/__tests__/cashier.spec.tsx +++ b/packages/cashier/src/containers/cashier/__tests__/cashier.spec.tsx @@ -12,6 +12,38 @@ import { APIProvider } from '@deriv/api'; jest.mock('@deriv/hooks', () => { return { ...jest.requireActual('@deriv/hooks'), + usePaymentAgentList: jest.fn(() => ({ + data: [ + { + currencies: 'USD', + email: 'pa-test@email.com', + further_information: 'Further information', + max_withdrawal: '2000', + min_withdrawal: '10', + name: 'PA', + paymentagent_loginid: 'CR9999999', + phone_numbers: [ + { + phone_number: '+987654321', + }, + ], + summary: '', + supported_payment_methods: [ + { + payment_method: 'Visa', + }, + ], + urls: [ + { + url: 'https://test.test', + }, + ], + withdrawal_commission: '0', + }, + ], + isLoading: false, + isSuccess: true, + })), usePaymentAgentTransferVisible: jest.fn(() => ({ data: true, isLoading: false, @@ -106,9 +138,6 @@ describe('', () => { transaction_history: { is_transactions_crypto_visible: false, }, - payment_agent: { - is_payment_agent_visible: false, - }, }, }, }); @@ -156,9 +185,6 @@ describe('', () => { transaction_history: { is_transactions_crypto_visible: true, }, - payment_agent: { - is_payment_agent_visible: true, - }, }, }, }); @@ -209,9 +235,6 @@ describe('', () => { // transaction_history: { // is_transactions_crypto_visible: false, // }, - // payment_agent: { - // is_payment_agent_visible: true, - // }, // }, // }, // }); @@ -262,9 +285,6 @@ describe('', () => { transaction_history: { is_transactions_crypto_visible: true, }, - payment_agent: { - is_payment_agent_visible: true, - }, }, }, }); @@ -314,9 +334,6 @@ describe('', () => { transaction_history: { is_transactions_crypto_visible: true, }, - payment_agent: { - is_payment_agent_visible: true, - }, }, }, }); @@ -367,9 +384,6 @@ describe('', () => { transaction_history: { is_transactions_crypto_visible: true, }, - payment_agent: { - is_payment_agent_visible: true, - }, }, }, }); diff --git a/packages/cashier/src/containers/cashier/cashier.tsx b/packages/cashier/src/containers/cashier/cashier.tsx index 7cbf588b6ce5..99f4330b1800 100644 --- a/packages/cashier/src/containers/cashier/cashier.tsx +++ b/packages/cashier/src/containers/cashier/cashier.tsx @@ -16,11 +16,12 @@ import { useOnrampVisible, useAccountTransferVisible, useIsP2PEnabled, + usePaymentAgentList, usePaymentAgentTransferVisible, useP2PNotificationCount, useP2PSettings, } from '@deriv/hooks'; -import { getSelectedRoute, getStaticUrl, routes, setPerformanceValue, WS } from '@deriv/shared'; +import { getSelectedRoute, getStaticUrl, routes, setPerformanceValue, WS, matchRoute } from '@deriv/shared'; import ErrorDialog from '../../components/error-dialog'; import { TRoute } from '../../types'; import { localize } from '@deriv/translations'; @@ -52,7 +53,7 @@ type TCashierOptions = { const Cashier = observer(({ history, location, routes: routes_config }: TCashierProps) => { const { common, ui, client } = useStore(); - const { withdraw, general_store, payment_agent } = useCashierStore(); + const { withdraw, general_store } = useCashierStore(); const { error } = withdraw; const { is_cashier_onboarding, @@ -65,13 +66,18 @@ const Cashier = observer(({ history, location, routes: routes_config }: TCashier } = general_store; const { data: is_payment_agent_transfer_visible, - isLoading: is_payment_agent_checking, + isLoading: is_payment_agent_transfer_checking, isSuccess: is_payment_agent_transfer_visible_is_success, } = usePaymentAgentTransferVisible(); - const { is_payment_agent_visible } = payment_agent; const { is_from_derivgo } = common; const { is_cashier_visible: is_visible, is_mobile, toggleCashier, toggleReadyToDepositModal } = ui; const { currency, is_account_setting_loaded, is_logged_in, is_logging_in, is_svg, is_virtual } = client; + const { + data: paymentAgentList, + isLoading: is_payment_agent_list_loading, + isSuccess: is_payment_agent_list_success, + } = usePaymentAgentList(currency); + const is_payment_agent_visible = paymentAgentList && paymentAgentList.length > 0; const is_account_transfer_visible = useAccountTransferVisible(); const is_onramp_visible = useOnrampVisible(); const p2p_notification_count = useP2PNotificationCount(); @@ -240,15 +246,26 @@ const Cashier = observer(({ history, location, routes: routes_config }: TCashier toggleReadyToDepositModal, ]); - if ( + const is_p2p_loading = is_p2p_enabled_loading && !is_p2p_enabled_success; + const is_payment_agent_loading = is_payment_agent_list_loading && !is_payment_agent_list_success; + const is_cashier_loading = ((!is_logged_in || is_mobile) && is_logging_in) || !is_account_setting_loaded || - is_payment_agent_checking || - (is_p2p_enabled_loading && !is_p2p_enabled_success) - ) { + is_payment_agent_transfer_checking || + is_p2p_loading || + is_payment_agent_loading; + + if (is_cashier_loading) { return ; } + // Calculation of `initial_tab_index` must be performed after cashier loading + // Because at this stage `getMenuOptions` list has all available routes + const initial_tab_index = Math.max( + getMenuOptions.findIndex(item => matchRoute(item, location.pathname)), + 0 + ); + // measure performance metrics (load cashier time) setPerformanceValue('load_cashier_time'); @@ -260,6 +277,7 @@ const Cashier = observer(({ history, location, routes: routes_config }: TCashier { const history = useHistory(); - const { ui } = useStore(); + const { client, ui } = useStore(); + const { loginid } = client; const { general_store } = useCashierStore(); const { setIsCashierOnboarding } = general_store; const { toggleSetCurrencyModal } = ui; const has_set_currency = useHasSetCurrency(); + useEffect(() => { + if (loginid) { + Analytics.trackEvent('ce_cashier_deposit_onboarding_form', { + action: 'open', + form_name: 'ce_cashier_deposit_onboarding_form', + login_id: loginid, + }); + } + }, [loginid]); + useEffect(() => { setIsCashierOnboarding(true); diff --git a/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-card/__test__/cashier-onboarding-card.test.tsx b/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-card/__test__/cashier-onboarding-card.test.tsx index b7f61951b6b4..b24950208c20 100644 --- a/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-card/__test__/cashier-onboarding-card.test.tsx +++ b/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-card/__test__/cashier-onboarding-card.test.tsx @@ -10,6 +10,7 @@ describe('CashierOnboardingCard', () => { const props: React.ComponentProps = { title: 'foo', description: 'bar', + depositCategory: 'crypto', onClick: jest.fn(), }; diff --git a/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-card/cashier-onboarding-card.tsx b/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-card/cashier-onboarding-card.tsx index 760d9f157695..31361c6be00c 100644 --- a/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-card/cashier-onboarding-card.tsx +++ b/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-card/cashier-onboarding-card.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { Analytics } from '@deriv-com/analytics'; import { Icon, Text } from '@deriv/components'; import { observer, useStore } from '@deriv/stores'; import './cashier-onboarding-card.scss'; @@ -6,14 +7,27 @@ import './cashier-onboarding-card.scss'; type TProps = { title: string; description: string; + depositCategory: 'crypto' | 'fiat' | 'fiat_onramp' | 'payment_agent' | 'p2p'; onClick?: VoidFunction; }; const CashierOnboardingCard: React.FC> = observer( - ({ title, description, onClick, children }) => { - const { ui } = useStore(); + ({ title, description, depositCategory, onClick, children }) => { + const { client, ui } = useStore(); + const { currency, loginid } = client; const { is_dark_mode_on, is_mobile } = ui; + const onClickHandler = () => { + onClick?.(); + Analytics.trackEvent('ce_cashier_deposit_onboarding_form', { + action: 'click_deposit_card', + form_name: 'ce_cashier_deposit_onboarding_form', + deposit_category: depositCategory, + currency, + login_id: loginid, + }); + }; + return (
@@ -22,7 +36,7 @@ const CashierOnboardingCard: React.FC> = observe
diff --git a/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-crypto-card/cashier-onboarding-crypto-card.tsx b/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-crypto-card/cashier-onboarding-crypto-card.tsx index 31841bb2b6ba..a5e3e35b8fc2 100644 --- a/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-crypto-card/cashier-onboarding-crypto-card.tsx +++ b/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-crypto-card/cashier-onboarding-crypto-card.tsx @@ -36,6 +36,7 @@ const CashierOnboardingCryptoCard: React.FC = observer(() => { `${icon}${is_dark_mode_on ? 'Dark' : 'Light'}`)} /> diff --git a/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-fiat-card/cashier-onboarding-fiat-card.tsx b/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-fiat-card/cashier-onboarding-fiat-card.tsx index b923097d8f72..ced34110e5a9 100644 --- a/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-fiat-card/cashier-onboarding-fiat-card.tsx +++ b/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-fiat-card/cashier-onboarding-fiat-card.tsx @@ -42,12 +42,17 @@ const CashierOnboardingFiatCard: React.FC = observer(() => { }; return ( - - `${icon}${is_dark_mode_on ? 'Dark' : 'Light'}`)} /> + + + `${icon}${is_dark_mode_on ? 'Dark' : 'Light'}`)} + /> + {can_switch_to_fiat_account && ( { onSwitchDone={onSwitchDone} /> )} - + ); }); diff --git a/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-onramp-card/cashier-onboarding-onramp-card.tsx b/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-onramp-card/cashier-onboarding-onramp-card.tsx index e4282458acdc..99bde98ffc10 100644 --- a/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-onramp-card/cashier-onboarding-onramp-card.tsx +++ b/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-onramp-card/cashier-onboarding-onramp-card.tsx @@ -34,6 +34,7 @@ const CashierOnboardingOnrampCard: React.FC = observer(() => { : localize('Buy cryptocurrencies via fiat onramp') } description={localize('Choose any of these exchanges to buy cryptocurrencies:')} + depositCategory='fiat_onramp' onClick={onClick} > `${icon}${is_dark_mode_on ? 'Dark' : 'Light'}`)} /> diff --git a/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-p2p-card/cashier-onboarding-p2p-card.tsx b/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-p2p-card/cashier-onboarding-p2p-card.tsx index 05bab9fa7eef..d5a505ef2e4a 100644 --- a/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-p2p-card/cashier-onboarding-p2p-card.tsx +++ b/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-p2p-card/cashier-onboarding-p2p-card.tsx @@ -46,13 +46,15 @@ const CashierOnboardingP2PCard: React.FC = observer(() => { if (!should_show_p2p_card) return null; return ( - + + {can_switch_to_fiat_account && ( { onSwitchDone={onSwitchDone} /> )} - + ); }); diff --git a/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-payment-agent-card/cashier-onboarding-payment-agent-card.tsx b/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-payment-agent-card/cashier-onboarding-payment-agent-card.tsx index 11cef7dc3bb6..81101dec37de 100644 --- a/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-payment-agent-card/cashier-onboarding-payment-agent-card.tsx +++ b/packages/cashier/src/modules/cashier-onboarding/components/cashier-onboarding-payment-agent-card/cashier-onboarding-payment-agent-card.tsx @@ -28,6 +28,7 @@ const CashierOnboardingPaymentAgentCard: React.FC = observer(() => { description={localize( 'Deposit in your local currency via an authorised, independent payment agent in your country.' )} + depositCategory='payment_agent' onClick={onClick} /> ); diff --git a/packages/cashier/src/modules/deposit-crypto/components/deposit-crypto-wallet-address/deposit-crypto-wallet-address.tsx b/packages/cashier/src/modules/deposit-crypto/components/deposit-crypto-wallet-address/deposit-crypto-wallet-address.tsx index 0ed63bcbcea3..16022218c158 100644 --- a/packages/cashier/src/modules/deposit-crypto/components/deposit-crypto-wallet-address/deposit-crypto-wallet-address.tsx +++ b/packages/cashier/src/modules/deposit-crypto/components/deposit-crypto-wallet-address/deposit-crypto-wallet-address.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { Analytics } from '@deriv-com/analytics'; import { Button, Clipboard, InlineMessage, Loading, Text } from '@deriv/components'; import { useDepositCryptoAddress } from '@deriv/hooks'; import { observer, useStore } from '@deriv/stores'; @@ -9,7 +10,8 @@ import { DepositCryptoDisclaimers } from '../deposit-crypto-disclaimers'; import './deposit-crypto-wallet-address.scss'; const DepositCryptoWalletAddress: React.FC = observer(() => { - const { ui } = useStore(); + const { client, ui } = useStore(); + const { currency, loginid } = client; const { is_mobile } = ui; const { data: deposit_crypto_address, isLoading, error, resend } = useDepositCryptoAddress(); @@ -17,6 +19,15 @@ const DepositCryptoWalletAddress: React.FC = observer(() => { setPerformanceValue('load_crypto_deposit_cashier_time'); + const onClickHandler = () => { + Analytics.trackEvent('ce_cashier_deposit_onboarding_form', { + action: 'click_copy_crypto_address', + form_name: 'ce_cashier_deposit_onboarding_form', + currency, + login_id: loginid, + }); + }; + if (error) { return (
@@ -49,6 +60,7 @@ const DepositCryptoWalletAddress: React.FC = observer(() => { text_copy={deposit_crypto_address || ''} info_message={is_mobile ? undefined : localize('copy')} success_message={localize('copied!')} + onClickHandler={onClickHandler} popoverAlignment={is_mobile ? 'left' : 'bottom'} />
diff --git a/packages/cashier/src/modules/deposit-crypto/deposit-crypto.tsx b/packages/cashier/src/modules/deposit-crypto/deposit-crypto.tsx index b3d2418252ea..1777800cf34b 100644 --- a/packages/cashier/src/modules/deposit-crypto/deposit-crypto.tsx +++ b/packages/cashier/src/modules/deposit-crypto/deposit-crypto.tsx @@ -2,6 +2,7 @@ import React, { useEffect } from 'react'; import { observer, useStore } from '@deriv/stores'; import { Divider } from '../../components/divider'; import { PageContainer } from '../../components/page-container'; +import { DepositSubPageAnalyticsEventTracker } from '../../components/deposit-sub-page-analytics-event-tracker'; import { useCashierStore } from '../../stores/useCashierStores'; import { DepositCryptoCurrencyDetails, DepositCryptoSideNotes, DepositCryptoWalletAddress } from './components'; import DepositCryptoSideNoteTryFiatOnRamp from './components/deposit-crypto-side-notes/deposit-crypto-side-note-try-fiat-onramp'; @@ -27,6 +28,7 @@ const DepositCrypto: React.FC = observer(() => { // side notes for consistency and then we can remove unnecessary components from the children. right={is_mobile ? undefined : } > + diff --git a/packages/cashier/src/modules/deposit-fiat/deposit-fiat.tsx b/packages/cashier/src/modules/deposit-fiat/deposit-fiat.tsx index d045db2819ab..516d5299b55c 100644 --- a/packages/cashier/src/modules/deposit-fiat/deposit-fiat.tsx +++ b/packages/cashier/src/modules/deposit-fiat/deposit-fiat.tsx @@ -3,6 +3,7 @@ import { SideNote } from '@deriv/components'; import { observer, useStore } from '@deriv/stores'; import { Localize } from '@deriv/translations'; import { PageContainer } from '../../components/page-container'; +import { DepositSubPageAnalyticsEventTracker } from '../../components/deposit-sub-page-analytics-event-tracker'; import { DepositFiatIframe } from './components'; import { SideNoteFAQ } from 'Components/side-notes'; @@ -41,6 +42,7 @@ const DepositFiat: React.FC = observer(() => { } > + ); diff --git a/packages/cashier/src/pages/on-ramp/on-ramp.tsx b/packages/cashier/src/pages/on-ramp/on-ramp.tsx index 80059d0d07ae..b42d6bd7e9d2 100644 --- a/packages/cashier/src/pages/on-ramp/on-ramp.tsx +++ b/packages/cashier/src/pages/on-ramp/on-ramp.tsx @@ -8,6 +8,7 @@ import CashierLocked from '../../components/cashier-locked'; import SideNote from '../../components/side-note'; import OnRampProviderCard from './on-ramp-provider-card'; import OnRampProviderPopup from './on-ramp-provider-popup'; +import { DepositSubPageAnalyticsEventTracker } from '../../components/deposit-sub-page-analytics-event-tracker'; import { useCashierStore } from '../../stores/useCashierStores'; import './on-ramp.scss'; @@ -112,56 +113,55 @@ const OnRamp = observer(({ menu_options, setSideNotes }: TOnRampProps) => { } return ( - -
- {isMobile() && ( - - { - if (e.currentTarget.value !== selected_cashier_path) { - setSelectedCashierPath(e.currentTarget.value); - } - }} - /> - - - )} - - - - {filtered_onramp_providers.map(provider => ( - - ))} - setIsOnRampModalOpen(!is_onramp_modal_open)} - onUnmount={resetPopup} - width={should_show_dialog ? '44rem' : '62.8rem'} - > - - - - -
-
+
+ + {isMobile() && ( + + { + if (e.currentTarget.value !== selected_cashier_path) { + setSelectedCashierPath(e.currentTarget.value); + } + }} + /> + + + )} + + + + {filtered_onramp_providers.map(provider => ( + + ))} + setIsOnRampModalOpen(!is_onramp_modal_open)} + onUnmount={resetPopup} + width={should_show_dialog ? '44rem' : '62.8rem'} + > + + + + +
); }); diff --git a/packages/cashier/src/pages/payment-agent/payment-agent-list/payment-agent-list.tsx b/packages/cashier/src/pages/payment-agent/payment-agent-list/payment-agent-list.tsx index e0a9b01e2aeb..dcfcea6b7908 100644 --- a/packages/cashier/src/pages/payment-agent/payment-agent-list/payment-agent-list.tsx +++ b/packages/cashier/src/pages/payment-agent/payment-agent-list/payment-agent-list.tsx @@ -9,6 +9,7 @@ import DepositTab from './deposit-tab'; import WithdrawalTab from './withdrawal-tab'; import MissingPaymentMethodNote from '../missing-payment-method-note'; import PaymentAgentDisclaimer from '../payment-agent-disclaimer'; +import { DepositSubPageAnalyticsEventTracker } from '../../../components/deposit-sub-page-analytics-event-tracker'; import { useCashierStore } from '../../../stores/useCashierStores'; import './payment-agent-list.scss'; @@ -44,6 +45,7 @@ const PaymentAgentList = observer(({ setSideNotes }: TProps) => { return (
+
; @@ -23,6 +24,7 @@ const Clipboard = ({ icon, success_message, className, + onClickHandler, popoverClassName, popover_props = {}, popoverAlignment = 'bottom', @@ -40,6 +42,7 @@ const Clipboard = ({ } }, 2000); event.stopPropagation(); + onClickHandler?.(); }; React.useEffect(() => { diff --git a/packages/components/src/components/vertical-tab/vertical-tab-content-container.tsx b/packages/components/src/components/vertical-tab/vertical-tab-content-container.tsx index 338d792cfb02..215f3cdedac9 100644 --- a/packages/components/src/components/vertical-tab/vertical-tab-content-container.tsx +++ b/packages/components/src/components/vertical-tab/vertical-tab-content-container.tsx @@ -1,5 +1,5 @@ import classNames from 'classnames'; -import React from 'react'; +import React, { memo, useMemo } from 'react'; import { Route, Switch } from 'react-router-dom'; import Icon from '../icon/icon'; import { TItem } from './vertical-tab-header'; @@ -9,10 +9,6 @@ type TSideNotes = { side_notes: React.ReactNode[] | null; }; -type TContentWrapper = { - has_side_note?: boolean; -}; - type TContent = { is_routed?: boolean; items: TItem[]; @@ -50,39 +46,37 @@ const SideNotes = ({ class_name, side_notes }: TSideNotes) => { ); }; -const ContentWrapper = ({ children, has_side_note }: React.PropsWithChildren) => { - if (has_side_note) { - return
{children}
; - } - return children as JSX.Element; -}; - -const Content = ({ is_routed, items, selected }: TContent) => { +const Content = memo(({ is_routed, items, selected }: TContent) => { const selected_item = items.find(item => item.label === selected.label); - const TabContent = selected_item?.value as React.ElementType; const [side_notes, setSideNotes] = React.useState(null); const addToNotesQueue = React.useCallback((notes: React.ReactNode[]) => { setSideNotes(notes); }, []); + const MemoizedTabContent = useMemo(() => { + return selected_item?.value as React.ElementType; + }, [selected_item?.value]); + + const memoized_routes = useMemo(() => { + return items.map(({ value, component, path, icon }, idx) => { + const Component = (value as React.ElementType) || component; + return ( + } + /> + ); + }); + }, [addToNotesQueue, items]); + return ( {is_routed ? ( - - {items.map(({ value, component, path, icon }, idx) => { - const Component = (value as React.ElementType) || component; - return ( - } - /> - ); - })} - + {memoized_routes} ) : ( - + )} {selected.has_side_note && ( // for components that have side note, even if no note is passed currently, @@ -91,7 +85,9 @@ const Content = ({ is_routed, items, selected }: TContent) => { )} ); -}; +}); + +Content.displayName = 'Content'; const VerticalTabContentContainer = ({ action_bar, @@ -134,10 +130,16 @@ const VerticalTabContentContainer = ({ })}
)} -
- - - +
+
); diff --git a/packages/components/src/components/vertical-tab/vertical-tab.scss b/packages/components/src/components/vertical-tab/vertical-tab.scss index 5d82977e0af2..d1726d664e7d 100644 --- a/packages/components/src/components/vertical-tab/vertical-tab.scss +++ b/packages/components/src/components/vertical-tab/vertical-tab.scss @@ -38,13 +38,10 @@ $MIN_HEIGHT_FLOATING: calc( display: flex; flex-flow: column nowrap; flex-grow: 1; - } - &__content-inner { - position: absolute; - z-index: 0; - height: 100%; - width: 100%; - display: flex; + + &--has-side-note { + flex-flow: unset; + } } &--full-screen { min-height: $MIN_HEIGHT_FULL_SCREEN; diff --git a/packages/components/src/components/vertical-tab/vertical-tab.tsx b/packages/components/src/components/vertical-tab/vertical-tab.tsx index ba870ca7e1f9..ef338d055265 100644 --- a/packages/components/src/components/vertical-tab/vertical-tab.tsx +++ b/packages/components/src/components/vertical-tab/vertical-tab.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useMemo } from 'react'; import classNames from 'classnames'; import { matchRoute } from '@deriv/shared'; import VerticalTabContentContainer, { TAction_bar } from './vertical-tab-content-container'; @@ -29,6 +29,7 @@ type TVerticalTab = { has_mixed_dimensions?: boolean; header_classname?: string; header_title?: string; + initial_vertical_tab_index?: number; is_collapsible?: boolean; is_floating?: boolean; is_grid?: boolean; @@ -81,6 +82,7 @@ const VerticalTab = ({ has_mixed_dimensions, header_classname, header_title, + initial_vertical_tab_index, is_collapsible, is_floating, is_grid, @@ -95,7 +97,8 @@ const VerticalTab = ({ title, vertical_tab_index, }: TVerticalTab) => { - const [curr_tab_index, setCurrTabIndex] = React.useState(vertical_tab_index || 0); + const [curr_tab_index, setCurrTabIndex] = React.useState(initial_vertical_tab_index ?? (vertical_tab_index || 0)); + const selected = useMemo(() => list[curr_tab_index] || list[0], [curr_tab_index, list]); const changeSelected = (e: TItem) => { setSelectedIndex({ @@ -153,7 +156,7 @@ const VerticalTab = ({ items={list} item_groups={list_groups} onChange={changeSelected} - selected={list[curr_tab_index] || list[0]} + selected={selected} has_mixed_dimensions={has_mixed_dimensions} is_collapsible={is_collapsible} is_floating={is_floating} @@ -172,7 +175,7 @@ const VerticalTab = ({ className={className} is_floating={is_floating} items={list} - selected={list[curr_tab_index] || list[0]} + selected={selected} is_routed={is_routed} />
diff --git a/packages/p2p/package.json b/packages/p2p/package.json index c2574afc2bcd..a74ca03fdb77 100644 --- a/packages/p2p/package.json +++ b/packages/p2p/package.json @@ -32,6 +32,7 @@ "author": "", "license": "ISC", "dependencies": { + "@deriv-com/analytics": "1.11.0", "@deriv-com/utils": "^0.0.25", "@deriv/api": "^1.0.0", "@deriv/api-types": "1.0.172", diff --git a/packages/p2p/src/pages/app.jsx b/packages/p2p/src/pages/app.jsx index 846bf918f2bf..fa40a4acd0b4 100644 --- a/packages/p2p/src/pages/app.jsx +++ b/packages/p2p/src/pages/app.jsx @@ -1,6 +1,7 @@ import React from 'react'; import { useHistory, useLocation } from 'react-router-dom'; import { reaction } from 'mobx'; +import { Analytics } from '@deriv-com/analytics'; import { Loading } from '@deriv/components'; import { useP2PCompletedOrdersNotification, useP2PSettings, useGrowthbookGetFeatureValue } from '@deriv/hooks'; import { isEmptyObject, routes, WS } from '@deriv/shared'; @@ -22,7 +23,7 @@ const App = () => { defaultValue: false, }); const { notifications, client, ui, common, modules } = useStore(); - const { balance, is_logging_in } = client; + const { balance, currency, is_logging_in, loginid } = client; const { setOnRemount } = modules?.cashier?.general_store; const { is_mobile } = ui; @@ -193,6 +194,18 @@ const App = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [setQueryOrder]); + React.useEffect(() => { + if (loginid && currency) { + Analytics.trackEvent('ce_cashier_deposit_onboarding_form', { + action: 'open_deposit_subpage', + form_name: 'ce_cashier_deposit_onboarding_form', + deposit_category: 'p2p', + currency, + login_id: loginid, + }); + } + }, [currency, loginid]); + const setQueryOrder = React.useCallback( input_order_id => { const current_query_params = new URLSearchParams(location.search); diff --git a/packages/p2p/webpack.config.js b/packages/p2p/webpack.config.js index 16cbb75678f4..37c45c4e0fb2 100644 --- a/packages/p2p/webpack.config.js +++ b/packages/p2p/webpack.config.js @@ -174,6 +174,7 @@ module.exports = function (env) { 'react-router': 'react-router', 'react-router-dom': 'react-router-dom', 'prop-types': 'prop-types', + '@deriv-com/analytics': '@deriv-com/analytics', ...(is_publishing ? {} : { 'lodash.debounce': 'lodash.debounce', formik: 'formik' }), ...publisher_utils.getLocalDerivPackageExternals(__dirname, is_publishing), },