From bbd1b547c33ee99f28c02bdfacaba0a663c1e1a6 Mon Sep 17 00:00:00 2001 From: Farrah Mae Ochoa Date: Mon, 16 Sep 2024 14:43:19 +0400 Subject: [PATCH 01/39] fix: cypress bugs --- src/components/BuySellForm/BuySellForm.tsx | 1 + .../BuySellPaymentSection/BuySellPaymentSection.tsx | 4 +++- .../__tests__/BuySellPaymentSection.spec.tsx | 5 ++++- .../AdCreateEditSuccessModal/AdCreateEditSuccessModal.tsx | 4 ++-- .../__tests__/AdCreateEditSuccessModal.spec.tsx | 2 +- .../Modals/OrderTimeTooltipModal/OrderTimeTooltipModal.tsx | 2 +- .../__tests__/OrderTimeTooltipModal.spec.tsx | 2 +- .../AdvertiserBlockOverlay/AdvertiserBlockOverlay.tsx | 5 ++++- src/pages/my-ads/components/AdTypeSection/AdTypeSection.tsx | 4 ++++ src/pages/orders/components/ChatFooter/ChatFooter.tsx | 2 +- .../components/ChatFooter/__tests__/ChatFooter.spec.tsx | 2 +- src/utils/ad-utils.ts | 4 ++-- 12 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/components/BuySellForm/BuySellForm.tsx b/src/components/BuySellForm/BuySellForm.tsx index 10257232..2b1374cc 100644 --- a/src/components/BuySellForm/BuySellForm.tsx +++ b/src/components/BuySellForm/BuySellForm.tsx @@ -319,6 +319,7 @@ const BuySellForm = ({ advertId, isModalOpen, onRequestClose }: TBuySellFormProp {isBuy && paymentMethodNames && paymentMethodNames?.length > 0 && ( void; @@ -17,6 +18,7 @@ type TBuySellPaymentSectionProps = { }; const BuySellPaymentSection = ({ + advertiserPaymentMethods, availablePaymentMethods, isDisabled = false, onSelectPaymentMethodCard, @@ -58,7 +60,7 @@ const BuySellPaymentSection = ({ - {sortedList && sortedList.length > 0 ? ( + {advertiserPaymentMethods?.length > 0 ? ( ) : ( diff --git a/src/components/BuySellForm/BuySellPaymentSection/__tests__/BuySellPaymentSection.spec.tsx b/src/components/BuySellForm/BuySellPaymentSection/__tests__/BuySellPaymentSection.spec.tsx index fa3c1fcd..11029d2a 100644 --- a/src/components/BuySellForm/BuySellPaymentSection/__tests__/BuySellPaymentSection.spec.tsx +++ b/src/components/BuySellForm/BuySellPaymentSection/__tests__/BuySellPaymentSection.spec.tsx @@ -6,6 +6,7 @@ import BuySellPaymentSection from '../BuySellPaymentSection'; type TType = 'memo' | 'text'; const mockProps = { + advertiserPaymentMethods: [], availablePaymentMethods: [], isDisabled: false, onSelectPaymentMethodCard: jest.fn(), @@ -63,7 +64,9 @@ describe('', () => { it('should render the payment method cards when there are available payment methods', async () => { render(); expect(screen.getByText('Receive payment to')).toBeInTheDocument(); - expect(screen.getByText('You may choose up to 3.')).toBeInTheDocument(); + expect( + screen.getByText('To place an order, add one of the advertiser’s preferred payment methods:') + ).toBeInTheDocument(); expect(screen.getByText('Other')).toBeInTheDocument(); const checkbox = screen.getByRole('checkbox'); await userEvent.click(checkbox); diff --git a/src/components/Modals/AdCreateEditSuccessModal/AdCreateEditSuccessModal.tsx b/src/components/Modals/AdCreateEditSuccessModal/AdCreateEditSuccessModal.tsx index 2ef6ddaf..403dbbef 100644 --- a/src/components/Modals/AdCreateEditSuccessModal/AdCreateEditSuccessModal.tsx +++ b/src/components/Modals/AdCreateEditSuccessModal/AdCreateEditSuccessModal.tsx @@ -52,14 +52,14 @@ const AdCreateEditSuccessModal = ({ } + label={} name='ad-create-success-message' onChange={onToggleCheckbox} /> diff --git a/src/components/Modals/AdCreateEditSuccessModal/__tests__/AdCreateEditSuccessModal.spec.tsx b/src/components/Modals/AdCreateEditSuccessModal/__tests__/AdCreateEditSuccessModal.spec.tsx index ade25746..801e0087 100644 --- a/src/components/Modals/AdCreateEditSuccessModal/__tests__/AdCreateEditSuccessModal.spec.tsx +++ b/src/components/Modals/AdCreateEditSuccessModal/__tests__/AdCreateEditSuccessModal.spec.tsx @@ -46,7 +46,7 @@ describe('AdCreateEditSuccessModal', () => { }); it('should handle ok button click', async () => { render(); - const okButton = screen.getByRole('button', { name: 'Ok' }); + const okButton = screen.getByRole('button', { name: 'OK' }); expect(okButton).toBeInTheDocument(); await userEvent.click(okButton); expect(mockProps.onRequestClose).toBeCalledTimes(1); diff --git a/src/components/Modals/OrderTimeTooltipModal/OrderTimeTooltipModal.tsx b/src/components/Modals/OrderTimeTooltipModal/OrderTimeTooltipModal.tsx index 6a75eada..e59dc288 100644 --- a/src/components/Modals/OrderTimeTooltipModal/OrderTimeTooltipModal.tsx +++ b/src/components/Modals/OrderTimeTooltipModal/OrderTimeTooltipModal.tsx @@ -19,7 +19,7 @@ const OrderTimeTooltipModal = ({ isModalOpen, onRequestClose }: TOrderTimeToolti diff --git a/src/components/Modals/OrderTimeTooltipModal/__tests__/OrderTimeTooltipModal.spec.tsx b/src/components/Modals/OrderTimeTooltipModal/__tests__/OrderTimeTooltipModal.spec.tsx index 00b39c7b..bc7b3bc6 100644 --- a/src/components/Modals/OrderTimeTooltipModal/__tests__/OrderTimeTooltipModal.spec.tsx +++ b/src/components/Modals/OrderTimeTooltipModal/__tests__/OrderTimeTooltipModal.spec.tsx @@ -14,7 +14,7 @@ describe('', () => { }); it('should handle the onclick for ok button', async () => { render(); - const okButton = screen.getByRole('button', { name: 'Ok' }); + const okButton = screen.getByRole('button', { name: 'OK' }); await userEvent.click(okButton); expect(mockProps.onRequestClose).toBeCalledTimes(1); }); diff --git a/src/pages/advertiser/screens/AdvertiserBlockOverlay/AdvertiserBlockOverlay.tsx b/src/pages/advertiser/screens/AdvertiserBlockOverlay/AdvertiserBlockOverlay.tsx index 298aa820..73edf3fb 100644 --- a/src/pages/advertiser/screens/AdvertiserBlockOverlay/AdvertiserBlockOverlay.tsx +++ b/src/pages/advertiser/screens/AdvertiserBlockOverlay/AdvertiserBlockOverlay.tsx @@ -32,7 +32,10 @@ const AdvertiserBlockOverlay = ({ size={isDesktop ? 'md' : 'lg'} weight='bold' > - + - diff --git a/src/components/ProfileContent/ProfileDailyLimit/ProfileDailyLimit.tsx b/src/components/ProfileContent/ProfileDailyLimit/ProfileDailyLimit.tsx index 25a7e6a0..cbfe8062 100644 --- a/src/components/ProfileContent/ProfileDailyLimit/ProfileDailyLimit.tsx +++ b/src/components/ProfileContent/ProfileDailyLimit/ProfileDailyLimit.tsx @@ -3,6 +3,7 @@ import { api } from '@/hooks'; import { useAdvertiserStats, useModalManager } from '@/hooks/custom-hooks'; import { Localize } from '@deriv-com/translations'; import { Button, Text, useDevice } from '@deriv-com/ui'; +import { FormatUtils } from '@deriv-com/utils'; import './ProfileDailyLimit.scss'; const ProfileDailyLimit = () => { @@ -21,8 +22,12 @@ const ProfileDailyLimit = () => { i18n_default_text='Want to increase your daily limits to <0>{{maxDailyBuy}} {{currency}} (buy) and <1>{{maxDailySell}} {{currency}} (sell)?' values={{ currency: activeAccount?.currency, - maxDailyBuy: advertiserStats?.daily_buy_limit, - maxDailySell: advertiserStats?.daily_sell_limit, + maxDailyBuy: FormatUtils.formatMoney( + advertiserStats?.upgradable_daily_limits?.max_daily_buy + ), + maxDailySell: FormatUtils.formatMoney( + advertiserStats?.upgradable_daily_limits?.max_daily_sell + ), }} /> diff --git a/src/constants/index.ts b/src/constants/index.ts index 01676826..7a662fd7 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -4,6 +4,7 @@ export * from './buy-sell'; export * from './chat-constants'; export * from './firebase-init-data'; export * from './languages'; +export * from './notification'; export * from './orders'; export * from './p2p-logo'; export * from './payment-methods'; diff --git a/src/constants/notification.ts b/src/constants/notification.ts new file mode 100644 index 00000000..2b4a40fb --- /dev/null +++ b/src/constants/notification.ts @@ -0,0 +1,41 @@ +import { TLocalize } from 'types'; +import { FormatUtils } from '@deriv-com/utils'; + +export const getNotification = (localize: TLocalize, messageKey: string, payload?: string) => { + const values = payload ? JSON.parse(payload) : {}; + const notification = { + actionText: '', + buttonAction: () => {}, + message: '', + title: '', + }; + + switch (messageKey) { + case 'p2p-order-complete': + notification.title = localize('Your order {{order_id}} is complete', values); + notification.message = localize( + '{{name}} has released your funds. Would you like to give your feedback?', + values + ); + notification.actionText = localize('Give feedback', values); + + break; + case 'p2p-limit-upgrade-available': + notification.title = localize('Enjoy higher daily limits', values); + notification.message = localize( + 'Would you like to increase your daily limits to {{new_buy_limit}} {{currency}} (buy) and {{new_sell_limit}} {{currency}} (sell)?', + { + currency: values.account_currency, + new_buy_limit: FormatUtils.formatMoney(values.new_buy_limit), + new_sell_limit: FormatUtils.formatMoney(values.new_sell_limit), + } + ); + notification.actionText = localize('Yes, increase my limits'); + + break; + default: + notification.message = messageKey; + } + + return notification; +}; diff --git a/src/hooks/api/index.ts b/src/hooks/api/index.ts index 46ae17ba..e296660f 100644 --- a/src/hooks/api/index.ts +++ b/src/hooks/api/index.ts @@ -4,6 +4,7 @@ export * from './advertiser'; export * from './chat'; export * from './counterparty'; export * from './exchange-rates'; +export * as notification from './notification'; export * from './order'; export * from './order-dispute'; export * from './order-review'; diff --git a/src/hooks/api/notification/__tests__/useNotificationList.spec.ts b/src/hooks/api/notification/__tests__/useNotificationList.spec.ts new file mode 100644 index 00000000..446b1a09 --- /dev/null +++ b/src/hooks/api/notification/__tests__/useNotificationList.spec.ts @@ -0,0 +1,36 @@ +import { renderHook } from '@testing-library/react'; +import useNotificationList from '../useNotificationList'; + +const mockNotificationListData = { + data: { + notifications_list: { + messages: [ + { + category: 'see', + message_key: 'p2p-limit-upgrade-available', + }, + { + category: 'see', + message_key: 'poi-verified', + }, + ], + }, + }, +}; + +jest.mock('@deriv-com/api-hooks', () => ({ + useSubscribe: jest.fn(() => mockNotificationListData), +})); + +describe('useNotificationList', () => { + it('should return the list of p2p-related notifications', () => { + const { result } = renderHook(() => useNotificationList()); + + expect(result.current.data).toEqual([ + { + category: 'see', + message_key: 'p2p-limit-upgrade-available', + }, + ]); + }); +}); diff --git a/src/hooks/api/notification/index.ts b/src/hooks/api/notification/index.ts new file mode 100644 index 00000000..0db7a4b1 --- /dev/null +++ b/src/hooks/api/notification/index.ts @@ -0,0 +1,2 @@ +export { default as useGetList } from './useNotificationList'; +export { default as useUpdate } from './useNotificationUpdate'; diff --git a/src/hooks/api/notification/useNotificationList.ts b/src/hooks/api/notification/useNotificationList.ts new file mode 100644 index 00000000..9ff7adbb --- /dev/null +++ b/src/hooks/api/notification/useNotificationList.ts @@ -0,0 +1,32 @@ +import { useMemo } from 'react'; +import { useSubscribe } from '@deriv-com/api-hooks'; + +/** + * Hook that returns the list of notifications. + * + * @example const { data: notifications } = useNotificationList(); + */ +const useNotificationList = () => { + // @ts-expect-error Type undefined. This endpoint will be added to api-hooks. + const { data, ...rest } = useSubscribe('notifications_list'); + + const modified_data = useMemo(() => { + // @ts-expect-error Type undefined. + if (!data?.notifications_list.messages) return undefined; + + // TODO: Remove this filter once all the notifications are implemented + // @ts-expect-error Type undefined. + const notifications = data?.notifications_list.messages.filter((notification: { message_key: string }) => + ['p2p-limit-upgrade-available'].includes(notification.message_key) + ); + + return notifications; + }, [data]); + + return { + data: modified_data || [], + ...rest, + }; +}; + +export default useNotificationList; diff --git a/src/hooks/api/notification/useNotificationUpdate.ts b/src/hooks/api/notification/useNotificationUpdate.ts new file mode 100644 index 00000000..8eeb47f5 --- /dev/null +++ b/src/hooks/api/notification/useNotificationUpdate.ts @@ -0,0 +1,25 @@ +import { useMutation } from '@deriv-com/api-hooks'; + +/** + * Hook that updates the status of a notification. The notification can be removed or marked as read or unread. + * + * @example + * const { data, mutate } = useNotificationUpdate(); + * mutate({ notifications_update_status: 'read', ids: [notification_id]}); + * mutate({ notifications_update_status: 'unread', ids: [notification_id]}); + * mutate({ notifications_update_status: 'remove', ids: []}); + */ +const useNotificationUpdate = () => { + const { data, ...rest } = useMutation({ + // @ts-expect-error Type undefined. This endpoint will be added to api-hooks. + name: 'notifications_update_status', + }); + + return { + // @ts-expect-error Type undefined. + data: data?.notifications_update_status, + ...rest, + }; +}; + +export default useNotificationUpdate; diff --git a/src/hooks/custom-hooks/index.ts b/src/hooks/custom-hooks/index.ts index 64e06c1b..a8fe9d0b 100644 --- a/src/hooks/custom-hooks/index.ts +++ b/src/hooks/custom-hooks/index.ts @@ -6,6 +6,7 @@ export { default as useExtendedOrderDetails } from './useExtendedOrderDetails'; export { default as useFetchMore } from './useFetchMore'; export { default as useFloatingRate } from './useFloatingRate'; export { default as useFullScreen } from './useFullScreen'; +export { default as useGrowthbookGetFeatureValue } from './useGrowthbookGetFeatureValue'; export { default as useHandleRouteChange } from './useHandleRouteChange'; export { default as useIsAdvertiser } from './useIsAdvertiser'; export { default as useIsAdvertiserBarred } from './useIsAdvertiserBarred'; From f6be0d2c67a2b8d5ff30282951fb26a928c82449 Mon Sep 17 00:00:00 2001 From: Farrah Mae Ochoa Date: Wed, 4 Sep 2024 10:31:20 +0400 Subject: [PATCH 04/39] fix: buy/sell limit --- .../ProfileContent/ProfileDailyLimit/ProfileDailyLimit.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/ProfileContent/ProfileDailyLimit/ProfileDailyLimit.tsx b/src/components/ProfileContent/ProfileDailyLimit/ProfileDailyLimit.tsx index cbfe8062..5639575c 100644 --- a/src/components/ProfileContent/ProfileDailyLimit/ProfileDailyLimit.tsx +++ b/src/components/ProfileContent/ProfileDailyLimit/ProfileDailyLimit.tsx @@ -23,10 +23,10 @@ const ProfileDailyLimit = () => { values={{ currency: activeAccount?.currency, maxDailyBuy: FormatUtils.formatMoney( - advertiserStats?.upgradable_daily_limits?.max_daily_buy + Number(advertiserStats?.upgradable_daily_limits?.max_daily_buy) ), maxDailySell: FormatUtils.formatMoney( - advertiserStats?.upgradable_daily_limits?.max_daily_sell + Number(advertiserStats?.upgradable_daily_limits?.max_daily_sell) ), }} /> From 89ce02ee10911f3512fb8bdb54f2c777085e5959 Mon Sep 17 00:00:00 2001 From: Farrah Mae Ochoa Date: Wed, 4 Sep 2024 10:49:54 +0400 Subject: [PATCH 05/39] fix: test --- .../Modals/DailyLimitModal/__tests__/DailyLimitModal.spec.tsx | 3 +++ src/constants/notification.ts | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/Modals/DailyLimitModal/__tests__/DailyLimitModal.spec.tsx b/src/components/Modals/DailyLimitModal/__tests__/DailyLimitModal.spec.tsx index 9d46c8bd..ca802f9a 100644 --- a/src/components/Modals/DailyLimitModal/__tests__/DailyLimitModal.spec.tsx +++ b/src/components/Modals/DailyLimitModal/__tests__/DailyLimitModal.spec.tsx @@ -21,6 +21,9 @@ jest.mock('@/hooks', () => ({ advertiser: { useUpdate: jest.fn(() => mockUseAdvertiserUpdate), }, + notification: { + useUpdate: jest.fn(() => ({ mutate: jest.fn() })), + }, }, })); diff --git a/src/constants/notification.ts b/src/constants/notification.ts index 2b4a40fb..c9d9f856 100644 --- a/src/constants/notification.ts +++ b/src/constants/notification.ts @@ -5,7 +5,6 @@ export const getNotification = (localize: TLocalize, messageKey: string, payload const values = payload ? JSON.parse(payload) : {}; const notification = { actionText: '', - buttonAction: () => {}, message: '', title: '', }; From e5c5d3b316106e73da4e34bd9529cb847abbd122 Mon Sep 17 00:00:00 2001 From: Farrah Mae Ochoa Date: Thu, 5 Sep 2024 16:06:17 +0400 Subject: [PATCH 06/39] fix: subscription --- .../api/notification/useNotificationList.ts | 55 +++++++++++++++++-- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/src/hooks/api/notification/useNotificationList.ts b/src/hooks/api/notification/useNotificationList.ts index 9ff7adbb..09a7aad1 100644 --- a/src/hooks/api/notification/useNotificationList.ts +++ b/src/hooks/api/notification/useNotificationList.ts @@ -1,6 +1,42 @@ -import { useMemo } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import { useSubscribe } from '@deriv-com/api-hooks'; +type TNotificationLinks = { + href: string; + rel: string; +}; +type TNotification = { + category: string; + id: number; + links: TNotificationLinks[]; + message_key: string; + payload: string; + read: boolean; + removed: boolean; +}; + +const handleData = (incomingMessages: TNotification[], prevMessages: TNotification[]) => { + if (!incomingMessages) return prevMessages; + + let notifications = prevMessages; + for (let updateIdx = 0; updateIdx < incomingMessages.length; updateIdx++) { + const update = incomingMessages[updateIdx]; + + const existingMessageIndex = notifications.findIndex((message: TNotification) => message.id === update.id); + const existingMessage = notifications[existingMessageIndex]; + + if (existingMessage) { + if (update.removed) + notifications = notifications.filter((message: TNotification) => message.id !== update.id); + else notifications[existingMessageIndex] = { ...existingMessage, ...update }; + } else notifications.unshift(update); + } + + notifications.sort((a: TNotification, b: TNotification) => b.id - a.id); + + return [...notifications]; +}; + /** * Hook that returns the list of notifications. * @@ -9,18 +45,27 @@ import { useSubscribe } from '@deriv-com/api-hooks'; const useNotificationList = () => { // @ts-expect-error Type undefined. This endpoint will be added to api-hooks. const { data, ...rest } = useSubscribe('notifications_list'); + const [messages, setMessages] = useState([]); const modified_data = useMemo(() => { - // @ts-expect-error Type undefined. - if (!data?.notifications_list.messages) return undefined; + if (!messages) return undefined; // TODO: Remove this filter once all the notifications are implemented - // @ts-expect-error Type undefined. - const notifications = data?.notifications_list.messages.filter((notification: { message_key: string }) => + const notifications = messages.filter((notification: { message_key: string }) => ['p2p-limit-upgrade-available'].includes(notification.message_key) ); return notifications; + }, [messages]); + + useEffect(() => { + // @ts-expect-error Type undefined. + if (data?.notifications_list) { + setMessages(prevMessages => { + // @ts-expect-error Type undefined. + return handleData(data.notifications_list.messages, prevMessages); + }); + } }, [data]); return { From e8a7db8d0f0b0a9ac0982d8ebed3529651e93d50 Mon Sep 17 00:00:00 2001 From: Farrah Mae Ochoa Date: Thu, 5 Sep 2024 16:18:57 +0400 Subject: [PATCH 07/39] fix: remove text size --- src/components/AppHeader/Notifications/Notifications.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/AppHeader/Notifications/Notifications.tsx b/src/components/AppHeader/Notifications/Notifications.tsx index 28c62a53..472ef52a 100644 --- a/src/components/AppHeader/Notifications/Notifications.tsx +++ b/src/components/AppHeader/Notifications/Notifications.tsx @@ -5,7 +5,7 @@ import { getNotification, MY_PROFILE_URL } from '@/constants'; import { api } from '@/hooks'; import { LegacyAnnouncementIcon, LegacyNotificationIcon } from '@deriv/quill-icons'; import { useTranslations } from '@deriv-com/translations'; -import { Badge, Notifications as UINotifications, Text, useDevice } from '@deriv-com/ui'; +import { Badge, Notifications as UINotifications, useDevice } from '@deriv-com/ui'; const Notifications = () => { const [isOpen, setIsOpen] = useState(false); @@ -32,7 +32,7 @@ const Notifications = () => { setIsOpen(false); }, icon: , - message: {message}, + message, title, }; }); From 300c4c07aba4004d7aa634c2bf0f3ee8dd9b817a Mon Sep 17 00:00:00 2001 From: Farrah Mae Ochoa Date: Thu, 5 Sep 2024 17:08:16 +0400 Subject: [PATCH 08/39] fix: test --- .../api/notification/__tests__/useNotificationList.spec.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hooks/api/notification/__tests__/useNotificationList.spec.ts b/src/hooks/api/notification/__tests__/useNotificationList.spec.ts index 446b1a09..bf2a772e 100644 --- a/src/hooks/api/notification/__tests__/useNotificationList.spec.ts +++ b/src/hooks/api/notification/__tests__/useNotificationList.spec.ts @@ -7,10 +7,12 @@ const mockNotificationListData = { messages: [ { category: 'see', + id: 1, message_key: 'p2p-limit-upgrade-available', }, { category: 'see', + id: 2, message_key: 'poi-verified', }, ], @@ -29,6 +31,7 @@ describe('useNotificationList', () => { expect(result.current.data).toEqual([ { category: 'see', + id: 1, message_key: 'p2p-limit-upgrade-available', }, ]); From c58aceb7e5929a7249939053cf9650d00e8db78b Mon Sep 17 00:00:00 2001 From: Farrah Mae Ochoa Date: Wed, 4 Sep 2024 13:04:11 +0400 Subject: [PATCH 09/39] fix: poa issue for existing users --- src/components/AdvertsTableRow/AdvertsTableRow.tsx | 4 ++-- src/pages/my-ads/screens/MyAds/MyAds.tsx | 5 +++-- src/pages/my-profile/screens/MyProfile/MyProfile.tsx | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/components/AdvertsTableRow/AdvertsTableRow.tsx b/src/components/AdvertsTableRow/AdvertsTableRow.tsx index 0ff712dd..0d1479dd 100644 --- a/src/components/AdvertsTableRow/AdvertsTableRow.tsx +++ b/src/components/AdvertsTableRow/AdvertsTableRow.tsx @@ -212,12 +212,12 @@ const AdvertsTableRow = memo((props: TAdvertsTableRowRenderer) => { className='lg:min-w-[7.5rem]' disabled={isAdvertiserBarred} onClick={() => { - if (!isPoaVerified || !isPoiVerified) { + if (!isAdvertiser && (!isPoaVerified || !isPoiVerified)) { const searchParams = new URLSearchParams(location.search); searchParams.set('poi_poa_verified', 'false'); history.replace({ pathname: location.pathname, search: searchParams.toString() }); } else { - if (!isAdvertiser) setSelectedAdvertId(advertId); + setSelectedAdvertId(advertId); showModal(isAdvertiser ? 'BuySellForm' : 'NicknameModal'); } }} diff --git a/src/pages/my-ads/screens/MyAds/MyAds.tsx b/src/pages/my-ads/screens/MyAds/MyAds.tsx index d7720417..13860303 100644 --- a/src/pages/my-ads/screens/MyAds/MyAds.tsx +++ b/src/pages/my-ads/screens/MyAds/MyAds.tsx @@ -1,13 +1,14 @@ import { TemporarilyBarredHint, Verification } from '@/components'; -import { useIsAdvertiserBarred, usePoiPoaStatus } from '@/hooks/custom-hooks'; +import { useIsAdvertiser, useIsAdvertiserBarred, usePoiPoaStatus } from '@/hooks/custom-hooks'; import { MyAdsTable } from './MyAdsTable'; const MyAds = () => { + const isAdvertiser = useIsAdvertiser(); const isAdvertiserBarred = useIsAdvertiserBarred(); const { data } = usePoiPoaStatus(); const { isPoaVerified, isPoiVerified } = data || {}; - if (!isPoaVerified || !isPoiVerified) return ; + if (!isAdvertiser && (!isPoaVerified || !isPoiVerified)) return ; return (
diff --git a/src/pages/my-profile/screens/MyProfile/MyProfile.tsx b/src/pages/my-profile/screens/MyProfile/MyProfile.tsx index 649908d6..441f0e81 100644 --- a/src/pages/my-profile/screens/MyProfile/MyProfile.tsx +++ b/src/pages/my-profile/screens/MyProfile/MyProfile.tsx @@ -49,7 +49,7 @@ const MyProfile = () => { return ; } - if (!isPoiVerified || !isPoaVerified) { + if (!isAdvertiser && (!isPoiVerified || !isPoaVerified)) { return ; } From edfa2788ef048104640980c7466717e625381be5 Mon Sep 17 00:00:00 2001 From: Farrah Mae Ochoa Date: Wed, 4 Sep 2024 16:46:08 +0400 Subject: [PATCH 10/39] fix: test --- .../screens/BuySellTable/__tests__/BuySellTable.spec.tsx | 1 + src/pages/my-ads/screens/MyAds/__tests__/MyAds.spec.tsx | 1 + .../screens/MyProfile/__tests__/MyProfile.spec.tsx | 6 ++++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/pages/buy-sell/screens/BuySellTable/__tests__/BuySellTable.spec.tsx b/src/pages/buy-sell/screens/BuySellTable/__tests__/BuySellTable.spec.tsx index a731c6ad..5aadb98a 100644 --- a/src/pages/buy-sell/screens/BuySellTable/__tests__/BuySellTable.spec.tsx +++ b/src/pages/buy-sell/screens/BuySellTable/__tests__/BuySellTable.spec.tsx @@ -235,6 +235,7 @@ describe('', () => { }); it('should call history.replace if user clicks on Buy/Sell button and POA/POI is not verified', async () => { + mockUseIsAdvertiser = false; mockUseModalManager.isModalOpenFor.mockReturnValue(false); mockUsePoiPoaStatus.mockReturnValueOnce({ data: { isPoaVerified: false, isPoiVerified: false } }); diff --git a/src/pages/my-ads/screens/MyAds/__tests__/MyAds.spec.tsx b/src/pages/my-ads/screens/MyAds/__tests__/MyAds.spec.tsx index f7f3f7ff..d703fa57 100644 --- a/src/pages/my-ads/screens/MyAds/__tests__/MyAds.spec.tsx +++ b/src/pages/my-ads/screens/MyAds/__tests__/MyAds.spec.tsx @@ -9,6 +9,7 @@ jest.mock('@/components', () => ({ })); jest.mock('@/hooks/custom-hooks', () => ({ + useIsAdvertiser: jest.fn(() => false), useIsAdvertiserBarred: jest.fn().mockReturnValue(false), usePoiPoaStatus: jest.fn().mockReturnValue({ data: { diff --git a/src/pages/my-profile/screens/MyProfile/__tests__/MyProfile.spec.tsx b/src/pages/my-profile/screens/MyProfile/__tests__/MyProfile.spec.tsx index 957ef026..4865140d 100644 --- a/src/pages/my-profile/screens/MyProfile/__tests__/MyProfile.spec.tsx +++ b/src/pages/my-profile/screens/MyProfile/__tests__/MyProfile.spec.tsx @@ -94,7 +94,8 @@ describe('MyProfile', () => { render(); expect(screen.getByTestId('dt_derivs-loader')).toBeInTheDocument(); }); - it('should render the verification component if user has not completed POI ', () => { + it('should render the verification component if a new user has not completed POI ', () => { + (mockUseIsAdvertiser as jest.Mock).mockReturnValueOnce(false); (mockUsePoiPoaStatus as jest.Mock).mockReturnValueOnce({ data: { isPoaVerified: true, isPoiVerified: false }, isLoading: false, @@ -103,7 +104,8 @@ describe('MyProfile', () => { render(); expect(screen.getByText('Verification')).toBeInTheDocument(); }); - it('should render the verification component if user has not completed POA', () => { + it('should render the verification component if a new user has not completed POA', () => { + (mockUseIsAdvertiser as jest.Mock).mockReturnValueOnce(false); (mockUsePoiPoaStatus as jest.Mock).mockReturnValueOnce({ data: { isPoaVerified: false, isPoiVerified: true }, isLoading: false, From 67e552d03ba28fbfcc3f548026ec69824ec8fed3 Mon Sep 17 00:00:00 2001 From: Nada Date: Thu, 15 Aug 2024 11:20:36 +0400 Subject: [PATCH 11/39] fix: version update --- package-lock.json | 34 +++++++++++-------- package.json | 2 +- .../AdvertiserName/BlockDropdown.scss | 7 ++++ .../AdvertiserName/BlockDropdown.tsx | 25 ++++++++------ .../AdvertiserName/BlockUserCount.tsx | 6 ++-- src/components/AppFooter/AccountLimits.tsx | 11 ++---- src/components/AppFooter/ChangeTheme.tsx | 6 ++-- src/components/AppFooter/Deriv.tsx | 6 ++-- src/components/AppFooter/FullScreen.tsx | 6 ++-- src/components/AppFooter/HelpCentre.tsx | 6 ++-- src/components/AppFooter/LanguageSettings.tsx | 7 ++-- src/components/AppFooter/Livechat.tsx | 6 ++-- src/components/AppFooter/NetworkStatus.tsx | 7 ++-- .../AppFooter/ResponsibleTrading.tsx | 6 ++-- src/components/AppFooter/ServerTime.tsx | 13 ++----- src/components/AppFooter/WhatsApp.tsx | 6 ++-- src/components/AppHeader/AppHeader.tsx | 8 ++--- .../AppHeader/Notifications/Notifications.tsx | 10 +++--- .../PopoverDropdown/PopoverDropdown.tsx | 8 ++--- .../AlertComponent/AlertComponent.tsx | 11 ++---- .../OrderTimeSelection/OrderTimeSelection.tsx | 11 +++--- 21 files changed, 96 insertions(+), 106 deletions(-) diff --git a/package-lock.json b/package-lock.json index dfe35408..8dd6f20f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@deriv-com/analytics": "^1.16.1", "@deriv-com/api-hooks": "^1.4.9", "@deriv-com/translations": "^1.3.7", - "@deriv-com/ui": "^1.29.0", + "@deriv-com/ui": "^1.29.10", "@deriv-com/utils": "^0.0.28", "@deriv/quill-icons": "^1.23.8", "@sendbird/chat": "^4.11.3", @@ -3892,12 +3892,13 @@ ] }, "node_modules/@deriv-com/ui": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/@deriv-com/ui/-/ui-1.29.0.tgz", - "integrity": "sha512-AbeUDhHLzY9hFzi6SE4/otFnea/yoUtmoK7uiTn7P28k9esNzeRfywO+TUL18SX3suCJbhMqGp5GtGa57//kAw==", + "version": "1.29.10", + "resolved": "https://registry.npmjs.org/@deriv-com/ui/-/ui-1.29.10.tgz", + "integrity": "sha512-4exI6OoE31sN7WLd4BckO8L4vzEGfrN8DsvEiH+ktKf40wDt8sDa19nXMw+QDqNWhkbp+Xwd2mwJ/muzWTyVUg==", "dependencies": { + "@popperjs/core": "^2.11.8", "@types/react-modal": "^3.16.3", - "react-tiny-popover": "^8.0.4" + "react-popper": "^2.3.0" }, "optionalDependencies": { "@rollup/rollup-linux-x64-gnu": "^4.13.0" @@ -18099,6 +18100,20 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, + "node_modules/react-popper": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz", + "integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==", + "dependencies": { + "react-fast-compare": "^3.0.1", + "warning": "^4.0.2" + }, + "peerDependencies": { + "@popperjs/core": "^2.0.0", + "react": "^16.8.0 || ^17 || ^18", + "react-dom": "^16.8.0 || ^17 || ^18" + } + }, "node_modules/react-refresh": { "version": "0.14.2", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", @@ -18239,15 +18254,6 @@ } } }, - "node_modules/react-tiny-popover": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/react-tiny-popover/-/react-tiny-popover-8.0.4.tgz", - "integrity": "sha512-pn0Y/G0gyMdYTBEWSKCCnaZsXAa54PkfnRE4fnMM5633SSClYrXxwXKc6vPYgJ9shLatGginxMjnhXq6guZmng==", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, "node_modules/react-transition-group": { "version": "4.4.5", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", diff --git a/package.json b/package.json index 1fd7fdc9..a2590485 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "@deriv-com/analytics": "^1.16.1", "@deriv-com/api-hooks": "^1.4.9", "@deriv-com/translations": "^1.3.7", - "@deriv-com/ui": "^1.29.0", + "@deriv-com/ui": "^1.29.10", "@deriv-com/utils": "^0.0.28", "@deriv/quill-icons": "^1.23.8", "@sendbird/chat": "^4.11.3", diff --git a/src/components/AdvertiserName/BlockDropdown.scss b/src/components/AdvertiserName/BlockDropdown.scss index f5624966..04444649 100644 --- a/src/components/AdvertiserName/BlockDropdown.scss +++ b/src/components/AdvertiserName/BlockDropdown.scss @@ -29,4 +29,11 @@ } } } + + &__button { + position: relative; + & .deriv-dropdown { + position: absolute; + } + } } diff --git a/src/components/AdvertiserName/BlockDropdown.tsx b/src/components/AdvertiserName/BlockDropdown.tsx index 3aacc44d..4efcccdd 100644 --- a/src/components/AdvertiserName/BlockDropdown.tsx +++ b/src/components/AdvertiserName/BlockDropdown.tsx @@ -17,17 +17,20 @@ const BlockDropdown = ({ id, onClickBlocked }: TBlockDropdownProps) => { const { is_blocked: isBlocked, name = '' } = data ?? {}; return (
- } - list={[ - { - text: localize('Block'), - value: 'block', - }, - ]} - name='block-user-dropdown' - onSelect={() => showModal('BlockUnblockUserModal')} - /> +
+ + showModal('BlockUnblockUserModal')} + /> +
{isModalOpenFor('BlockUnblockUserModal') && ( { const { isDesktop, isMobile } = useDevice(); return (
- { {count ?? 0} - + {!!isModalOpenFor('BlockUserCountModal') && ( )} diff --git a/src/components/AppFooter/AccountLimits.tsx b/src/components/AppFooter/AccountLimits.tsx index c2282e54..482debe0 100644 --- a/src/components/AppFooter/AccountLimits.tsx +++ b/src/components/AppFooter/AccountLimits.tsx @@ -1,20 +1,15 @@ import { ACCOUNT_LIMITS } from '@/constants'; import { LegacyAccountLimitsIcon } from '@deriv/quill-icons'; import { useTranslations } from '@deriv-com/translations'; -import { TooltipMenuIcon } from '../TooltipMenuIcon'; +import { Tooltip } from '@deriv-com/ui'; const AccountLimits = () => { const { localize } = useTranslations(); return ( - + - + ); }; diff --git a/src/components/AppFooter/ChangeTheme.tsx b/src/components/AppFooter/ChangeTheme.tsx index 530cfdf3..0eb5c633 100644 --- a/src/components/AppFooter/ChangeTheme.tsx +++ b/src/components/AppFooter/ChangeTheme.tsx @@ -1,6 +1,6 @@ import { LegacyThemeLightIcon } from '@deriv/quill-icons'; import { useTranslations } from '@deriv-com/translations'; -import { TooltipMenuIcon } from '../TooltipMenuIcon'; +import { Tooltip } from '@deriv-com/ui'; const ChangeTheme = () => { const { localize } = useTranslations(); @@ -8,9 +8,9 @@ const ChangeTheme = () => { return ( // TODO need to add theme logic // TODO update the component's tests after adding the logic - + - + ); }; diff --git a/src/components/AppFooter/Deriv.tsx b/src/components/AppFooter/Deriv.tsx index 643556d0..b072bd65 100644 --- a/src/components/AppFooter/Deriv.tsx +++ b/src/components/AppFooter/Deriv.tsx @@ -1,13 +1,13 @@ import { DERIV_COM } from '@/constants'; import { LegacyDerivIcon } from '@deriv/quill-icons'; import { useTranslations } from '@deriv-com/translations'; -import { TooltipMenuIcon } from '../TooltipMenuIcon'; +import { Tooltip } from '@deriv-com/ui'; const Deriv = () => { const { localize } = useTranslations(); return ( - { tooltipContent={localize('Go to deriv.com')} > - + ); }; diff --git a/src/components/AppFooter/FullScreen.tsx b/src/components/AppFooter/FullScreen.tsx index c1e0da75..edbbdc3e 100644 --- a/src/components/AppFooter/FullScreen.tsx +++ b/src/components/AppFooter/FullScreen.tsx @@ -1,21 +1,21 @@ import { useFullScreen } from '@/hooks'; import { LegacyFullscreen1pxIcon } from '@deriv/quill-icons'; import { useTranslations } from '@deriv-com/translations'; -import { TooltipMenuIcon } from '../TooltipMenuIcon'; +import { Tooltip } from '@deriv-com/ui'; const FullScreen = () => { const { toggleFullScreenMode } = useFullScreen(); const { localize } = useTranslations(); return ( - - + ); }; diff --git a/src/components/AppFooter/HelpCentre.tsx b/src/components/AppFooter/HelpCentre.tsx index 350ff9be..85c7ba57 100644 --- a/src/components/AppFooter/HelpCentre.tsx +++ b/src/components/AppFooter/HelpCentre.tsx @@ -1,13 +1,13 @@ import { HELP_CENTRE } from '@/constants'; import { LegacyHelpCentreIcon } from '@deriv/quill-icons'; import { useTranslations } from '@deriv-com/translations'; -import { TooltipMenuIcon } from '../TooltipMenuIcon'; +import { Tooltip } from '@deriv-com/ui'; const HelpCentre = () => { const { localize } = useTranslations(); return ( - { tooltipContent={localize('Help centre')} > - + ); }; diff --git a/src/components/AppFooter/LanguageSettings.tsx b/src/components/AppFooter/LanguageSettings.tsx index d8c98356..d1e4cee8 100644 --- a/src/components/AppFooter/LanguageSettings.tsx +++ b/src/components/AppFooter/LanguageSettings.tsx @@ -1,9 +1,8 @@ import { useMemo } from 'react'; import { LANGUAGES } from '@/constants'; import { useTranslations } from '@deriv-com/translations'; -import { Text } from '@deriv-com/ui'; +import { Text, Tooltip } from '@deriv-com/ui'; import { LocalStorageUtils } from '@deriv-com/utils'; -import { TooltipMenuIcon } from '../TooltipMenuIcon'; type TLanguageSettings = { openLanguageSettingModal: () => void; @@ -19,7 +18,7 @@ const LanguageSettings = ({ openLanguageSettingModal }: TLanguageSettings) => { ); return ( - { {currentLang} - + ); }; diff --git a/src/components/AppFooter/Livechat.tsx b/src/components/AppFooter/Livechat.tsx index 08848cd8..2a6ae165 100644 --- a/src/components/AppFooter/Livechat.tsx +++ b/src/components/AppFooter/Livechat.tsx @@ -1,14 +1,14 @@ import { useLiveChat } from '@/hooks/custom-hooks'; import { LegacyLiveChatOutlineIcon } from '@deriv/quill-icons'; import { useTranslations } from '@deriv-com/translations'; -import { TooltipMenuIcon } from '../TooltipMenuIcon'; +import { Tooltip } from '@deriv-com/ui'; const Livechat = () => { const { LiveChatWidget } = useLiveChat(); const { localize } = useTranslations(); return ( - { @@ -17,7 +17,7 @@ const Livechat = () => { tooltipContent={localize('Live chat')} > - + ); }; diff --git a/src/components/AppFooter/NetworkStatus.tsx b/src/components/AppFooter/NetworkStatus.tsx index 5468bc1d..6e2680ec 100644 --- a/src/components/AppFooter/NetworkStatus.tsx +++ b/src/components/AppFooter/NetworkStatus.tsx @@ -2,7 +2,7 @@ import { useMemo } from 'react'; import clsx from 'clsx'; import { useNetworkStatus } from '@/hooks'; import { useTranslations } from '@deriv-com/translations'; -import { TooltipMenuIcon } from '../TooltipMenuIcon'; +import { Tooltip } from '@deriv-com/ui'; const statusConfigs = { blinking: { @@ -20,15 +20,14 @@ const NetworkStatus = () => { const { className, tooltip } = useMemo(() => statusConfigs[status], [status]); return ( -
- + ); }; diff --git a/src/components/AppFooter/ResponsibleTrading.tsx b/src/components/AppFooter/ResponsibleTrading.tsx index a9449baf..9c87029b 100644 --- a/src/components/AppFooter/ResponsibleTrading.tsx +++ b/src/components/AppFooter/ResponsibleTrading.tsx @@ -1,13 +1,13 @@ import { RESPONSIBLE } from '@/constants'; import { LegacyResponsibleTradingIcon } from '@deriv/quill-icons'; import { useTranslations } from '@deriv-com/translations'; -import { TooltipMenuIcon } from '../TooltipMenuIcon'; +import { Tooltip } from '@deriv-com/ui'; const ResponsibleTrading = () => { const { localize } = useTranslations(); return ( - { tooltipContent={localize('Responsible trading')} > - + ); }; diff --git a/src/components/AppFooter/ServerTime.tsx b/src/components/AppFooter/ServerTime.tsx index 9972a6f9..1311fdba 100644 --- a/src/components/AppFooter/ServerTime.tsx +++ b/src/components/AppFooter/ServerTime.tsx @@ -1,8 +1,7 @@ import { DATE_TIME_FORMAT_WITH_GMT, DATE_TIME_FORMAT_WITH_OFFSET } from '@/constants'; import { useSyncedTime } from '@/hooks'; import { epochToLocal, epochToUTC } from '@/utils'; -import { Text, useDevice } from '@deriv-com/ui'; -import { TooltipMenuIcon } from '../TooltipMenuIcon'; +import { Text, Tooltip, useDevice } from '@deriv-com/ui'; const ServerTime = () => { const time = useSyncedTime(); @@ -11,15 +10,9 @@ const ServerTime = () => { const { isDesktop } = useDevice(); return ( - + {UTCFormat} - + ); }; diff --git a/src/components/AppFooter/WhatsApp.tsx b/src/components/AppFooter/WhatsApp.tsx index 1c2fe02d..9540bfa6 100644 --- a/src/components/AppFooter/WhatsApp.tsx +++ b/src/components/AppFooter/WhatsApp.tsx @@ -1,13 +1,13 @@ import { LegacyWhatsappIcon } from '@deriv/quill-icons'; import { useTranslations } from '@deriv-com/translations'; +import { Tooltip } from '@deriv-com/ui'; import { URLConstants } from '@deriv-com/utils'; -import { TooltipMenuIcon } from '../TooltipMenuIcon'; const WhatsApp = () => { const { localize } = useTranslations(); return ( - { tooltipContent={localize('WhatsApp')} > - + ); }; diff --git a/src/components/AppHeader/AppHeader.tsx b/src/components/AppHeader/AppHeader.tsx index 5fdca055..eccfa5e3 100644 --- a/src/components/AppHeader/AppHeader.tsx +++ b/src/components/AppHeader/AppHeader.tsx @@ -5,9 +5,8 @@ import { getCurrentRoute } from '@/utils'; import { StandaloneCircleUserRegularIcon } from '@deriv/quill-icons'; import { useAuthData } from '@deriv-com/api-hooks'; import { useTranslations } from '@deriv-com/translations'; -import { Button, Header, Text, useDevice, Wrapper } from '@deriv-com/ui'; +import { Button, Header, Text, Tooltip, useDevice, Wrapper } from '@deriv-com/ui'; import { LocalStorageUtils } from '@deriv-com/utils'; -import { TooltipMenuIcon } from '../TooltipMenuIcon'; import { AccountsInfoLoader } from './AccountsInfoLoader'; import { AccountSwitcher } from './AccountSwitcher'; import { AppLogo } from './AppLogo'; @@ -42,16 +41,15 @@ const AppHeader = () => { <> {isDesktop && ( - - + )} diff --git a/src/components/PaymentMethodCard/PaymentMethodCardHeader/PaymentMethodCardHeader.tsx b/src/components/PaymentMethodCard/PaymentMethodCardHeader/PaymentMethodCardHeader.tsx index c4cc1fa9..6d939b8d 100644 --- a/src/components/PaymentMethodCard/PaymentMethodCardHeader/PaymentMethodCardHeader.tsx +++ b/src/components/PaymentMethodCard/PaymentMethodCardHeader/PaymentMethodCardHeader.tsx @@ -61,8 +61,8 @@ const PaymentMethodCardHeader = ({ /> {isEditable && ( } className='payment-method-card__header-dropdown' - dropdownIcon={} list={getActions(localize)} name='payment-method-actions' onSelect={value => { diff --git a/src/components/PaymentMethodForm/PaymentMethodFormAutocomplete/PaymentMethodFormAutocomplete.tsx b/src/components/PaymentMethodForm/PaymentMethodFormAutocomplete/PaymentMethodFormAutocomplete.tsx index e1aacfad..9e364d4e 100644 --- a/src/components/PaymentMethodForm/PaymentMethodFormAutocomplete/PaymentMethodFormAutocomplete.tsx +++ b/src/components/PaymentMethodForm/PaymentMethodFormAutocomplete/PaymentMethodFormAutocomplete.tsx @@ -55,7 +55,7 @@ const PaymentMethodFormAutocomplete = ({ return ( <> } + chevronIcon={} isFullWidth label={localize('Payment method')} list={availablePaymentMethodsList} diff --git a/src/pages/buy-sell/components/SortDropdown/SortDropdown.tsx b/src/pages/buy-sell/components/SortDropdown/SortDropdown.tsx index 28fc7e49..08662594 100644 --- a/src/pages/buy-sell/components/SortDropdown/SortDropdown.tsx +++ b/src/pages/buy-sell/components/SortDropdown/SortDropdown.tsx @@ -32,7 +32,7 @@ const SortDropdown = ({ list, onSelect, setIsFilterModalOpen, value }: TSortDrop return (
} + chevronIcon={} label={localize('Sort by')} list={list as unknown as MutableOption[]} name='Sort by' diff --git a/src/pages/my-ads/components/AlertComponent/AlertComponent.tsx b/src/pages/my-ads/components/AlertComponent/AlertComponent.tsx index 6985f12f..80473cf0 100644 --- a/src/pages/my-ads/components/AlertComponent/AlertComponent.tsx +++ b/src/pages/my-ads/components/AlertComponent/AlertComponent.tsx @@ -11,7 +11,7 @@ const AlertComponent = ({ onClick }: TAlertComponentProps) => { const { localize } = useTranslations(); return (
- +
diff --git a/src/pages/my-ads/components/BuyPaymentMethodsList/BuyPaymentMethodsList.tsx b/src/pages/my-ads/components/BuyPaymentMethodsList/BuyPaymentMethodsList.tsx index e7df9525..b89d6342 100644 --- a/src/pages/my-ads/components/BuyPaymentMethodsList/BuyPaymentMethodsList.tsx +++ b/src/pages/my-ads/components/BuyPaymentMethodsList/BuyPaymentMethodsList.tsx @@ -14,9 +14,9 @@ const BuyPaymentMethodsList = ({ list, onSelectPaymentMethod }: TBuyPaymentMetho return (
} className='buy-payment-methods-list__dropdown' data-testid='dt_buy_payment_methods_list' - dropdownIcon={
} emptyResultMessage={localize('No results found')} icon={} isFullWidth diff --git a/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesHeader/MyProfileCounterpartiesHeader.tsx b/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesHeader/MyProfileCounterpartiesHeader.tsx index adddf2e2..64cee15d 100644 --- a/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesHeader/MyProfileCounterpartiesHeader.tsx +++ b/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesHeader/MyProfileCounterpartiesHeader.tsx @@ -34,7 +34,7 @@ const MyProfileCounterpartiesHeader = ({ /> {isDesktop ? ( } + chevronIcon={} label={localize('Filter by')} list={getCounterpartiesDropdownList(localize) as unknown as MutableOption[]} listHeight='sm' From 71cb0decdf774c46516734435df93ef40faebc10 Mon Sep 17 00:00:00 2001 From: Nada Date: Wed, 21 Aug 2024 12:07:12 +0400 Subject: [PATCH 13/39] fix: position for input field error message --- src/components/AdvertiserName/BlockUserCount.scss | 4 ++++ src/components/BuySellForm/BuySellData/BuySellData.tsx | 2 +- src/routes/AppContent/index.scss | 5 +++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/components/AdvertiserName/BlockUserCount.scss b/src/components/AdvertiserName/BlockUserCount.scss index c6411263..310e692f 100644 --- a/src/components/AdvertiserName/BlockUserCount.scss +++ b/src/components/AdvertiserName/BlockUserCount.scss @@ -26,5 +26,9 @@ & .deriv-tooltip { padding: 0.8rem; + + @include mobile-or-tablet-screen { + display: none; + } } } diff --git a/src/components/BuySellForm/BuySellData/BuySellData.tsx b/src/components/BuySellForm/BuySellData/BuySellData.tsx index dae16721..9714b497 100644 --- a/src/components/BuySellForm/BuySellData/BuySellData.tsx +++ b/src/components/BuySellForm/BuySellData/BuySellData.tsx @@ -76,7 +76,7 @@ const BuySellData = forwardRef( {isFloating && ( diff --git a/src/routes/AppContent/index.scss b/src/routes/AppContent/index.scss index 3ed793dd..0fd9cf0f 100644 --- a/src/routes/AppContent/index.scss +++ b/src/routes/AppContent/index.scss @@ -63,3 +63,8 @@ .languages-modal__body { margin: 1.6rem; } + +// to fix the helper message position instead of individually changing for all the forms and fields +.deriv-input__helper-message { + position: unset; +} From 6c1990c19919e137f858bc51cf51c633628dd061 Mon Sep 17 00:00:00 2001 From: Nada Date: Wed, 21 Aug 2024 14:12:53 +0400 Subject: [PATCH 14/39] fix: style fixes --- .../PopoverDropdown/PopoverDropdown.scss | 17 ++++------------- .../AlertComponent/AlertComponent.tsx | 2 +- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/components/PopoverDropdown/PopoverDropdown.scss b/src/components/PopoverDropdown/PopoverDropdown.scss index cb20731c..360adc9a 100644 --- a/src/components/PopoverDropdown/PopoverDropdown.scss +++ b/src/components/PopoverDropdown/PopoverDropdown.scss @@ -2,20 +2,11 @@ display: flex; flex-direction: column; position: relative; + justify-content: center; + padding: 0.1rem 0.8rem; - & .tooltip-menu-icon { - width: 3.2rem; - display: flex; - justify-content: center; - border-radius: 4px; - - @include mobile-or-tablet-screen { - margin-top: -0.5rem; - - &:hover { - background-color: transparent; - } - } + @include mobile-or-tablet-screen { + margin-top: -1rem; } &__list { diff --git a/src/pages/my-ads/components/AlertComponent/AlertComponent.tsx b/src/pages/my-ads/components/AlertComponent/AlertComponent.tsx index 80473cf0..537a0df6 100644 --- a/src/pages/my-ads/components/AlertComponent/AlertComponent.tsx +++ b/src/pages/my-ads/components/AlertComponent/AlertComponent.tsx @@ -11,7 +11,7 @@ const AlertComponent = ({ onClick }: TAlertComponentProps) => { const { localize } = useTranslations(); return (
- +
From aa96f2683fdfa4d61a1248643eb2933df14e7e99 Mon Sep 17 00:00:00 2001 From: Nada Date: Wed, 21 Aug 2024 16:19:26 +0400 Subject: [PATCH 15/39] fix: remove unused components --- .../AdvertiserName/AdvertiserNameStats.scss | 2 +- .../AdvertiserName/AdvertiserNameStats.tsx | 10 +- src/components/Input/Input.scss | 65 -------- src/components/Input/Input.tsx | 47 ------ src/components/Input/index.ts | 1 - src/components/TextField/HelperMessage.tsx | 45 ------ src/components/TextField/TextField.scss | 143 ------------------ src/components/TextField/TextField.tsx | 103 ------------- src/components/TextField/index.ts | 2 - .../TooltipMenuIcon/TooltipMenuIcon.scss | 5 - .../TooltipMenuIcon/TooltipMenuIcon.tsx | 54 ------- .../__test__/TooltipMenuIcon.spec.tsx | 43 ------ src/components/TooltipMenuIcon/index.ts | 1 - src/components/index.ts | 2 - 14 files changed, 6 insertions(+), 517 deletions(-) delete mode 100644 src/components/Input/Input.scss delete mode 100644 src/components/Input/Input.tsx delete mode 100644 src/components/Input/index.ts delete mode 100644 src/components/TextField/HelperMessage.tsx delete mode 100644 src/components/TextField/TextField.scss delete mode 100644 src/components/TextField/TextField.tsx delete mode 100644 src/components/TextField/index.ts delete mode 100644 src/components/TooltipMenuIcon/TooltipMenuIcon.scss delete mode 100644 src/components/TooltipMenuIcon/TooltipMenuIcon.tsx delete mode 100644 src/components/TooltipMenuIcon/__test__/TooltipMenuIcon.spec.tsx delete mode 100644 src/components/TooltipMenuIcon/index.ts diff --git a/src/components/AdvertiserName/AdvertiserNameStats.scss b/src/components/AdvertiserName/AdvertiserNameStats.scss index d58736ae..e25aa289 100644 --- a/src/components/AdvertiserName/AdvertiserNameStats.scss +++ b/src/components/AdvertiserName/AdvertiserNameStats.scss @@ -9,7 +9,7 @@ gap: 1rem; } - & div { + & div:not(.deriv-tooltip) { display: flex; align-items: center; gap: 0.8rem; diff --git a/src/components/AdvertiserName/AdvertiserNameStats.tsx b/src/components/AdvertiserName/AdvertiserNameStats.tsx index 4c9b29bf..2eea5e81 100644 --- a/src/components/AdvertiserName/AdvertiserNameStats.tsx +++ b/src/components/AdvertiserName/AdvertiserNameStats.tsx @@ -5,9 +5,8 @@ import { useModalManager } from '@/hooks'; import { getCurrentRoute } from '@/utils'; import { LabelPairedThumbsUpSmRegularIcon } from '@deriv/quill-icons'; import { Localize, useTranslations } from '@deriv-com/translations'; -import { Text, useDevice } from '@deriv-com/ui'; +import { Text, Tooltip, useDevice } from '@deriv-com/ui'; import { BlockUserCountModal } from '../Modals'; -import { TooltipMenuIcon } from '../TooltipMenuIcon'; import BlockUserCount from './BlockUserCount'; import './AdvertiserNameStats.scss'; @@ -39,11 +38,12 @@ const AdvertiserNameStats = ({ advertiserStats }: { advertiserStats: DeepPartial daysSinceJoined, is_online: isOnline, last_online_time: lastOnlineTime, - rating_average: ratingAverage, + // rating_average: ratingAverage, rating_count: ratingCount, recommended_average: recommendedAverage, recommended_count: recommendedCount = 0, } = advertiserStats || {}; + const ratingAverage = 4.5; const textSize = isMobile ? 'xs' : 'sm'; @@ -99,7 +99,7 @@ const AdvertiserNameStats = ({ advertiserStats }: { advertiserStats: DeepPartial
- { @@ -111,7 +111,7 @@ const AdvertiserNameStats = ({ advertiserStats }: { advertiserStats: DeepPartial {recommendedAverage || 0}% - +
)} diff --git a/src/components/Input/Input.scss b/src/components/Input/Input.scss deleted file mode 100644 index e85012aa..00000000 --- a/src/components/Input/Input.scss +++ /dev/null @@ -1,65 +0,0 @@ -.input { - display: flex; - justify-content: center; - margin: 0.5rem 0 3.6rem; - width: 100%; - - &__leading-icon { - position: absolute; - display: flex; - align-items: center; - margin: 0 1.6rem; - } - - @include mobile-or-tablet-screen { - flex-direction: column; - margin-bottom: 1rem; - } - - &__error { - padding-top: 0.2rem; - position: absolute; - margin-left: 1rem; - bottom: 13.3rem; - left: 4.5rem; - - @include mobile-or-tablet-screen { - bottom: 0; - box-decoration-break: clone; - padding-top: 0.4rem; - margin: 0 0 0.6rem 1.6rem; - margin-bottom: 0.6rem; - position: relative; - left: 0; - } - } - - &__field { - display: flex; - width: 92%; - height: 4rem; - padding: 1rem 1.6rem; - justify-content: center; - align-items: center; - border-radius: 4px; - border: 1px solid #d6dadb; - - @include mobile-or-tablet-screen { - width: 100%; - } - - &:focus-visible { - outline: none; - border-color: #85acb0; - } - - &::placeholder { - color: #999; - } - - &--error { - // stylelint-disable-next-line declaration-no-important - border-color: #ec3f3f !important; - } - } -} diff --git a/src/components/Input/Input.tsx b/src/components/Input/Input.tsx deleted file mode 100644 index 72a1029b..00000000 --- a/src/components/Input/Input.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { forwardRef, ReactElement } from 'react'; -import clsx from 'clsx'; -import { Text, useDevice } from '@deriv-com/ui'; -import './Input.scss'; - -type TInputProps = { - errorMessage?: string; - hasError?: boolean; - leadingIcon?: ReactElement; - name: string; - onBlur?: () => void; - onChange?: () => void; - placeholder?: string; - value?: string; -}; - -const Input = forwardRef( - ({ errorMessage, hasError, leadingIcon, onBlur, onChange, placeholder, value, ...props }, ref) => { - const { isDesktop } = useDevice(); - - return ( -
- {leadingIcon &&
{leadingIcon}
} - - {hasError && ( - - {errorMessage} - - )} -
- ); - } -); - -Input.displayName = 'Input'; - -export default Input; diff --git a/src/components/Input/index.ts b/src/components/Input/index.ts deleted file mode 100644 index b4d38647..00000000 --- a/src/components/Input/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as Input } from './Input'; diff --git a/src/components/TextField/HelperMessage.tsx b/src/components/TextField/HelperMessage.tsx deleted file mode 100644 index 51a6d7b1..00000000 --- a/src/components/TextField/HelperMessage.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { ComponentProps, FC, InputHTMLAttributes, memo } from 'react'; -import { Text } from '@deriv-com/ui'; - -export type HelperMessageProps = { - inputValue?: InputHTMLAttributes['value']; - isError?: boolean; - maxLength?: InputHTMLAttributes['maxLength']; - message?: string; - messageVariant?: 'error' | 'general' | 'warning'; -}; - -const HelperMessage: FC = memo( - ({ inputValue, isError, maxLength, message, messageVariant = 'general' }) => { - const HelperMessageColors: Record['color']> = { - error: 'error', - general: 'less-prominent', - warning: 'warning', - }; - - return ( - <> - {message && ( -
- - {message} - -
- )} - {maxLength && ( -
- - {inputValue?.toString().length || 0} / {maxLength} - -
- )} - - ); - } -); - -HelperMessage.displayName = 'HelperMessage'; -export default HelperMessage; diff --git a/src/components/TextField/TextField.scss b/src/components/TextField/TextField.scss deleted file mode 100644 index b130873a..00000000 --- a/src/components/TextField/TextField.scss +++ /dev/null @@ -1,143 +0,0 @@ -.textfield { - min-width: 12rem; - width: 100%; - position: relative; - display: flex; - flex-direction: column; - gap: 0.2rem; - - &--error { - .textfield__box, - .textfield__box:hover { - border: 1px solid var(--status-light-danger, #ec3f3f); - } - - .textfield__box:has(.textfield__field:focus) { - border: 1px solid var(--brand-blue, #ec3f3f); - } - - .textfield__box:has(.textfield__field:valid) { - border: 1px solid var(--brand-blue, #ec3f3f); - } - - .textfield__label { - color: #ec3f3f; - } - - .textfield__field:focus ~ .textfield__label { - color: #ec3f3f; - } - } - - &--disabled { - & .textfield__box, - .textfield__box:hover { - border: 1px solid var(--system-light-5-active-background, #eaeced); - - & input { - color: var(--system-light-5-active-background, #999); - background: transparent; - } - } - & .textfield__box:has(.textfield__field:focus) { - border: 1px solid var(--system-light-5-active-background, #eaeced); - } - & .textfield__field { - background: inherit; - } - } - - &__box { - height: 4rem; - width: 100%; - border-radius: 0.4rem; - padding: 1rem 1.6rem; - border: 1px solid var(--system-light-5-active-background, #d6dadb); - display: inline-flex; - align-items: center; - transition: border-color 0.2s; - - &:hover { - border-color: var(--system-light-3-less-prominent-text, #999); - } - } - - &__box:has(&__field:focus) { - border: 1px solid var(--brand-blue, #85acb0); - } - - &__box:has(&__field:invalid) { - border: 1px solid var(--status-light-danger, #ec3f3f); - } - - &__field { - min-width: 0; - font-family: inherit; - outline: 0; - font-size: 1.4rem; - color: var(--system-light-2-general-text, #333); - transition: border-color 0.2s; - flex: 1; - } - - &__field::placeholder { - color: transparent; - } - - &__field:placeholder-shown ~ &__label { - font-size: 1.4rem; - cursor: text; - top: 2rem; - padding: 0; - } - - label, - &__field:focus ~ &__label { - position: absolute; - top: 0%; - transform: translateY(-50%); - display: block; - transition: 0.2s; - font-size: 1rem; - color: var(--system-light-3-less-prominent-text, #999); - background: var(--system-light-8-primary-background, #fff); - padding-inline: 0.4rem; - left: 1.6rem; - -webkit-user-select: none; - -ms-user-select: none; - user-select: none; - } - - &__field:focus ~ &__label { - color: var(--brand-blue, #85acb0); - } - - &__field:invalid ~ &__label { - color: var(--status-light-danger, #ec3f3f); - } - - &__icon { - &-left { - margin-right: 0.8rem; - } - - &-right { - margin-left: 1.6rem; - } - } - - &__message-container { - height: 2rem; - padding: 0rem 0rem 0rem 1.6rem; - width: 100%; - - &--maxchar { - float: right; - } - - &--msg { - float: left; - text-align: left; - } - } -} diff --git a/src/components/TextField/TextField.tsx b/src/components/TextField/TextField.tsx deleted file mode 100644 index 89c75860..00000000 --- a/src/components/TextField/TextField.tsx +++ /dev/null @@ -1,103 +0,0 @@ -import { ChangeEvent, ComponentProps, forwardRef, ReactNode, Ref, useState } from 'react'; -import clsx from 'clsx'; -import HelperMessage, { HelperMessageProps } from './HelperMessage'; -import './TextField.scss'; - -export interface TextFieldProps extends ComponentProps<'input'>, HelperMessageProps { - defaultValue?: string; - disabled?: boolean; - errorMessage?: string[] | string; - isInvalid?: boolean; - label?: string; - renderLeftIcon?: () => ReactNode; - renderRightIcon?: () => ReactNode; - shouldShowWarningMessage?: boolean; - showMessage?: boolean; -} - -const TextField = forwardRef( - ( - { - defaultValue = '', - disabled, - errorMessage, - isInvalid, - label, - maxLength, - message, - messageVariant = 'general', - name = 'textField', - onChange, - renderLeftIcon, - renderRightIcon, - shouldShowWarningMessage = false, - showMessage = false, - ...rest - }: TextFieldProps, - ref: Ref - ) => { - const [value, setValue] = useState(defaultValue); - - const handleChange = (e: ChangeEvent) => { - const newValue = e.target.value; - setValue(newValue); - onChange?.(e); - }; - - return ( -
-
- {typeof renderLeftIcon === 'function' && ( -
{renderLeftIcon()}
- )} - - {label && ( - - )} - {typeof renderRightIcon === 'function' && ( -
{renderRightIcon()}
- )} -
-
- {showMessage && !isInvalid && ( - - )} - {errorMessage && (isInvalid || (!isInvalid && shouldShowWarningMessage)) && ( - - )} -
-
- ); - } -); - -TextField.displayName = 'TextField'; -export default TextField; diff --git a/src/components/TextField/index.ts b/src/components/TextField/index.ts deleted file mode 100644 index 97d7c656..00000000 --- a/src/components/TextField/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -// TODO: Delete this component once @deriv-com/ui has it published -export { default as TextField } from './TextField'; diff --git a/src/components/TooltipMenuIcon/TooltipMenuIcon.scss b/src/components/TooltipMenuIcon/TooltipMenuIcon.scss deleted file mode 100644 index 94c03f33..00000000 --- a/src/components/TooltipMenuIcon/TooltipMenuIcon.scss +++ /dev/null @@ -1,5 +0,0 @@ -.tooltip-menu-icon { - &:hover { - background: #e6e9e9; - } -} diff --git a/src/components/TooltipMenuIcon/TooltipMenuIcon.tsx b/src/components/TooltipMenuIcon/TooltipMenuIcon.tsx deleted file mode 100644 index 951a9615..00000000 --- a/src/components/TooltipMenuIcon/TooltipMenuIcon.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { ComponentProps, ElementType, PropsWithChildren } from 'react'; -import clsx from 'clsx'; -import { extendTheme, ThemeProvider, Tooltip, TooltipProps } from '@chakra-ui/react'; -import './TooltipMenuIcon.scss'; - -const theme = extendTheme({ - zIndices: { - tooltip: 1800, - }, -}); - -type AsElement = 'a' | 'button' | 'div'; -type TTooltipMenuIcon = ComponentProps & { - as: T; - disableHover?: boolean; - tooltipContent: string; - tooltipPosition?: TooltipProps['placement']; -}; - -// TODO replace this with deriv/ui -const TooltipMenuIcon = ({ - as, - children, - className, - disableHover = false, - tooltipContent, - tooltipPosition = 'top', - ...rest -}: PropsWithChildren>) => { - const Tag = as as ElementType; - - return ( - - - - {children} - - - - ); -}; - -export default TooltipMenuIcon; diff --git a/src/components/TooltipMenuIcon/__test__/TooltipMenuIcon.spec.tsx b/src/components/TooltipMenuIcon/__test__/TooltipMenuIcon.spec.tsx deleted file mode 100644 index 3c34da64..00000000 --- a/src/components/TooltipMenuIcon/__test__/TooltipMenuIcon.spec.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { render, screen } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; -import { TooltipMenuIcon } from '..'; - -describe('TooltipMenuIcon Component', () => { - it('renders correctly with default props', () => { - render( - - Hover me - - ); - expect(screen.getByRole('button')).toHaveTextContent('Hover me'); - }); - - it('displays tooltip on hover', async () => { - render( - - Hover me - - ); - await userEvent.hover(screen.getByRole('button')); - expect(screen.getByText('Tooltip text')).toBeInTheDocument(); - }); - - it('accepts and applies custom tooltip position', async () => { - render( - - Hover me - - ); - await userEvent.hover(screen.getByRole('button')); - expect(screen.getByText('Tooltip text')).toBeInTheDocument(); - }); - - it("renders correctly with as='a'", () => { - render( - - Hover me - - ); - expect(screen.getByRole('link')).toHaveTextContent('Hover me'); - }); -}); diff --git a/src/components/TooltipMenuIcon/index.ts b/src/components/TooltipMenuIcon/index.ts deleted file mode 100644 index 6cb8e0f8..00000000 --- a/src/components/TooltipMenuIcon/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as TooltipMenuIcon } from './TooltipMenuIcon'; diff --git a/src/components/index.ts b/src/components/index.ts index a460022e..ed4d0a79 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -14,7 +14,6 @@ export * from './FileDropzone'; export * from './FloatingRate'; export * from './FormProgress'; export * from './FullPageMobileWrapper'; -export * from './Input'; export * from './LightDivider'; export * from './MobileTabs'; export * from './OnlineStatus'; @@ -33,7 +32,6 @@ export * from './Search'; export * from './StarRating'; export * from './Table'; export * from './TemporarilyBarredHint'; -export * from './TextField'; export * from './UserAvatar'; export * from './Verification'; export * from './Wizard'; From 728c104de3e03591a2ad853d1dd3dddf3b473406 Mon Sep 17 00:00:00 2001 From: Nada Date: Wed, 21 Aug 2024 16:34:00 +0400 Subject: [PATCH 16/39] fix: remove constant --- src/components/AdvertiserName/AdvertiserNameStats.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/AdvertiserName/AdvertiserNameStats.tsx b/src/components/AdvertiserName/AdvertiserNameStats.tsx index 2eea5e81..4b1a4d84 100644 --- a/src/components/AdvertiserName/AdvertiserNameStats.tsx +++ b/src/components/AdvertiserName/AdvertiserNameStats.tsx @@ -38,12 +38,11 @@ const AdvertiserNameStats = ({ advertiserStats }: { advertiserStats: DeepPartial daysSinceJoined, is_online: isOnline, last_online_time: lastOnlineTime, - // rating_average: ratingAverage, + rating_average: ratingAverage, rating_count: ratingCount, recommended_average: recommendedAverage, recommended_count: recommendedCount = 0, } = advertiserStats || {}; - const ratingAverage = 4.5; const textSize = isMobile ? 'xs' : 'sm'; From 6f6c7d8082dba3210a333051f3060420b4c6968a Mon Sep 17 00:00:00 2001 From: Nada Date: Thu, 22 Aug 2024 08:17:35 +0400 Subject: [PATCH 17/39] fix: text capitalize for label --- src/routes/AppContent/index.scss | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/routes/AppContent/index.scss b/src/routes/AppContent/index.scss index 0fd9cf0f..2b4454e1 100644 --- a/src/routes/AppContent/index.scss +++ b/src/routes/AppContent/index.scss @@ -68,3 +68,10 @@ .deriv-input__helper-message { position: unset; } + +// to fix the issue with text capitalize in dropdown label +.deriv-dropdown { + label { + text-transform: none; + } +} From 1213407d23fbdf4a87b49b23b5262a66b5d8554f Mon Sep 17 00:00:00 2001 From: Nada Date: Mon, 16 Sep 2024 10:15:13 +0400 Subject: [PATCH 18/39] fix: tooltip hide in mobile and tablet --- src/components/PopoverDropdown/PopoverDropdown.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/PopoverDropdown/PopoverDropdown.tsx b/src/components/PopoverDropdown/PopoverDropdown.tsx index 357446c1..f85ad505 100644 --- a/src/components/PopoverDropdown/PopoverDropdown.tsx +++ b/src/components/PopoverDropdown/PopoverDropdown.tsx @@ -29,6 +29,7 @@ const PopoverDropdown = ({ dropdownList, isBarred, onClick, tooltipMessage }: TP ) : ( setVisible(prevState => !prevState)} tooltipContent={tooltipMessage} tooltipPosition='top' From 2243662527feb38d218d47798577ff1806d40457 Mon Sep 17 00:00:00 2001 From: Nada Date: Mon, 16 Sep 2024 11:13:57 +0400 Subject: [PATCH 19/39] fix: dropdown styles --- .../components/SortDropdown/SortDropdown.scss | 2 +- .../BuyPaymentMethodsList.scss | 2 +- .../OrderTimeSelection.scss | 2 +- .../OrderTimeSelection/OrderTimeSelection.tsx | 30 ++++++++++++------- .../MyProfileCounterpartiesHeader.scss | 6 +++- 5 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/pages/buy-sell/components/SortDropdown/SortDropdown.scss b/src/pages/buy-sell/components/SortDropdown/SortDropdown.scss index 7de7291a..ab0dfd64 100644 --- a/src/pages/buy-sell/components/SortDropdown/SortDropdown.scss +++ b/src/pages/buy-sell/components/SortDropdown/SortDropdown.scss @@ -1,6 +1,6 @@ .sort-dropdown { .deriv-dropdown__items { - top: 4.4rem; + top: 3.6rem; width: 24rem; } diff --git a/src/pages/my-ads/components/BuyPaymentMethodsList/BuyPaymentMethodsList.scss b/src/pages/my-ads/components/BuyPaymentMethodsList/BuyPaymentMethodsList.scss index 615047e3..6ecdb73e 100644 --- a/src/pages/my-ads/components/BuyPaymentMethodsList/BuyPaymentMethodsList.scss +++ b/src/pages/my-ads/components/BuyPaymentMethodsList/BuyPaymentMethodsList.scss @@ -23,7 +23,7 @@ } &__items { top: unset; - bottom: 5rem; + bottom: 7rem; max-height: 20rem; } } diff --git a/src/pages/my-ads/components/OrderTimeSelection/OrderTimeSelection.scss b/src/pages/my-ads/components/OrderTimeSelection/OrderTimeSelection.scss index 17c3b3e3..5ac5e99a 100644 --- a/src/pages/my-ads/components/OrderTimeSelection/OrderTimeSelection.scss +++ b/src/pages/my-ads/components/OrderTimeSelection/OrderTimeSelection.scss @@ -1,8 +1,8 @@ .order-time-selection { margin: 1rem 0; - & .deriv-dropdown { &__items { + top: 4rem; box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.16); } & .deriv-input__container { diff --git a/src/pages/my-ads/components/OrderTimeSelection/OrderTimeSelection.tsx b/src/pages/my-ads/components/OrderTimeSelection/OrderTimeSelection.tsx index c8db516b..b02ec934 100644 --- a/src/pages/my-ads/components/OrderTimeSelection/OrderTimeSelection.tsx +++ b/src/pages/my-ads/components/OrderTimeSelection/OrderTimeSelection.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react'; +import { MouseEvent, useEffect, useState } from 'react'; import { Controller, useFormContext } from 'react-hook-form'; import { TOrderExpiryOptions } from 'types'; import { OrderTimeTooltipModal } from '@/components/Modals'; @@ -43,6 +43,10 @@ const OrderTimeSelection = ({ orderExpiryOptions }: { orderExpiryOptions: TOrder return options; }; + const handleDropdownMouseDown = (event: MouseEvent) => { + event.preventDefault(); + }; + return (
@@ -68,16 +72,20 @@ const OrderTimeSelection = ({ orderExpiryOptions }: { orderExpiryOptions: TOrder control={control} name='order-completion-time' render={({ field: { onChange, value } }) => ( - a.value - b.value)} - name='order-completion-time' - onSelect={onChange} - shouldClearValue - value={value} - variant='comboBox' - /> +
+ a.value - b.value)} + name='order-completion-time' + onSelect={onChange} + shouldClearValue + value={value} + variant='comboBox' + /> +
)} /> diff --git a/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesHeader/MyProfileCounterpartiesHeader.scss b/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesHeader/MyProfileCounterpartiesHeader.scss index e9e287f5..097d3f8f 100644 --- a/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesHeader/MyProfileCounterpartiesHeader.scss +++ b/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesHeader/MyProfileCounterpartiesHeader.scss @@ -5,7 +5,7 @@ & .deriv-dropdown__items { width: 20rem; - margin-top: 0.8rem; + margin-top: 0.5rem; } & .deriv-input { @@ -14,6 +14,10 @@ &__container { width: 20rem; + & .deriv-input__helper-message { + display: none; + } + @include mobile-or-tablet-screen { width: 100%; } From 39e44c509d0bc304d8990d2acc06850ef91fa4d5 Mon Sep 17 00:00:00 2001 From: Nada Date: Mon, 16 Sep 2024 11:25:45 +0400 Subject: [PATCH 20/39] fix: tooltip spacing --- src/components/AdvertiserName/AdvertiserNameStats.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AdvertiserName/AdvertiserNameStats.scss b/src/components/AdvertiserName/AdvertiserNameStats.scss index e25aa289..7d1c156c 100644 --- a/src/components/AdvertiserName/AdvertiserNameStats.scss +++ b/src/components/AdvertiserName/AdvertiserNameStats.scss @@ -27,7 +27,7 @@ } @include desktop { &:nth-child(2) { - & div { + & div:not(.deriv-tooltip) { padding-right: 0; } } From d46363383acedacb52f089abbfac4d77e22fd0e9 Mon Sep 17 00:00:00 2001 From: Nada Date: Mon, 16 Sep 2024 11:42:50 +0400 Subject: [PATCH 21/39] fix: spacing issue --- src/components/AdvertiserName/AdvertiserNameStats.tsx | 1 + .../PaymentMethodCardHeader/PaymentMethodCardHeader.scss | 1 + 2 files changed, 2 insertions(+) diff --git a/src/components/AdvertiserName/AdvertiserNameStats.tsx b/src/components/AdvertiserName/AdvertiserNameStats.tsx index 4b1a4d84..a4b7513b 100644 --- a/src/components/AdvertiserName/AdvertiserNameStats.tsx +++ b/src/components/AdvertiserName/AdvertiserNameStats.tsx @@ -101,6 +101,7 @@ const AdvertiserNameStats = ({ advertiserStats }: { advertiserStats: DeepPartial { isDesktop ? undefined : showModal('BlockUserCountModal'); }} diff --git a/src/components/PaymentMethodCard/PaymentMethodCardHeader/PaymentMethodCardHeader.scss b/src/components/PaymentMethodCard/PaymentMethodCardHeader/PaymentMethodCardHeader.scss index 9f1c5b37..0a4498e4 100644 --- a/src/components/PaymentMethodCard/PaymentMethodCardHeader/PaymentMethodCardHeader.scss +++ b/src/components/PaymentMethodCard/PaymentMethodCardHeader/PaymentMethodCardHeader.scss @@ -21,6 +21,7 @@ width: 12.8rem; border: 0; padding: 0; + margin-top: unset; } .deriv-input { From cd45c070e9e2db6498257508d5de7a5a547a422c Mon Sep 17 00:00:00 2001 From: Nada Date: Mon, 16 Sep 2024 15:18:44 +0400 Subject: [PATCH 22/39] fix: button submit issue --- .../OrderTimeSelection/OrderTimeSelection.scss | 11 ++++++++--- .../OrderTimeSelection/OrderTimeSelection.tsx | 4 ++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/pages/my-ads/components/OrderTimeSelection/OrderTimeSelection.scss b/src/pages/my-ads/components/OrderTimeSelection/OrderTimeSelection.scss index 5ac5e99a..130dc77c 100644 --- a/src/pages/my-ads/components/OrderTimeSelection/OrderTimeSelection.scss +++ b/src/pages/my-ads/components/OrderTimeSelection/OrderTimeSelection.scss @@ -5,10 +5,15 @@ top: 4rem; box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.16); } - & .deriv-input__container { - width: 100%; - } + & .deriv-input { + &__container { + width: 100%; + } + &__helper-message { + display: none; + } + } & .deriv-dropdown__items--xs { margin-top: 0.5rem; max-height: 20rem; diff --git a/src/pages/my-ads/components/OrderTimeSelection/OrderTimeSelection.tsx b/src/pages/my-ads/components/OrderTimeSelection/OrderTimeSelection.tsx index b02ec934..e5a9268f 100644 --- a/src/pages/my-ads/components/OrderTimeSelection/OrderTimeSelection.tsx +++ b/src/pages/my-ads/components/OrderTimeSelection/OrderTimeSelection.tsx @@ -43,7 +43,7 @@ const OrderTimeSelection = ({ orderExpiryOptions }: { orderExpiryOptions: TOrder return options; }; - const handleDropdownMouseDown = (event: MouseEvent) => { + const handleDropdownClick = (event: MouseEvent) => { event.preventDefault(); }; @@ -73,7 +73,7 @@ const OrderTimeSelection = ({ orderExpiryOptions }: { orderExpiryOptions: TOrder name='order-completion-time' render={({ field: { onChange, value } }) => (
Date: Mon, 16 Sep 2024 15:37:53 +0400 Subject: [PATCH 23/39] fix: default submission of PM --- .../PaymentMethodFormAutocomplete.tsx | 46 +++++++++++-------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/src/components/PaymentMethodForm/PaymentMethodFormAutocomplete/PaymentMethodFormAutocomplete.tsx b/src/components/PaymentMethodForm/PaymentMethodFormAutocomplete/PaymentMethodFormAutocomplete.tsx index 9e364d4e..76edfbcd 100644 --- a/src/components/PaymentMethodForm/PaymentMethodFormAutocomplete/PaymentMethodFormAutocomplete.tsx +++ b/src/components/PaymentMethodForm/PaymentMethodFormAutocomplete/PaymentMethodFormAutocomplete.tsx @@ -1,3 +1,4 @@ +import { MouseEvent } from 'react'; import { TFormState, THooks, TPaymentMethod, TSelectedPaymentMethod } from 'types'; import { LabelPairedSearchMdRegularIcon, LegacyCloseCircle1pxBlackIcon } from '@deriv/quill-icons'; import { Localize, useTranslations } from '@deriv-com/translations'; @@ -52,27 +53,34 @@ const PaymentMethodFormAutocomplete = ({ } return ''; }; + + const handleDropdownClick = (event: MouseEvent) => { + event.preventDefault(); + }; return ( <> - } - isFullWidth - label={localize('Payment method')} - list={availablePaymentMethodsList} - name='Payment method' - onSelect={value => { - const selectedPaymentMethod = availablePaymentMethods?.find(p => p.id === value); - if (selectedPaymentMethod) { - onAdd?.({ - displayName: selectedPaymentMethod?.display_name, - fields: selectedPaymentMethod?.fields, - method: selectedPaymentMethod?.id, - }); - } - }} - value={getValue()} - variant='prompt' - /> + {/* To prevent default submission */} +
+ } + isFullWidth + label={localize('Payment method')} + list={availablePaymentMethodsList} + name='Payment method' + onSelect={value => { + const selectedPaymentMethod = availablePaymentMethods?.find(p => p.id === value); + if (selectedPaymentMethod) { + onAdd?.({ + displayName: selectedPaymentMethod?.display_name, + fields: selectedPaymentMethod?.fields, + method: selectedPaymentMethod?.id, + }); + } + }} + value={getValue()} + variant='prompt' + /> +
From 7a55d2629f390408526a2a420af4626324819018 Mon Sep 17 00:00:00 2001 From: Nada Date: Mon, 16 Sep 2024 16:11:07 +0400 Subject: [PATCH 24/39] fix: floating badge position fix --- src/components/BuySellForm/BuySellData/BuySellData.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/BuySellForm/BuySellData/BuySellData.tsx b/src/components/BuySellForm/BuySellData/BuySellData.tsx index 9714b497..69a95e08 100644 --- a/src/components/BuySellForm/BuySellData/BuySellData.tsx +++ b/src/components/BuySellForm/BuySellData/BuySellData.tsx @@ -76,7 +76,8 @@ const BuySellData = forwardRef( {isFloating && ( From ca1da42cbff6c977854a739636be881d84cc3f1d Mon Sep 17 00:00:00 2001 From: Nada Date: Mon, 16 Sep 2024 16:26:19 +0400 Subject: [PATCH 25/39] fix: hover background in manage ad --- .../PopoverDropdown/PopoverDropdown.scss | 17 +++++++++++++++++ .../AlertComponent/AlertComponent.scss | 2 +- .../AlertComponent/AlertComponent.tsx | 5 +++-- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/components/PopoverDropdown/PopoverDropdown.scss b/src/components/PopoverDropdown/PopoverDropdown.scss index 360adc9a..b567a535 100644 --- a/src/components/PopoverDropdown/PopoverDropdown.scss +++ b/src/components/PopoverDropdown/PopoverDropdown.scss @@ -5,10 +5,27 @@ justify-content: center; padding: 0.1rem 0.8rem; + @include desktop { + width: 4.2rem; + } + @include mobile-or-tablet-screen { margin-top: -1rem; } + @include desktop { + & .deriv-tooltip__trigger { + display: flex; + width: 100%; + justify-content: center; + + &:hover { + border-radius: 4px; + background-color: #e6e9e9; + } + } + } + &__list { display: flex; flex-direction: column; diff --git a/src/pages/my-ads/components/AlertComponent/AlertComponent.scss b/src/pages/my-ads/components/AlertComponent/AlertComponent.scss index f5eb5c0a..c36a606f 100644 --- a/src/pages/my-ads/components/AlertComponent/AlertComponent.scss +++ b/src/pages/my-ads/components/AlertComponent/AlertComponent.scss @@ -3,7 +3,7 @@ justify-content: center; position: absolute; align-items: center; - right: 3.6rem; + right: 3.7rem; height: 100%; span { diff --git a/src/pages/my-ads/components/AlertComponent/AlertComponent.tsx b/src/pages/my-ads/components/AlertComponent/AlertComponent.tsx index 537a0df6..fdc13eaa 100644 --- a/src/pages/my-ads/components/AlertComponent/AlertComponent.tsx +++ b/src/pages/my-ads/components/AlertComponent/AlertComponent.tsx @@ -1,6 +1,6 @@ import { LegacyWarningIcon } from '@deriv/quill-icons'; import { useTranslations } from '@deriv-com/translations'; -import { Tooltip } from '@deriv-com/ui'; +import { Tooltip, useDevice } from '@deriv-com/ui'; import './AlertComponent.scss'; type TAlertComponentProps = { @@ -9,9 +9,10 @@ type TAlertComponentProps = { const AlertComponent = ({ onClick }: TAlertComponentProps) => { const { localize } = useTranslations(); + const { isDesktop } = useDevice(); return (
- +
From e358ec431fc5f559b56d883d50a17ba34604a74d Mon Sep 17 00:00:00 2001 From: Nada Date: Mon, 16 Sep 2024 16:42:58 +0400 Subject: [PATCH 26/39] fix: coveralls --- .../AlertComponent/__tests__/AlertComponent.spec.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/pages/my-ads/components/AlertComponent/__tests__/AlertComponent.spec.tsx b/src/pages/my-ads/components/AlertComponent/__tests__/AlertComponent.spec.tsx index 7ced1132..c9823418 100644 --- a/src/pages/my-ads/components/AlertComponent/__tests__/AlertComponent.spec.tsx +++ b/src/pages/my-ads/components/AlertComponent/__tests__/AlertComponent.spec.tsx @@ -5,6 +5,12 @@ import AlertComponent from '../AlertComponent'; const mockProps = { onClick: jest.fn(), }; + +jest.mock('@deriv-com/ui', () => ({ + ...jest.requireActual('@deriv-com/ui'), + useDevice: () => ({ isDesktop: true }), +})); + describe('AlertComponent', () => { it('should render the component as expected', () => { render(); From 1616efaebf162d99a09cb02f75ddaff779d76908 Mon Sep 17 00:00:00 2001 From: Nada Date: Tue, 17 Sep 2024 13:20:32 +0400 Subject: [PATCH 27/39] fix: spacing in mobile --- .../my-ads/components/AlertComponent/AlertComponent.scss | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pages/my-ads/components/AlertComponent/AlertComponent.scss b/src/pages/my-ads/components/AlertComponent/AlertComponent.scss index c36a606f..e9455b8c 100644 --- a/src/pages/my-ads/components/AlertComponent/AlertComponent.scss +++ b/src/pages/my-ads/components/AlertComponent/AlertComponent.scss @@ -3,7 +3,7 @@ justify-content: center; position: absolute; align-items: center; - right: 3.7rem; + right: 4.6rem; height: 100%; span { @@ -12,7 +12,8 @@ @include mobile-or-tablet-screen { position: unset; margin-top: -0.4rem; - margin-left: 1rem; + margin-left: 2.5rem; + margin-right: 1.5rem; } & .tooltip-menu-icon:hover { From 94cf27b8e02b11d312f50702debf04a517ab9a90 Mon Sep 17 00:00:00 2001 From: Nada Date: Tue, 10 Sep 2024 17:11:19 +0400 Subject: [PATCH 28/39] chore: empty commit From 2f806b33c4d6565bbc7219953ed5eff386973ba4 Mon Sep 17 00:00:00 2001 From: Nada Date: Tue, 10 Sep 2024 17:55:08 +0400 Subject: [PATCH 29/39] fix: height issue --- src/pages/buy-sell/screens/BuySell/BuySell.scss | 5 +++++ src/pages/buy-sell/screens/BuySell/BuySell.tsx | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/pages/buy-sell/screens/BuySell/BuySell.scss b/src/pages/buy-sell/screens/BuySell/BuySell.scss index a5c7410a..59fcd8b2 100644 --- a/src/pages/buy-sell/screens/BuySell/BuySell.scss +++ b/src/pages/buy-sell/screens/BuySell/BuySell.scss @@ -1,5 +1,10 @@ .buy-sell { height: 100%; + + &--not-verified { + overflow-y: auto; + height: calc(100% - 11rem); + } & .buy-sell-table { & .table { @include mobile-or-tablet-screen { diff --git a/src/pages/buy-sell/screens/BuySell/BuySell.tsx b/src/pages/buy-sell/screens/BuySell/BuySell.tsx index 23ae112b..35cb0b92 100644 --- a/src/pages/buy-sell/screens/BuySell/BuySell.tsx +++ b/src/pages/buy-sell/screens/BuySell/BuySell.tsx @@ -16,14 +16,14 @@ const BuySell = () => { if (poiPoaVerified === 'false') { return ( - <> +
history.replace({ pathname: BUY_SELL_URL, search: '' })} pageTitle={localize('Verification')} weight='bold' /> - +
); } From d6e0ac41322b9aa46a1d059c9bae0303699346e1 Mon Sep 17 00:00:00 2001 From: Nada Date: Wed, 11 Sep 2024 10:23:49 +0400 Subject: [PATCH 30/39] fix: height issue when no ads --- .../BuySellTableRenderer.tsx | 50 ++++++++++--------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/src/pages/buy-sell/screens/BuySellTable/BuySellTableRenderer/BuySellTableRenderer.tsx b/src/pages/buy-sell/screens/BuySellTable/BuySellTableRenderer/BuySellTableRenderer.tsx index 976cfc05..a9a3964f 100644 --- a/src/pages/buy-sell/screens/BuySellTable/BuySellTableRenderer/BuySellTableRenderer.tsx +++ b/src/pages/buy-sell/screens/BuySellTable/BuySellTableRenderer/BuySellTableRenderer.tsx @@ -41,30 +41,32 @@ const BuySellTableRenderer = ({ if ((!data && !searchValue) || (data.length === 0 && !searchValue)) { return ( -
- history.push(MY_ADS_URL)} - size='lg' - textSize={isMobile ? 'md' : 'sm'} - > - - - } - description={ - - - - } - icon={} - title={ - - - - } - /> +
+
+ history.push(MY_ADS_URL)} + size='lg' + textSize={isMobile ? 'md' : 'sm'} + > + + + } + description={ + + + + } + icon={} + title={ + + + + } + /> +
); } From 64854256d5dc78df53b9d411b946c015182bd53e Mon Sep 17 00:00:00 2001 From: Nada Date: Wed, 11 Sep 2024 11:02:25 +0400 Subject: [PATCH 31/39] fix: height issue for verificatio in myads, myprofile --- src/pages/my-ads/screens/MyAds/MyAds.tsx | 7 ++++++- src/pages/my-profile/screens/MyProfile/MyProfile.tsx | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/pages/my-ads/screens/MyAds/MyAds.tsx b/src/pages/my-ads/screens/MyAds/MyAds.tsx index d7720417..d8e22eb2 100644 --- a/src/pages/my-ads/screens/MyAds/MyAds.tsx +++ b/src/pages/my-ads/screens/MyAds/MyAds.tsx @@ -7,7 +7,12 @@ const MyAds = () => { const { data } = usePoiPoaStatus(); const { isPoaVerified, isPoiVerified } = data || {}; - if (!isPoaVerified || !isPoiVerified) return ; + if (!isPoaVerified || !isPoiVerified) + return ( +
+ ; +
+ ); return (
diff --git a/src/pages/my-profile/screens/MyProfile/MyProfile.tsx b/src/pages/my-profile/screens/MyProfile/MyProfile.tsx index 649908d6..4aa9911e 100644 --- a/src/pages/my-profile/screens/MyProfile/MyProfile.tsx +++ b/src/pages/my-profile/screens/MyProfile/MyProfile.tsx @@ -50,7 +50,11 @@ const MyProfile = () => { } if (!isPoiVerified || !isPoaVerified) { - return ; + return ( +
+ +
+ ); } if (!isDesktop) { From d6434d614d24d9273d0ddadaf05874fed33fa57e Mon Sep 17 00:00:00 2001 From: ameerul-deriv Date: Fri, 6 Sep 2024 17:09:03 +0800 Subject: [PATCH 32/39] fix: merge conflicts --- .../BlockUnblockUserModal.tsx | 49 ++++++-- .../__tests__/BlockUnblockUserModal.spec.tsx | 106 +++++++++++++++++- src/constants/api-error-codes.ts | 1 + .../custom-hooks/useIsAdvertiserBarred.ts | 14 +-- .../AdvertiserBlockOverlay.tsx | 18 +-- .../MyProfileCounterpartiesTable.tsx | 31 +++-- .../MyProfileCounterpartiesTable.spec.tsx | 45 ++++++++ .../MyProfileCounterpartiesTableRow.tsx | 27 ++--- .../MyProfileCounterpartiesTableRow.spec.tsx | 1 + src/stores/index.ts | 1 + src/stores/useErrorStore.ts | 39 +++++++ 11 files changed, 277 insertions(+), 55 deletions(-) create mode 100644 src/stores/useErrorStore.ts diff --git a/src/components/Modals/BlockUnblockUserModal/BlockUnblockUserModal.tsx b/src/components/Modals/BlockUnblockUserModal/BlockUnblockUserModal.tsx index 35d9d17b..10e961b8 100644 --- a/src/components/Modals/BlockUnblockUserModal/BlockUnblockUserModal.tsx +++ b/src/components/Modals/BlockUnblockUserModal/BlockUnblockUserModal.tsx @@ -1,7 +1,13 @@ -import { Dispatch, SetStateAction, useEffect } from 'react'; -import { api } from '@/hooks'; +import { useEffect } from 'react'; +import { useHistory } from 'react-router-dom'; +import { useShallow } from 'zustand/react/shallow'; +import { BUY_SELL_URL, ERROR_CODES } from '@/constants'; +import { api, useModalManager } from '@/hooks'; +import { useErrorStore } from '@/stores'; +import { getCurrentRoute } from '@/utils'; import { Localize, useTranslations } from '@deriv-com/translations'; import { Button, Modal, Text, useDevice } from '@deriv-com/ui'; +import { ErrorModal } from '../ErrorModal'; import './BlockUnblockUserModal.scss'; type TBlockUnblockUserModalProps = { @@ -11,7 +17,6 @@ type TBlockUnblockUserModalProps = { isModalOpen: boolean; onClickBlocked?: () => void; onRequestClose: () => void; - setErrorMessage?: Dispatch>; }; const BlockUnblockUserModal = ({ @@ -21,10 +26,9 @@ const BlockUnblockUserModal = ({ isModalOpen, onClickBlocked, onRequestClose, - setErrorMessage, }: TBlockUnblockUserModalProps) => { - const { isMobile } = useDevice(); const { localize } = useTranslations(); + const { isMobile } = useDevice(); const { mutate: blockAdvertiser, mutation: { error, isSuccess }, @@ -33,17 +37,28 @@ const BlockUnblockUserModal = ({ mutate: unblockAdvertiser, mutation: { error: unblockError, isSuccess: unblockIsSuccess }, } = api.counterparty.useUnblock(); + const { hideModal, isModalOpenFor, showModal } = useModalManager(); + const { errorMessages, setErrorMessages } = useErrorStore( + useShallow(state => ({ errorMessages: state.errorMessages, setErrorMessages: state.setErrorMessages })) + ); + const isAdvertiser = getCurrentRoute() === 'advertiser'; + const history = useHistory(); useEffect(() => { if (isSuccess || unblockIsSuccess) { onClickBlocked?.(); onRequestClose(); } else if (error || unblockError) { - setErrorMessage?.(error?.message || unblockError?.message); - onRequestClose(); + setErrorMessages(error || unblockError); + + if (error?.code === ERROR_CODES.PERMISSION_DENIED && isAdvertiser) { + showModal('ErrorModal'); + } else { + onRequestClose(); + } } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [isSuccess, onClickBlocked, unblockIsSuccess, unblockError, error, setErrorMessage]); + }, [isSuccess, onClickBlocked, unblockIsSuccess, unblockError, error, setErrorMessages]); const textSize = isMobile ? 'md' : 'sm'; const getModalTitle = () => @@ -70,6 +85,24 @@ const BlockUnblockUserModal = ({ } }; + const permissionDeniedError = errorMessages.find(error => error.code === ERROR_CODES.PERMISSION_DENIED); + + if (permissionDeniedError && isModalOpenFor('ErrorModal')) { + return ( + { + hideModal(); + history.push(BUY_SELL_URL); + }} + title={localize('Unable to block advertiser')} + /> + ); + } + return ( ({ + ...jest.requireActual('react-router-dom'), + useHistory: () => ({ push: mockPush }), +})); jest.mock('@/hooks', () => ({ ...jest.requireActual('@/hooks'), @@ -12,10 +36,7 @@ jest.mock('@/hooks', () => ({ counterparty: { useBlock: jest.fn(() => ({ mutate: mockUseBlockMutate, - mutation: { - error: {}, - isSuccess: false, - }, + mutation: mockBlockMutation, })), useUnblock: jest.fn(() => ({ mutate: mockUseUnblockMutate, @@ -28,11 +49,25 @@ jest.mock('@/hooks', () => ({ }, })); +jest.mock('@/hooks/custom-hooks', () => ({ + useModalManager: jest.fn(() => mockModalManager), +})); + +jest.mock('@/utils', () => ({ + getCurrentRoute: jest.fn().mockReturnValue('my-profile'), +})); + jest.mock('@deriv-com/ui', () => ({ ...jest.requireActual('@deriv-com/ui'), useDevice: jest.fn(() => ({ isMobile: false })), })); +jest.mock('@/stores', () => ({ + useErrorStore: jest.fn(selector => (selector ? selector(mockStore) : mockStore)), +})); + +const mockGetCurrentRoute = getCurrentRoute as jest.Mock; + describe('BlockUnblockUserModal', () => { it('should render the modal with correct title and behaviour for blocking user', async () => { render( @@ -100,4 +135,67 @@ describe('BlockUnblockUserModal', () => { expect(mockOnRequestClose).toBeCalled(); }); + + it('should call onClickBlocked and onRequestClose if isSuccess if mutation returns success', async () => { + mockBlockMutation.isSuccess = true; + const mockOnClickBlocked = jest.fn(); + render( + + ); + + expect(mockOnRequestClose).toHaveBeenCalled(); + expect(mockOnClickBlocked).toHaveBeenCalled(); + }); + + it('should show error modal when permission is denied and current route is advertiser', async () => { + mockGetCurrentRoute.mockReturnValue('advertiser'); + mockModalManager.isModalOpenFor.mockImplementation((modalName: string) => modalName === 'ErrorModal'); + const error = { + code: 'PermissionDenied', + message: 'You are not allowed to block this user', + }; + // @ts-expect-error - mock values + mockStore.errorMessages = [error]; + mockBlockMutation.error = error; + mockBlockMutation.isSuccess = false; + render( + + ); + + expect(screen.queryByText('Unable to block advertiser')).toBeVisible(); + expect(screen.queryByText('You are not allowed to block this user')).toBeVisible(); + }); + + it('should call hideModal and history.push when user clicks on Got it button', async () => { + render( + + ); + + const gotItBtn = screen.getByRole('button', { + name: 'Got it', + }); + await userEvent.click(gotItBtn); + + expect(mockModalManager.hideModal).toHaveBeenCalled(); + expect(mockPush).toHaveBeenCalledWith(BUY_SELL_URL); + }); }); diff --git a/src/constants/api-error-codes.ts b/src/constants/api-error-codes.ts index 35900e95..fc74769f 100644 --- a/src/constants/api-error-codes.ts +++ b/src/constants/api-error-codes.ts @@ -17,4 +17,5 @@ export const ERROR_CODES = { ORDER_CREATE_FAIL_RATE_SLIPPAGE: 'OrderCreateFailRateSlippage', ORDER_EMAIL_VERIFICATION_REQUIRED: 'OrderEmailVerificationRequired', PERMISSION_DENIED: 'PermissionDenied', + TEMPORARY_BAR: 'TemporaryBar', } as const; diff --git a/src/hooks/custom-hooks/useIsAdvertiserBarred.ts b/src/hooks/custom-hooks/useIsAdvertiserBarred.ts index 26009ad7..fa6b31b2 100644 --- a/src/hooks/custom-hooks/useIsAdvertiserBarred.ts +++ b/src/hooks/custom-hooks/useIsAdvertiserBarred.ts @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react'; +import { useMemo } from 'react'; import useInvalidateQuery from '../api/useInvalidateQuery'; import { api } from '..'; @@ -8,16 +8,14 @@ import { api } from '..'; */ const useIsAdvertiserBarred = (): boolean => { const { data = {} } = api.advertiser.useGetInfo(); - const [isAdvertiserBarred, setIsAdvertiserBarred] = useState(false); const invalidate = useInvalidateQuery(); - useEffect(() => { - if (isAdvertiserBarred !== !!data.blocked_until) { - invalidate('p2p_advertiser_adverts'); - setIsAdvertiserBarred(!!data.blocked_until); - } + const isAdvertiserBarred = useMemo(() => { + invalidate('p2p_advertiser_adverts'); + return !!data.blocked_until; + // eslint-disable-next-line react-hooks/exhaustive-deps - }, [isAdvertiserBarred, data.blocked_until]); + }, [data.blocked_until]); return isAdvertiserBarred; }; diff --git a/src/pages/advertiser/screens/AdvertiserBlockOverlay/AdvertiserBlockOverlay.tsx b/src/pages/advertiser/screens/AdvertiserBlockOverlay/AdvertiserBlockOverlay.tsx index 298aa820..db3d9223 100644 --- a/src/pages/advertiser/screens/AdvertiserBlockOverlay/AdvertiserBlockOverlay.tsx +++ b/src/pages/advertiser/screens/AdvertiserBlockOverlay/AdvertiserBlockOverlay.tsx @@ -46,14 +46,16 @@ const AdvertiserBlockOverlay = ({
{children} - setShowOverlay(false)} - onRequestClose={hideModal} - /> + {isModalOpenFor('BlockUnblockUserModal') && ( + setShowOverlay(false)} + onRequestClose={hideModal} + /> + )}
); } diff --git a/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTable/MyProfileCounterpartiesTable.tsx b/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTable/MyProfileCounterpartiesTable.tsx index 3fb98c44..085bddf2 100644 --- a/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTable/MyProfileCounterpartiesTable.tsx +++ b/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTable/MyProfileCounterpartiesTable.tsx @@ -1,6 +1,10 @@ -import { Dispatch, SetStateAction, useEffect, useState } from 'react'; +import { useEffect } from 'react'; +import { useShallow } from 'zustand/react/shallow'; import { Table } from '@/components'; +import { ERROR_CODES } from '@/constants'; import { api } from '@/hooks'; +import { useIsAdvertiserBarred } from '@/hooks/custom-hooks'; +import { useErrorStore } from '@/stores'; import { DerivLightIcBlockedAdvertisersBarredIcon } from '@deriv/quill-icons'; import { Localize } from '@deriv-com/translations'; import { Loader, Text, useDevice } from '@deriv-com/ui'; @@ -18,21 +22,14 @@ type TMyProfileCounterpartiesTableRowRendererProps = { id?: string; is_blocked: boolean; name?: string; - setErrorMessage: Dispatch>; }; const MyProfileCounterpartiesTableRowRenderer = ({ id, is_blocked: isBlocked, name, - setErrorMessage, }: TMyProfileCounterpartiesTableRowRendererProps) => ( - + ); const MyProfileCounterpartiesTable = ({ @@ -50,8 +47,14 @@ const MyProfileCounterpartiesTable = ({ is_blocked: dropdownValue === 'blocked' ? 1 : 0, trade_partners: 1, }); - const [errorMessage, setErrorMessage] = useState(''); const { isDesktop } = useDevice(); + const { errorMessages, reset } = useErrorStore( + useShallow(state => ({ errorMessages: state.errorMessages, reset: state.reset })) + ); + const isAdvertiserBarred = useIsAdvertiserBarred(); + const errorMessage = errorMessages.find( + error => error.code === ERROR_CODES.TEMPORARY_BAR || error.code === ERROR_CODES.PERMISSION_DENIED + )?.message; useEffect(() => { if (data.length > 0) { @@ -62,6 +65,13 @@ const MyProfileCounterpartiesTable = ({ } }, [data, errorMessage, setShowHeader]); + useEffect(() => { + if (!isAdvertiserBarred && errorMessages.some(error => error.code === ERROR_CODES.TEMPORARY_BAR)) { + setShowHeader(true); + reset(); + } + }, [errorMessage, errorMessages, isAdvertiserBarred, reset, setShowHeader]); + if (isLoading) { return ; } @@ -93,7 +103,6 @@ const MyProfileCounterpartiesTable = ({ rowRender={(rowData: unknown) => ( )} tableClassname='my-profile-counterparties-table' diff --git a/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTable/__tests__/MyProfileCounterpartiesTable.spec.tsx b/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTable/__tests__/MyProfileCounterpartiesTable.spec.tsx index a199320c..6c59ecd3 100644 --- a/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTable/__tests__/MyProfileCounterpartiesTable.spec.tsx +++ b/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTable/__tests__/MyProfileCounterpartiesTable.spec.tsx @@ -1,4 +1,5 @@ import { api } from '@/hooks'; +import { useIsAdvertiserBarred } from '@/hooks/custom-hooks'; import { render, screen, waitFor } from '@testing-library/react'; import MyProfileCounterpartiesTable from '../MyProfileCounterpartiesTable'; @@ -15,12 +16,18 @@ const mockApiValues = { loadMoreAdvertisers: jest.fn(), }; +const mockStore = { + errorMessages: [], + reset: jest.fn(), +}; + jest.mock('@deriv-com/ui', () => ({ ...jest.requireActual('@deriv-com/ui'), useDevice: jest.fn(() => ({ isMobile: false })), })); jest.mock('@/hooks', () => ({ + ...jest.requireActual('@/hooks'), api: { advertiser: { useGetList: jest.fn(() => mockApiValues), @@ -29,6 +36,14 @@ jest.mock('@/hooks', () => ({ useIsRtl: jest.fn(() => false), })); +jest.mock('@/hooks/custom-hooks', () => ({ + useIsAdvertiserBarred: jest.fn(() => false), +})); + +jest.mock('@/stores', () => ({ + useErrorStore: jest.fn(selector => (selector ? selector(mockStore) : mockStore)), +})); + const mockUseModalManager = { hideModal: jest.fn(), isModalOpenFor: jest.fn(), @@ -46,6 +61,8 @@ jest.mock('@/components/Modals/BlockUnblockUserModal', () => ({ })); const mockUseGetList = api.advertiser.useGetList as jest.Mock; +const mockUseIsAdvertiserBarred = useIsAdvertiserBarred as jest.Mock; + describe('MyProfileCounterpartiesTable', () => { it('should render the empty results when there is no data', () => { render(); @@ -82,4 +99,32 @@ describe('MyProfileCounterpartiesTable', () => { render(); expect(screen.getByText('There are no matching name.')).toBeInTheDocument(); }); + + it('should show error message when error code is TEMPORARY_BAR', () => { + // @ts-expect-error - mock values + mockStore.errorMessages = [{ code: 'TemporaryBar', message: 'Temporary Bar' }]; + mockUseIsAdvertiserBarred.mockReturnValue(true); + mockUseGetList.mockReturnValue({ + ...mockApiValues, + data: [{ id: 'id1', is_blocked: false, name: 'name1' }], + }); + + render(); + expect(screen.getByText('Temporary Bar')).toBeInTheDocument(); + }); + + it('should call reset and setShowHeader if isAdvertiserBarred is false and error code is', () => { + // @ts-expect-error - mock values + mockStore.errorMessages = [{ code: 'TemporaryBar', message: 'Temporary Bar' }]; + mockUseIsAdvertiserBarred.mockReturnValue(false); + mockUseGetList.mockReturnValue({ + ...mockApiValues, + data: [{ id: 'id1', is_blocked: false, name: 'name1' }], + }); + + render(); + + expect(mockProps.setShowHeader).toHaveBeenCalledWith(true); + expect(mockStore.reset).toHaveBeenCalled(); + }); }); diff --git a/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTableRow/MyProfileCounterpartiesTableRow.tsx b/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTableRow/MyProfileCounterpartiesTableRow.tsx index 161b80c9..962e008e 100644 --- a/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTableRow/MyProfileCounterpartiesTableRow.tsx +++ b/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTableRow/MyProfileCounterpartiesTableRow.tsx @@ -1,4 +1,4 @@ -import { Dispatch, memo, SetStateAction } from 'react'; +import { memo } from 'react'; import clsx from 'clsx'; import { useHistory } from 'react-router-dom'; import { UserAvatar } from '@/components'; @@ -13,15 +13,9 @@ type TMyProfileCounterpartiesTableRowProps = { id: string; isBlocked: boolean; nickname: string; - setErrorMessage: Dispatch>; }; -const MyProfileCounterpartiesTableRow = ({ - id, - isBlocked, - nickname, - setErrorMessage, -}: TMyProfileCounterpartiesTableRowProps) => { +const MyProfileCounterpartiesTableRow = ({ id, isBlocked, nickname }: TMyProfileCounterpartiesTableRowProps) => { const { isDesktop } = useDevice(); const history = useHistory(); const { hideModal, isModalOpenFor, showModal } = useModalManager(); @@ -54,14 +48,15 @@ const MyProfileCounterpartiesTableRow = ({ {isBlocked ? localize('Unblock') : localize('Block')}
- + {isModalOpenFor('BlockUnblockUserModal') && ( + + )} ); }; diff --git a/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTableRow/__tests__/MyProfileCounterpartiesTableRow.spec.tsx b/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTableRow/__tests__/MyProfileCounterpartiesTableRow.spec.tsx index 56561134..76313e30 100644 --- a/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTableRow/__tests__/MyProfileCounterpartiesTableRow.spec.tsx +++ b/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTableRow/__tests__/MyProfileCounterpartiesTableRow.spec.tsx @@ -34,6 +34,7 @@ const mockModalManager = { }; jest.mock('@/hooks', () => ({ + ...jest.requireActual('@/hooks'), api: { counterparty: { useBlock: () => ({ diff --git a/src/stores/index.ts b/src/stores/index.ts index 0d8fcad6..818cb5a4 100644 --- a/src/stores/index.ts +++ b/src/stores/index.ts @@ -1,2 +1,3 @@ export { default as useBuySellFiltersStore } from './useBuySellFiltersStore'; +export { default as useErrorStore } from './useErrorStore'; export { default as useTabsStore } from './useTabsStore'; diff --git a/src/stores/useErrorStore.ts b/src/stores/useErrorStore.ts new file mode 100644 index 00000000..8d3b3876 --- /dev/null +++ b/src/stores/useErrorStore.ts @@ -0,0 +1,39 @@ +import { create } from 'zustand'; + +type TError = { + code: string; + message: string; +}; + +type TErrorState = { + errorMessages: TError[]; +}; + +type TErrorAction = { + reset: () => void; + setErrorMessages: (errorMessages: TError | null) => void; +}; + +const useErrorStore = create()(set => ({ + errorMessages: [], + reset: () => set({ errorMessages: [] }), + setErrorMessages: errorMessages => + set(state => { + if (!errorMessages) { + return { ...state, errorMessages: [] }; + } + + const isErrorMessageIncluded = state.errorMessages.some( + error => error.code === errorMessages.code && error.message === errorMessages.message + ); + + return { + ...state, + errorMessages: isErrorMessageIncluded + ? state.errorMessages + : [...state.errorMessages, { code: errorMessages.code, message: errorMessages.message }], + }; + }), +})); + +export default useErrorStore; From 9cfeb79ed27b879c465cfd1ffd19f419e8902719 Mon Sep 17 00:00:00 2001 From: ameerul-deriv Date: Fri, 6 Sep 2024 17:26:02 +0800 Subject: [PATCH 33/39] chore: added test case for error store --- src/stores/__tests__/useErrorStore.spec.ts | 61 ++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/stores/__tests__/useErrorStore.spec.ts diff --git a/src/stores/__tests__/useErrorStore.spec.ts b/src/stores/__tests__/useErrorStore.spec.ts new file mode 100644 index 00000000..7084e4d4 --- /dev/null +++ b/src/stores/__tests__/useErrorStore.spec.ts @@ -0,0 +1,61 @@ +import { act } from 'react'; +import { renderHook } from '@testing-library/react'; +import useErrorStore from '../useErrorStore'; + +describe('useErrorStore', () => { + it('should update the store state correctly', () => { + const { result } = renderHook(() => useErrorStore()); + + expect(result.current.errorMessages).toEqual([]); + + act(() => { + result.current.setErrorMessages({ code: 'error-code', message: 'error-message' }); + }); + + expect(result.current.errorMessages).toEqual([{ code: 'error-code', message: 'error-message' }]); + + act(() => { + result.current.setErrorMessages(null); + }); + }); + + it('should not add the same error message twice', () => { + const { result } = renderHook(() => useErrorStore()); + + expect(result.current.errorMessages).toEqual([]); + + act(() => { + result.current.setErrorMessages({ code: 'error-code', message: 'error-message' }); + }); + + expect(result.current.errorMessages).toEqual([{ code: 'error-code', message: 'error-message' }]); + + act(() => { + result.current.setErrorMessages({ code: 'error-code', message: 'error-message' }); + }); + + expect(result.current.errorMessages).toEqual([{ code: 'error-code', message: 'error-message' }]); + + act(() => { + result.current.setErrorMessages(null); + }); + }); + + it('should reset the error messages', () => { + const { result } = renderHook(() => useErrorStore()); + + expect(result.current.errorMessages).toEqual([]); + + act(() => { + result.current.setErrorMessages({ code: 'error-code', message: 'error-message' }); + }); + + expect(result.current.errorMessages).toEqual([{ code: 'error-code', message: 'error-message' }]); + + act(() => { + result.current.reset(); + }); + + expect(result.current.errorMessages).toEqual([]); + }); +}); From 0f2a2efe234dfb4515ee6a077bbc96a7ae3cf7ec Mon Sep 17 00:00:00 2001 From: ameerul-deriv Date: Tue, 10 Sep 2024 10:09:45 +0800 Subject: [PATCH 34/39] chore: changed test case description --- .../__tests__/BlockUnblockUserModal.spec.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Modals/BlockUnblockUserModal/__tests__/BlockUnblockUserModal.spec.tsx b/src/components/Modals/BlockUnblockUserModal/__tests__/BlockUnblockUserModal.spec.tsx index bc34303c..a1775bb2 100644 --- a/src/components/Modals/BlockUnblockUserModal/__tests__/BlockUnblockUserModal.spec.tsx +++ b/src/components/Modals/BlockUnblockUserModal/__tests__/BlockUnblockUserModal.spec.tsx @@ -136,7 +136,7 @@ describe('BlockUnblockUserModal', () => { expect(mockOnRequestClose).toBeCalled(); }); - it('should call onClickBlocked and onRequestClose if isSuccess if mutation returns success', async () => { + it('should call onClickBlocked and onRequestClose if isSuccess or mutation returns success', async () => { mockBlockMutation.isSuccess = true; const mockOnClickBlocked = jest.fn(); render( From 808e9e529400d174c331e3b0710db51262032c70 Mon Sep 17 00:00:00 2001 From: ameerul-deriv Date: Wed, 18 Sep 2024 13:17:24 +0800 Subject: [PATCH 35/39] chore: call getServerInfo on reset --- src/pages/endpoint/screens/Endpoint/Endpoint.tsx | 3 ++- .../screens/Endpoint/__tests__/Endpoint.spec.tsx | 9 ++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/pages/endpoint/screens/Endpoint/Endpoint.tsx b/src/pages/endpoint/screens/Endpoint/Endpoint.tsx index 2e1face3..e1c4ff42 100644 --- a/src/pages/endpoint/screens/Endpoint/Endpoint.tsx +++ b/src/pages/endpoint/screens/Endpoint/Endpoint.tsx @@ -1,4 +1,5 @@ import { Controller, useForm } from 'react-hook-form'; +import { getServerInfo } from '@/constants'; import { Button, Input, Text } from '@deriv-com/ui'; import { LocalStorageConstants, LocalStorageUtils } from '@deriv-com/utils'; import './Endpoint.scss'; @@ -86,7 +87,7 @@ const Endpoint = () => { LocalStorageUtils.setValue(LocalStorageConstants.configServerURL, ''); LocalStorageUtils.setValue(LocalStorageConstants.configAppId, ''); reset(); - window.location.reload(); + getServerInfo(); }} variant='outlined' > diff --git a/src/pages/endpoint/screens/Endpoint/__tests__/Endpoint.spec.tsx b/src/pages/endpoint/screens/Endpoint/__tests__/Endpoint.spec.tsx index 984e5b81..bc22acc7 100644 --- a/src/pages/endpoint/screens/Endpoint/__tests__/Endpoint.spec.tsx +++ b/src/pages/endpoint/screens/Endpoint/__tests__/Endpoint.spec.tsx @@ -2,6 +2,12 @@ import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import Endpoint from '../Endpoint'; +const mockGetServerInfo = jest.fn(); + +jest.mock('@/constants', () => ({ + getServerInfo: jest.fn(() => mockGetServerInfo()), +})); + describe('', () => { it('should render the endpoint component', () => { render(); @@ -28,7 +34,7 @@ describe('', () => { expect(JSON.parse(localStorage.getItem('config.app_id') || '')).toBe('123'); }); - it('should reset the server_url and app_id when user clicks on the reset button', async () => { + it('should call getServerInfo and reset the inputs when user clicks on the reset button', async () => { render(); const serverUrlInput = screen.getByTestId('dt_endpoint_server_url_input'); @@ -41,5 +47,6 @@ describe('', () => { expect(JSON.parse(localStorage.getItem('config.server_url') || '')).toBe(''); expect(JSON.parse(localStorage.getItem('config.app_id') || '')).toBe(''); + expect(mockGetServerInfo).toHaveBeenCalled(); }); }); From 9e10f69954030bfc75d7537e450bc057e0d3b09d Mon Sep 17 00:00:00 2001 From: ameerul-deriv Date: Mon, 9 Sep 2024 14:03:17 +0800 Subject: [PATCH 36/39] chore: added error state to logout user when error code is AccountDisabled --- src/constants/api-error-codes.ts | 1 + src/hooks/api/account/useActiveAccount.ts | 3 ++- src/routes/AppContent/index.tsx | 14 ++++++++++++-- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/constants/api-error-codes.ts b/src/constants/api-error-codes.ts index 35900e95..437c5c2b 100644 --- a/src/constants/api-error-codes.ts +++ b/src/constants/api-error-codes.ts @@ -1,4 +1,5 @@ export const ERROR_CODES = { + ACCOUNT_DISABLED: 'AccountDisabled', AD_EXCEEDS_BALANCE: 'advertiser_balance', AD_EXCEEDS_DAILY_LIMIT: 'advertiser_daily_limit', ADVERT_INACTIVE: 'advert_inactive', diff --git a/src/hooks/api/account/useActiveAccount.ts b/src/hooks/api/account/useActiveAccount.ts index f72ace20..1e46b165 100644 --- a/src/hooks/api/account/useActiveAccount.ts +++ b/src/hooks/api/account/useActiveAccount.ts @@ -5,7 +5,7 @@ import { useAccountList, useAuthData } from '@deriv-com/api-hooks'; /** A custom hook that returns the account object for the current active account. */ const useActiveAccount = () => { const { data, ...rest } = useAccountList(); - const { activeLoginid } = useAuthData(); + const { activeLoginid, error } = useAuthData(); const { data: balanceData } = api.account.useBalance(); const activeAccount = useMemo( () => data?.find(account => account.loginid === activeLoginid), @@ -23,6 +23,7 @@ const useActiveAccount = () => { return { /** User's current active account. */ + authError: error, data: modifiedAccount, ...rest, }; diff --git a/src/routes/AppContent/index.tsx b/src/routes/AppContent/index.tsx index 098b73e2..82b34d66 100644 --- a/src/routes/AppContent/index.tsx +++ b/src/routes/AppContent/index.tsx @@ -2,7 +2,7 @@ import { useEffect, useRef, useState } from 'react'; import { useHistory, useLocation } from 'react-router-dom'; import { BlockedScenarios } from '@/components/BlockedScenarios'; import { BUY_SELL_URL, ERROR_CODES } from '@/constants'; -import { api, useIsP2PBlocked, useLiveChat } from '@/hooks'; +import { api, useIsP2PBlocked, useLiveChat, useOAuth } from '@/hooks'; import { GuideTooltip } from '@/pages/guide/components'; import { AdvertiserInfoStateProvider } from '@/providers/AdvertiserInfoStateProvider'; import { getCurrentRoute } from '@/utils'; @@ -17,10 +17,16 @@ const AppContent = () => { const history = useHistory(); const location = useLocation(); const { isDesktop } = useDevice(); - const { data: activeAccountData, isFetched, isLoading: isLoadingActiveAccount } = api.account.useActiveAccount(); + const { + authError, + data: activeAccountData, + isFetched, + isLoading: isLoadingActiveAccount, + } = api.account.useActiveAccount(); const { init: initLiveChat } = useLiveChat(); const { isP2PBlocked, status } = useIsP2PBlocked(); const { localize } = useTranslations(); + const { oAuthLogout } = useOAuth(); const routes = getRoutes(localize); const tabRoutesConfiguration = routes.filter( @@ -79,6 +85,10 @@ const AppContent = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [location]); + useEffect(() => { + if (authError?.code === ERROR_CODES.ACCOUNT_DISABLED) oAuthLogout(); + }, [authError, oAuthLogout]); + useEffect(() => { if (!isGtmTracking.current) { window.dataLayer.push({ event: 'allow_tracking' }); From 117f73464bdac535b603b403db033455be64ec98 Mon Sep 17 00:00:00 2001 From: Farrah Mae Ochoa Date: Wed, 18 Sep 2024 15:30:35 +0400 Subject: [PATCH 37/39] fix: update ui --- package-lock.json | 8 ++++---- package.json | 4 ++-- .../AppHeader/Notifications/Notifications.tsx | 14 +++++++++----- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 757da0a5..43361a36 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@deriv-com/analytics": "^1.16.1", "@deriv-com/api-hooks": "^1.4.9", "@deriv-com/translations": "^1.3.7", - "@deriv-com/ui": "^1.30.2", + "@deriv-com/ui": "^1.35.5", "@deriv-com/utils": "^0.0.28", "@deriv/quill-icons": "^1.23.8", "@sendbird/chat": "^4.11.3", @@ -3892,9 +3892,9 @@ ] }, "node_modules/@deriv-com/ui": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/@deriv-com/ui/-/ui-1.30.2.tgz", - "integrity": "sha512-ovmfrK7F5IIzBfHttgfsPJOQxLB/8va9AtMBknLUHYPwlmYx+mBr6WJ/hPUxxxojvTW2mUIPN1zGh/WZd0s6SQ==", + "version": "1.35.5", + "resolved": "https://registry.npmjs.org/@deriv-com/ui/-/ui-1.35.5.tgz", + "integrity": "sha512-v6eKPhpjPt8Z8OvOEC6sheCFTcO6Xmiexps+kXd8+/RwzqIugeU+SjhF9MRy2V396cKBzt/ph9zumZUnNm/Kew==", "dependencies": { "@popperjs/core": "^2.11.8", "@types/react-modal": "^3.16.3", diff --git a/package.json b/package.json index 33991972..181612d3 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "@deriv-com/analytics": "^1.16.1", "@deriv-com/api-hooks": "^1.4.9", "@deriv-com/translations": "^1.3.7", - "@deriv-com/ui": "^1.30.2", + "@deriv-com/ui": "^1.35.5", "@deriv-com/utils": "^0.0.28", "@deriv/quill-icons": "^1.23.8", "@sendbird/chat": "^4.11.3", @@ -116,4 +116,4 @@ "optionalDependencies": { "@rollup/rollup-linux-x64-gnu": "4.9.5" } -} +} \ No newline at end of file diff --git a/src/components/AppHeader/Notifications/Notifications.tsx b/src/components/AppHeader/Notifications/Notifications.tsx index f9f997ee..b3fadf35 100644 --- a/src/components/AppHeader/Notifications/Notifications.tsx +++ b/src/components/AppHeader/Notifications/Notifications.tsx @@ -4,14 +4,14 @@ import { getNotification, MY_PROFILE_URL } from '@/constants'; import { api } from '@/hooks'; import { LegacyAnnouncementIcon, LegacyNotificationIcon } from '@deriv/quill-icons'; import { useTranslations } from '@deriv-com/translations'; -import { Badge, Notifications as UINotifications, Tooltip, useDevice } from '@deriv-com/ui'; +import { Badge, Notifications as UINotifications, Text, Tooltip, useDevice } from '@deriv-com/ui'; const Notifications = () => { const [isOpen, setIsOpen] = useState(false); const { localize } = useTranslations(); const { isDesktop, isMobile } = useDevice(); const { data: activeAccountData } = api.account.useActiveAccount(); - const { data: notifications, subscribe, unsubscribe } = api.notification.useGetList(); + const { data: notifications, isLoading, subscribe, unsubscribe } = api.notification.useGetList(); const { mutate: updateNotification } = api.notification.useUpdate(); const history = useHistory(); @@ -32,7 +32,7 @@ const Notifications = () => { }, icon: , id: notification.message_key, - message, + message: {message}, title, }; }); @@ -62,7 +62,11 @@ const Notifications = () => { {notifications?.length > 0 && ( { noNotificationsMessage: localize('You have yet to receive any notifications'), noNotificationsTitle: localize('No notifications'), }} - isLoading={false} + isLoading={isLoading} isOpen={isOpen} notifications={modifiedNotifications || []} setIsOpen={setIsOpen} From 62c284997e442eb75894b59e0f3248045b8f3376 Mon Sep 17 00:00:00 2001 From: Farrah Mae Ochoa Date: Wed, 18 Sep 2024 16:12:49 +0400 Subject: [PATCH 38/39] fix: hide tooltip on mobile --- src/components/AppHeader/Notifications/Notifications.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/AppHeader/Notifications/Notifications.tsx b/src/components/AppHeader/Notifications/Notifications.tsx index b3fadf35..7b5f3d86 100644 --- a/src/components/AppHeader/Notifications/Notifications.tsx +++ b/src/components/AppHeader/Notifications/Notifications.tsx @@ -54,6 +54,7 @@ const Notifications = () => { setIsOpen(prev => !prev)} tooltipContent={localize('View notifications')} tooltipPosition='bottom' From b258731719ea4269b4b6be560652bac4be2d84a4 Mon Sep 17 00:00:00 2001 From: Farrah Mae Ochoa Date: Thu, 19 Sep 2024 10:28:06 +0400 Subject: [PATCH 39/39] fix: loader --- src/components/AppHeader/Notifications/Notifications.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/AppHeader/Notifications/Notifications.tsx b/src/components/AppHeader/Notifications/Notifications.tsx index 7b5f3d86..d49369f6 100644 --- a/src/components/AppHeader/Notifications/Notifications.tsx +++ b/src/components/AppHeader/Notifications/Notifications.tsx @@ -11,7 +11,7 @@ const Notifications = () => { const { localize } = useTranslations(); const { isDesktop, isMobile } = useDevice(); const { data: activeAccountData } = api.account.useActiveAccount(); - const { data: notifications, isLoading, subscribe, unsubscribe } = api.notification.useGetList(); + const { data: notifications, subscribe, unsubscribe } = api.notification.useGetList(); const { mutate: updateNotification } = api.notification.useUpdate(); const history = useHistory(); @@ -87,7 +87,7 @@ const Notifications = () => { noNotificationsMessage: localize('You have yet to receive any notifications'), noNotificationsTitle: localize('No notifications'), }} - isLoading={isLoading} + isLoading={false} isOpen={isOpen} notifications={modifiedNotifications || []} setIsOpen={setIsOpen}