From 5b04099d5278791d1a9cbe099a2548adbde4d620 Mon Sep 17 00:00:00 2001 From: nada-deriv <122768621+nada-deriv@users.noreply.github.com> Date: Mon, 27 May 2024 11:51:14 +0400 Subject: [PATCH] fix: blocked message for temp barred user, green save button for ad details (#78) * fix: blocked message for temp barred user, green save button for ad details * fix: avatar resize issue fixed * fix: font sizes difference issue fixed * fix: added localize * fix: removed assertion --- .../AdvertiserName/AdvertiserName.tsx | 8 +-- .../AdvertiserName/AdvertiserNameStats.tsx | 2 +- .../__tests__/AdvertiserName.spec.tsx | 8 ++- .../BlockUnblockUserModal.scss | 32 +----------- .../BlockUnblockUserModal.tsx | 51 ++++++++++++------- .../__tests__/BlockUnblockUserModal.spec.tsx | 7 +++ .../InvalidVerificationLinkModal.tsx | 8 +-- .../ProfileBalance/ProfileBalance.tsx | 33 ++++++------ .../MyProfileAdDetails.scss | 7 +++ .../MyProfileAdDetails/MyProfileAdDetails.tsx | 12 ++++- .../MyProfileCounterpartiesTable.scss | 8 +-- .../MyProfileCounterpartiesTable.tsx | 34 +++++++++++-- .../MyProfileCounterpartiesTableRow.scss | 4 ++ .../MyProfileCounterpartiesTableRow.tsx | 23 +++++++-- .../MyProfileCounterpartiesTableRow.spec.tsx | 1 + .../MyProfileStats/MyProfileStatsItem.tsx | 7 ++- 16 files changed, 153 insertions(+), 92 deletions(-) diff --git a/src/components/AdvertiserName/AdvertiserName.tsx b/src/components/AdvertiserName/AdvertiserName.tsx index a9f08093..2a67923f 100644 --- a/src/components/AdvertiserName/AdvertiserName.tsx +++ b/src/components/AdvertiserName/AdvertiserName.tsx @@ -16,14 +16,14 @@ type TAdvertiserNameProps = { const AdvertiserName = ({ advertiserStats, onClickBlocked }: TAdvertiserNameProps) => { const { data } = useGetSettings(); - const { isDesktop } = useDevice(); + const { isMobile } = useDevice(); const isMyProfile = getCurrentRoute() === 'my-profile'; const name = advertiserStats?.name || data?.email; return (
- +
@@ -38,8 +38,8 @@ const AdvertiserName = ({ advertiserStats, onClickBlocked }: TAdvertiserNameProp
- {isDesktop && isMyProfile && } - {isDesktop && !isMyProfile && !advertiserStats?.is_blocked && ( + {!isMobile && isMyProfile && } + {!isMobile && !isMyProfile && !advertiserStats?.is_blocked && ( )}
diff --git a/src/components/AdvertiserName/AdvertiserNameStats.tsx b/src/components/AdvertiserName/AdvertiserNameStats.tsx index 36ea5fe7..232c7d5e 100644 --- a/src/components/AdvertiserName/AdvertiserNameStats.tsx +++ b/src/components/AdvertiserName/AdvertiserNameStats.tsx @@ -50,7 +50,7 @@ const AdvertiserNameStats = ({ advertiserStats }: { advertiserStats: DeepPartial {daysSinceJoined && daysSinceJoined > 0 ? ( ) : ( - + )}
diff --git a/src/components/AdvertiserName/__tests__/AdvertiserName.spec.tsx b/src/components/AdvertiserName/__tests__/AdvertiserName.spec.tsx index 04aced61..1dd1fadc 100644 --- a/src/components/AdvertiserName/__tests__/AdvertiserName.spec.tsx +++ b/src/components/AdvertiserName/__tests__/AdvertiserName.spec.tsx @@ -10,12 +10,18 @@ const mockProps = { }; jest.mock('@deriv-com/api-hooks', () => ({ + ...jest.requireActual('@deriv-com/api-hooks'), useGetSettings: jest.fn(() => ({ email: 'test@gmail.com' })), })); jest.mock('@deriv-com/ui', () => ({ ...jest.requireActual('@deriv-com/ui'), - useDevice: jest.fn(() => ({ isMobile: false })), + useDevice: jest.fn(() => ({ isMobile: true })), +})); + +jest.mock('@/utils', () => ({ + ...jest.requireActual('@/utils'), + getCurrentRoute: jest.fn(() => ''), })); describe('AdvertiserName', () => { diff --git a/src/components/Modals/BlockUnblockUserModal/BlockUnblockUserModal.scss b/src/components/Modals/BlockUnblockUserModal/BlockUnblockUserModal.scss index 6863b49a..eb97e8c1 100644 --- a/src/components/Modals/BlockUnblockUserModal/BlockUnblockUserModal.scss +++ b/src/components/Modals/BlockUnblockUserModal/BlockUnblockUserModal.scss @@ -1,33 +1,3 @@ .block-unblock-user-modal { - position: absolute; - top: 50%; - left: 50%; - right: auto; - bottom: auto; - margin-right: -50%; - transform: translate(-50%, -50%); - width: 44rem; - padding: 2.4rem; - border-radius: 8px; - background: #fff; - box-shadow: 0px 32px 64px 0px rgba(14, 14, 14, 0.14); - - &__text { - margin: 2.4rem 0; - - @include mobile { - margin: 1.6rem 0; - } - } - - @include mobile { - padding: 1.6rem; - width: 32.8rem; - } - - &__footer { - display: flex; - justify-content: flex-end; - gap: 0.8rem; - } + @include default-modal; } diff --git a/src/components/Modals/BlockUnblockUserModal/BlockUnblockUserModal.tsx b/src/components/Modals/BlockUnblockUserModal/BlockUnblockUserModal.tsx index 86d26c3b..120e2d48 100644 --- a/src/components/Modals/BlockUnblockUserModal/BlockUnblockUserModal.tsx +++ b/src/components/Modals/BlockUnblockUserModal/BlockUnblockUserModal.tsx @@ -1,9 +1,7 @@ -import { useEffect } from 'react'; -import Modal from 'react-modal'; +import { Dispatch, SetStateAction, useEffect } from 'react'; import { api } from '@/hooks'; import { Localize } from '@deriv-com/translations'; -import { Button, Text } from '@deriv-com/ui'; -import { customStyles } from '../helpers'; +import { Button, Modal, Text, useDevice } from '@deriv-com/ui'; import './BlockUnblockUserModal.scss'; type TBlockUnblockUserModalProps = { @@ -13,6 +11,7 @@ type TBlockUnblockUserModalProps = { isModalOpen: boolean; onClickBlocked?: () => void; onRequestClose: () => void; + setErrorMessage?: Dispatch>; }; const BlockUnblockUserModal = ({ @@ -22,17 +21,28 @@ const BlockUnblockUserModal = ({ isModalOpen, onClickBlocked, onRequestClose, + setErrorMessage, }: TBlockUnblockUserModalProps) => { - const { mutate: blockAdvertiser, mutation } = api.counterparty.useBlock(); - const { mutate: unblockAdvertiser, mutation: unblockMutation } = api.counterparty.useUnblock(); + const { isMobile } = useDevice(); + const { + mutate: blockAdvertiser, + mutation: { error, isSuccess }, + } = api.counterparty.useBlock(); + const { + mutate: unblockAdvertiser, + mutation: { error: unblockError, isSuccess: unblockIsSuccess }, + } = api.counterparty.useUnblock(); useEffect(() => { - if (mutation.isSuccess || unblockMutation.isSuccess) { + if (isSuccess || unblockIsSuccess) { onClickBlocked?.(); onRequestClose(); + } else if (error || unblockError) { + setErrorMessage?.(error?.error.message || unblockError?.error.message); + onRequestClose(); } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [mutation.isSuccess, onClickBlocked, unblockMutation.isSuccess]); + }, [isSuccess, onClickBlocked, unblockIsSuccess, unblockError, error, setErrorMessage]); const getModalTitle = () => (isBlocked ? `Unblock ${advertiserName}?` : `Block ${advertiserName}?`); @@ -64,15 +74,18 @@ const BlockUnblockUserModal = ({ isOpen={isModalOpen} onRequestClose={onRequestClose} shouldCloseOnOverlayClick={false} - style={customStyles} > - - {getModalTitle()} - - - {getModalContent()} - -
+ + + {getModalTitle()} + + + + + {getModalContent()} + + + -
+ ); }; diff --git a/src/components/Modals/BlockUnblockUserModal/__tests__/BlockUnblockUserModal.spec.tsx b/src/components/Modals/BlockUnblockUserModal/__tests__/BlockUnblockUserModal.spec.tsx index 05779542..a1ee69b5 100644 --- a/src/components/Modals/BlockUnblockUserModal/__tests__/BlockUnblockUserModal.spec.tsx +++ b/src/components/Modals/BlockUnblockUserModal/__tests__/BlockUnblockUserModal.spec.tsx @@ -13,12 +13,14 @@ jest.mock('@/hooks', () => ({ useBlock: jest.fn(() => ({ mutate: mockUseBlockMutate, mutation: { + error: {}, isSuccess: false, }, })), useUnblock: jest.fn(() => ({ mutate: mockUseUnblockMutate, mutation: { + error: {}, isSuccess: false, }, })), @@ -26,6 +28,11 @@ jest.mock('@/hooks', () => ({ }, })); +jest.mock('@deriv-com/ui', () => ({ + ...jest.requireActual('@deriv-com/ui'), + useDevice: jest.fn(() => ({ isMobile: false })), +})); + describe('BlockUnblockUserModal', () => { it('should render the modal with correct title and behaviour for blocking user', async () => { render( diff --git a/src/components/Modals/InvalidVerificationLinkModal/InvalidVerificationLinkModal.tsx b/src/components/Modals/InvalidVerificationLinkModal/InvalidVerificationLinkModal.tsx index 0e98cffa..17de3bd3 100644 --- a/src/components/Modals/InvalidVerificationLinkModal/InvalidVerificationLinkModal.tsx +++ b/src/components/Modals/InvalidVerificationLinkModal/InvalidVerificationLinkModal.tsx @@ -52,9 +52,11 @@ const InvalidVerificationLinkModal = ({ )} - {error?.message && - {error.message} - } + {error?.message && ( + + {error.message} + + )} }) => { const { data: activeAccount } = api.account.useActiveAccount(); - const { isDesktop } = useDevice(); + const { isMobile } = useDevice(); const [shouldShowAvailableBalanceModal, setShouldShowAvailableBalanceModal] = useState(false); const currency = activeAccount?.currency || 'USD'; @@ -36,6 +37,8 @@ const ProfileBalance = ({ advertiserStats }: { advertiserStats: DeepPartial
- - Available Deriv P2P Balance + + setShouldShowAvailableBalanceModal(true)} />
- + {numberToCurrencyText(advertiserStats?.balance_available || 0)} USD
@@ -62,25 +65,21 @@ const ProfileBalance = ({ advertiserStats }: { advertiserStats: DeepPartial {dailyLimits.map(({ available, dailyLimit, type }) => (
- {type} + {type}
- Daily limit - + + + + {dailyLimit}
- Available - + + + + {available}
diff --git a/src/pages/my-profile/screens/MyProfileAdDetails/MyProfileAdDetails.scss b/src/pages/my-profile/screens/MyProfileAdDetails/MyProfileAdDetails.scss index 75bf0688..a0ddfa4f 100644 --- a/src/pages/my-profile/screens/MyProfileAdDetails/MyProfileAdDetails.scss +++ b/src/pages/my-profile/screens/MyProfileAdDetails/MyProfileAdDetails.scss @@ -26,4 +26,11 @@ } } } + + &__button { + &--submitting { + //TODO: add this variant to deriv-com/ui + background-color: #4bb4b3 !important; + } + } } diff --git a/src/pages/my-profile/screens/MyProfileAdDetails/MyProfileAdDetails.tsx b/src/pages/my-profile/screens/MyProfileAdDetails/MyProfileAdDetails.tsx index 6a511ba4..09f982e2 100644 --- a/src/pages/my-profile/screens/MyProfileAdDetails/MyProfileAdDetails.tsx +++ b/src/pages/my-profile/screens/MyProfileAdDetails/MyProfileAdDetails.tsx @@ -2,6 +2,7 @@ import { Dispatch, SetStateAction, useEffect, useMemo, useState } from 'react'; import { FullPageMobileWrapper } from '@/components'; import { api } from '@/hooks'; import { useQueryString } from '@/hooks/custom-hooks'; +import { LabelPairedCheckMdFillIcon } from '@deriv/quill-icons'; import { Localize, useTranslations } from '@deriv-com/translations'; import { Button, Loader, Text, TextArea, useDevice } from '@deriv-com/ui'; import './MyProfileAdDetails.scss'; @@ -49,7 +50,7 @@ const MyProfileAdDetailsTextArea = ({ const MyProfileAdDetails = () => { const { data: advertiserInfo, isLoading } = api.advertiser.useGetInfo(); - const { mutate: updateAdvertiser } = api.advertiser.useUpdate(); + const { isPending, mutate: updateAdvertiser } = api.advertiser.useUpdate(); const [contactInfo, setContactInfo] = useState(''); const [advertDescription, setAdvertDescription] = useState(''); const { isMobile } = useDevice(); @@ -116,7 +117,14 @@ const MyProfileAdDetails = () => { setContactInfo={setContactInfo} />
-
diff --git a/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTable/MyProfileCounterpartiesTable.scss b/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTable/MyProfileCounterpartiesTable.scss index ccdf90bb..92243ac1 100644 --- a/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTable/MyProfileCounterpartiesTable.scss +++ b/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTable/MyProfileCounterpartiesTable.scss @@ -6,14 +6,16 @@ height: calc(100vh - 30rem); max-height: 100%; } + + &__row { + border-bottom: 1px solid #f2f3f4; + } } &__row { &:last-child { position: relative; } - &:not(:last-child) { - border-bottom: 1px solid #f2f3f4; - } + border-bottom: 1px solid #f2f3f4; } } diff --git a/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTable/MyProfileCounterpartiesTable.tsx b/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTable/MyProfileCounterpartiesTable.tsx index 8586a172..a6fe2382 100644 --- a/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTable/MyProfileCounterpartiesTable.tsx +++ b/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTable/MyProfileCounterpartiesTable.tsx @@ -1,7 +1,8 @@ -import { useEffect } from 'react'; +import { Dispatch, SetStateAction, useEffect, useState } from 'react'; import { api } from '@/hooks'; +import { DerivLightIcBlockedAdvertisersBarredIcon } from '@deriv/quill-icons'; import { Localize } from '@deriv-com/translations'; -import { Loader, Table, Text } from '@deriv-com/ui'; +import { Loader, Table, Text, useDevice } from '@deriv-com/ui'; import { MyProfileCounterpartiesEmpty } from '../MyProfileCounterpartiesEmpty'; import { MyProfileCounterpartiesTableRow } from '../MyProfileCounterpartiesTableRow'; import './MyProfileCounterpartiesTable.scss'; @@ -16,17 +17,23 @@ type TMyProfileCounterpartiesTableRowRendererProps = { id?: string; is_blocked: boolean; name?: string; + setErrorMessage: Dispatch>; }; const MyProfileCounterpartiesTableRowRenderer = ({ id, is_blocked: isBlocked, name, + setErrorMessage, }: TMyProfileCounterpartiesTableRowRendererProps) => ( - + ); -//TODO: rewrite the implementation in accordance with @deriv-com/ui table component const MyProfileCounterpartiesTable = ({ dropdownValue, searchValue, @@ -42,12 +49,17 @@ const MyProfileCounterpartiesTable = ({ is_blocked: dropdownValue === 'blocked' ? 1 : 0, trade_partners: 1, }); + const [errorMessage, setErrorMessage] = useState(''); + const { isMobile } = useDevice(); useEffect(() => { if (data.length > 0) { setShowHeader(true); } - }, [data, setShowHeader]); + if (errorMessage) { + setShowHeader(false); + } + }, [data, errorMessage, setShowHeader]); if (isLoading) { return ; @@ -62,6 +74,17 @@ const MyProfileCounterpartiesTable = ({ ); } + if (errorMessage) { + return ( +
+ + + {errorMessage} + +
+ ); + } + return ( ( )} tableClassname='my-profile-counterparties-table' diff --git a/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTableRow/MyProfileCounterpartiesTableRow.scss b/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTableRow/MyProfileCounterpartiesTableRow.scss index a691e367..bff4fded 100644 --- a/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTableRow/MyProfileCounterpartiesTableRow.scss +++ b/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTableRow/MyProfileCounterpartiesTableRow.scss @@ -12,5 +12,9 @@ align-items: center; gap: 0.8rem; cursor: pointer; + + &--barred { + cursor: not-allowed; + } } } diff --git a/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTableRow/MyProfileCounterpartiesTableRow.tsx b/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTableRow/MyProfileCounterpartiesTableRow.tsx index 1f3d51b0..c47f8201 100644 --- a/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTableRow/MyProfileCounterpartiesTableRow.tsx +++ b/src/pages/my-profile/screens/MyProfileCounterparties/MyProfileCounterpartiesTableRow/MyProfileCounterpartiesTableRow.tsx @@ -1,9 +1,10 @@ -import { memo } from 'react'; +import { Dispatch, memo, SetStateAction } from 'react'; +import clsx from 'clsx'; import { useHistory } from 'react-router-dom'; import { UserAvatar } from '@/components'; import { BlockUnblockUserModal } from '@/components/Modals'; import { ADVERTISER_URL } from '@/constants'; -import { useModalManager } from '@/hooks/custom-hooks'; +import { useIsAdvertiserBarred, useModalManager } from '@/hooks/custom-hooks'; import { Button, Text, useDevice } from '@deriv-com/ui'; import './MyProfileCounterpartiesTableRow.scss'; @@ -11,19 +12,30 @@ type TMyProfileCounterpartiesTableRowProps = { id: string; isBlocked: boolean; nickname: string; + setErrorMessage: Dispatch>; }; -const MyProfileCounterpartiesTableRow = ({ id, isBlocked, nickname }: TMyProfileCounterpartiesTableRowProps) => { +const MyProfileCounterpartiesTableRow = ({ + id, + isBlocked, + nickname, + setErrorMessage, +}: TMyProfileCounterpartiesTableRowProps) => { const { isMobile } = useDevice(); const history = useHistory(); const { hideModal, isModalOpenFor, showModal } = useModalManager(); + const isAdvertiserBarred = useIsAdvertiserBarred(); return ( <>
history.push(`${ADVERTISER_URL}/${id}`, { from: 'MyProfile' })} + className={clsx('my-profile-counterparties-table-row__nickname-wrapper', { + 'my-profile-counterparties-table-row__nickname-wrapper--barred': isAdvertiserBarred, + })} + onClick={() => { + isAdvertiserBarred ? undefined : history.push(`${ADVERTISER_URL}/${id}`, { from: 'MyProfile' }); + }} > {nickname} @@ -46,6 +58,7 @@ const MyProfileCounterpartiesTableRow = ({ id, isBlocked, nickname }: TMyProfile isBlocked={isBlocked} isModalOpen={!!isModalOpenFor('BlockUnblockUserModal')} onRequestClose={hideModal} + setErrorMessage={setErrorMessage} /> ); 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 3fb4b5b5..c1713ca4 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 @@ -6,6 +6,7 @@ const mockProps = { id: 'id1', isBlocked: false, nickname: 'nickname', + setErrorMessage: jest.fn(), }; const mockPush = jest.fn(); diff --git a/src/pages/my-profile/screens/MyProfileStats/MyProfileStatsItem.tsx b/src/pages/my-profile/screens/MyProfileStats/MyProfileStatsItem.tsx index 08ceadbe..39db5a27 100644 --- a/src/pages/my-profile/screens/MyProfileStats/MyProfileStatsItem.tsx +++ b/src/pages/my-profile/screens/MyProfileStats/MyProfileStatsItem.tsx @@ -40,6 +40,7 @@ const MyProfileStatsItem = ({ {shouldShowDuration && (