diff --git a/packages/cashier/src/components/cashier-notifications/__tests__/cashier-notifications.spec.tsx b/packages/cashier/src/components/cashier-notifications/__tests__/cashier-notifications.spec.tsx deleted file mode 100644 index ac47061d5c8a..000000000000 --- a/packages/cashier/src/components/cashier-notifications/__tests__/cashier-notifications.spec.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react'; -import { render, screen } from '@testing-library/react'; -import CashierNotifications from '../cashier-notifications'; - -jest.mock('@deriv/components', () => { - const original_module = jest.requireActual('@deriv/components') as any; - - return { - ...original_module, - Icon: jest.fn(() => 'mockedIcon'), - Counter: jest.fn(() => 'mockedCounter'), - }; -}); - -describe('', () => { - it('should only show the icon if there are no p2p notifications', () => { - render(); - - expect(screen.getByText('mockedIcon')).toBeInTheDocument(); - }); - - it('should show the icon and no. of notifications if there are p2p notifications', () => { - render(); - - expect(screen.getByText(/mockedIcon/i)).toBeInTheDocument(); - expect(screen.getByText(/mockedCounter/i)).toBeInTheDocument(); - }); -}); diff --git a/packages/cashier/src/components/cashier-notifications/cashier-notifications.tsx b/packages/cashier/src/components/cashier-notifications/cashier-notifications.tsx deleted file mode 100644 index d8281f1aeba0..000000000000 --- a/packages/cashier/src/components/cashier-notifications/cashier-notifications.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react'; -import { Icon, Counter } from '@deriv/components'; - -type TCashierNotificationsProps = { - p2p_notification_count: number; -}; - -const CashierNotifications = ({ p2p_notification_count }: TCashierNotificationsProps) => ( - - - {!!p2p_notification_count && } - -); - -export default CashierNotifications; diff --git a/packages/cashier/src/components/cashier-notifications/index.ts b/packages/cashier/src/components/cashier-notifications/index.ts deleted file mode 100644 index d4d62d36f900..000000000000 --- a/packages/cashier/src/components/cashier-notifications/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import CashierNotifications from './cashier-notifications'; - -export default CashierNotifications; diff --git a/packages/cashier/src/stores/__tests__/general-store.spec.ts b/packages/cashier/src/stores/__tests__/general-store.spec.ts index faae35a4a70c..758893e665bb 100644 --- a/packages/cashier/src/stores/__tests__/general-store.spec.ts +++ b/packages/cashier/src/stores/__tests__/general-store.spec.ts @@ -2,24 +2,11 @@ import { configure } from 'mobx'; import { waitFor } from '@testing-library/react'; import { routes } from '@deriv/shared'; import GeneralStore from '../general-store'; -import CashierNotifications from 'Components/cashier-notifications'; import type { TWebSocket, TRootStore } from 'Types'; -type TMenuItem = { - icon: JSX.Element; - id: string; - link_to: string | boolean; - login_only: boolean; - onClick: boolean | (() => void); - text: () => string; -}; - configure({ safeDescriptors: false }); -let cashier_menu: TMenuItem, - general_store: GeneralStore, - root_store: DeepPartial, - WS: DeepPartial; +let general_store: GeneralStore, root_store: DeepPartial, WS: DeepPartial; beforeEach(() => { root_store = { @@ -97,23 +84,9 @@ beforeEach(() => { wait: jest.fn(), }; general_store = new GeneralStore(WS as TWebSocket, root_store as TRootStore); - - cashier_menu = { - id: 'dt_cashier_tab', - icon: CashierNotifications({ p2p_notification_count: general_store.p2p_notification_count }), - text: expect.any(Function), - link_to: routes.cashier, - onClick: false, - login_only: true, - }; }); describe('GeneralStore', () => { - it('should set has_set_currency equal to true and attach cashier menu with proper data, if "when" reaction was called in constructor', () => { - expect(general_store.has_set_currency).toBeTruthy(); - expect(general_store.root_store.menu.attach).toHaveBeenCalledWith(cashier_menu); - }); - it('should set function on remount', () => { // TODO: Check this // const remountFunc = () => 'function'; @@ -180,49 +153,6 @@ describe('GeneralStore', () => { expect(general_store.show_p2p_in_cashier_onboarding).toBeTruthy(); }); - it('should call setHasSetCurrency method if has_set_currency is equal to false and attach cashier menu with proper properties', () => { - general_store.has_set_currency = false; - const spySetHasSetCurrency = jest.spyOn(general_store, 'setHasSetCurrency'); - general_store.attachCashierToMenu(); - - expect(spySetHasSetCurrency).toHaveBeenCalledTimes(1); - expect(general_store.root_store.menu.attach).toHaveBeenCalledWith(cashier_menu); - }); - - it('should attach cashier menu and set onClick property to ui.toggleSetCurrencyModal and link_to = false if the client did not set the currency', () => { - general_store.has_set_currency = false; - general_store.root_store.client.account_list = [{ is_virtual: 0, title: 'Real' }]; - general_store.root_store.client.has_active_real_account = true; - general_store.attachCashierToMenu(); - - expect(general_store.root_store.menu.attach).toHaveBeenCalledWith({ - ...cashier_menu, - link_to: false, - onClick: general_store.root_store.ui.toggleSetCurrencyModal, - }); - }); - - it('should replace cashier menu onClick to false if the client set the currency', () => { - general_store.replaceCashierMenuOnclick(); - - expect(general_store.root_store.menu.update).toHaveBeenCalledWith(cashier_menu, 1); - }); - - it('should replace cashier menu onClick to ui.toggleSetCurrencyModal if the client did not set the currency', () => { - general_store.root_store.client.account_list = [{ is_virtual: 0, title: 'Real' }]; - general_store.root_store.client.has_active_real_account = true; - general_store.replaceCashierMenuOnclick(); - - expect(general_store.root_store.menu.update).toHaveBeenCalledWith( - { - ...cashier_menu, - link_to: false, - onClick: general_store.root_store.ui.toggleSetCurrencyModal, - }, - 1 - ); - }); - it('should set has_set_currency equal to true if the client has real USD account', () => { general_store.setHasSetCurrency(); diff --git a/packages/cashier/src/stores/general-store.ts b/packages/cashier/src/stores/general-store.ts index 88d87d760f62..8aaa2f61a504 100644 --- a/packages/cashier/src/stores/general-store.ts +++ b/packages/cashier/src/stores/general-store.ts @@ -1,9 +1,7 @@ import { action, computed, observable, reaction, when, makeObservable } from 'mobx'; import { isCryptocurrency, isEmptyObject, getPropertyValue, routes, ContentFlag } from '@deriv/shared'; import type { P2PAdvertInfo } from '@deriv/api-types'; -import { localize } from '@deriv/translations'; import Constants from 'Constants/constants'; -import CashierNotifications from 'Components/cashier-notifications'; import BaseStore from './base-store'; import PaymentAgentStore from './payment-agent-store'; import type { TRootStore, TWebSocket } from 'Types'; @@ -13,7 +11,6 @@ export default class GeneralStore extends BaseStore { super({ root_store }); makeObservable(this, { - attachCashierToMenu: action.bound, calculatePercentage: action.bound, cashier_route_tab_index: observable, changeSetCurrencyModalTitle: action.bound, @@ -42,7 +39,6 @@ export default class GeneralStore extends BaseStore { percentage: observable, percentageSelectorSelectionStatus: action.bound, payment_agent: observable, - replaceCashierMenuOnclick: action.bound, setAccountSwitchListener: action.bound, setActiveTab: action.bound, setCashierTabIndex: action.bound, @@ -68,7 +64,6 @@ export default class GeneralStore extends BaseStore { () => this.root_store.client.is_logged_in, () => { this.setHasSetCurrency(); - this.attachCashierToMenu(); } ); @@ -161,41 +156,6 @@ export default class GeneralStore extends BaseStore { } } - attachCashierToMenu(): void { - const { menu, ui } = this.root_store; - - if (!this.has_set_currency) { - this.setHasSetCurrency(); - } - - menu.attach({ - id: 'dt_cashier_tab', - icon: CashierNotifications({ p2p_notification_count: this.p2p_notification_count }), - text: () => localize('Cashier'), - link_to: this.has_set_currency && routes.cashier, - onClick: !this.has_set_currency && ui.toggleSetCurrencyModal, - login_only: true, - }); - } - - replaceCashierMenuOnclick(): void { - const { menu, ui } = this.root_store; - - this.setHasSetCurrency(); - - menu.update( - { - id: 'dt_cashier_tab', - icon: CashierNotifications({ p2p_notification_count: this.p2p_notification_count }), - text: () => localize('Cashier'), - link_to: this.has_set_currency && routes.cashier, - onClick: !this.has_set_currency ? ui.toggleSetCurrencyModal : false, - login_only: true, - }, - 1 - ); - } - setHasSetCurrency(): void { const { account_list, has_active_real_account } = this.root_store.client; diff --git a/packages/core/src/App/Components/Layout/Header/menu-links.jsx b/packages/core/src/App/Components/Layout/Header/menu-links.jsx index f8b706cd23be..2d7e904546c2 100644 --- a/packages/core/src/App/Components/Layout/Header/menu-links.jsx +++ b/packages/core/src/App/Components/Layout/Header/menu-links.jsx @@ -1,70 +1,71 @@ -import PropTypes from 'prop-types'; import React from 'react'; -import { Text } from '@deriv/components'; +import { Text, Icon, Counter } from '@deriv/components'; import { BinaryLink } from '../../Routes'; +import { observer, useStore } from '@deriv/stores'; +import { routes } from '@deriv/shared'; +import { localize } from '@deriv/translations'; +import { useP2PNotificationCount } from '@deriv/hooks'; +import './menu-links.scss'; -const MenuItems = ({ item, hide_menu_item }) => { - const { id, link_to, href, text, image, logo, icon } = item; - return hide_menu_item ? null : ( +const MenuItems = ({ id, text, icon, link_to }) => { + return ( - + {icon} - {text()} - {logo} + {text} - - {image} - {logo} - ); }; -const MenuLinks = ({ is_logged_in, is_mobile, items, is_pre_appstore }) => ( - - {!!items.length && ( -
- {items.map(item => { - return ( - is_logged_in && ( - - ) - ); - })} -
- )} -
+const ReportTab = () => ( + } + text={localize('Reports')} + link_to={routes.reports} + /> ); -MenuLinks.propTypes = { - items: PropTypes.arrayOf( - PropTypes.shape({ - icon: PropTypes.shape({ - className: PropTypes.string, - }), - is_logged_in: PropTypes.bool, - link_to: PropTypes.string, - text: PropTypes.func, - }) - ), - is_mobile: PropTypes.bool, - is_logged_in: PropTypes.bool, - is_pre_appstore: PropTypes.bool, -}; +const CashierTab = observer(() => { + const p2p_notification_count = useP2PNotificationCount(); + + return ( + + + {p2p_notification_count > 0 && ( + + )} + + } + text={localize('Cashier')} + link_to={routes.cashier} + /> + ); +}); + +const MenuLinks = observer(() => { + const { client, ui } = useStore(); + const { is_logged_in, is_pre_appstore } = client; + const { is_mobile } = ui; + + if (!is_logged_in) return <>; + + return ( +
+ {!is_pre_appstore && } + {!is_pre_appstore && !is_mobile && } +
+ ); +}); export { MenuLinks }; diff --git a/packages/core/src/App/Components/Layout/Header/menu-links.scss b/packages/core/src/App/Components/Layout/Header/menu-links.scss new file mode 100644 index 000000000000..3923e75c0812 --- /dev/null +++ b/packages/core/src/App/Components/Layout/Header/menu-links.scss @@ -0,0 +1,7 @@ +.cashier { + &__counter { + position: absolute; + top: 0.4rem; + right: -1.5rem; + } +} diff --git a/packages/core/src/App/Containers/Layout/header/default-header.jsx b/packages/core/src/App/Containers/Layout/header/default-header.jsx index 1ae635fde512..9847a92a2587 100644 --- a/packages/core/src/App/Containers/Layout/header/default-header.jsx +++ b/packages/core/src/App/Containers/Layout/header/default-header.jsx @@ -41,12 +41,10 @@ const DefaultHeader = ({ is_route_modal_on, is_trading_assessment_for_existing_user_enabled, is_virtual, - menu_items, notifications_count, openRealAccountSignup, platform, removeNotificationMessage, - replaceCashierMenuOnclick, setIsPreAppStore, toggleAccountsDialog, toggleNotifications, @@ -59,10 +57,6 @@ const DefaultHeader = ({ [removeNotificationMessage] ); - React.useEffect(() => { - if (is_logged_in) replaceCashierMenuOnclick(); - }, [is_logged_in]); - React.useEffect(() => { document.addEventListener('IgnorePWAUpdate', removeUpdateNotification); return () => document.removeEventListener('IgnorePWAUpdate', removeUpdateNotification); @@ -140,7 +134,7 @@ const DefaultHeader = ({
{header_extension}
)} - + {is_logging_in ? null @@ -230,18 +224,16 @@ DefaultHeader.propTypes = { openRealAccountSignup: PropTypes.func, platform: PropTypes.string, removeNotificationMessage: PropTypes.func, - replaceCashierMenuOnclick: PropTypes.func, toggleAccountsDialog: PropTypes.func, toggleNotifications: PropTypes.func, country_standpoint: PropTypes.object, history: PropTypes.object, - menu_items: PropTypes.array, setIsPreAppStore: PropTypes.func, is_landing_company_loaded: PropTypes.bool, is_switching: PropTypes.bool, }; -export default connect(({ client, common, ui, menu, modules, notifications }) => ({ +export default connect(({ client, common, ui, notifications }) => ({ acc_switcher_disabled_message: ui.account_switcher_disabled_message, account_type: client.account_type, addNotificationMessage: notifications.addNotificationMessage, @@ -265,10 +257,8 @@ export default connect(({ client, common, ui, menu, modules, notifications }) => is_notifications_visible: notifications.is_notifications_visible, is_route_modal_on: ui.is_route_modal_on, is_virtual: client.is_virtual, - menu_items: menu.extensions, notifications_count: notifications.notifications.length, openRealAccountSignup: ui.openRealAccountSignup, - replaceCashierMenuOnclick: modules.cashier.general_store.replaceCashierMenuOnclick, platform: common.platform, removeNotificationMessage: notifications.removeNotificationMessage, toggleAccountsDialog: ui.toggleAccountsDialog, diff --git a/packages/core/src/App/Containers/Layout/header/dtrader-header.jsx b/packages/core/src/App/Containers/Layout/header/dtrader-header.jsx index d2c2a5e07def..9f3f9b1740c9 100644 --- a/packages/core/src/App/Containers/Layout/header/dtrader-header.jsx +++ b/packages/core/src/App/Containers/Layout/header/dtrader-header.jsx @@ -17,8 +17,6 @@ import { TradersHubHomeButton } from './trading-hub-header'; const Divider = () =>
; -const MemoizedMenuLinks = React.memo(MenuLinks); - const DTraderHeader = ({ acc_switcher_disabled_message, account_type, @@ -45,11 +43,9 @@ const DTraderHeader = ({ is_pre_appstore, is_route_modal_on, is_virtual, - menu_items, notifications_count, openRealAccountSignup, platform, - replaceCashierMenuOnclick, removeNotificationMessage, toggleAccountsDialog, toggleNotifications, @@ -111,8 +107,7 @@ const DTraderHeader = ({ - {menu_items && is_logged_in && replaceCashierMenuOnclick()} - +
({ +export default connect(({ client, common, ui, notifications }) => ({ acc_switcher_disabled_message: ui.account_switcher_disabled_message, account_type: client.account_type, addNotificationMessage: notifications.addNotificationMessage, @@ -230,10 +223,8 @@ export default connect(({ client, common, ui, menu, modules, notifications }) => is_notifications_visible: notifications.is_notifications_visible, is_route_modal_on: ui.is_route_modal_on, is_virtual: client.is_virtual, - menu_items: menu.extensions, notifications_count: notifications.notifications.length, openRealAccountSignup: ui.openRealAccountSignup, - replaceCashierMenuOnclick: modules.cashier.general_store.replaceCashierMenuOnclick, platform: common.platform, removeNotificationMessage: notifications.removeNotificationMessage, toggleAccountsDialog: ui.toggleAccountsDialog, diff --git a/packages/core/src/App/Containers/Layout/header/trading-hub-header.jsx b/packages/core/src/App/Containers/Layout/header/trading-hub-header.jsx index ca6f7b89e42d..c7652526b357 100644 --- a/packages/core/src/App/Containers/Layout/header/trading-hub-header.jsx +++ b/packages/core/src/App/Containers/Layout/header/trading-hub-header.jsx @@ -113,7 +113,7 @@ const ShowNotifications = ({ is_notifications_visible, notifications_count, togg
); }; -const MemoizedMenuLinks = React.memo(MenuLinks); + const TradingHubHeader = ({ content_flag, header_extension, @@ -121,15 +121,11 @@ const TradingHubHeader = ({ is_eu_country, is_eu, is_logged_in, - is_mobile, is_mt5_allowed, is_notifications_visible, - is_pre_appstore, loginid, - menu_items, modal_data, notifications_count, - replaceCashierMenuOnclick, setIsOnboardingVisited, setIsPreAppStore, should_show_exit_traders_modal, @@ -165,13 +161,7 @@ const TradingHubHeader = ({ - {menu_items && is_logged_in && replaceCashierMenuOnclick()} - +
@@ -263,16 +253,12 @@ TradingHubHeader.propTypes = { is_eu_country: PropTypes.bool, is_eu: PropTypes.bool, is_logged_in: PropTypes.bool, - is_mobile: PropTypes.bool, is_mt5_allowed: PropTypes.bool, is_notifications_visible: PropTypes.bool, - is_pre_appstore: PropTypes.bool, is_settings_modal_on: PropTypes.bool, loginid: PropTypes.string, - menu_items: PropTypes.array, modal_data: PropTypes.object, notifications_count: PropTypes.number, - replaceCashierMenuOnclick: PropTypes.func, setIsPreAppStore: PropTypes.func, setIsOnboardingVisited: PropTypes.func, settings_extension: PropTypes.array, @@ -284,22 +270,18 @@ TradingHubHeader.propTypes = { switchToCRAccount: PropTypes.func, }; -export default connect(({ client, modules, notifications, ui, menu, traders_hub }) => ({ +export default connect(({ client, notifications, ui, traders_hub }) => ({ header_extension: ui.header_extension, is_dark_mode: ui.is_dark_mode_on, is_eu_country: client.is_eu_country, is_eu: client.is_eu, is_logged_in: client.is_logged_in, - is_mobile: ui.is_mobile, is_mt5_allowed: client.is_mt5_allowed, is_notifications_visible: notifications.is_notifications_visible, - is_pre_appstore: client.is_pre_appstore, modal_data: traders_hub.modal_data, notifications_count: notifications.notifications.length, toggleNotifications: notifications.toggleNotificationsModal, loginid: client.loginid, - menu_items: menu.extensions, - replaceCashierMenuOnclick: modules.cashier.general_store.replaceCashierMenuOnclick, setIsOnboardingVisited: traders_hub.setIsOnboardingVisited, setIsPreAppStore: client.setIsPreAppStore, should_show_exit_traders_modal: traders_hub.should_show_exit_traders_modal, diff --git a/packages/core/src/App/Containers/RealAccountSignup/real-account-signup.jsx b/packages/core/src/App/Containers/RealAccountSignup/real-account-signup.jsx index 4cff6b1edaab..7c1d5240da15 100644 --- a/packages/core/src/App/Containers/RealAccountSignup/real-account-signup.jsx +++ b/packages/core/src/App/Containers/RealAccountSignup/real-account-signup.jsx @@ -112,7 +112,6 @@ const RealAccountSignup = ({ is_real_acc_signup_on, real_account_signup_target, realAccountSignup, - replaceCashierMenuOnclick, routing_history, setIsDeposit, setIsTradingAssessmentForNewUserEnabled, @@ -291,7 +290,6 @@ const RealAccountSignup = ({ }; const closeModalThenOpenCashier = () => { - replaceCashierMenuOnclick(); closeRealAccountSignup(); history.push(routes.cashier_deposit); }; @@ -360,7 +358,6 @@ const RealAccountSignup = ({ }, [is_from_restricted_country, is_real_acc_signup_on]); const closeModal = e => { - replaceCashierMenuOnclick(); // Do not close modal on external link and popover click event if ( e?.target.getAttribute('rel') === 'noopener noreferrer' || @@ -643,7 +640,6 @@ export default connect(({ ui, client, common, traders_hub, modules }) => ({ is_real_acc_signup_on: ui.is_real_acc_signup_on, real_account_signup_target: ui.real_account_signup_target, realAccountSignup: client.realAccountSignup, - replaceCashierMenuOnclick: modules.cashier.general_store.replaceCashierMenuOnclick, routing_history: common.app_routing_history, setCFDScore: client.setCFDScore, setIsDeposit: modules.cashier.general_store.setIsDeposit, diff --git a/packages/core/src/Stores/index.js b/packages/core/src/Stores/index.js index 0c1e8e15cfb3..0a6dad2e6b9d 100644 --- a/packages/core/src/Stores/index.js +++ b/packages/core/src/Stores/index.js @@ -4,7 +4,6 @@ import GTMStore from './gtm-store'; import RudderStackStore from './rudderstack-store'; import PushWooshStore from './pushwoosh-store'; import ModulesStore from './Modules'; -import MenuStore from './menu-store'; import NotificationStore from './notification-store'; import UIStore from './ui-store'; import ActiveSymbolsStore from './active-symbols-store'; @@ -22,7 +21,6 @@ export default class RootStore { this.ui = new UIStore(this); this.gtm = new GTMStore(this); this.rudderstack = new RudderStackStore(this); - this.menu = new MenuStore(this); this.pushwoosh = new PushWooshStore(this); this.notifications = new NotificationStore(this); this.active_symbols = new ActiveSymbolsStore(this); diff --git a/packages/core/src/Stores/menu-store.js b/packages/core/src/Stores/menu-store.js deleted file mode 100644 index 42cf4ef91dfa..000000000000 --- a/packages/core/src/Stores/menu-store.js +++ /dev/null @@ -1,46 +0,0 @@ -import React from 'react'; -import { action, observable, makeObservable } from 'mobx'; -import { Icon } from '@deriv/components'; -import { localize } from '@deriv/translations'; -import { routes } from '@deriv/shared'; -import BaseStore from './base-store'; - -export default class MenuStore extends BaseStore { - extensions = [ - { - id: 'dt_reports_tab', - icon: , - text: () => localize('Reports'), - link_to: routes.reports, - login_only: true, - }, - ]; - - constructor() { - // TODO: [mobx-undecorate] verify the constructor arguments and the arguments of this automatically generated super call - super(); - - makeObservable(this, { - extensions: observable, - attach: action.bound, - detach: action.bound, - }); - } - - attach(menu) { - if (!(menu instanceof Object)) { - throw new TypeError('Menu is not an instance of object.'); - } - this.extensions.push(menu); - } - - update(menu, index) { - if (this.extensions[index]) { - this.extensions[index] = menu; - } - } - - detach(menu) { - this.extensions = this.extensions.filter(extension => extension.id !== menu); - } -} diff --git a/packages/hooks/src/index.ts b/packages/hooks/src/index.ts index 4417d0dd313a..0961e4908618 100644 --- a/packages/hooks/src/index.ts +++ b/packages/hooks/src/index.ts @@ -5,4 +5,7 @@ export { default as useNeedFinancialAssessment } from './useNeedFinancialAssessm export { default as useRealSTPAccount } from './useRealSTPAccount'; export { default as useNeedTNC } from './useNeedTNC'; export { default as useDepositLocked } from './useDepositLocked'; +export { default as useHasSetCurrency } from './useHasSetCurrency'; +export { default as useHasActiveRealAccount } from './useHasActiveRealAccount'; +export { default as useP2PNotificationCount } from './useP2PNotificationCount'; export { default as useOnrampVisible } from './useOnrampVisible'; diff --git a/packages/hooks/src/useHasActiveRealAccount.ts b/packages/hooks/src/useHasActiveRealAccount.ts new file mode 100644 index 000000000000..df58321dfc95 --- /dev/null +++ b/packages/hooks/src/useHasActiveRealAccount.ts @@ -0,0 +1,12 @@ +import { useStore } from '@deriv/stores'; + +const useHasActiveRealAccount = () => { + const { client } = useStore(); + const { active_accounts } = client; + + const has_active_real_account = active_accounts.some(account => account.is_virtual === 0); + + return has_active_real_account; +}; + +export default useHasActiveRealAccount; diff --git a/packages/hooks/src/useHasSetCurrency.ts b/packages/hooks/src/useHasSetCurrency.ts new file mode 100644 index 000000000000..702323dad4a5 --- /dev/null +++ b/packages/hooks/src/useHasSetCurrency.ts @@ -0,0 +1,17 @@ +import { useStore } from '@deriv/stores'; +import useHasActiveRealAccount from './useHasActiveRealAccount'; + +const useHasSetCurrency = () => { + const { client } = useStore(); + const { account_list } = client; + const has_active_real_account = useHasActiveRealAccount(); + const has_real_account = account_list + .filter(account => !account.is_virtual) + .some(account => account.title !== 'Real'); + + const has_set_currency = has_real_account || !has_active_real_account; + + return has_set_currency; +}; + +export default useHasSetCurrency; diff --git a/packages/hooks/src/useP2PNotificationCount.ts b/packages/hooks/src/useP2PNotificationCount.ts new file mode 100644 index 000000000000..ef193a648628 --- /dev/null +++ b/packages/hooks/src/useP2PNotificationCount.ts @@ -0,0 +1,46 @@ +import { useStore } from '@deriv/stores'; +import { useEffect, useState } from 'react'; + +type TNotification = { + order_id: string; + is_seen: boolean; + is_active: boolean; +}; + +type TClientData = { + is_cached: boolean; + notifications: TNotification[]; +}; + +type TP2PSettings = Record; + +const useP2PNotificationCount = () => { + const [p2p_settings, setP2PSettings] = useState( + JSON.parse(localStorage.getItem('p2p_settings') || '{}') + ); + const { client } = useStore(); + const { loginid } = client; + const notifications = loginid ? p2p_settings[loginid]?.notifications : null; + + useEffect(() => { + const onStorageChanged = () => { + const data = localStorage.getItem('p2p_settings'); + + if (data) { + setP2PSettings(JSON.parse(data)); + } + }; + + window.addEventListener('storage', onStorageChanged); + + return () => { + window.removeEventListener('storage', onStorageChanged); + }; + }, []); + + const p2p_notification_count = notifications?.filter(notification => !notification.is_seen).length || 0; + + return p2p_notification_count; +}; + +export default useP2PNotificationCount; diff --git a/packages/p2p/src/stores/general-store.js b/packages/p2p/src/stores/general-store.js index 2f275e2986ca..a63c36269ccf 100644 --- a/packages/p2p/src/stores/general-store.js +++ b/packages/p2p/src/stores/general-store.js @@ -889,6 +889,7 @@ export default class GeneralStore extends BaseStore { p2p_settings[this.client.loginid] = user_settings; localStorage.setItem('p2p_settings', JSON.stringify(p2p_settings)); + window.dispatchEvent(new Event('storage')); this.setNotificationCount(notification_count); this.setActiveNotificationCount(active_notification_count); diff --git a/packages/stores/types.ts b/packages/stores/types.ts index 01b2c79601d2..20d6d864fc34 100644 --- a/packages/stores/types.ts +++ b/packages/stores/types.ts @@ -30,6 +30,7 @@ type TAccountsList = { // balance is missing in @deriv/api-types type TActiveAccount = TAccount & { balance?: number; + is_virtual: number; }; type TAuthenticationStatus = { document_status: string; identity_status: string };