diff --git a/packages/components/src/components/icon/common/ic-menu-dots.svg b/packages/components/src/components/icon/common/ic-menu-dots.svg new file mode 100644 index 000000000000..36f7407a70fc --- /dev/null +++ b/packages/components/src/components/icon/common/ic-menu-dots.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/components/src/components/icon/icons.js b/packages/components/src/components/icon/icons.js index 640a757c4496..b31b5e4c9ce3 100644 --- a/packages/components/src/components/icon/icons.js +++ b/packages/components/src/components/icon/icons.js @@ -278,6 +278,7 @@ import './common/ic-logout.svg'; import './common/ic-lookbacks.svg'; import './common/ic-loss.svg'; import './common/ic-macos.svg'; +import './common/ic-menu-dots.svg'; import './common/ic-message-delivered.svg'; import './common/ic-message-errored.svg'; import './common/ic-message-pending.svg'; diff --git a/packages/components/stories/icon/icons.js b/packages/components/stories/icon/icons.js index b7c809b732ec..7482fda2c724 100644 --- a/packages/components/stories/icon/icons.js +++ b/packages/components/stories/icon/icons.js @@ -13,7 +13,7 @@ export const icons = 'IcBrandDmt5', 'IcBrandDtrader', 'IcBrandDxtrade', - 'IcBrandSmarttrader', + 'IcBrandSmarttrader' ], 'cashier': [ 'IcCashierAdd', @@ -140,7 +140,7 @@ export const icons = 'IcCashierXanpoolLight', 'IcCashierXanpoolSmallDark', 'IcCashierXanpoolSmallLight', - 'IcCashier', + 'IcCashier' ], 'common': [ 'IcAccountError', @@ -285,6 +285,7 @@ export const icons = 'IcLookbacks', 'IcLoss', 'IcMacos', + 'IcMenuDots', 'IcMessageDelivered', 'IcMessageErrored', 'IcMessagePending', @@ -388,7 +389,7 @@ export const icons = 'IcWindows', 'IcWip', 'IcZoomIn', - 'IcZoomOut', + 'IcZoomOut' ], 'contract': [ 'IcContractBarrier', @@ -404,7 +405,7 @@ export const icons = 'IcContractSafeguard', 'IcContractStartTimeCircle', 'IcContractStartTime', - 'IcContractTarget', + 'IcContractTarget' ], 'currency': [ 'IcCurrencyAud', @@ -426,7 +427,7 @@ export const icons = 'IcCurrencyUsdc', 'IcCurrencyUsdk', 'IcCurrencyUst', - 'IcCurrencyVirtual', + 'IcCurrencyVirtual' ], 'dxtrade': [ 'IcDxtradeDeviceDesktopLight', @@ -441,7 +442,7 @@ export const icons = 'IcDxtradeFinancial', 'IcDxtradeOnePassword', 'IcDxtradeSyntheticPlatform', - 'IcDxtradeSynthetic', + 'IcDxtradeSynthetic' ], 'flag': [ 'IcFlagDe', @@ -457,7 +458,7 @@ export const icons = 'IcFlagUk', 'IcFlagVi', 'IcFlagZhCn', - 'IcFlagZhTw', + 'IcFlagZhTw' ], 'mt5': [ 'IcMt5CfdPlatform', @@ -483,7 +484,7 @@ export const icons = 'IcMt5SyntheticIndices', 'IcMt5SyntheticPlatform', 'IcMt5Synthetic', - 'IcMt5TradeTypes', + 'IcMt5TradeTypes' ], 'option': [ 'IcOptionCallPutReset', @@ -501,7 +502,7 @@ export const icons = 'IcOptionRaiseFall', 'IcOptionStayinGoesout', 'IcOptionTouchNotouch', - 'IcOptionUpDownAsian', + 'IcOptionUpDownAsian' ], 'stock': [ 'IcStockAdidasSalomon', @@ -551,7 +552,7 @@ export const icons = 'IcStockVisa', 'IcStockWallMart', 'IcStockWaltDisney', - 'IcStockZoom', + 'IcStockZoom' ], 'tradetype': [ 'IcTradetypeAsiand', @@ -586,7 +587,7 @@ export const icons = 'IcTradetypeRunlow', 'IcTradetypeTickhigh', 'IcTradetypeTicklow', - 'IcTradetypeUpordown', + 'IcTradetypeUpordown' ], 'underlying': [ 'IcUnderlying1HZ100V', @@ -743,7 +744,7 @@ export const icons = 'IcUnderlyingWLDEUR', 'IcUnderlyingWLDGBP', 'IcUnderlyingWLDUSD', - 'IcUnderlyingWLDXAU', + 'IcUnderlyingWLDXAU' ], 'wallet': [ 'IcWalletClearFunds', @@ -779,6 +780,6 @@ export const icons = 'IcWalletWebmoneyLight', 'IcWalletWebmoney', 'IcWalletZingpayDark', - 'IcWalletZingpayLight', - ], -} + 'IcWalletZingpayLight' + ] +} \ No newline at end of file diff --git a/packages/p2p/src/components/advertiser-page/advertiser-page-dropdown-menu.jsx b/packages/p2p/src/components/advertiser-page/advertiser-page-dropdown-menu.jsx new file mode 100644 index 000000000000..e978b95ca58a --- /dev/null +++ b/packages/p2p/src/components/advertiser-page/advertiser-page-dropdown-menu.jsx @@ -0,0 +1,66 @@ +import React from 'react'; +import { observer } from 'mobx-react-lite'; +import PropTypes from 'prop-types'; +import { Dropdown, Icon, Text } from '@deriv/components'; +import { Localize } from 'Components/i18next'; +import { useStores } from 'Stores'; +import { useOnClickOutside } from '../../../../components/src/hooks'; +import './advertiser-page.scss'; + +const AdvertiserPageDropdownMenu = ({ is_my_advert }) => { + const dropdown_menu_ref = React.useRef(); + const { advertiser_page_store } = useStores(); + + const onClickOutside = () => { + advertiser_page_store.setIsDropdownMenuVisible(false); + }; + + useOnClickOutside(dropdown_menu_ref, onClickOutside, () => advertiser_page_store.is_dropdown_menu_visible); + + return ( + !advertiser_page_store.is_counterparty_advertiser_blocked && ( +
+ + advertiser_page_store.setIsDropdownMenuVisible(!advertiser_page_store.is_dropdown_menu_visible) + } + size={16} + /> + {advertiser_page_store.is_dropdown_menu_visible && ( +
+ + + + } + /> +
+ )} +
+ ) + ); +}; + +export default observer(AdvertiserPageDropdownMenu); + +AdvertiserPageDropdownMenu.propTypes = { + is_my_advert: PropTypes.bool, +}; diff --git a/packages/p2p/src/components/advertiser-page/advertiser-page.jsx b/packages/p2p/src/components/advertiser-page/advertiser-page.jsx index cc7b5a787bda..7c681491b4e5 100644 --- a/packages/p2p/src/components/advertiser-page/advertiser-page.jsx +++ b/packages/p2p/src/components/advertiser-page/advertiser-page.jsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Loading, Text } from '@deriv/components'; +import { DesktopWrapper, Loading, MobileWrapper, Text } from '@deriv/components'; import { daysSince, isMobile } from '@deriv/shared'; import { reaction } from 'mobx'; import { observer } from 'mobx-react-lite'; @@ -12,6 +12,7 @@ import UserAvatar from 'Components/user/user-avatar/user-avatar.jsx'; import { useStores } from 'Stores'; import AdvertiserPageStats from './advertiser-page-stats.jsx'; import AdvertiserPageAdverts from './advertiser-page-adverts.jsx'; +import AdvertiserPageDropdownMenu from './advertiser-page-dropdown-menu.jsx'; import TradeBadge from '../trade-badge/trade-badge.jsx'; import BlockUserOverlay from './block-user/block-user-overlay'; import BlockUserModal from 'Components/block-user/block-user-modal'; @@ -27,13 +28,17 @@ const AdvertiserPage = () => { created_time, first_name, full_verification, + id, last_name, + name, sell_orders_count, } = advertiser_page_store.advertiser_info; const joined_since = daysSince(created_time); + const is_my_advert = id === general_store.advertiser_id; React.useEffect(() => { advertiser_page_store.onMount(); + advertiser_page_store.setIsDropdownMenuVisible(false); return reaction( () => advertiser_page_store.active_index, @@ -59,15 +64,11 @@ const AdvertiserPage = () => { })} > general_store.setIsBlockUserModalOpen(false)} - onSubmit={() => - general_store.blockUnblockUser( - !advertiser_page_store.is_counterparty_advertiser_blocked, - advertiser_page_store.advertiser_details_id - ) - } + onCancel={advertiser_page_store.onCancel} + onSubmit={advertiser_page_store.onSubmit} /> { setShouldShowPopup={advertiser_page_store.setShowAdPopup} table_type={advertiser_page_store.counterparty_type === buy_sell.BUY ? buy_sell.BUY : buy_sell.SELL} /> - +
+ + + + +
general_store.setIsBlockUserModalOpen(true)} @@ -123,6 +129,9 @@ const AdvertiserPage = () => { /> + + + diff --git a/packages/p2p/src/components/advertiser-page/advertiser-page.scss b/packages/p2p/src/components/advertiser-page/advertiser-page.scss index 3f991c5372f2..a61dd334b6c3 100644 --- a/packages/p2p/src/components/advertiser-page/advertiser-page.scss +++ b/packages/p2p/src/components/advertiser-page/advertiser-page.scss @@ -3,6 +3,71 @@ display: flex; flex-direction: column; + &__dropdown { + box-shadow: 0 1rem 2rem var(--shadow-menu); + border-radius: $BORDER_RADIUS; + cursor: pointer; + position: absolute; + right: 0; + z-index: 2; + + .dc-dropdown__display { + background-color: var(--general-main-2); + border: 1px solid var(--general-active); + + span { + background-color: var(--general-main-2); + } + + &-placeholder { + top: auto; + } + } + + &-container { + margin-top: 0; + + &--disabled { + margin-top: 0; + + span { + color: var(--text-disabled) !important; + } + } + } + + &:hover { + .dc-dropdown__display { + background-color: var(--border-normal); + border: 1px solid var(--border-normal); + + span { + background-color: var(--border-normal); + } + } + } + } + + &__menu-dots-icon { + cursor: pointer; + margin-bottom: 0.8rem; + } + + &__menu-dots-toggle { + position: absolute; + right: 2.4rem; + + @include mobile { + bottom: 0.8rem; + right: 1.2rem; + } + } + + &__page-return-header { + display: flex; + position: relative; + } + &--no-scroll { overflow: hidden; } diff --git a/packages/p2p/src/components/advertiser-page/block-user/block-user-count.jsx b/packages/p2p/src/components/advertiser-page/block-user/block-user-count.jsx index 3727d5e45326..0600303ec29b 100644 --- a/packages/p2p/src/components/advertiser-page/block-user/block-user-count.jsx +++ b/packages/p2p/src/components/advertiser-page/block-user/block-user-count.jsx @@ -12,10 +12,14 @@ const BlockUserCount = () => { const [is_block_user_count_modal_open, setIsBlockUserCountModalOpen] = React.useState(false); - const message = - blocked_by_count === 0 - ? localize('Nobody has blocked you. Yay!') - : localize('{{blocked_by_count}} people have blocked you.', { blocked_by_count }); + const getMessage = () => { + if (blocked_by_count === 0) { + return localize('Nobody has blocked you. Yay!'); + } else if (blocked_by_count === 1) { + return localize('{{blocked_by_count}} person has blocked you', { blocked_by_count }); + } + return localize('{{blocked_by_count}} people have blocked you', { blocked_by_count }); + }; React.useEffect(() => { my_profile_store.getAdvertiserInfo(); @@ -29,7 +33,7 @@ const BlockUserCount = () => { - {message} + {getMessage()} @@ -50,7 +54,7 @@ const BlockUserCount = () => { alignment='top' className='block-user-count' classNameTarget='block-user-count__container' - message={message} + message={getMessage()} > diff --git a/packages/p2p/src/components/advertiser-page/block-user/block-user-overlay/block-user-overlay.scss b/packages/p2p/src/components/advertiser-page/block-user/block-user-overlay/block-user-overlay.scss index 90694358b213..c10035ac605d 100644 --- a/packages/p2p/src/components/advertiser-page/block-user/block-user-overlay/block-user-overlay.scss +++ b/packages/p2p/src/components/advertiser-page/block-user/block-user-overlay/block-user-overlay.scss @@ -16,7 +16,7 @@ top: 0; left: 0; width: 94rem; - z-index: 9999; + z-index: 1; @include mobile { border: none; diff --git a/packages/p2p/src/components/block-user/block-user-modal/block-user-modal.jsx b/packages/p2p/src/components/block-user/block-user-modal/block-user-modal.jsx index 67f678a5c952..bb6949e6def7 100644 --- a/packages/p2p/src/components/block-user/block-user-modal/block-user-modal.jsx +++ b/packages/p2p/src/components/block-user/block-user-modal/block-user-modal.jsx @@ -2,14 +2,12 @@ import PropTypes from 'prop-types'; import React from 'react'; import { Button, Modal, Text } from '@deriv/components'; import { observer } from 'mobx-react-lite'; -import { useStores } from 'Stores'; import { Localize } from 'Components/i18next'; -const BlockUserModal = ({ is_advertiser_blocked, is_block_user_modal_open, onCancel, onSubmit }) => { - const { advertiser_page_store } = useStores(); - +const BlockUserModal = ({ advertiser_name, is_advertiser_blocked, is_block_user_modal_open, onCancel, onSubmit }) => { return ( {is_advertiser_blocked ? ( ) : ( )} } > - + {is_advertiser_blocked ? ( ) : ( )} @@ -65,6 +63,7 @@ const BlockUserModal = ({ is_advertiser_blocked, is_block_user_modal_open, onCan }; BlockUserModal.propTypes = { + advertiser_name: PropTypes.string.isRequired, is_advertiser_blocked: PropTypes.bool.isRequired, is_block_user_modal_open: PropTypes.bool.isRequired, onCancel: PropTypes.func.isRequired, diff --git a/packages/p2p/src/components/block-user/block-user-modal/block-user-modal.scss b/packages/p2p/src/components/block-user/block-user-modal/block-user-modal.scss new file mode 100644 index 000000000000..84d470158208 --- /dev/null +++ b/packages/p2p/src/components/block-user/block-user-modal/block-user-modal.scss @@ -0,0 +1,5 @@ +.block-user-modal { + &__body { + padding: 0 2.4rem; + } +} diff --git a/packages/p2p/src/components/block-user/block-user-modal/index.js b/packages/p2p/src/components/block-user/block-user-modal/index.js index 7a60699e574b..385476da1fa2 100644 --- a/packages/p2p/src/components/block-user/block-user-modal/index.js +++ b/packages/p2p/src/components/block-user/block-user-modal/index.js @@ -1,3 +1,4 @@ import BlockUserModal from './block-user-modal.jsx'; +import './block-user-modal.scss'; export default BlockUserModal; diff --git a/packages/p2p/src/components/buy-sell/buy-sell.jsx b/packages/p2p/src/components/buy-sell/buy-sell.jsx index 8037bfdbe735..8c278c0516d6 100644 --- a/packages/p2p/src/components/buy-sell/buy-sell.jsx +++ b/packages/p2p/src/components/buy-sell/buy-sell.jsx @@ -48,7 +48,7 @@ const BuySell = () => { ); } - + // TODO: Refactor this within next release as discussed with design team regarding the tabs // if (buy_sell_store.show_advertiser_page && !buy_sell_store.should_show_verification) { // return ( diff --git a/packages/p2p/src/stores/advertiser-page-store.js b/packages/p2p/src/stores/advertiser-page-store.js index cbeac0478aa7..947c8a9639df 100644 --- a/packages/p2p/src/stores/advertiser-page-store.js +++ b/packages/p2p/src/stores/advertiser-page-store.js @@ -16,6 +16,7 @@ export default class AdvertiserPageStore extends BaseStore { @observable form_error_message = ''; @observable has_more_adverts_to_load = false; @observable is_counterparty_advertiser_blocked = false; + @observable is_dropdown_menu_visible = false; @observable is_loading = true; @observable is_loading_adverts = true; @observable is_submit_disabled = true; @@ -115,6 +116,12 @@ export default class AdvertiserPageStore extends BaseStore { } } + @action.bound + onCancel() { + this.root_store.general_store.setIsBlockUserModalOpen(false); + this.setIsDropdownMenuVisible(false); + } + @action.bound onCancelClick() { this.setShowAdPopup(false); @@ -131,6 +138,15 @@ export default class AdvertiserPageStore extends BaseStore { this.getAdvertiserInfo(); } + @action.bound + onSubmit() { + this.root_store.general_store.blockUnblockUser( + !this.is_counterparty_advertiser_blocked, + this.advertiser_details_id + ); + this.setIsDropdownMenuVisible(false); + } + onTabChange() { this.setAdverts([]); this.loadMoreAdvertiserAdverts({ startIndex: 0 }); @@ -191,6 +207,11 @@ export default class AdvertiserPageStore extends BaseStore { this.has_more_adverts_to_load = has_more_adverts_to_load; } + @action.bound + setIsDropdownMenuVisible(is_dropdown_menu_visible) { + this.is_dropdown_menu_visible = is_dropdown_menu_visible; + } + @action.bound setIsLoading(is_loading) { this.is_loading = is_loading; @@ -224,4 +245,14 @@ export default class AdvertiserPageStore extends BaseStore { this.setShowAdPopup(true); } } + + @action.bound + showBlockUserModal() { + if ( + !this.is_counterparty_advertiser_blocked && + this.advertiser_info.id !== this.root_store.general_store.advertiser_id + ) { + this.root_store.general_store.setIsBlockUserModalOpen(true); + } + } }