diff --git a/src/nft/components/collection/CollectionNfts.tsx b/src/nft/components/collection/CollectionNfts.tsx
index 04ed28d89f..ae8f6c61b0 100644
--- a/src/nft/components/collection/CollectionNfts.tsx
+++ b/src/nft/components/collection/CollectionNfts.tsx
@@ -4,6 +4,7 @@ import { CollectionAsset } from 'nft/components/collection/CollectionAsset'
import * as styles from 'nft/components/collection/CollectionNfts.css'
import { Center } from 'nft/components/Flex'
import { bodySmall, buttonTextMedium, header2 } from 'nft/css/common.css'
+import { useCollectionFilters } from 'nft/hooks'
import { AssetsFetcher } from 'nft/queries'
import { useMemo } from 'react'
import InfiniteScroll from 'react-infinite-scroll-component'
@@ -14,6 +15,8 @@ interface CollectionNftsProps {
}
export const CollectionNfts = ({ contractAddress }: CollectionNftsProps) => {
+ const buyNow = useCollectionFilters((state) => state.buyNow)
+
const {
data: collectionAssets,
isSuccess: AssetsFetchSuccess,
@@ -24,11 +27,13 @@ export const CollectionNfts = ({ contractAddress }: CollectionNftsProps) => {
'collectionNfts',
{
contractAddress,
+ notForSale: !buyNow,
},
],
async ({ pageParam = 0 }) => {
return await AssetsFetcher({
contractAddress,
+ notForSale: !buyNow,
pageParam,
})
},
diff --git a/src/nft/components/collection/FilterButton.css.ts b/src/nft/components/collection/FilterButton.css.ts
new file mode 100644
index 0000000000..02ea134ddf
--- /dev/null
+++ b/src/nft/components/collection/FilterButton.css.ts
@@ -0,0 +1,23 @@
+import { style } from '@vanilla-extract/css'
+import { sprinkles, themeVars, vars } from 'nft/css/sprinkles.css'
+
+export const filterButton = sprinkles({
+ backgroundColor: 'blue400',
+ color: 'explicitWhite',
+})
+
+export const filterButtonExpanded = style({
+ background: vars.color.lightGrayButton,
+ color: themeVars.colors.blackBlue,
+})
+
+export const filterBadge = style([
+ sprinkles({
+ position: 'absolute',
+ left: '18',
+ fontSize: '28',
+ }),
+ {
+ top: '-3px',
+ },
+])
diff --git a/src/nft/components/collection/FilterButton.tsx b/src/nft/components/collection/FilterButton.tsx
new file mode 100644
index 0000000000..04a3e7d0ff
--- /dev/null
+++ b/src/nft/components/collection/FilterButton.tsx
@@ -0,0 +1,69 @@
+import clsx from 'clsx'
+import { Box } from 'nft/components/Box'
+import * as styles from 'nft/components/collection/FilterButton.css'
+import { Row } from 'nft/components/Flex'
+import { FilterIcon } from 'nft/components/icons'
+import { useCollectionFilters } from 'nft/hooks'
+import { putCommas } from 'nft/utils/putCommas'
+
+export const FilterButton = ({
+ onClick,
+ isMobile,
+ isFiltersExpanded,
+ results,
+}: {
+ isMobile: boolean
+ isFiltersExpanded: boolean
+ results?: number
+ onClick: () => void
+}) => {
+ const { minPrice, maxPrice, minRarity, maxRarity, traits, markets, buyNow } = useCollectionFilters((state) => ({
+ minPrice: state.minPrice,
+ maxPrice: state.maxPrice,
+ minRarity: state.minRarity,
+ maxRarity: state.maxRarity,
+ traits: state.traits,
+ markets: state.markets,
+ buyNow: state.buyNow,
+ }))
+
+ const showFilterBadge = minPrice || maxPrice || minRarity || maxRarity || traits.length || markets.length || buyNow
+ return (
+
+ {showFilterBadge && (
+
+ •
+
+ )}
+
+ {!isMobile && !isFiltersExpanded && 'Filter'}
+
+ {showFilterBadge && !isMobile ? (
+
+ {!isFiltersExpanded && (
+
+ •
+
+ )}
+ {results ? putCommas(results) : 0} results
+
+ ) : null}
+
+ )
+}
diff --git a/src/nft/components/collection/Filters.css.ts b/src/nft/components/collection/Filters.css.ts
new file mode 100644
index 0000000000..119b67281f
--- /dev/null
+++ b/src/nft/components/collection/Filters.css.ts
@@ -0,0 +1,82 @@
+import { style } from '@vanilla-extract/css'
+import { breakpoints, sprinkles, themeVars } from 'nft/css/sprinkles.css'
+
+export const container = style([
+ sprinkles({
+ overflow: 'auto',
+ height: 'viewHeight',
+ paddingTop: '24',
+ }),
+ {
+ width: '300px',
+ paddingBottom: '96px',
+ '@media': {
+ [`(max-width: ${breakpoints.sm - 1}px)`]: {
+ width: 'auto',
+ height: 'auto',
+ paddingBottom: '0px',
+ },
+ },
+ selectors: {
+ '&::-webkit-scrollbar': {
+ display: 'none',
+ },
+ },
+ },
+])
+
+export const rowHover = style([
+ sprinkles({
+ borderRadius: '12',
+ }),
+ {
+ ':hover': {
+ background: themeVars.colors.lightGray,
+ },
+ },
+])
+
+export const rowHoverOpen = style([
+ sprinkles({
+ borderTopLeftRadius: '12',
+ borderTopRightRadius: '12',
+ borderBottomLeftRadius: '0',
+ borderBottomRightRadius: '0',
+ }),
+ {
+ ':hover': {
+ background: themeVars.colors.medGray,
+ },
+ },
+])
+
+export const subRowHover = style({
+ ':hover': {
+ background: themeVars.colors.medGray,
+ },
+})
+
+export const detailsOpen = sprinkles({
+ background: 'darkGray10',
+ overflow: 'hidden',
+ borderStyle: 'solid',
+ borderWidth: '1px',
+ borderColor: 'medGray',
+})
+
+export const summaryOpen = sprinkles({
+ borderStyle: 'solid',
+ borderWidth: '1px',
+ borderColor: 'medGray',
+})
+
+export const filterDropDowns = style([
+ sprinkles({
+ overflowY: 'scroll',
+ }),
+ {
+ maxHeight: '190px',
+ '::-webkit-scrollbar': { display: 'none' },
+ scrollbarWidth: 'none',
+ },
+])
diff --git a/src/nft/components/collection/Filters.tsx b/src/nft/components/collection/Filters.tsx
new file mode 100644
index 0000000000..ce5dce238a
--- /dev/null
+++ b/src/nft/components/collection/Filters.tsx
@@ -0,0 +1,51 @@
+import { Box } from 'nft/components/Box'
+import * as styles from 'nft/components/collection/Filters.css'
+import { Column, Row } from 'nft/components/Flex'
+import { Radio } from 'nft/components/layout/Radio'
+import { useCollectionFilters } from 'nft/hooks'
+import { useReducer } from 'react'
+
+export const Filters = () => {
+ const { buyNow, setBuyNow } = useCollectionFilters((state) => ({
+ buyNow: state.buyNow,
+ setBuyNow: state.setBuyNow,
+ }))
+ const [buyNowHovered, toggleBuyNowHover] = useReducer((state) => !state, false)
+
+ const handleBuyNowToggle = () => {
+ setBuyNow(!buyNow)
+ }
+
+ return (
+
+
+
+ Filters
+
+
+
+ {
+ e.preventDefault()
+ handleBuyNowToggle()
+ }}
+ onMouseEnter={toggleBuyNowHover}
+ onMouseLeave={toggleBuyNowHover}
+ >
+
+ Buy now
+
+
+
+
+
+ )
+}
diff --git a/src/nft/components/collection/index.ts b/src/nft/components/collection/index.ts
new file mode 100644
index 0000000000..6d254dddb1
--- /dev/null
+++ b/src/nft/components/collection/index.ts
@@ -0,0 +1,4 @@
+export { CollectionNfts } from './CollectionNfts'
+export { CollectionStats } from './CollectionStats'
+export { FilterButton } from './FilterButton'
+export { Filters } from './Filters'
diff --git a/src/nft/components/layout/Radio.css.ts b/src/nft/components/layout/Radio.css.ts
new file mode 100644
index 0000000000..9afcb1b686
--- /dev/null
+++ b/src/nft/components/layout/Radio.css.ts
@@ -0,0 +1,53 @@
+import { style } from '@vanilla-extract/css'
+import { sprinkles, vars } from 'nft/css/sprinkles.css'
+
+export const radio = style([
+ sprinkles({
+ position: 'relative',
+ display: 'inline-block',
+ height: '24',
+ width: '24',
+ cursor: 'pointer',
+ background: 'transparent',
+ borderRadius: { default: 'round', before: 'round' },
+ borderStyle: 'solid',
+ borderWidth: '2px',
+ top: '0',
+ left: '0',
+ right: '0',
+ bottom: '0',
+ transition: {
+ default: '250',
+ before: '250',
+ },
+ }),
+])
+
+export const greyBorderRadio = style([
+ radio,
+ sprinkles({
+ borderColor: 'grey400',
+ }),
+])
+
+export const blueBorderRadio = style([
+ radio,
+ sprinkles({
+ borderColor: 'blue400',
+ }),
+])
+
+export const selectedRadio = style([
+ blueBorderRadio,
+ {
+ ':before': {
+ position: 'absolute',
+ backgroundColor: vars.color.blue400,
+ content: '',
+ height: '14px',
+ width: '14px',
+ top: 3,
+ left: 3,
+ },
+ },
+])
diff --git a/src/nft/components/layout/Radio.tsx b/src/nft/components/layout/Radio.tsx
new file mode 100644
index 0000000000..3bc530d39e
--- /dev/null
+++ b/src/nft/components/layout/Radio.tsx
@@ -0,0 +1,21 @@
+import { Box } from 'nft/components/Box'
+import * as styles from 'nft/components/layout/Radio.css'
+import { MouseEvent } from 'react'
+
+interface RadioProps {
+ hovered: boolean
+ checked: boolean
+ onClick: (e: MouseEvent) => void
+}
+
+export const Radio = ({ hovered, checked, onClick }: RadioProps) => {
+ return (
+
+ )
+}
+
+Radio.displayName = 'Radio'
diff --git a/src/nft/pages/collection/index.tsx b/src/nft/pages/collection/index.tsx
index 839186f2cd..fc36d82659 100644
--- a/src/nft/pages/collection/index.tsx
+++ b/src/nft/pages/collection/index.tsx
@@ -1,22 +1,31 @@
import { AnimatedBox, Box } from 'nft/components/Box'
-import { CollectionNfts } from 'nft/components/collection/CollectionNfts'
-import { CollectionStats } from 'nft/components/collection/CollectionStats'
+import { CollectionNfts, CollectionStats, FilterButton, Filters } from 'nft/components/collection'
import { Column, Row } from 'nft/components/Flex'
-import { useIsMobile } from 'nft/hooks/useIsMobile'
+import { useFiltersExpanded, useIsMobile } from 'nft/hooks'
import * as styles from 'nft/pages/collection/index.css'
import { CollectionStatsFetcher } from 'nft/queries'
import { useQuery } from 'react-query'
import { useParams } from 'react-router-dom'
+import { useSpring } from 'react-spring/web'
+
+const FILTER_WIDTH = 332
const Collection = () => {
const { contractAddress } = useParams()
const isMobile = useIsMobile()
+ const [isFiltersExpanded, setFiltersExpanded] = useFiltersExpanded()
const { data: collectionStats } = useQuery(['collectionStats', contractAddress], () =>
CollectionStatsFetcher(contractAddress as string)
)
+ /// @reviewer these look the same now but will be diff later
+ const { gridX, gridWidthOffset } = useSpring({
+ gridX: isFiltersExpanded ? FILTER_WIDTH : 0,
+ gridWidthOffset: isFiltersExpanded ? FILTER_WIDTH : 0,
+ })
+
return (
@@ -34,8 +43,30 @@ const Collection = () => {
)}
-
-
+
+
+ {isFiltersExpanded && }
+
+
+ {/* @ts-ignore: https://github.com/microsoft/TypeScript/issues/34933 */}
+ `translate(${x as number}px)`),
+ width: gridWidthOffset.interpolate((x) => `calc(100% - ${x as number}px)`),
+ }}
+ >
+
+
+
+ setFiltersExpanded(!isFiltersExpanded)}
+ />
+
+
+
+
{contractAddress && }
diff --git a/src/nft/utils/index.ts b/src/nft/utils/index.ts
new file mode 100644
index 0000000000..7e38dd39ed
--- /dev/null
+++ b/src/nft/utils/index.ts
@@ -0,0 +1,5 @@
+export * from './buildActivityAsset'
+export * from './buildSellObject'
+export * from './calcPoolPrice'
+export * from './currency'
+export * from './listNfts'