fix(nft): empty bag state render (#4947)
* fix empty bag state render * add tests
This commit is contained in:
parent
a97a6b7fa8
commit
0987a311cf
@ -6,11 +6,9 @@ import { BagFooter } from 'nft/components/bag/BagFooter'
|
||||
import ListingModal from 'nft/components/bag/profile/ListingModal'
|
||||
import { Box } from 'nft/components/Box'
|
||||
import { Portal } from 'nft/components/common/Portal'
|
||||
import { Center, Column } from 'nft/components/Flex'
|
||||
import { LargeBagIcon, LargeTagIcon } from 'nft/components/icons'
|
||||
import { Column } from 'nft/components/Flex'
|
||||
import { Overlay } from 'nft/components/modals/Overlay'
|
||||
import { buttonTextMedium, commonButtonStyles, subhead } from 'nft/css/common.css'
|
||||
import { themeVars } from 'nft/css/sprinkles.css'
|
||||
import { buttonTextMedium, commonButtonStyles } from 'nft/css/common.css'
|
||||
import {
|
||||
useBag,
|
||||
useIsMobile,
|
||||
@ -34,39 +32,9 @@ import { useLocation } from 'react-router-dom'
|
||||
import * as styles from './Bag.css'
|
||||
import { BagContent } from './BagContent'
|
||||
import { BagHeader } from './BagHeader'
|
||||
import EmptyState from './EmptyContent'
|
||||
import { ProfileBagContent } from './profile/ProfileBagContent'
|
||||
|
||||
const EmptyState = () => {
|
||||
const { pathname } = useLocation()
|
||||
const isProfilePage = pathname.startsWith('/profile')
|
||||
|
||||
return (
|
||||
<Center height="full">
|
||||
<Column gap={isProfilePage ? '16' : '12'}>
|
||||
<Center>
|
||||
{isProfilePage ? (
|
||||
<LargeTagIcon color={themeVars.colors.textTertiary} />
|
||||
) : (
|
||||
<LargeBagIcon color={themeVars.colors.textTertiary} />
|
||||
)}
|
||||
</Center>
|
||||
{isProfilePage ? (
|
||||
<span className={subhead}>No NFTs Selected</span>
|
||||
) : (
|
||||
<Column gap="16">
|
||||
<Center className={subhead} style={{ lineHeight: '24px' }}>
|
||||
Your bag is empty
|
||||
</Center>
|
||||
<Center fontSize="12" fontWeight="normal" color="textSecondary" style={{ lineHeight: '16px' }}>
|
||||
Selected NFTs will appear here
|
||||
</Center>
|
||||
</Column>
|
||||
)}
|
||||
</Column>
|
||||
</Center>
|
||||
)
|
||||
}
|
||||
|
||||
interface SeparatorProps {
|
||||
top?: boolean
|
||||
show?: boolean
|
||||
@ -282,6 +250,13 @@ const Bag = () => {
|
||||
setScrollProgress(scrollTop ? ((scrollTop + containerHeight) / scrollHeight) * 100 : 0)
|
||||
}
|
||||
|
||||
const isBuyingAssets = itemsInBag.length > 0
|
||||
const isSellingAssets = sellAssets.length > 0
|
||||
|
||||
const shouldRenderEmptyState = Boolean(
|
||||
(!isProfilePage && !isBuyingAssets && bagStatus === BagStatus.ADDING_TO_BAG) || (isProfilePage && !isSellingAssets)
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
{bagExpanded && shouldShowBag ? (
|
||||
@ -295,8 +270,7 @@ const Bag = () => {
|
||||
resetFlow={isProfilePage ? resetSellAssets : reset}
|
||||
isProfilePage={isProfilePage}
|
||||
/>
|
||||
{(!isProfilePage && itemsInBag.length === 0 && bagStatus === BagStatus.ADDING_TO_BAG) ||
|
||||
(isProfilePage && sellAssets.length === 0 && <EmptyState />)}
|
||||
{shouldRenderEmptyState && <EmptyState />}
|
||||
<ScrollingIndicator top show={userCanScroll && scrollProgress > 0} />
|
||||
<Column ref={scrollRef} className={styles.assetsContainer} onScroll={scrollHandler} gap="12">
|
||||
{isProfilePage ? <ProfileBagContent /> : <BagContent />}
|
||||
@ -314,7 +288,7 @@ const Bag = () => {
|
||||
assetsAreInReview={itemsInBag.some((item) => item.status === BagItemStatus.REVIEWING_PRICE_CHANGE)}
|
||||
/>
|
||||
)}
|
||||
{sellAssets.length !== 0 && isProfilePage && (
|
||||
{isSellingAssets && isProfilePage && (
|
||||
<Box
|
||||
marginTop="32"
|
||||
marginX="28"
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { style } from '@vanilla-extract/css'
|
||||
import { subhead } from 'nft/css/common.css'
|
||||
import { headlineSmall } from 'nft/css/common.css'
|
||||
import { sprinkles, vars } from 'nft/css/sprinkles.css'
|
||||
|
||||
export const header = style([
|
||||
subhead,
|
||||
headlineSmall,
|
||||
sprinkles({
|
||||
color: 'textPrimary',
|
||||
justifyContent: 'space-between',
|
||||
|
36
src/nft/components/bag/EmptyContent.tsx
Normal file
36
src/nft/components/bag/EmptyContent.tsx
Normal file
@ -0,0 +1,36 @@
|
||||
import { Center, Column } from 'nft/components/Flex'
|
||||
import { LargeBagIcon, LargeTagIcon } from 'nft/components/icons'
|
||||
import { subhead } from 'nft/css/common.css'
|
||||
import { themeVars } from 'nft/css/sprinkles.css'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
|
||||
const EmptyState = () => {
|
||||
const { pathname } = useLocation()
|
||||
const isProfilePage = pathname.startsWith('/profile')
|
||||
|
||||
return (
|
||||
<Column gap={isProfilePage ? '16' : '12'} marginTop="36">
|
||||
<Center>
|
||||
{isProfilePage ? (
|
||||
<LargeTagIcon color={themeVars.colors.textTertiary} />
|
||||
) : (
|
||||
<LargeBagIcon color={themeVars.colors.textTertiary} />
|
||||
)}
|
||||
</Center>
|
||||
{isProfilePage ? (
|
||||
<span className={subhead}>No NFTs Selected</span>
|
||||
) : (
|
||||
<Column gap="16">
|
||||
<Center className={subhead} style={{ lineHeight: '24px' }}>
|
||||
Your bag is empty
|
||||
</Center>
|
||||
<Center fontSize="12" fontWeight="normal" color="textSecondary" style={{ lineHeight: '16px' }}>
|
||||
Selected NFTs will appear here
|
||||
</Center>
|
||||
</Column>
|
||||
)}
|
||||
</Column>
|
||||
)
|
||||
}
|
||||
|
||||
export default EmptyState
|
3
src/nft/components/bag/__snapshots__/bag.test.tsx.snap
Normal file
3
src/nft/components/bag/__snapshots__/bag.test.tsx.snap
Normal file
@ -0,0 +1,3 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Bag.tsx matches base snapshot 1`] = `<DocumentFragment />`;
|
21
src/nft/components/bag/bag.test.tsx
Normal file
21
src/nft/components/bag/bag.test.tsx
Normal file
@ -0,0 +1,21 @@
|
||||
import { render } from 'test-utils'
|
||||
|
||||
import Bag from './Bag'
|
||||
|
||||
jest.mock('@web3-react/core', () => {
|
||||
const web3React = jest.requireActual('@web3-react/core')
|
||||
return {
|
||||
useWeb3React: () => ({
|
||||
account: '0x52270d8234b864dcAC9947f510CE9275A8a116Db',
|
||||
isActive: true,
|
||||
}),
|
||||
...web3React,
|
||||
}
|
||||
})
|
||||
|
||||
describe('Bag.tsx', () => {
|
||||
it('matches base snapshot', () => {
|
||||
const { asFragment } = render(<Bag />)
|
||||
expect(asFragment()).toMatchSnapshot()
|
||||
})
|
||||
})
|
@ -1,5 +1,4 @@
|
||||
import * as useV3Positions from 'hooks/useV3Positions'
|
||||
import { BrowserRouter as Router } from 'react-router-dom'
|
||||
import { render, screen } from 'test-utils'
|
||||
|
||||
import CTACards from './CTACards'
|
||||
@ -20,11 +19,7 @@ describe('CTAcard links', () => {
|
||||
return { loading: false, positions: undefined }
|
||||
})
|
||||
|
||||
render(
|
||||
<Router>
|
||||
<CTACards />
|
||||
</Router>
|
||||
)
|
||||
render(<CTACards />)
|
||||
expect(screen.getByTestId('cta-infolink')).toHaveAttribute('href', 'https://info.uniswap.org/#/pools')
|
||||
})
|
||||
})
|
||||
|
@ -1,6 +1,5 @@
|
||||
import * as chains from 'constants/chains'
|
||||
import * as useV3Positions from 'hooks/useV3Positions'
|
||||
import { BrowserRouter as Router } from 'react-router-dom'
|
||||
import { render, screen } from 'test-utils'
|
||||
|
||||
import Pool from '.'
|
||||
@ -22,11 +21,7 @@ describe('networks', () => {
|
||||
return { loading: false, positions: undefined }
|
||||
})
|
||||
|
||||
render(
|
||||
<Router>
|
||||
<Pool />
|
||||
</Router>
|
||||
)
|
||||
render(<Pool />)
|
||||
expect(screen.getByText('Your connected network is unsupported.')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
@ -36,11 +31,7 @@ describe('networks', () => {
|
||||
return { loading: false, positions: undefined }
|
||||
})
|
||||
|
||||
render(
|
||||
<Router>
|
||||
<Pool />
|
||||
</Router>
|
||||
)
|
||||
render(<Pool />)
|
||||
expect(screen.getByText('Your active V3 liquidity positions will appear here.')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
@ -3,9 +3,12 @@ import { I18nProvider } from '@lingui/react'
|
||||
import { render } from '@testing-library/react'
|
||||
import Web3Provider from 'components/Web3Provider'
|
||||
import { DEFAULT_LOCALE } from 'constants/locales'
|
||||
import { BlockNumberProvider } from 'lib/hooks/useBlockNumber'
|
||||
import { en } from 'make-plural/plurals'
|
||||
import { ReactElement, ReactNode } from 'react'
|
||||
import { QueryClient, QueryClientProvider } from 'react-query'
|
||||
import { Provider } from 'react-redux'
|
||||
import { HashRouter } from 'react-router-dom'
|
||||
import store from 'state'
|
||||
import ThemeProvider from 'theme'
|
||||
|
||||
@ -20,14 +23,21 @@ i18n.loadLocaleData({
|
||||
i18n.activate(DEFAULT_LOCALE)
|
||||
|
||||
const MockedI18nProvider = ({ children }: any) => <I18nProvider i18n={i18n}>{children}</I18nProvider>
|
||||
const queryClient = new QueryClient()
|
||||
|
||||
const WithProviders = ({ children }: { children?: ReactNode }) => {
|
||||
return (
|
||||
<MockedI18nProvider>
|
||||
<Provider store={store}>
|
||||
<Web3Provider>
|
||||
<ThemeProvider>{children}</ThemeProvider>
|
||||
</Web3Provider>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<HashRouter>
|
||||
<Web3Provider>
|
||||
<BlockNumberProvider>
|
||||
<ThemeProvider>{children}</ThemeProvider>
|
||||
</BlockNumberProvider>
|
||||
</Web3Provider>
|
||||
</HashRouter>
|
||||
</QueryClientProvider>
|
||||
</Provider>
|
||||
</MockedI18nProvider>
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user