feat: profile entry point in wallet dropdown (#4760)
* refactor sell and select page to profile page * add renamed profile pages * add profile entry button * add profile details header * small adjustments for small screens * add new details component * show tag on correct page * fix wallet dropdown height * update header spacing Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
This commit is contained in:
parent
106ac7ea35
commit
1138101dd0
@ -5,9 +5,9 @@ import useENSAvatar from 'hooks/useENSAvatar'
|
|||||||
import { useLayoutEffect, useMemo, useRef, useState } from 'react'
|
import { useLayoutEffect, useMemo, useRef, useState } from 'react'
|
||||||
import styled from 'styled-components/macro'
|
import styled from 'styled-components/macro'
|
||||||
|
|
||||||
const StyledIdenticon = styled.div<{ isNavbarEnabled: boolean }>`
|
const StyledIdenticon = styled.div<{ iconSize: number }>`
|
||||||
height: ${({ isNavbarEnabled }) => (isNavbarEnabled ? '24px' : '1rem')};
|
height: ${({ iconSize }) => `${iconSize}px`};
|
||||||
width: ${({ isNavbarEnabled }) => (isNavbarEnabled ? '24px' : '1rem')};
|
width: ${({ iconSize }) => `${iconSize}px`};
|
||||||
border-radius: 1.125rem;
|
border-radius: 1.125rem;
|
||||||
background-color: ${({ theme }) => theme.deprecated_bg4};
|
background-color: ${({ theme }) => theme.deprecated_bg4};
|
||||||
font-size: initial;
|
font-size: initial;
|
||||||
@ -19,12 +19,12 @@ const StyledAvatar = styled.img`
|
|||||||
border-radius: inherit;
|
border-radius: inherit;
|
||||||
`
|
`
|
||||||
|
|
||||||
export default function Identicon() {
|
export default function Identicon({ size }: { size?: number }) {
|
||||||
const { account } = useWeb3React()
|
const { account } = useWeb3React()
|
||||||
const { avatar } = useENSAvatar(account ?? undefined)
|
const { avatar } = useENSAvatar(account ?? undefined)
|
||||||
const [fetchable, setFetchable] = useState(true)
|
const [fetchable, setFetchable] = useState(true)
|
||||||
const isNavbarEnabled = useNavBarFlag() === NavBarVariant.Enabled
|
const isNavbarEnabled = useNavBarFlag() === NavBarVariant.Enabled
|
||||||
const iconSize = isNavbarEnabled ? 24 : 16
|
const iconSize = size ? size : isNavbarEnabled ? 24 : 16
|
||||||
|
|
||||||
const icon = useMemo(() => account && jazzicon(iconSize, parseInt(account.slice(2, 10), 16)), [account, iconSize])
|
const icon = useMemo(() => account && jazzicon(iconSize, parseInt(account.slice(2, 10), 16)), [account, iconSize])
|
||||||
const iconRef = useRef<HTMLDivElement>(null)
|
const iconRef = useRef<HTMLDivElement>(null)
|
||||||
@ -44,7 +44,7 @@ export default function Identicon() {
|
|||||||
}, [icon, iconRef])
|
}, [icon, iconRef])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledIdenticon isNavbarEnabled={isNavbarEnabled}>
|
<StyledIdenticon iconSize={iconSize}>
|
||||||
{avatar && fetchable ? (
|
{avatar && fetchable ? (
|
||||||
<StyledAvatar alt="avatar" src={avatar} onError={() => setFetchable(false)}></StyledAvatar>
|
<StyledAvatar alt="avatar" src={avatar} onError={() => setFetchable(false)}></StyledAvatar>
|
||||||
) : (
|
) : (
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { Trans } from '@lingui/macro'
|
import { Trans } from '@lingui/macro'
|
||||||
import FeatureFlagModal from 'components/FeatureFlagModal/FeatureFlagModal'
|
import FeatureFlagModal from 'components/FeatureFlagModal/FeatureFlagModal'
|
||||||
import { PrivacyPolicyModal } from 'components/PrivacyPolicy'
|
import { PrivacyPolicyModal } from 'components/PrivacyPolicy'
|
||||||
import { NftVariant, useNftFlag } from 'featureFlags/flags/nft'
|
|
||||||
import { useOnClickOutside } from 'hooks/useOnClickOutside'
|
import { useOnClickOutside } from 'hooks/useOnClickOutside'
|
||||||
import { Box } from 'nft/components/Box'
|
import { Box } from 'nft/components/Box'
|
||||||
import { Column, Row } from 'nft/components/Flex'
|
import { Column, Row } from 'nft/components/Flex'
|
||||||
@ -11,7 +10,6 @@ import {
|
|||||||
EllipsisIcon,
|
EllipsisIcon,
|
||||||
GithubIconMenu,
|
GithubIconMenu,
|
||||||
GovernanceIcon,
|
GovernanceIcon,
|
||||||
ThinTagIcon,
|
|
||||||
TwitterIconMenu,
|
TwitterIconMenu,
|
||||||
} from 'nft/components/icons'
|
} from 'nft/components/icons'
|
||||||
import { body, bodySmall } from 'nft/css/common.css'
|
import { body, bodySmall } from 'nft/css/common.css'
|
||||||
@ -117,7 +115,6 @@ export const MenuDropdown = () => {
|
|||||||
const [isOpen, toggleOpen] = useReducer((s) => !s, false)
|
const [isOpen, toggleOpen] = useReducer((s) => !s, false)
|
||||||
const togglePrivacyPolicy = useToggleModal(ApplicationModal.PRIVACY_POLICY)
|
const togglePrivacyPolicy = useToggleModal(ApplicationModal.PRIVACY_POLICY)
|
||||||
const openFeatureFlagsModal = useToggleModal(ApplicationModal.FEATURE_FLAGS)
|
const openFeatureFlagsModal = useToggleModal(ApplicationModal.FEATURE_FLAGS)
|
||||||
const nftFlag = useNftFlag()
|
|
||||||
|
|
||||||
const ref = useRef<HTMLDivElement>(null)
|
const ref = useRef<HTMLDivElement>(null)
|
||||||
useOnClickOutside(ref, isOpen ? toggleOpen : undefined)
|
useOnClickOutside(ref, isOpen ? toggleOpen : undefined)
|
||||||
@ -133,16 +130,6 @@ export const MenuDropdown = () => {
|
|||||||
<NavDropdown top={{ sm: 'unset', lg: '56' }} bottom={{ sm: '56', lg: 'unset' }} right="0">
|
<NavDropdown top={{ sm: 'unset', lg: '56' }} bottom={{ sm: '56', lg: 'unset' }} right="0">
|
||||||
<Column gap="16">
|
<Column gap="16">
|
||||||
<Column paddingX="8" gap="4">
|
<Column paddingX="8" gap="4">
|
||||||
{nftFlag === NftVariant.Enabled && (
|
|
||||||
<PrimaryMenuRow to="/nfts/sell" close={toggleOpen}>
|
|
||||||
<Icon>
|
|
||||||
<ThinTagIcon width={24} height={24} />
|
|
||||||
</Icon>
|
|
||||||
<PrimaryMenuRow.Text>
|
|
||||||
<Trans>Sell NFTs</Trans>
|
|
||||||
</PrimaryMenuRow.Text>
|
|
||||||
</PrimaryMenuRow>
|
|
||||||
)}
|
|
||||||
<PrimaryMenuRow to="/vote" close={toggleOpen}>
|
<PrimaryMenuRow to="/vote" close={toggleOpen}>
|
||||||
<Icon>
|
<Icon>
|
||||||
<GovernanceIcon width={24} height={24} />
|
<GovernanceIcon width={24} height={24} />
|
||||||
|
@ -23,11 +23,11 @@ export const ShoppingBag = () => {
|
|||||||
setSellQuantity(sellAssets.length)
|
setSellQuantity(sellAssets.length)
|
||||||
}, [sellAssets])
|
}, [sellAssets])
|
||||||
|
|
||||||
const isSell = location.pathname === '/nfts/sell'
|
const isProfilePage = location.pathname === '/profile'
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NavIcon onClick={toggleBag}>
|
<NavIcon onClick={toggleBag}>
|
||||||
{isSell ? (
|
{isProfilePage ? (
|
||||||
<>
|
<>
|
||||||
<TagIcon width={20} height={20} />
|
<TagIcon width={20} height={20} />
|
||||||
{sellQuantity ? (
|
{sellQuantity ? (
|
||||||
|
@ -68,7 +68,7 @@ const PageTabs = () => {
|
|||||||
|
|
||||||
const Navbar = () => {
|
const Navbar = () => {
|
||||||
const { pathname } = useLocation()
|
const { pathname } = useLocation()
|
||||||
const isNftPage = pathname.startsWith('/nfts')
|
const showShoppingBag = pathname.startsWith('/nfts') || pathname.startsWith('/profile')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -96,7 +96,7 @@ const Navbar = () => {
|
|||||||
<Box display={{ sm: 'none', lg: 'flex' }}>
|
<Box display={{ sm: 'none', lg: 'flex' }}>
|
||||||
<MenuDropdown />
|
<MenuDropdown />
|
||||||
</Box>
|
</Box>
|
||||||
{isNftPage && <ShoppingBag />}
|
{showShoppingBag && <ShoppingBag />}
|
||||||
<Box display={{ sm: 'none', lg: 'flex' }}>
|
<Box display={{ sm: 'none', lg: 'flex' }}>
|
||||||
<ChainSelector />
|
<ChainSelector />
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -10,7 +10,7 @@ import { useLocation } from 'react-router-dom'
|
|||||||
import { useModalIsOpen, useToggleModal } from 'state/application/hooks'
|
import { useModalIsOpen, useToggleModal } from 'state/application/hooks'
|
||||||
import { ApplicationModal } from 'state/application/reducer'
|
import { ApplicationModal } from 'state/application/reducer'
|
||||||
|
|
||||||
const Cart = lazy(() => import('nft/components/sell/modal/ListingTag'))
|
const Cart = lazy(() => import('nft/components/profile/modal/ListingTag'))
|
||||||
const Bag = lazy(() => import('nft/components/bag/Bag'))
|
const Bag = lazy(() => import('nft/components/bag/Bag'))
|
||||||
const TransactionCompleteModal = lazy(() => import('nft/components/collection/TransactionCompleteModal'))
|
const TransactionCompleteModal = lazy(() => import('nft/components/collection/TransactionCompleteModal'))
|
||||||
|
|
||||||
|
@ -4,11 +4,13 @@ import { useWeb3React } from '@web3-react/core'
|
|||||||
import { getConnection } from 'connection/utils'
|
import { getConnection } from 'connection/utils'
|
||||||
import { getChainInfoOrDefault } from 'constants/chainInfo'
|
import { getChainInfoOrDefault } from 'constants/chainInfo'
|
||||||
import { SupportedChainId } from 'constants/chains'
|
import { SupportedChainId } from 'constants/chains'
|
||||||
|
import { NftVariant, useNftFlag } from 'featureFlags/flags/nft'
|
||||||
import useCopyClipboard from 'hooks/useCopyClipboard'
|
import useCopyClipboard from 'hooks/useCopyClipboard'
|
||||||
import useStablecoinPrice from 'hooks/useStablecoinPrice'
|
import useStablecoinPrice from 'hooks/useStablecoinPrice'
|
||||||
import useNativeCurrency from 'lib/hooks/useNativeCurrency'
|
import useNativeCurrency from 'lib/hooks/useNativeCurrency'
|
||||||
import { useCallback, useMemo } from 'react'
|
import { useCallback, useMemo } from 'react'
|
||||||
import { Copy, ExternalLink, Power } from 'react-feather'
|
import { Copy, ExternalLink, Power } from 'react-feather'
|
||||||
|
import { useNavigate } from 'react-router-dom'
|
||||||
import { Text } from 'rebass'
|
import { Text } from 'rebass'
|
||||||
import { useCurrencyBalanceString } from 'state/connection/hooks'
|
import { useCurrencyBalanceString } from 'state/connection/hooks'
|
||||||
import { useAppDispatch } from 'state/hooks'
|
import { useAppDispatch } from 'state/hooks'
|
||||||
@ -16,15 +18,14 @@ import { updateSelectedWallet } from 'state/user/reducer'
|
|||||||
import styled from 'styled-components/macro'
|
import styled from 'styled-components/macro'
|
||||||
|
|
||||||
import { shortenAddress } from '../../nft/utils/address'
|
import { shortenAddress } from '../../nft/utils/address'
|
||||||
import { useToggleModal } from '../../state/application/hooks'
|
import { useCloseModal, useToggleModal } from '../../state/application/hooks'
|
||||||
import { ApplicationModal } from '../../state/application/reducer'
|
import { ApplicationModal } from '../../state/application/reducer'
|
||||||
import { useUserHasAvailableClaim, useUserUnclaimedAmount } from '../../state/claim/hooks'
|
import { useUserHasAvailableClaim, useUserUnclaimedAmount } from '../../state/claim/hooks'
|
||||||
import { ButtonPrimary } from '../Button'
|
import { ButtonPrimary } from '../Button'
|
||||||
import StatusIcon from '../Identicon/StatusIcon'
|
import StatusIcon from '../Identicon/StatusIcon'
|
||||||
import IconButton, { IconHoverText } from './IconButton'
|
import IconButton, { IconHoverText } from './IconButton'
|
||||||
|
|
||||||
const UNIbutton = styled(ButtonPrimary)`
|
const WalletButton = styled(ButtonPrimary)`
|
||||||
background: linear-gradient(to right, #9139b0 0%, #4261d6 100%);
|
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
@ -33,6 +34,16 @@ const UNIbutton = styled(ButtonPrimary)`
|
|||||||
border: none;
|
border: none;
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const ProfileButton = styled(WalletButton)`
|
||||||
|
background: ${({ theme }) => theme.backgroundInteractive};
|
||||||
|
transition: ${({ theme }) => theme.transition.duration.fast} ${({ theme }) => theme.transition.timing.ease}
|
||||||
|
background-color;
|
||||||
|
`
|
||||||
|
|
||||||
|
const UNIButton = styled(WalletButton)`
|
||||||
|
background: linear-gradient(to right, #9139b0 0%, #4261d6 100%);
|
||||||
|
`
|
||||||
|
|
||||||
const Column = styled.div`
|
const Column = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -97,6 +108,9 @@ const AuthenticatedHeader = () => {
|
|||||||
nativeCurrency: { symbol: nativeCurrencySymbol },
|
nativeCurrency: { symbol: nativeCurrencySymbol },
|
||||||
explorer,
|
explorer,
|
||||||
} = getChainInfoOrDefault(chainId ? chainId : SupportedChainId.MAINNET)
|
} = getChainInfoOrDefault(chainId ? chainId : SupportedChainId.MAINNET)
|
||||||
|
const nftFlag = useNftFlag()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const closeModal = useCloseModal(ApplicationModal.WALLET_DROPDOWN)
|
||||||
|
|
||||||
const unclaimedAmount: CurrencyAmount<Token> | undefined = useUserUnclaimedAmount(account)
|
const unclaimedAmount: CurrencyAmount<Token> | undefined = useUserUnclaimedAmount(account)
|
||||||
const isUnclaimed = useUserHasAvailableClaim(account)
|
const isUnclaimed = useUserHasAvailableClaim(account)
|
||||||
@ -118,6 +132,11 @@ const AuthenticatedHeader = () => {
|
|||||||
return price * balance
|
return price * balance
|
||||||
}, [balanceString, nativeCurrencyPrice])
|
}, [balanceString, nativeCurrencyPrice])
|
||||||
|
|
||||||
|
const navigateToProfile = () => {
|
||||||
|
navigate('/profile')
|
||||||
|
closeModal()
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AuthenticatedHeaderWrapper>
|
<AuthenticatedHeaderWrapper>
|
||||||
<HeaderWrapper>
|
<HeaderWrapper>
|
||||||
@ -147,10 +166,15 @@ const AuthenticatedHeader = () => {
|
|||||||
</Text>
|
</Text>
|
||||||
<USDText>${amountUSD.toFixed(2)} USD</USDText>
|
<USDText>${amountUSD.toFixed(2)} USD</USDText>
|
||||||
</BalanceWrapper>
|
</BalanceWrapper>
|
||||||
|
{nftFlag === NftVariant.Enabled && (
|
||||||
|
<ProfileButton onClick={navigateToProfile}>
|
||||||
|
<Trans>View and sell NFTs</Trans>
|
||||||
|
</ProfileButton>
|
||||||
|
)}
|
||||||
{isUnclaimed && (
|
{isUnclaimed && (
|
||||||
<UNIbutton onClick={openClaimModal}>
|
<UNIButton onClick={openClaimModal}>
|
||||||
<Trans>Claim</Trans> {unclaimedAmount?.toFixed(0, { groupSeparator: ',' } ?? '-')} <Trans>reward</Trans>
|
<Trans>Claim</Trans> {unclaimedAmount?.toFixed(0, { groupSeparator: ',' } ?? '-')} <Trans>reward</Trans>
|
||||||
</UNIbutton>
|
</UNIButton>
|
||||||
)}
|
)}
|
||||||
</Column>
|
</Column>
|
||||||
</AuthenticatedHeaderWrapper>
|
</AuthenticatedHeaderWrapper>
|
||||||
|
@ -11,7 +11,6 @@ import { TransactionHistoryMenu } from './TransactionMenu'
|
|||||||
const WalletWrapper = styled.div`
|
const WalletWrapper = styled.div`
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
width: 320px;
|
width: 320px;
|
||||||
max-height: 376px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
@ -119,9 +119,9 @@ const Bag = () => {
|
|||||||
const isConnected = !!provider && !!address
|
const isConnected = !!provider && !!address
|
||||||
|
|
||||||
const { pathname } = useLocation()
|
const { pathname } = useLocation()
|
||||||
const isNFTSellPage = pathname.startsWith('/nfts/sell')
|
const isProfilePage = pathname.startsWith('/profile')
|
||||||
const isNFTPage = pathname.startsWith('/nfts')
|
const isNFTPage = pathname.startsWith('/nfts')
|
||||||
const shouldShowBag = isNFTPage && !isNFTSellPage
|
const shouldShowBag = isNFTPage && !isProfilePage
|
||||||
const isMobile = useIsMobile()
|
const isMobile = useIsMobile()
|
||||||
|
|
||||||
const sendTransaction = useSendTransaction((state) => state.sendTransaction)
|
const sendTransaction = useSendTransaction((state) => state.sendTransaction)
|
||||||
|
@ -31,10 +31,10 @@ export const FilterButton = ({
|
|||||||
}))
|
}))
|
||||||
const collectionFilters = useWalletCollections((state) => state.collectionFilters)
|
const collectionFilters = useWalletCollections((state) => state.collectionFilters)
|
||||||
const { pathname } = useLocation()
|
const { pathname } = useLocation()
|
||||||
const isSellPage = pathname.startsWith('/nfts/sell')
|
const isProfilePage = pathname.startsWith('/profile')
|
||||||
const isCollectionNftsLoading = useIsCollectionLoading((state) => state.isCollectionNftsLoading)
|
const isCollectionNftsLoading = useIsCollectionLoading((state) => state.isCollectionNftsLoading)
|
||||||
|
|
||||||
const showFilterBadge = isSellPage
|
const showFilterBadge = isProfilePage
|
||||||
? collectionFilters.length > 0
|
? collectionFilters.length > 0
|
||||||
: minPrice || maxPrice || minRarity || maxRarity || traits.length || markets.length || buyNow
|
: minPrice || maxPrice || minRarity || maxRarity || traits.length || markets.length || buyNow
|
||||||
return (
|
return (
|
||||||
|
@ -26,8 +26,15 @@ import {
|
|||||||
subheadSmall,
|
subheadSmall,
|
||||||
} from 'nft/css/common.css'
|
} from 'nft/css/common.css'
|
||||||
import { themeVars } from 'nft/css/sprinkles.css'
|
import { themeVars } from 'nft/css/sprinkles.css'
|
||||||
import { useBag, useNFTList, useSellAsset, useSellPageState } from 'nft/hooks'
|
import { useBag, useNFTList, useProfilePageState, useSellAsset } from 'nft/hooks'
|
||||||
import { DropDownOption, ListingMarket, ListingStatus, ListingWarning, SellPageStateType, WalletAsset } from 'nft/types'
|
import {
|
||||||
|
DropDownOption,
|
||||||
|
ListingMarket,
|
||||||
|
ListingStatus,
|
||||||
|
ListingWarning,
|
||||||
|
ProfilePageStateType,
|
||||||
|
WalletAsset,
|
||||||
|
} from 'nft/types'
|
||||||
import { formatEth, formatUsdPrice } from 'nft/utils/currency'
|
import { formatEth, formatUsdPrice } from 'nft/utils/currency'
|
||||||
import { fetchPrice } from 'nft/utils/fetchPrice'
|
import { fetchPrice } from 'nft/utils/fetchPrice'
|
||||||
import { ListingMarkets } from 'nft/utils/listNfts'
|
import { ListingMarkets } from 'nft/utils/listNfts'
|
||||||
@ -834,7 +841,7 @@ const NFTListRow = ({ asset, globalPriceMethod, globalPrice, setGlobalPrice, sel
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const ListPage = () => {
|
export const ListPage = () => {
|
||||||
const { setSellPageState } = useSellPageState()
|
const { setProfilePageState: setSellPageState } = useProfilePageState()
|
||||||
const setGlobalMarketplaces = useSellAsset((state) => state.setGlobalMarketplaces)
|
const setGlobalMarketplaces = useSellAsset((state) => state.setGlobalMarketplaces)
|
||||||
const [selectedMarkets, setSelectedMarkets] = useState([ListingMarkets[2]]) // default marketplace: x2y2
|
const [selectedMarkets, setSelectedMarkets] = useState([ListingMarkets[2]]) // default marketplace: x2y2
|
||||||
const toggleBag = useBag((s) => s.toggleBag)
|
const toggleBag = useBag((s) => s.toggleBag)
|
||||||
@ -869,7 +876,7 @@ export const ListPage = () => {
|
|||||||
aria-label="Back"
|
aria-label="Back"
|
||||||
as="button"
|
as="button"
|
||||||
border="none"
|
border="none"
|
||||||
onClick={() => setSellPageState(SellPageStateType.SELECTING)}
|
onClick={() => setSellPageState(ProfilePageStateType.VIEWING)}
|
||||||
type="button"
|
type="button"
|
||||||
backgroundColor="transparent"
|
backgroundColor="transparent"
|
||||||
cursor="pointer"
|
cursor="pointer"
|
0
src/nft/components/sell/modal/ListingButton.tsx → src/nft/components/profile/modal/ListingButton.tsx
0
src/nft/components/sell/modal/ListingButton.tsx → src/nft/components/profile/modal/ListingButton.tsx
0
src/nft/components/sell/modal/ListingModal.tsx → src/nft/components/profile/modal/ListingModal.tsx
0
src/nft/components/sell/modal/ListingModal.tsx → src/nft/components/profile/modal/ListingModal.tsx
0
src/nft/components/sell/modal/ListingTag.css.ts → src/nft/components/profile/modal/ListingTag.css.ts
0
src/nft/components/sell/modal/ListingTag.css.ts → src/nft/components/profile/modal/ListingTag.css.ts
@ -3,8 +3,8 @@ import { Box } from 'nft/components/Box'
|
|||||||
import { Column } from 'nft/components/Flex'
|
import { Column } from 'nft/components/Flex'
|
||||||
import { CloseDropDownIcon } from 'nft/components/icons'
|
import { CloseDropDownIcon } from 'nft/components/icons'
|
||||||
import { bodySmall, buttonMedium, headlineSmall } from 'nft/css/common.css'
|
import { bodySmall, buttonMedium, headlineSmall } from 'nft/css/common.css'
|
||||||
import { useBag, useIsMobile, useSellAsset, useSellPageState } from 'nft/hooks'
|
import { useBag, useIsMobile, useProfilePageState, useSellAsset } from 'nft/hooks'
|
||||||
import { SellPageStateType } from 'nft/types'
|
import { ProfilePageStateType } from 'nft/types'
|
||||||
import { lazy, Suspense } from 'react'
|
import { lazy, Suspense } from 'react'
|
||||||
import { useLocation } from 'react-router-dom'
|
import { useLocation } from 'react-router-dom'
|
||||||
|
|
||||||
@ -15,10 +15,10 @@ const ListingModal = lazy(() => import('./ListingModal'))
|
|||||||
|
|
||||||
const Cart = () => {
|
const Cart = () => {
|
||||||
const { pathname } = useLocation()
|
const { pathname } = useLocation()
|
||||||
const isNFTSellPage = pathname.startsWith('/nfts/sell')
|
const isProfilePage = pathname.startsWith('/profile')
|
||||||
const sellAssets = useSellAsset((state) => state.sellAssets)
|
const sellAssets = useSellAsset((state) => state.sellAssets)
|
||||||
const setSellPageState = useSellPageState((state) => state.setSellPageState)
|
const setSellPageState = useProfilePageState((state) => state.setProfilePageState)
|
||||||
const sellPageState = useSellPageState((state) => state.state)
|
const sellPageState = useProfilePageState((state) => state.state)
|
||||||
const toggleCart = useBag((state) => state.toggleBag)
|
const toggleCart = useBag((state) => state.toggleBag)
|
||||||
const isMobile = useIsMobile()
|
const isMobile = useIsMobile()
|
||||||
const bagExpanded = useBag((s) => s.bagExpanded)
|
const bagExpanded = useBag((s) => s.bagExpanded)
|
||||||
@ -32,7 +32,7 @@ const Cart = () => {
|
|||||||
left={{ sm: '0', md: 'unset' }}
|
left={{ sm: '0', md: 'unset' }}
|
||||||
right={{ sm: 'unset', md: '0' }}
|
right={{ sm: 'unset', md: '0' }}
|
||||||
top={{ sm: '0', md: 'unset' }}
|
top={{ sm: '0', md: 'unset' }}
|
||||||
display={bagExpanded && isNFTSellPage ? 'flex' : 'none'}
|
display={bagExpanded && isProfilePage ? 'flex' : 'none'}
|
||||||
>
|
>
|
||||||
<Suspense fallback={<Loader />}>
|
<Suspense fallback={<Loader />}>
|
||||||
<Column
|
<Column
|
||||||
@ -45,7 +45,7 @@ const Cart = () => {
|
|||||||
marginLeft="0"
|
marginLeft="0"
|
||||||
justifyContent="flex-start"
|
justifyContent="flex-start"
|
||||||
>
|
>
|
||||||
{sellPageState === SellPageStateType.LISTING ? (
|
{sellPageState === ProfilePageStateType.LISTING ? (
|
||||||
<ListingModal />
|
<ListingModal />
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
@ -70,7 +70,7 @@ const Cart = () => {
|
|||||||
disabled={sellAssets.length === 0}
|
disabled={sellAssets.length === 0}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
isMobile && toggleCart()
|
isMobile && toggleCart()
|
||||||
setSellPageState(SellPageStateType.LISTING)
|
setSellPageState(ProfilePageStateType.LISTING)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Continue
|
Continue
|
2
src/nft/components/sell/select/FilterSidebar.tsx → src/nft/components/profile/view/FilterSidebar.tsx
2
src/nft/components/sell/select/FilterSidebar.tsx → src/nft/components/profile/view/FilterSidebar.tsx
@ -9,7 +9,7 @@ import { WalletCollection } from 'nft/types'
|
|||||||
import { Dispatch, FormEvent, SetStateAction, useCallback, useEffect, useReducer, useState } from 'react'
|
import { Dispatch, FormEvent, SetStateAction, useCallback, useEffect, useReducer, useState } from 'react'
|
||||||
import { useSpring } from 'react-spring'
|
import { useSpring } from 'react-spring'
|
||||||
|
|
||||||
import * as styles from './SelectPage.css'
|
import * as styles from './ProfilePage.css'
|
||||||
|
|
||||||
export const FilterSidebar = ({ SortDropdown }: { SortDropdown: () => JSX.Element }) => {
|
export const FilterSidebar = ({ SortDropdown }: { SortDropdown: () => JSX.Element }) => {
|
||||||
const collectionFilters = useWalletCollections((state) => state.collectionFilters)
|
const collectionFilters = useWalletCollections((state) => state.collectionFilters)
|
40
src/nft/components/profile/view/ProfileAccountDetails.tsx
Normal file
40
src/nft/components/profile/view/ProfileAccountDetails.tsx
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { Trans } from '@lingui/macro'
|
||||||
|
import { useWeb3React } from '@web3-react/core'
|
||||||
|
import Identicon from 'components/Identicon'
|
||||||
|
import { MouseoverTooltip } from 'components/Tooltip'
|
||||||
|
import useCopyClipboard from 'hooks/useCopyClipboard'
|
||||||
|
import { Box } from 'nft/components/Box'
|
||||||
|
import { Row } from 'nft/components/Flex'
|
||||||
|
import { caption, headlineLarge, lightGrayOverlayOnHover } from 'nft/css/common.css'
|
||||||
|
import { useCallback } from 'react'
|
||||||
|
import { Copy } from 'react-feather'
|
||||||
|
import { shortenAddress } from 'utils'
|
||||||
|
|
||||||
|
export const ProfileAccountDetails = () => {
|
||||||
|
const { account, ENSName } = useWeb3React()
|
||||||
|
const [isCopied, setCopied] = useCopyClipboard()
|
||||||
|
const copy = useCallback(() => {
|
||||||
|
setCopied(account ?? '')
|
||||||
|
}, [account, setCopied])
|
||||||
|
|
||||||
|
return account ? (
|
||||||
|
<Row className={headlineLarge} marginBottom="48" gap="4">
|
||||||
|
<Identicon size={44} />
|
||||||
|
<Box textOverflow="ellipsis" overflow="hidden" marginLeft="8">
|
||||||
|
{ENSName ?? shortenAddress(account)}
|
||||||
|
</Box>
|
||||||
|
<MouseoverTooltip
|
||||||
|
text={
|
||||||
|
<Box className={caption} color="textPrimary">
|
||||||
|
{isCopied ? <Trans>Copied!</Trans> : <Trans>Copy</Trans>}
|
||||||
|
</Box>
|
||||||
|
}
|
||||||
|
placement="right"
|
||||||
|
>
|
||||||
|
<Box paddingX="12" borderRadius="12" cursor="pointer" className={lightGrayOverlayOnHover} onClick={copy}>
|
||||||
|
<Copy strokeWidth={1.5} size={20} />{' '}
|
||||||
|
</Box>
|
||||||
|
</MouseoverTooltip>
|
||||||
|
</Row>
|
||||||
|
) : null
|
||||||
|
}
|
@ -14,27 +14,28 @@ import {
|
|||||||
TagFillIcon,
|
TagFillIcon,
|
||||||
VerifiedIcon,
|
VerifiedIcon,
|
||||||
} from 'nft/components/icons'
|
} from 'nft/components/icons'
|
||||||
import { FilterSidebar } from 'nft/components/sell/select/FilterSidebar'
|
import { FilterSidebar } from 'nft/components/profile/view/FilterSidebar'
|
||||||
import { subhead, subheadSmall } from 'nft/css/common.css'
|
import { subhead, subheadSmall } from 'nft/css/common.css'
|
||||||
import { vars } from 'nft/css/sprinkles.css'
|
import { vars } from 'nft/css/sprinkles.css'
|
||||||
import {
|
import {
|
||||||
useBag,
|
useBag,
|
||||||
useFiltersExpanded,
|
useFiltersExpanded,
|
||||||
useIsMobile,
|
useIsMobile,
|
||||||
|
useProfilePageState,
|
||||||
useSellAsset,
|
useSellAsset,
|
||||||
useSellPageState,
|
|
||||||
useWalletBalance,
|
useWalletBalance,
|
||||||
useWalletCollections,
|
useWalletCollections,
|
||||||
} from 'nft/hooks'
|
} from 'nft/hooks'
|
||||||
import { fetchMultipleCollectionStats, fetchWalletAssets, OSCollectionsFetcher } from 'nft/queries'
|
import { fetchMultipleCollectionStats, fetchWalletAssets, OSCollectionsFetcher } from 'nft/queries'
|
||||||
import { DropDownOption, SellPageStateType, WalletAsset, WalletCollection } from 'nft/types'
|
import { DropDownOption, ProfilePageStateType, WalletAsset, WalletCollection } from 'nft/types'
|
||||||
import { Dispatch, FormEvent, SetStateAction, useEffect, useMemo, useReducer, useState } from 'react'
|
import { Dispatch, FormEvent, SetStateAction, useEffect, useMemo, useReducer, useState } from 'react'
|
||||||
import InfiniteScroll from 'react-infinite-scroll-component'
|
import InfiniteScroll from 'react-infinite-scroll-component'
|
||||||
import { useInfiniteQuery, useQuery } from 'react-query'
|
import { useInfiniteQuery, useQuery } from 'react-query'
|
||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
import { useSpring } from 'react-spring'
|
import { useSpring } from 'react-spring'
|
||||||
|
|
||||||
import * as styles from './SelectPage.css'
|
import { ProfileAccountDetails } from './ProfileAccountDetails'
|
||||||
|
import * as styles from './ProfilePage.css'
|
||||||
|
|
||||||
enum SortBy {
|
enum SortBy {
|
||||||
FloorPrice,
|
FloorPrice,
|
||||||
@ -58,7 +59,7 @@ function roundFloorPrice(price?: number, n?: number) {
|
|||||||
return price ? Math.round(price * Math.pow(10, n ?? 3) + Number.EPSILON) / Math.pow(10, n ?? 3) : 0
|
return price ? Math.round(price * Math.pow(10, n ?? 3) + Number.EPSILON) / Math.pow(10, n ?? 3) : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SelectPage = () => {
|
export const ProfilePage = () => {
|
||||||
const { address } = useWalletBalance()
|
const { address } = useWalletBalance()
|
||||||
const collectionFilters = useWalletCollections((state) => state.collectionFilters)
|
const collectionFilters = useWalletCollections((state) => state.collectionFilters)
|
||||||
const setCollectionFilters = useWalletCollections((state) => state.setCollectionFilters)
|
const setCollectionFilters = useWalletCollections((state) => state.setCollectionFilters)
|
||||||
@ -115,7 +116,7 @@ export const SelectPage = () => {
|
|||||||
const listFilter = useWalletCollections((state) => state.listFilter)
|
const listFilter = useWalletCollections((state) => state.listFilter)
|
||||||
const sellAssets = useSellAsset((state) => state.sellAssets)
|
const sellAssets = useSellAsset((state) => state.sellAssets)
|
||||||
const reset = useSellAsset((state) => state.reset)
|
const reset = useSellAsset((state) => state.reset)
|
||||||
const setSellPageState = useSellPageState((state) => state.setSellPageState)
|
const setSellPageState = useProfilePageState((state) => state.setProfilePageState)
|
||||||
const [sortBy, setSortBy] = useState(SortBy.DateAcquired)
|
const [sortBy, setSortBy] = useState(SortBy.DateAcquired)
|
||||||
const [orderByASC, setOrderBy] = useState(true)
|
const [orderByASC, setOrderBy] = useState(true)
|
||||||
const [searchText, setSearchText] = useState('')
|
const [searchText, setSearchText] = useState('')
|
||||||
@ -245,65 +246,66 @@ export const SelectPage = () => {
|
|||||||
const SortWalletAssetsDropdown = () => <SortDropdown dropDownOptions={sortDropDownOptions} />
|
const SortWalletAssetsDropdown = () => <SortDropdown dropDownOptions={sortDropDownOptions} />
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column width="full">
|
<Column
|
||||||
<Row
|
width="full"
|
||||||
alignItems="flex-start"
|
paddingLeft={{ sm: '16', md: '52' }}
|
||||||
position="relative"
|
paddingRight={{ sm: '0', md: '72' }}
|
||||||
paddingLeft={{ sm: '16', md: '52' }}
|
paddingTop={{ sm: '16', md: '40' }}
|
||||||
paddingRight={{ sm: '0', md: '72' }}
|
>
|
||||||
paddingTop={{ sm: '16', md: '40' }}
|
<Row alignItems="flex-start" position="relative">
|
||||||
>
|
|
||||||
<FilterSidebar SortDropdown={SortWalletAssetsDropdown} />
|
<FilterSidebar SortDropdown={SortWalletAssetsDropdown} />
|
||||||
|
|
||||||
{(!isMobile || !isFiltersExpanded) && (
|
{(!isMobile || !isFiltersExpanded) && (
|
||||||
// @ts-ignore
|
<Column width="full">
|
||||||
<AnimatedBox
|
<ProfileAccountDetails />
|
||||||
paddingLeft={isFiltersExpanded ? '24' : '16'}
|
<AnimatedBox
|
||||||
flexShrink="0"
|
paddingLeft={isFiltersExpanded ? '24' : '16'}
|
||||||
style={{
|
flexShrink="0"
|
||||||
transform: gridX.to((x) => `translate(${Number(x) - (!isMobile && isFiltersExpanded ? 300 : 0)}px)`),
|
style={{
|
||||||
width: gridWidthOffset.to((x) => `calc(100% - ${x}px)`),
|
transform: gridX.to((x) => `translate(${Number(x) - (!isMobile && isFiltersExpanded ? 300 : 0)}px)`),
|
||||||
}}
|
width: gridWidthOffset.to((x) => `calc(100% - ${x}px)`),
|
||||||
>
|
}}
|
||||||
<Row gap="8" flexWrap="nowrap">
|
|
||||||
<FilterButton
|
|
||||||
isMobile={isMobile}
|
|
||||||
isFiltersExpanded={isFiltersExpanded}
|
|
||||||
results={displayAssets.length}
|
|
||||||
onClick={() => setFiltersExpanded(!isFiltersExpanded)}
|
|
||||||
/>
|
|
||||||
{!isMobile && <SortDropdown dropDownOptions={sortDropDownOptions} />}
|
|
||||||
<CollectionSearch searchText={searchText} setSearchText={setSearchText} />
|
|
||||||
<SelectAllButton />
|
|
||||||
</Row>
|
|
||||||
<Row>
|
|
||||||
<CollectionFiltersRow
|
|
||||||
collections={walletCollections}
|
|
||||||
collectionFilters={collectionFilters}
|
|
||||||
setCollectionFilters={setCollectionFilters}
|
|
||||||
clearCollectionFilters={clearCollectionFilters}
|
|
||||||
/>
|
|
||||||
</Row>
|
|
||||||
<InfiniteScroll
|
|
||||||
next={fetchNextPage}
|
|
||||||
hasMore={hasNextPage ?? false}
|
|
||||||
loader={
|
|
||||||
hasNextPage ? (
|
|
||||||
<Center>
|
|
||||||
<LoadingSparkle />
|
|
||||||
</Center>
|
|
||||||
) : null
|
|
||||||
}
|
|
||||||
dataLength={displayAssets.length}
|
|
||||||
style={{ overflow: 'unset' }}
|
|
||||||
>
|
>
|
||||||
<div className={assetList}>
|
<Row gap="8" flexWrap="nowrap">
|
||||||
{displayAssets && displayAssets.length
|
<FilterButton
|
||||||
? displayAssets.map((asset, index) => <WalletAssetDisplay asset={asset} key={index} />)
|
isMobile={isMobile}
|
||||||
: null}
|
isFiltersExpanded={isFiltersExpanded}
|
||||||
</div>
|
results={displayAssets.length}
|
||||||
</InfiniteScroll>
|
onClick={() => setFiltersExpanded(!isFiltersExpanded)}
|
||||||
</AnimatedBox>
|
/>
|
||||||
|
{!isMobile && <SortDropdown dropDownOptions={sortDropDownOptions} />}
|
||||||
|
<CollectionSearch searchText={searchText} setSearchText={setSearchText} />
|
||||||
|
<SelectAllButton />
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<CollectionFiltersRow
|
||||||
|
collections={walletCollections}
|
||||||
|
collectionFilters={collectionFilters}
|
||||||
|
setCollectionFilters={setCollectionFilters}
|
||||||
|
clearCollectionFilters={clearCollectionFilters}
|
||||||
|
/>
|
||||||
|
</Row>
|
||||||
|
<InfiniteScroll
|
||||||
|
next={fetchNextPage}
|
||||||
|
hasMore={hasNextPage ?? false}
|
||||||
|
loader={
|
||||||
|
hasNextPage ? (
|
||||||
|
<Center>
|
||||||
|
<LoadingSparkle />
|
||||||
|
</Center>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
dataLength={displayAssets.length}
|
||||||
|
style={{ overflow: 'unset' }}
|
||||||
|
>
|
||||||
|
<div className={assetList}>
|
||||||
|
{displayAssets && displayAssets.length
|
||||||
|
? displayAssets.map((asset, index) => <WalletAssetDisplay asset={asset} key={index} />)
|
||||||
|
: null}
|
||||||
|
</div>
|
||||||
|
</InfiniteScroll>
|
||||||
|
</AnimatedBox>
|
||||||
|
</Column>
|
||||||
)}
|
)}
|
||||||
</Row>
|
</Row>
|
||||||
{sellAssets.length > 0 && (
|
{sellAssets.length > 0 && (
|
||||||
@ -338,7 +340,7 @@ export const SelectPage = () => {
|
|||||||
fontSize="14"
|
fontSize="14"
|
||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
backgroundColor="genieBlue"
|
backgroundColor="genieBlue"
|
||||||
onClick={() => setSellPageState(SellPageStateType.LISTING)}
|
onClick={() => setSellPageState(ProfilePageStateType.LISTING)}
|
||||||
lineHeight="16"
|
lineHeight="16"
|
||||||
borderRadius="12"
|
borderRadius="12"
|
||||||
padding="8"
|
padding="8"
|
||||||
@ -384,7 +386,7 @@ export const WalletAssetDisplay = ({ asset }: { asset: WalletAsset }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
to={`/nfts/asset/${asset.asset_contract.address}/${asset.tokenId}?origin=sell`}
|
to={`/nfts/asset/${asset.asset_contract.address}/${asset.tokenId}?origin=profile`}
|
||||||
style={{ textDecoration: 'none' }}
|
style={{ textDecoration: 'none' }}
|
||||||
>
|
>
|
||||||
<Column
|
<Column
|
@ -7,10 +7,10 @@ export * from './useIsTablet'
|
|||||||
export * from './useMarketplaceSelect'
|
export * from './useMarketplaceSelect'
|
||||||
export * from './useNFTList'
|
export * from './useNFTList'
|
||||||
export * from './useNFTSelect'
|
export * from './useNFTSelect'
|
||||||
|
export * from './useProfilePageState'
|
||||||
export * from './useSearchHistory'
|
export * from './useSearchHistory'
|
||||||
export * from './useSelectAsset'
|
export * from './useSelectAsset'
|
||||||
export * from './useSellAsset'
|
export * from './useSellAsset'
|
||||||
export * from './useSellPageState'
|
|
||||||
export * from './useSendTransaction'
|
export * from './useSendTransaction'
|
||||||
export * from './useSweep'
|
export * from './useSweep'
|
||||||
export * from './useTransactionResponse'
|
export * from './useTransactionResponse'
|
||||||
|
25
src/nft/hooks/useProfilePageState.ts
Normal file
25
src/nft/hooks/useProfilePageState.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import create from 'zustand'
|
||||||
|
import { devtools } from 'zustand/middleware'
|
||||||
|
|
||||||
|
import { ProfilePageStateType } from '../types'
|
||||||
|
|
||||||
|
interface profilePageState {
|
||||||
|
/**
|
||||||
|
* State of user settings
|
||||||
|
*/
|
||||||
|
state: ProfilePageStateType
|
||||||
|
setProfilePageState: (state: ProfilePageStateType) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useProfilePageState = create<profilePageState>()(
|
||||||
|
devtools(
|
||||||
|
(set) => ({
|
||||||
|
state: ProfilePageStateType.VIEWING,
|
||||||
|
setProfilePageState: (newState) =>
|
||||||
|
set(() => ({
|
||||||
|
state: newState,
|
||||||
|
})),
|
||||||
|
}),
|
||||||
|
{ name: 'useProfilePageState' }
|
||||||
|
)
|
||||||
|
)
|
@ -1,25 +0,0 @@
|
|||||||
import create from 'zustand'
|
|
||||||
import { devtools } from 'zustand/middleware'
|
|
||||||
|
|
||||||
import { SellPageStateType } from '../types'
|
|
||||||
|
|
||||||
interface sellPageState {
|
|
||||||
/**
|
|
||||||
* State of user settings
|
|
||||||
*/
|
|
||||||
state: SellPageStateType
|
|
||||||
setSellPageState: (state: SellPageStateType) => void
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useSellPageState = create<sellPageState>()(
|
|
||||||
devtools(
|
|
||||||
(set) => ({
|
|
||||||
state: SellPageStateType.SELECTING,
|
|
||||||
setSellPageState: (newState) =>
|
|
||||||
set(() => ({
|
|
||||||
state: newState,
|
|
||||||
})),
|
|
||||||
}),
|
|
||||||
{ name: 'useSellPageState' }
|
|
||||||
)
|
|
||||||
)
|
|
@ -254,8 +254,8 @@ const Asset = () => {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (!parsed.origin || parsed.origin === 'collection') {
|
if (!parsed.origin || parsed.origin === 'collection') {
|
||||||
navigate(`/nfts/collection/${asset.address}`)
|
navigate(`/nfts/collection/${asset.address}`)
|
||||||
} else if (parsed.origin === 'sell') {
|
} else if (parsed.origin === 'profile') {
|
||||||
navigate('/nfts/sell', undefined)
|
navigate('/profile', undefined)
|
||||||
} else if (parsed.origin === 'explore') {
|
} else if (parsed.origin === 'explore') {
|
||||||
navigate(`/nfts`, undefined)
|
navigate(`/nfts`, undefined)
|
||||||
} else if (parsed.origin === 'activity') {
|
} else if (parsed.origin === 'activity') {
|
||||||
|
@ -2,12 +2,12 @@ import { useWeb3React } from '@web3-react/core'
|
|||||||
import { Box } from 'nft/components/Box'
|
import { Box } from 'nft/components/Box'
|
||||||
import { Center, Column, Row } from 'nft/components/Flex'
|
import { Center, Column, Row } from 'nft/components/Flex'
|
||||||
import { ChevronLeftIcon, XMarkIcon } from 'nft/components/icons'
|
import { ChevronLeftIcon, XMarkIcon } from 'nft/components/icons'
|
||||||
import { ListPage } from 'nft/components/sell/list/ListPage'
|
import { ListPage } from 'nft/components/profile/list/ListPage'
|
||||||
import { SelectPage } from 'nft/components/sell/select/SelectPage'
|
import { ProfilePage } from 'nft/components/profile/view/ProfilePage'
|
||||||
import { buttonMedium, headlineMedium, headlineSmall } from 'nft/css/common.css'
|
import { buttonMedium, headlineMedium, headlineSmall } from 'nft/css/common.css'
|
||||||
import { themeVars } from 'nft/css/sprinkles.css'
|
import { themeVars } from 'nft/css/sprinkles.css'
|
||||||
import { useBag, useNFTList, useSellAsset, useSellPageState, useWalletCollections } from 'nft/hooks'
|
import { useBag, useNFTList, useProfilePageState, useSellAsset, useWalletCollections } from 'nft/hooks'
|
||||||
import { ListingStatus, SellPageStateType } from 'nft/types'
|
import { ListingStatus, ProfilePageStateType } from 'nft/types'
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import { useNavigate } from 'react-router-dom'
|
import { useNavigate } from 'react-router-dom'
|
||||||
import { useToggleWalletModal } from 'state/application/hooks'
|
import { useToggleWalletModal } from 'state/application/hooks'
|
||||||
@ -16,9 +16,9 @@ import * as styles from './sell.css'
|
|||||||
|
|
||||||
const SHOPPING_BAG_WIDTH = 324
|
const SHOPPING_BAG_WIDTH = 324
|
||||||
|
|
||||||
const Sell = () => {
|
const Profile = () => {
|
||||||
const sellPageState = useSellPageState((state) => state.state)
|
const sellPageState = useProfilePageState((state) => state.state)
|
||||||
const setSellPageState = useSellPageState((state) => state.setSellPageState)
|
const setSellPageState = useProfilePageState((state) => state.setProfilePageState)
|
||||||
const removeAllMarketplaceWarnings = useSellAsset((state) => state.removeAllMarketplaceWarnings)
|
const removeAllMarketplaceWarnings = useSellAsset((state) => state.removeAllMarketplaceWarnings)
|
||||||
const resetSellAssets = useSellAsset((state) => state.reset)
|
const resetSellAssets = useSellAsset((state) => state.reset)
|
||||||
const clearCollectionFilters = useWalletCollections((state) => state.clearCollectionFilters)
|
const clearCollectionFilters = useWalletCollections((state) => state.clearCollectionFilters)
|
||||||
@ -35,7 +35,7 @@ const Sell = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
resetSellAssets()
|
resetSellAssets()
|
||||||
setSellPageState(SellPageStateType.SELECTING)
|
setSellPageState(ProfilePageStateType.VIEWING)
|
||||||
clearCollectionFilters()
|
clearCollectionFilters()
|
||||||
}, [account, resetSellAssets, setSellPageState, clearCollectionFilters])
|
}, [account, resetSellAssets, setSellPageState, clearCollectionFilters])
|
||||||
const cartExpanded = useBag((state) => state.bagExpanded)
|
const cartExpanded = useBag((state) => state.bagExpanded)
|
||||||
@ -50,13 +50,13 @@ const Sell = () => {
|
|||||||
<title>Genie | Sell</title>
|
<title>Genie | Sell</title>
|
||||||
</Head> */}
|
</Head> */}
|
||||||
<Row className={styles.mobileSellHeader}>
|
<Row className={styles.mobileSellHeader}>
|
||||||
{sellPageState === SellPageStateType.LISTING && (
|
{sellPageState === ProfilePageStateType.LISTING && (
|
||||||
<Box marginRight="4" onClick={() => setSellPageState(SellPageStateType.SELECTING)}>
|
<Box marginRight="4" onClick={() => setSellPageState(ProfilePageStateType.VIEWING)}>
|
||||||
<ChevronLeftIcon height={28} width={28} />
|
<ChevronLeftIcon height={28} width={28} />
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
<Box className={headlineSmall} paddingBottom="4" style={{ lineHeight: '28px' }}>
|
<Box className={headlineSmall} paddingBottom="4" style={{ lineHeight: '28px' }}>
|
||||||
{sellPageState === SellPageStateType.SELECTING ? 'Select NFTs' : 'Create Listing'}
|
{sellPageState === ProfilePageStateType.VIEWING ? 'Select NFTs' : 'Create Listing'}
|
||||||
</Box>
|
</Box>
|
||||||
<Box cursor="pointer" marginLeft="auto" marginRight="0" onClick={exitSellFlow}>
|
<Box cursor="pointer" marginLeft="auto" marginRight="0" onClick={exitSellFlow}>
|
||||||
<XMarkIcon height={28} width={28} fill={themeVars.colors.textPrimary} />
|
<XMarkIcon height={28} width={28} fill={themeVars.colors.textPrimary} />
|
||||||
@ -64,7 +64,7 @@ const Sell = () => {
|
|||||||
</Row>
|
</Row>
|
||||||
{account != null ? (
|
{account != null ? (
|
||||||
<Box style={{ width: `calc(100% - ${cartExpanded ? SHOPPING_BAG_WIDTH : 0}px)` }}>
|
<Box style={{ width: `calc(100% - ${cartExpanded ? SHOPPING_BAG_WIDTH : 0}px)` }}>
|
||||||
{sellPageState === SellPageStateType.SELECTING ? <SelectPage /> : <ListPage />}
|
{sellPageState === ProfilePageStateType.VIEWING ? <ProfilePage /> : <ListPage />}
|
||||||
</Box>
|
</Box>
|
||||||
) : (
|
) : (
|
||||||
<Column as="section" gap="60" className={styles.section}>
|
<Column as="section" gap="60" className={styles.section}>
|
||||||
@ -84,4 +84,4 @@ const Sell = () => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Sell
|
export default Profile
|
@ -184,6 +184,6 @@ export interface DropDownOption {
|
|||||||
|
|
||||||
export enum DetailsOrigin {
|
export enum DetailsOrigin {
|
||||||
COLLECTION = 'collection',
|
COLLECTION = 'collection',
|
||||||
SELL = 'sell',
|
PROFILE = 'profile',
|
||||||
EXPLORE = 'explore',
|
EXPLORE = 'explore',
|
||||||
}
|
}
|
||||||
|
@ -108,8 +108,8 @@ export interface CollectionRow extends AssetRow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Creating this as an enum and not boolean as we will likely have a success screen state to show
|
// Creating this as an enum and not boolean as we will likely have a success screen state to show
|
||||||
export enum SellPageStateType {
|
export enum ProfilePageStateType {
|
||||||
SELECTING,
|
VIEWING,
|
||||||
LISTING,
|
LISTING,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ const TokenDetails = lazy(() => import('./TokenDetails'))
|
|||||||
const Vote = lazy(() => import('./Vote'))
|
const Vote = lazy(() => import('./Vote'))
|
||||||
const NftExplore = lazy(() => import('nft/pages/explore'))
|
const NftExplore = lazy(() => import('nft/pages/explore'))
|
||||||
const Collection = lazy(() => import('nft/pages/collection'))
|
const Collection = lazy(() => import('nft/pages/collection'))
|
||||||
const Sell = lazy(() => import('nft/pages/sell/sell'))
|
const Profile = lazy(() => import('nft/pages/profile/profile'))
|
||||||
const Asset = lazy(() => import('nft/pages/asset/Asset'))
|
const Asset = lazy(() => import('nft/pages/asset/Asset'))
|
||||||
|
|
||||||
const AppWrapper = styled.div<{ redesignFlagEnabled: boolean }>`
|
const AppWrapper = styled.div<{ redesignFlagEnabled: boolean }>`
|
||||||
@ -236,8 +236,8 @@ export default function App() {
|
|||||||
|
|
||||||
{nftFlag === NftVariant.Enabled && (
|
{nftFlag === NftVariant.Enabled && (
|
||||||
<>
|
<>
|
||||||
|
<Route path="/profile" element={<Profile />} />
|
||||||
<Route path="/nfts" element={<NftExplore />} />
|
<Route path="/nfts" element={<NftExplore />} />
|
||||||
<Route path="/nfts/sell" element={<Sell />} />
|
|
||||||
<Route path="/nfts/asset/:contractAddress/:tokenId" element={<Asset />} />
|
<Route path="/nfts/asset/:contractAddress/:tokenId" element={<Asset />} />
|
||||||
<Route path="/nfts/collection/:contractAddress" element={<Collection />} />
|
<Route path="/nfts/collection/:contractAddress" element={<Collection />} />
|
||||||
<Route path="/nfts/collection/:contractAddress/activity" element={<Collection />} />
|
<Route path="/nfts/collection/:contractAddress/activity" element={<Collection />} />
|
||||||
|
Loading…
Reference in New Issue
Block a user