diff --git a/packages/core/src/App/Components/Elements/NotificationMessage/notification-order.jsx b/packages/core/src/App/Components/Elements/NotificationMessage/notification-order.jsx index 09eec8bfaec5..096b4d755591 100644 --- a/packages/core/src/App/Components/Elements/NotificationMessage/notification-order.jsx +++ b/packages/core/src/App/Components/Elements/NotificationMessage/notification-order.jsx @@ -68,9 +68,9 @@ const NotificationOrder = ({ action, header, message, onClose }) => { NotificationOrder.propTypes = { action: PropTypes.object, - header: PropTypes.string, + header: PropTypes.oneOfType([PropTypes.node, PropTypes.string, PropTypes.object]), is_auto_close: PropTypes.bool, - message: PropTypes.string, + message: PropTypes.oneOfType([PropTypes.node, PropTypes.string, PropTypes.object]), onClose: PropTypes.func, }; diff --git a/packages/core/src/App/Components/Elements/NotificationMessage/notification.jsx b/packages/core/src/App/Components/Elements/NotificationMessage/notification.jsx index e74941d52a98..1b33521ac875 100644 --- a/packages/core/src/App/Components/Elements/NotificationMessage/notification.jsx +++ b/packages/core/src/App/Components/Elements/NotificationMessage/notification.jsx @@ -18,6 +18,14 @@ const Notification = ({ data, removeNotificationMessage }) => { const destroy = is_closed_by_user => { removeNotificationMessage(data); + if (data.should_show_again) { + const closed_toast_notifications = JSON.parse(localStorage.getItem('closed_toast_notifications')) ?? []; + if (!closed_toast_notifications.includes(data.key)) { + closed_toast_notifications.push(data.key); + localStorage.setItem('closed_toast_notifications', JSON.stringify(closed_toast_notifications)); + } + } + if (data.closeOnClick) { data.closeOnClick(data, is_closed_by_user); } @@ -29,6 +37,9 @@ const Notification = ({ data, removeNotificationMessage }) => { setTimeout(destroy, data.delay || default_delay); } + const closed_toast_notifications = JSON.parse(localStorage.getItem('closed_toast_notifications')) ?? []; + if (closed_toast_notifications.includes(data.key)) return null; + switch (data.type) { case 'news': return ( @@ -160,18 +171,19 @@ Notification.propTypes = { className: PropTypes.string, closeOnClick: PropTypes.func, delay: PropTypes.number, - header: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), + header: PropTypes.oneOfType([PropTypes.node, PropTypes.string, PropTypes.object]), header_popup: PropTypes.string, img_alt: PropTypes.string, img_src: PropTypes.string, is_auto_close: PropTypes.bool, key: PropTypes.string, icon: PropTypes.string, - message: PropTypes.oneOfType([PropTypes.node, PropTypes.string]), + message: PropTypes.oneOfType([PropTypes.node, PropTypes.string, PropTypes.object]), message_popup: PropTypes.string, primary_btn: PropTypes.object, secondary_btn: PropTypes.object, should_hide_close_btn: PropTypes.bool, + should_show_again: PropTypes.bool, size: PropTypes.oneOf(['small']), timeout: PropTypes.number, timeoutMessage: PropTypes.func, diff --git a/packages/core/src/App/Containers/Layout/header/__tests__/header.spec.tsx b/packages/core/src/App/Containers/Layout/header/__tests__/header.spec.tsx index a3c1cb31dfd0..6982c588716f 100644 --- a/packages/core/src/App/Containers/Layout/header/__tests__/header.spec.tsx +++ b/packages/core/src/App/Containers/Layout/header/__tests__/header.spec.tsx @@ -5,7 +5,7 @@ import { render, screen } from '@testing-library/react'; import Header from '../header'; jest.mock('@deriv/hooks', () => ({ - ...jest.requireActual('react-router-dom'), + ...jest.requireActual('@deriv/hooks'), useFeatureFlags: jest.fn(() => ({ is_next_wallet_enabled: false })), useStoreWalletAccountsList: jest.fn(() => ({ data: [], has_wallet: false })), })); diff --git a/packages/core/src/App/Containers/Layout/header/header.tsx b/packages/core/src/App/Containers/Layout/header/header.tsx index db8471d5a16b..8718e2c629e5 100644 --- a/packages/core/src/App/Containers/Layout/header/header.tsx +++ b/packages/core/src/App/Containers/Layout/header/header.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { useLocation } from 'react-router-dom'; +import { useFeatureFlags, useP2PCompletedOrdersNotification, useStoreWalletAccountsList } from '@deriv/hooks'; import { routes } from '@deriv/shared'; import { observer, useStore } from '@deriv/stores'; -import { useFeatureFlags, useStoreWalletAccountsList } from '@deriv/hooks'; import DefaultHeader from './default-header'; import DTraderHeader from './dtrader-header'; import TradersHubHeader from './traders-hub-header'; @@ -13,6 +13,8 @@ const Header = observer(() => { const { client } = useStore(); const { accounts, is_logged_in, setAccounts, loginid, switchAccount } = client; const { pathname } = useLocation(); + + useP2PCompletedOrdersNotification(); const is_wallets_cashier_route = pathname.includes(routes.wallets_cashier); const traders_hub_routes = diff --git a/packages/core/src/Services/logout.js b/packages/core/src/Services/logout.js index 68b0f195be7b..00873c00690e 100644 --- a/packages/core/src/Services/logout.js +++ b/packages/core/src/Services/logout.js @@ -11,6 +11,7 @@ function endChat() { const doLogout = response => { if (response.logout !== 1) return undefined; removeCookies('affiliate_token', 'affiliate_tracking', 'onfido_token'); + localStorage.removeItem('closed_toast_notifications'); SocketCache.clear(); sessionStorage.clear(); endChat(); diff --git a/packages/core/src/Stores/notification-store.js b/packages/core/src/Stores/notification-store.js index c92bfe1e0899..17af9740022d 100644 --- a/packages/core/src/Stores/notification-store.js +++ b/packages/core/src/Stores/notification-store.js @@ -1,5 +1,4 @@ import React from 'react'; -import debounce from 'lodash.debounce'; import { action, computed, makeObservable, observable, reaction } from 'mobx'; import { StaticUrl } from '@deriv/components'; @@ -53,7 +52,7 @@ export default class NotificationStore extends BaseStore { trade_notifications = []; p2p_order_props = {}; p2p_redirect_to = {}; - p2p_completed_orders = null; + p2p_completed_orders = []; constructor(root_store) { super({ root_store }); @@ -66,7 +65,6 @@ export default class NotificationStore extends BaseStore { addVerificationNotifications: action.bound, client_notifications: observable, filterNotificationMessages: action.bound, - getP2pCompletedOrders: action.bound, handleClientNotifications: action.bound, is_notifications_empty: computed, is_notifications_visible: observable, @@ -98,8 +96,6 @@ export default class NotificationStore extends BaseStore { updateNotifications: action.bound, }); - const debouncedGetP2pCompletedOrders = debounce(this.getP2pCompletedOrders, 1000); - reaction( () => root_store.common.app_routing_history.map(i => i.pathname), () => { @@ -120,17 +116,7 @@ export default class NotificationStore extends BaseStore { this.p2p_order_props.order_id, root_store.client.p2p_advertiser_info, ], - async () => { - if ( - root_store.client.is_logged_in && - !root_store.client.is_virtual && - Object.keys(root_store.client.account_status || {}).length > 0 && - Object.keys(root_store.client.landing_companies || {}).length > 0 && - root_store.client.is_p2p_enabled - ) { - await debouncedGetP2pCompletedOrders(); - } - + () => { if ( !root_store.client.is_logged_in || (Object.keys(root_store.client.account_status || {}).length > 0 && @@ -145,6 +131,12 @@ export default class NotificationStore extends BaseStore { } } ); + reaction( + () => this.p2p_completed_orders, + () => { + this.handleClientNotifications(); + } + ); } get is_notifications_empty() { @@ -640,6 +632,7 @@ export default class NotificationStore extends BaseStore { ), platform: 'P2P', type: 'p2p_completed_order', + should_show_again: true, }); } @@ -682,7 +675,7 @@ export default class NotificationStore extends BaseStore { this.notification_messages = this.notification_messages.filter(n => n.key !== key); // Add notification messages to LocalStore when user closes, check for redundancy const active_loginid = LocalStore.get('active_loginid'); - if (!excluded_notifications.includes(key) && active_loginid) { + if (!excluded_notifications.includes(key) && !key.startsWith('p2p_order') && active_loginid) { let messages = LocalStore.getObject('notification_messages'); // Check if same message already exists in LocalStore for this account if (messages[active_loginid] && messages[active_loginid].includes(key)) { @@ -1617,13 +1610,4 @@ export default class NotificationStore extends BaseStore { platform: 'Account', }); }; - - async getP2pCompletedOrders() { - await WS.wait('authorize'); - const response = await WS.send?.({ p2p_order_list: 1, active: 0 }); - - if (!response?.error) { - this.p2p_completed_orders = response?.p2p_order_list?.list || []; - } - } } diff --git a/packages/hooks/src/__tests__/useP2PCompletedOrdersNotification.spec.tsx b/packages/hooks/src/__tests__/useP2PCompletedOrdersNotification.spec.tsx new file mode 100644 index 000000000000..1a6f4a6d21e1 --- /dev/null +++ b/packages/hooks/src/__tests__/useP2PCompletedOrdersNotification.spec.tsx @@ -0,0 +1,169 @@ +import * as React from 'react'; +import { useFetch, useSubscription } from '@deriv/api'; +import { mockStore, StoreProvider } from '@deriv/stores'; +import { renderHook } from '@testing-library/react-hooks'; +import useP2PCompletedOrdersNotification from '../useP2PCompletedOrdersNotification'; + +jest.mock('@deriv/api', () => ({ + ...jest.requireActual('@deriv/api'), + useFetch: jest.fn(), + useSubscription: jest.fn(), +})); + +const mockUseFetch = useFetch as jest.MockedFunction>; +const mockUseSubscription = useSubscription as jest.MockedFunction>; + +describe('useP2PCompletedOrdersNotification', () => { + test('should unsubscribe from p2p_order_list if user is not authorized', () => { + const mock = mockStore({ + client: { + is_authorize: false, + currency: 'USD', + }, + notifications: { + p2p_completed_orders: [], + }, + }); + + // @ts-expect-error need to come up with a way to mock the return type of useFetch + mockUseFetch.mockReturnValue({ data: { website_status: { p2p_config: { supported_currencies: ['usd'] } } } }); + + // @ts-expect-error need to come up with a way to mock the return type of useSubscription + mockUseSubscription.mockReturnValue({ + subscribe: jest.fn(), + unsubscribe: jest.fn(), + }); + + const wrapper = ({ children }: { children: JSX.Element }) => ( + {children} + ); + + renderHook(() => useP2PCompletedOrdersNotification(), { wrapper }); + + expect(mockUseSubscription('p2p_order_list').unsubscribe).toBeCalled(); + expect(mock.notifications.p2p_completed_orders).toEqual([]); + }); + + test('should unsubscribe from p2p_order_list if user p2p is disabled', () => { + const mock = mockStore({ + client: { + is_authorize: false, + currency: 'EUR', + }, + notifications: { + p2p_completed_orders: [], + }, + }); + + // @ts-expect-error need to come up with a way to mock the return type of useFetch + mockUseFetch.mockReturnValue({ data: { website_status: { p2p_config: { supported_currencies: ['usd'] } } } }); + + // @ts-expect-error need to come up with a way to mock the return type of useSubscription + mockUseSubscription.mockReturnValue({ + subscribe: jest.fn(), + unsubscribe: jest.fn(), + }); + + const wrapper = ({ children }: { children: JSX.Element }) => ( + {children} + ); + + renderHook(() => useP2PCompletedOrdersNotification(), { wrapper }); + + expect(mockUseSubscription('p2p_order_list').unsubscribe).toBeCalled(); + expect(mock.notifications.p2p_completed_orders).toEqual([]); + }); + + test('should subscribe to completed p2p_order_list', () => { + const mock = mockStore({ + client: { + is_authorize: true, + currency: 'USD', + }, + notifications: { + p2p_completed_orders: [], + }, + }); + + // @ts-expect-error need to come up with a way to mock the return type of useFetch + mockUseFetch.mockReturnValue({ data: { website_status: { p2p_config: { supported_currencies: ['usd'] } } } }); + + const mock_p2p_order_list = [ + { + account_currency: 'USD', + advert_details: { + block_trade: 0, + description: 'Created by script. Please call me 02203400', + id: '75', + payment_method: 'bank_transfer', + type: 'sell', + }, + advertiser_details: { + first_name: 'QA script', + id: '38', + is_online: 1, + last_name: 'farhanCpsta', + last_online_time: 1696519153, + loginid: 'CR90000238', + name: 'client CR90000238', + }, + amount: 0.1, + amount_display: '0.10', + chat_channel_url: 'p2porder_CR_52_1696518979', + client_details: { + first_name: 'QA script', + id: '39', + is_online: 1, + is_recommended: null, + last_name: 'farhansrjta', + last_online_time: 1696519090, + loginid: 'CR90000239', + name: 'client CR90000239', + }, + completion_time: 1696518988, + contact_info: 'Created by script. Please call me 02203400', + created_time: 1696518977, + dispute_details: { + dispute_reason: null, + disputer_loginid: null, + }, + expiry_time: 1696522577, + id: '52', + is_incoming: 1, + is_reviewable: 1, + local_currency: 'IDR', + payment_info: 'Transfer to account 000-1111', + price: 1350, + price_display: '1350.00', + rate: 13500, + rate_display: '13500.00', + status: 'completed', + type: 'buy', + }, + ]; + + mockUseSubscription.mockReturnValue({ + data: { + p2p_order_list: { + // @ts-expect-error need to come up with a way to mock the return type of useSubscription + list: mock_p2p_order_list, + }, + }, + subscribe: jest.fn(), + unsubscribe: jest.fn(), + }); + + const wrapper = ({ children }: { children: JSX.Element }) => ( + {children} + ); + + renderHook(() => useP2PCompletedOrdersNotification(), { wrapper }); + + expect(mockUseSubscription('p2p_order_list').subscribe).toBeCalledWith({ + payload: { + active: 0, + }, + }); + expect(mock.notifications.p2p_completed_orders).toEqual(mock_p2p_order_list); + }); +}); diff --git a/packages/hooks/src/__tests__/useP2POrderList.spec.tsx b/packages/hooks/src/__tests__/useP2POrderList.spec.tsx new file mode 100644 index 000000000000..0accb4fc1952 --- /dev/null +++ b/packages/hooks/src/__tests__/useP2POrderList.spec.tsx @@ -0,0 +1,106 @@ +import * as React from 'react'; +import { mockStore, StoreProvider } from '@deriv/stores'; +import { renderHook } from '@testing-library/react-hooks'; +import useP2POrderList from '../useP2POrderList'; +import { useSubscription } from '@deriv/api'; + +jest.mock('@deriv/api', () => ({ + ...jest.requireActual('@deriv/api'), + useSubscription: jest.fn(), +})); + +const mockUseSubscription = useSubscription as jest.MockedFunction>; + +describe('useP2POrderList', () => { + test('should return undefined if there is no order', () => { + const mock = mockStore({}); + + // @ts-expect-error need to come up with a way to mock the return type of useSubscription + mockUseSubscription.mockReturnValue({ + subscribe: jest.fn(), + }); + + const wrapper = ({ children }: { children: JSX.Element }) => ( + {children} + ); + + const { result } = renderHook(() => useP2POrderList(), { wrapper }); + + expect(result.current.data?.p2p_order_list?.list).toBeUndefined(); + }); + + test('should return p2p order list', () => { + const mock = mockStore({}); + const mock_p2p_order_list = [ + { + account_currency: 'USD', + advert_details: { + block_trade: 0, + description: 'Created by script. Please call me 02203400', + id: '75', + payment_method: 'bank_transfer', + type: 'sell', + }, + advertiser_details: { + first_name: 'QA script', + id: '38', + is_online: 1, + last_name: 'farhanCpsta', + last_online_time: 1696519153, + loginid: 'CR90000238', + name: 'client CR90000238', + }, + amount: 0.1, + amount_display: '0.10', + chat_channel_url: 'p2porder_CR_52_1696518979', + client_details: { + first_name: 'QA script', + id: '39', + is_online: 1, + is_recommended: null, + last_name: 'farhansrjta', + last_online_time: 1696519090, + loginid: 'CR90000239', + name: 'client CR90000239', + }, + completion_time: 1696518988, + contact_info: 'Created by script. Please call me 02203400', + created_time: 1696518977, + dispute_details: { + dispute_reason: null, + disputer_loginid: null, + }, + expiry_time: 1696522577, + id: '52', + is_incoming: 1, + is_reviewable: 1, + local_currency: 'IDR', + payment_info: 'Transfer to account 000-1111', + price: 1350, + price_display: '1350.00', + rate: 13500, + rate_display: '13500.00', + status: 'completed', + type: 'buy', + }, + ]; + + mockUseSubscription.mockReturnValue({ + data: { + p2p_order_list: { + // @ts-expect-error need to come up with a way to mock the return type of useSubscription + list: mock_p2p_order_list, + }, + }, + subscribe: jest.fn(), + }); + + const wrapper = ({ children }: { children: JSX.Element }) => ( + {children} + ); + + const { result } = renderHook(() => useP2POrderList(), { wrapper }); + + expect(result.current.data?.p2p_order_list?.list).toBe(mock_p2p_order_list); + }); +}); diff --git a/packages/hooks/src/index.ts b/packages/hooks/src/index.ts index 7c0489bf2948..9c869e414d54 100644 --- a/packages/hooks/src/index.ts +++ b/packages/hooks/src/index.ts @@ -21,6 +21,7 @@ export { default as useExchangeRate } from './useExchangeRate'; export { default as useExistingCFDAccounts } from './useExistingCFDAccounts'; export { default as useFeatureFlags } from './useFeatureFlags'; export { default as useFiatAccountList } from './useFiatAccountList'; +export { default as useFileUploader } from './useFileUploader'; export { default as useGetMFAccountStatus } from './useGetMFAccountStatus'; export { default as useHasActiveRealAccount } from './useHasActiveRealAccount'; export { default as useHasCryptoCurrency } from './useHasCryptoCurrency'; @@ -39,38 +40,39 @@ export { default as useIsClientHighRiskForMT5 } from './useIsClientHighRiskForMT export { default as useIsP2PEnabled } from './useIsP2PEnabled'; export { default as useIsRealAccountNeededForCashier } from './useIsRealAccountNeededForCashier'; export { default as useIsSystemMaintenance } from './useIsSystemMaintenance'; +export { default as useLandingCompanyDetails } from './useLandingCompanyDetails'; export { default as useLocalStorageData } from './useLocalStorageData'; export { default as useMFAccountStatus } from './useMFAccountStatus'; +export { default as useMT5SVGEligibleToMigrate } from './useMT5SVGEligibleToMigrate'; export { default as useNeedAuthentication } from './useNeedAuthentication'; export { default as useNeedFinancialAssessment } from './useNeedFinancialAssessment'; export { default as useNeedPOI } from './useNeedPOI'; export { default as useNeedTNC } from './useNeedTNC'; +export { default as useNotificationEvent } from './useNotificationEvent'; export { default as useOnrampVisible } from './useOnrampVisible'; export { default as useP2PAdvertInfo } from './useP2PAdvertInfo'; -export { default as useP2PAdvertiserPaymentMethods } from './useP2PAdvertiserPaymentMethods'; export { default as useP2PAdvertList } from './useP2PAdvertList'; +export { default as useP2PAdvertiserPaymentMethods } from './useP2PAdvertiserPaymentMethods'; +export { default as useP2PCompletedOrdersNotification } from './useP2PCompletedOrdersNotification'; export { default as useP2PConfig } from './useP2PConfig'; +export { default as useP2PExchangeRate } from './useP2PExchangeRate'; export { default as useP2PNotificationCount } from './useP2PNotificationCount'; +export { default as useP2POrderList } from './useP2POrderList'; export { default as useP2PPaymentMethods } from './useP2PPaymentMethods'; -export { default as useP2PExchangeRate } from './useP2PExchangeRate'; export { default as usePaymentAgentList } from './usePaymentAgentList'; export { default as usePaymentAgentTransferVisible } from './usePaymentAgentTransferVisible'; export { default as usePlatformAccounts } from './usePlatformAccounts'; export { default as usePlatformDemoAccount } from './usePlatformDemoAccount'; export { default as usePlatformRealAccounts } from './usePlatformRealAccounts'; export { default as useRealSTPAccount } from './useRealSTPAccount'; +export { default as useServiceToken } from './useServiceToken'; export { default as useStatesList } from './useStatesList'; +export { default as useStoreLinkedWalletsAccounts } from './useStoreLinkedWalletsAccounts'; +export { default as useStoreWalletAccountsList } from './useStoreWalletAccountsList'; export { default as useTotalAccountBalance } from './useTotalAccountBalance'; export { default as useTransferBetweenAccounts } from './useTransferBetweenAccounts'; export { default as useVerifyEmail } from './useVerifyEmail'; -export { default as useMT5SVGEligibleToMigrate } from './useMT5SVGEligibleToMigrate'; 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 useNotificationEvent } from './useNotificationEvent'; -export { default as useServiceToken } from './useServiceToken'; -export { default as useFileUploader } from './useFileUploader'; -export { default as useStoreWalletAccountsList } from './useStoreWalletAccountsList'; -export { default as useStoreLinkedWalletsAccounts } from './useStoreLinkedWalletsAccounts'; -export { default as useLandingCompanyDetails } from './useLandingCompanyDetails'; diff --git a/packages/hooks/src/useP2PCompletedOrdersNotification.ts b/packages/hooks/src/useP2PCompletedOrdersNotification.ts new file mode 100644 index 000000000000..c7df245d263c --- /dev/null +++ b/packages/hooks/src/useP2PCompletedOrdersNotification.ts @@ -0,0 +1,54 @@ +import React from 'react'; +import { useStore } from '@deriv/stores'; +import useIsP2PEnabled from './useIsP2PEnabled'; +import useP2POrderList from './useP2POrderList'; + +const useP2PCompletedOrdersNotification = () => { + const { data: is_p2p_enabled } = useIsP2PEnabled(); + const { subscribe, data, unsubscribe } = useP2POrderList(); + const { client, notifications } = useStore(); + const { is_authorize } = client; + + React.useEffect(() => { + if (is_authorize && is_p2p_enabled) { + subscribe({ + payload: { + active: 0, + }, + }); + } else { + unsubscribe(); + } + }, [is_authorize, is_p2p_enabled, subscribe, unsubscribe]); + + React.useEffect(() => { + if (data?.p2p_order_list?.list.length && data?.p2p_order_list?.list !== notifications.p2p_completed_orders) { + notifications.p2p_completed_orders = data.p2p_order_list.list; + } + // @ts-expect-error `p2p_order_list` return individual `p2p_order_info` if order info updated + else if (data?.p2p_order_info) { + if (notifications?.p2p_completed_orders) { + // replace order if order id is in the list + // @ts-expect-error `p2p_order_list` return individual `p2p_order_info` if order info updated + if (notifications?.p2p_completed_orders.some(order => order.id === data.p2p_order_info.id)) { + const index = notifications?.p2p_completed_orders.findIndex( + // @ts-expect-error `p2p_order_list` return individual `p2p_order_info` if order info updated + order => order.id === data.p2p_order_info.id + ); + // @ts-expect-error `p2p_order_list` return individual `p2p_order_info` if order info updated + notifications?.p2p_completed_orders.splice(index, 1, data.p2p_order_info); + } + // add order if order id is not in the list + else { + // @ts-expect-error `p2p_order_list` return individual `p2p_order_info` if order info updated + notifications?.p2p_completed_orders.unshift(data.p2p_order_info); + } + } + } + notifications?.p2p_completed_orders?.sort((a, b) => { + return (b.completion_time || 0) - (a.completion_time || 0); + }); + }, [data, notifications]); +}; + +export default useP2PCompletedOrdersNotification; diff --git a/packages/hooks/src/useP2POrderList.ts b/packages/hooks/src/useP2POrderList.ts new file mode 100644 index 000000000000..eda48d22608b --- /dev/null +++ b/packages/hooks/src/useP2POrderList.ts @@ -0,0 +1,14 @@ +import { useSubscription } from '@deriv/api'; + +/** A custom hook to subscribe to p2p_order_list */ +const useP2POrderList = () => { + const { data, ...rest } = useSubscription('p2p_order_list'); + + return { + /** List of p2p orders for the current user */ + data, + ...rest, + }; +}; + +export default useP2POrderList; diff --git a/packages/stores/src/mockStore.ts b/packages/stores/src/mockStore.ts index eaacf08a0ed5..e2fc0ddc4b05 100644 --- a/packages/stores/src/mockStore.ts +++ b/packages/stores/src/mockStore.ts @@ -542,6 +542,7 @@ const mock = (): TStores & { is_mock: boolean } => { is_notifications_visible: false, filterNotificationMessages: jest.fn(), notifications: [], + p2p_completed_orders: [], refreshNotifications: jest.fn(), removeAllNotificationMessages: jest.fn(), removeNotifications: jest.fn(), diff --git a/packages/stores/types.ts b/packages/stores/types.ts index 6d9913c1d7bf..5b9e16f8843c 100644 --- a/packages/stores/types.ts +++ b/packages/stores/types.ts @@ -20,6 +20,7 @@ import type { SetFinancialAssessmentResponse, StatesList, Transaction, + P2POrderListResponse, WebsiteStatus, } from '@deriv/api-types'; @@ -938,6 +939,7 @@ type TNotificationStore = { is_notifications_visible: boolean; filterNotificationMessages: () => void; notifications: TNotificationMessage[]; + p2p_completed_orders: NonNullable['list']; refreshNotifications: () => void; removeAllNotificationMessages: (should_close_persistent: boolean) => void; removeNotifications: (should_close_persistent: boolean) => void;