From 6974d0027f3bc768fa0966c500c86533a7f10af3 Mon Sep 17 00:00:00 2001 From: Geoffrey MERRAN Date: Wed, 4 Jan 2023 19:58:03 +0100 Subject: [PATCH 1/2] fix(marketplace): refacto filters and sort, feat(marketplace): add tab sold --- package-lock.json | 12 ++ src/components/Card/Card.module.scss | 8 + src/components/Card/ObjktCard.tsx | 20 ++- src/components/Gallery/GalleryMarketplace.tsx | 20 ++- src/containers/Marketplace.tsx | 112 ++----------- .../Marketplace/MarketplaceSold.tsx | 55 ++++++ src/containers/Marketplace/Tabs.tsx | 32 +++- src/pages/_app.tsx | 1 + src/pages/marketplace.tsx | 4 +- src/pages/marketplace/collections.tsx | 5 +- src/pages/marketplace/sold.tsx | 65 +++++++ src/queries/fragments/listing.ts | 1 + src/styles/globals.scss | 1 + src/types/entities/Listing.ts | 2 + src/utils/filters.ts | 158 +++++++++++++++--- src/utils/sort.ts | 24 +++ 16 files changed, 379 insertions(+), 141 deletions(-) create mode 100644 src/containers/Marketplace/MarketplaceSold.tsx create mode 100644 src/pages/marketplace/sold.tsx diff --git a/package-lock.json b/package-lock.json index 4ac7f7787..a5d5eea0c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6202,6 +6202,18 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.2.tgz", "integrity": "sha512-JZxotl7SxAJH0j7dN4pxsTV6ZLXoLdGME+PsjkL/DaBrVryK9kTGq06GfKrwcSOqypP+fdXGoCHE36b99fWVoA==" + }, + "@next/swc-android-arm-eabi": { + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-12.2.0.tgz", + "integrity": "sha512-hbneH8DNRB2x0Nf5fPCYoL8a0osvdTCe4pvOc9Rv5CpDsoOlf8BWBs2OWpeP0U2BktGvIsuUhmISmdYYGyrvTw==", + "optional": true + }, + "@next/swc-freebsd-x64": { + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/@next/swc-freebsd-x64/-/swc-freebsd-x64-12.2.0.tgz", + "integrity": "sha512-gRiAw8g3Akf6niTDLEm1Emfa7jXDjvaAj/crDO8hKASKA4Y1fS4kbi/tyWw5VtoFI4mUzRmCPmZ8eL0tBSG58A==", + "optional": true } } } \ No newline at end of file diff --git a/src/components/Card/Card.module.scss b/src/components/Card/Card.module.scss index bcffaa15e..5892a59d9 100644 --- a/src/components/Card/Card.module.scss +++ b/src/components/Card/Card.module.scss @@ -130,6 +130,14 @@ z-index: 1; } +.sold { + font-size: 12px; + color: var(--color-dark-green); + font-weight: bold; + + margin-bottom: 2px; +} + @media (max-width: $breakpoint-sm) { .content { padding: 5px; diff --git a/src/components/Card/ObjktCard.tsx b/src/components/Card/ObjktCard.tsx index b2791076e..2937fdb7d 100644 --- a/src/components/Card/ObjktCard.tsx +++ b/src/components/Card/ObjktCard.tsx @@ -11,24 +11,31 @@ import { Spacing } from "../Layout/Spacing" import { Objkt } from "../../types/entities/Objkt" import { getObjktUrl } from "../../utils/objkt" import { GenTokFlag } from "../../types/entities/GenerativeToken" -import { useContext } from "react" +import React, { useContext, useMemo } from "react" import { SettingsContext } from "../../context/Theme" import { DisplayTezos } from "../Display/DisplayTezos" import { EntityBadge } from "../User/EntityBadge" +import { format } from "date-fns" interface Props { objkt: Objkt showOwner?: boolean showRarity?: boolean + sold?: { + date: Date + price: number + } } export function ObjktCard({ objkt, + sold, showOwner = true, showRarity = false, }: Props) { const url = getObjktUrl(objkt) const settings = useContext(SettingsContext) + const soldDate = useMemo(() => sold?.date && new Date(sold.date), [sold]) return ( @@ -45,6 +52,14 @@ export function ObjktCard({ [WARNING: DUPLICATE] )} + {soldDate && ( +
+ Sold + +
+ )}
{objkt.name}
{showOwner && ( <> @@ -67,12 +82,13 @@ export function ObjktCard({
- {objkt.activeListing && ( + {objkt.activeListing && !sold && ( )} + {sold && }
{objkt.issuer && ( diff --git a/src/components/Gallery/GalleryMarketplace.tsx b/src/components/Gallery/GalleryMarketplace.tsx index 1eb4688b4..2716ed0f1 100644 --- a/src/components/Gallery/GalleryMarketplace.tsx +++ b/src/components/Gallery/GalleryMarketplace.tsx @@ -13,6 +13,7 @@ import { SortAndFilters } from "../SortAndFilters/SortAndFilters" import { getTagsFromFiltersObject } from "../../utils/filters" import { ExploreTagDef } from "../Exploration/ExploreTags" import { MarketplaceFilters } from "../../containers/Marketplace/MarketplaceFilters" +import { IOptions } from "../Input/Select" const ITEMS_PER_PAGE = 40 @@ -20,18 +21,22 @@ interface Props { initialSearchQuery?: string initialSort?: string initialFilters?: ListingFilters + defaultFilters?: ListingFilters onChangeSearch?: (value: string) => void onChangeFilters?: (updatedFilters: ListingFilters) => void onChangeSort?: (updatedSort: string) => void + defaultSortOptions?: IOptions[] } export const GalleryMarketplace = ({ initialSearchQuery, initialSort, initialFilters, + defaultFilters, onChangeSearch, onChangeFilters, onChangeSort, + defaultSortOptions = sortOptionsMarketplace, }: Props) => { const [hasNothingToFetch, setHasNothingToFetch] = useState(false) const { @@ -41,7 +46,7 @@ export const GalleryMarketplace = ({ restoreSort, setSearchSortOptions, sortOptions, - } = useSort(sortOptionsMarketplace, { + } = useSort(defaultSortOptions, { defaultSort: initialSort, defaultWithSearchOptions: initialFilters && !!initialFilters["searchQuery_eq"], @@ -64,6 +69,7 @@ export const GalleryMarketplace = ({ onChangeFilters?.(updatedFilters) }, initialFilters, + defaultFilters, }) // reference to an element at the top to scroll back @@ -161,7 +167,6 @@ export const GalleryMarketplace = ({ options: sortOptions, onChange: handleChangeSort, } - return (
{listings && listings.length > 0 && - listings.map((offer) => ( - - ))} + listings.map((offer) => { + const sold = offer.acceptedAt + ? { date: offer.acceptedAt, price: offer.price } + : undefined + return ( + + ) + })} {loading && CardsLoading({ number: ITEMS_PER_PAGE, diff --git a/src/containers/Marketplace.tsx b/src/containers/Marketplace.tsx index 08ac3ed10..92e93c68a 100644 --- a/src/containers/Marketplace.tsx +++ b/src/containers/Marketplace.tsx @@ -1,122 +1,34 @@ import { ListingFilters } from "../types/entities/Listing" import { useRouter } from "next/router" import { + getSortFromUrlQuery, getSortOptionsWithSearchOption, sortOptionsMarketplace, } from "../utils/sort" import { GalleryMarketplace } from "../components/Gallery/GalleryMarketplace" import { useEffect, useState } from "react" import { buildUrlFromQuery } from "../utils/url" - -interface Props { - urlQuery: Record -} - -// a map of (listing filter) => transformer -// to turn the query parameters into gql-ready variables -type TQueryFilterHandler = { - param: string - transform: (param?: string) => any | undefined - encode: (value?: any) => string | undefined -} -const queryListingFilterHandlers: Record< - keyof ListingFilters, - TQueryFilterHandler -> = { - price_lte: { - param: "price_lte", - transform: (param) => param || undefined, - encode: (value) => (value ? encodeURIComponent(value) : undefined), - }, - price_gte: { - param: "price_gte", - transform: (param) => param || undefined, - encode: (value) => (value ? encodeURIComponent(value) : undefined), - }, - fullyMinted_eq: { - param: "fullMint", - transform: (param) => (param ? param === "1" : undefined), - encode: (value) => - value !== undefined ? encodeURIComponent(value ? "1" : "0") : undefined, - }, - authorVerified_eq: { - param: "verified", - transform: (param) => (param ? param === "1" : undefined), - encode: (value) => - value !== undefined ? encodeURIComponent(value ? "1" : "0") : undefined, - }, - searchQuery_eq: { - param: "search", - transform: (param) => param || undefined, - encode: (value) => value || undefined, - }, - tokenSupply_lte: { - param: "supply_lte", - transform: (param) => (param ? parseInt(param) : undefined), - encode: (value) => (value ? encodeURIComponent(value) : undefined), - }, - tokenSupply_gte: { - param: "supply_gte", - transform: (param) => (param ? parseInt(param) : undefined), - encode: (value) => (value ? encodeURIComponent(value) : undefined), - }, -} - -/** - * Given a record of query parameters, outputs some Listing filters - */ -const getFiltersFromUrlQuery = (urlQuery: Record) => { - const loadedFilters: ListingFilters = {} - // go through each prop of the handler and eventually transform query param - for (const K in queryListingFilterHandlers) { - const F = K as keyof ListingFilters - const handler = queryListingFilterHandlers[F] - if (urlQuery[handler.param]) { - loadedFilters[F] = queryListingFilterHandlers[F].transform( - urlQuery[handler.param] - ) - } - } - return loadedFilters -} +import { + getFiltersFromUrlQuery, + getUrlQueryFromFilters, +} from "../utils/filters" const searchSortOptions = getSortOptionsWithSearchOption(sortOptionsMarketplace) -const getSortFromUrlQuery = (urlQuery: Record) => { - const { search, sort } = urlQuery - - // if there is a sort value in the url, pre-select it in the sort input - // else, select the default value - let defaultSortValue = search ? "relevance-desc" : "createdAt-desc" - if (sort) { - let sortValues = search ? searchSortOptions : sortOptionsMarketplace - return sortValues.map(({ value }) => value).includes(sort) - ? sort - : defaultSortValue - } - return defaultSortValue +interface Props { + urlQuery: Record } - export const Marketplace = ({ urlQuery }: Props) => { const [filters, setFilters] = useState( - getFiltersFromUrlQuery(urlQuery) + getFiltersFromUrlQuery(urlQuery) + ) + const [sort, setSort] = useState( + getSortFromUrlQuery(urlQuery, searchSortOptions, sortOptionsMarketplace) ) - const [sort, setSort] = useState(getSortFromUrlQuery(urlQuery)) const router = useRouter() useEffect(() => { - const query: any = {} - - // go through each prop of the handler and eventually encode query param - for (const K in queryListingFilterHandlers) { - const F = K as keyof ListingFilters - const handler = queryListingFilterHandlers[F] - const encoded = handler.encode(filters[F]) - if (encoded) { - query[handler.param] = encoded - } - } - + const query = getUrlQueryFromFilters(filters) query.sort = encodeURIComponent(sort) router.push( diff --git a/src/containers/Marketplace/MarketplaceSold.tsx b/src/containers/Marketplace/MarketplaceSold.tsx new file mode 100644 index 000000000..cb3efe022 --- /dev/null +++ b/src/containers/Marketplace/MarketplaceSold.tsx @@ -0,0 +1,55 @@ +import { ListingFilters } from "../../types/entities/Listing" +import { useRouter } from "next/router" +import { + getSortFromUrlQuery, + getSortOptionsWithSearchOption, + sortOptionsMarketplaceSold, +} from "../../utils/sort" +import { GalleryMarketplace } from "../../components/Gallery/GalleryMarketplace" +import { useEffect, useState } from "react" +import { buildUrlFromQuery } from "../../utils/url" +import { + getFiltersFromUrlQuery, + getUrlQueryFromFilters, +} from "../../utils/filters" + +const searchSortOptions = getSortOptionsWithSearchOption( + sortOptionsMarketplaceSold +) +const defaultFilters = { acceptedAt_exist: true } + +interface Props { + urlQuery: Record +} +export const MarketplaceSold = ({ urlQuery }: Props) => { + const [filters, setFilters] = useState( + getFiltersFromUrlQuery(urlQuery) + ) + const [sort, setSort] = useState( + getSortFromUrlQuery(urlQuery, searchSortOptions, sortOptionsMarketplaceSold) + ) + const router = useRouter() + + useEffect(() => { + const query = getUrlQueryFromFilters(filters) + query.sort = encodeURIComponent(sort) + + router.push( + { pathname: router.pathname, query }, + buildUrlFromQuery(router.pathname, query), + { shallow: true } + ) + }, [filters, sort]) + + return ( + + ) +} diff --git a/src/containers/Marketplace/Tabs.tsx b/src/containers/Marketplace/Tabs.tsx index b6c5f509b..9f8664228 100644 --- a/src/containers/Marketplace/Tabs.tsx +++ b/src/containers/Marketplace/Tabs.tsx @@ -1,11 +1,30 @@ import style from "./MarketplaceTabs.module.scss" import { PropsWithChildren } from "react" import Link from "next/link" -import { TabDefinition, Tabs } from "../../components/Layout/Tabs" +import { + checkIsTabKeyActive, + TabDefinition, + Tabs, +} from "../../components/Layout/Tabs" const definition: TabDefinition[] = [ - { name: "listed", props: { href: "/marketplace" } }, - { name: "collections", props: { href: "/marketplace/collections" } }, + { + key: "listed", + name: "listed", + props: { + href: "/marketplace", + }, + }, + { + key: "sold", + name: "sold", + props: { href: "/marketplace/sold" }, + }, + { + key: "collections", + name: "collections", + props: { href: "/marketplace/collections" }, + }, ] interface TabProps { @@ -25,14 +44,15 @@ export function MarketplaceTab({ } interface Props { - active: number + activeKey: "listed" | "sold" | "collections" } -export function MarketplaceTabs({ active }: Props) { +export function MarketplaceTabs({ activeKey }: Props) { return ( diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index aa2239023..498a6d144 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -21,6 +21,7 @@ const ROUTES_TO_RETAIN = [ "/explore/incoming", "/explore/articles", "/marketplace", + "/marketplace/sold", "/marketplace/collections", ] diff --git a/src/pages/marketplace.tsx b/src/pages/marketplace.tsx index b07a952b0..ca8b7b0a8 100644 --- a/src/pages/marketplace.tsx +++ b/src/pages/marketplace.tsx @@ -1,6 +1,6 @@ import type { NextPage } from "next" import { Spacing } from "../components/Layout/Spacing" -import ClientOnly, { ClientOnlyEmpty } from "../components/Utils/ClientOnly" +import { ClientOnlyEmpty } from "../components/Utils/ClientOnly" import { Marketplace } from "../containers/Marketplace" import Head from "next/head" import { MarketplaceTabs } from "../containers/Marketplace/Tabs" @@ -44,7 +44,7 @@ const MarketplacePage: NextPage = ({ query }: any) => {
- + diff --git a/src/pages/marketplace/collections.tsx b/src/pages/marketplace/collections.tsx index b83882a4a..93d14403f 100644 --- a/src/pages/marketplace/collections.tsx +++ b/src/pages/marketplace/collections.tsx @@ -1,11 +1,8 @@ import type { NextPage } from "next" -import layout from "../../styles/Layout.module.scss" -import cs from "classnames" import { Spacing } from "../../components/Layout/Spacing" import { SectionHeader } from "../../components/Layout/SectionHeader" import { ClientOnlyEmpty } from "../../components/Utils/ClientOnly" import Head from "next/head" -import { TitleHyphen } from "../../components/Layout/TitleHyphen" import { MarketplaceTabs } from "../../containers/Marketplace/Tabs" import { MarketplaceCollections } from "../../containers/Marketplace/Collections" import { SectionTitle } from "../../components/Layout/SectionTitle" @@ -47,7 +44,7 @@ const MarketplaceCollectionPage: NextPage = () => { - +
diff --git a/src/pages/marketplace/sold.tsx b/src/pages/marketplace/sold.tsx new file mode 100644 index 000000000..9c32af080 --- /dev/null +++ b/src/pages/marketplace/sold.tsx @@ -0,0 +1,65 @@ +import type { NextPage } from "next" +import { Spacing } from "../../components/Layout/Spacing" +import { ClientOnlyEmpty } from "../../components/Utils/ClientOnly" +import { Marketplace } from "../../containers/Marketplace" +import Head from "next/head" +import { MarketplaceTabs } from "../../containers/Marketplace/Tabs" +import { SectionHeader } from "../../components/Layout/SectionHeader"; +import { SectionTitle } from "../../components/Layout/SectionTitle"; +import { MarketplaceSold } from "../../containers/Marketplace/MarketplaceSold"; + +const MarketplacePage: NextPage = ({ query }: any) => { + return ( + <> + + fxhash — marketplace sold listings + + + + + + + + +
+ + marketplace / sold + + + +
+ + + +
+
+ + + + + + ) +} + +// get url parameters +MarketplacePage.getInitialProps = async ({ query }) => { + return { query } +} + +export default MarketplacePage diff --git a/src/queries/fragments/listing.ts b/src/queries/fragments/listing.ts index a18eec555..e9b992dec 100644 --- a/src/queries/fragments/listing.ts +++ b/src/queries/fragments/listing.ts @@ -23,6 +23,7 @@ export const Frag_ListingCardInfos = gql` id version price + acceptedAt objkt { id version diff --git a/src/styles/globals.scss b/src/styles/globals.scss index b68876132..6c1d5ab4f 100644 --- a/src/styles/globals.scss +++ b/src/styles/globals.scss @@ -33,6 +33,7 @@ body { --color-border: #000000; --color-border-input: #000000; --color-donator: #3496eb; + --color-dark-green: #008057; --layout-margin-big-lg: 80px; --layout-margin-small-lg: 30px; diff --git a/src/types/entities/Listing.ts b/src/types/entities/Listing.ts index 54cd2511a..5bab4991d 100644 --- a/src/types/entities/Listing.ts +++ b/src/types/entities/Listing.ts @@ -14,9 +14,11 @@ export interface Listing { createdAt: Date updatedAt: Date article: NFTArticle + acceptedAt: Date } export interface ListingFilters { + acceptedAt_exist?: boolean price_gte?: string price_lte?: string fullyMinted_eq?: boolean diff --git a/src/utils/filters.ts b/src/utils/filters.ts index f436cc096..f40c67392 100644 --- a/src/utils/filters.ts +++ b/src/utils/filters.ts @@ -1,33 +1,114 @@ import { displayMutez } from "./units" +type Transform = (param?: string) => any | undefined +type Encode = (value?: any) => string | undefined + +const transformDefault: Transform = (param) => param || undefined +const transformAsBoolean: Transform = (param) => + param ? param === "1" : undefined +const transformAsInt: Transform = (param) => + param ? parseInt(param) : undefined + +const encodeDefault: Encode = (value: string | number | boolean) => + value ? encodeURIComponent(value) : undefined +const encodeAsBoolean: Encode = (value) => + value !== undefined ? encodeURIComponent(value ? "1" : "0") : undefined + +interface Filter { + urlParam: string + transform: Transform + encode: Encode + getLabel: (value: Type) => string +} + +type FilterKey = + | "price_gte" + | "price_lte" + | "supply_gte" + | "supply_lte" + | "tokenSupply_gte" + | "tokenSupply_lte" + | "authorVerified_eq" + | "mintProgress_eq" + | "fullyMinted_eq" + | "searchQuery_eq" + | "activeListing_exist" + export interface ITagsFilters { - price_gte: (value: number) => string - price_lte: (value: number) => string supply_gte: (value: number) => string supply_lte: (value: number) => string - tokenSupply_gte: (value: number) => string - tokenSupply_lte: (value: number) => string - authorVerified_eq: (value: boolean) => string mintProgress_eq: (value: string) => string - fullyMinted_eq: (isFullyMinted: boolean) => string - searchQuery_eq: (value: string) => string activeListing_exist: (value: boolean) => string } -export const tagsFilters: ITagsFilters = { - price_gte: (value) => `price >= ${displayMutez(value)} tez`, - price_lte: (value) => `price <= ${displayMutez(value)} tez`, - supply_gte: (value) => `editions >= ${value}`, - supply_lte: (value) => `editions <= ${value}`, - tokenSupply_gte: (value) => `editions >= ${value}`, - tokenSupply_lte: (value) => `editions <= ${value}`, - authorVerified_eq: (value) => `artist: ${value ? "verified" : "un-verified"}`, - mintProgress_eq: (value) => `mint progress: ${value?.toLowerCase()}`, - fullyMinted_eq: (isFullyMinted) => - `mint: ${isFullyMinted ? "completed" : "on-going"}`, - searchQuery_eq: (value) => `search: ${value}`, - activeListing_exist: (value) => - `listings: ${value ? "for sale" : "not for sale"}`, +export const tagsFilters: Record> = { + price_gte: { + urlParam: "price_gte", + transform: transformDefault, + encode: encodeDefault, + getLabel: (value) => `price >= ${displayMutez(value)} tez`, + }, + price_lte: { + urlParam: "price_lte", + transform: transformDefault, + encode: encodeDefault, + getLabel: (value) => `price <= ${displayMutez(value)} tez`, + }, + supply_gte: { + urlParam: "editions_gte", + transform: transformAsInt, + encode: encodeDefault, + getLabel: (value) => `editions >= ${value}`, + }, + supply_lte: { + urlParam: "editions_lte", + transform: transformAsInt, + encode: encodeDefault, + getLabel: (value) => `editions <= ${value}`, + }, + tokenSupply_gte: { + urlParam: "supply_gte", + transform: transformAsInt, + encode: encodeDefault, + getLabel: (value) => `editions >= ${value}`, + }, + tokenSupply_lte: { + urlParam: "supply_lte", + transform: transformAsInt, + encode: encodeDefault, + getLabel: (value) => `editions <= ${value}`, + }, + authorVerified_eq: { + urlParam: "verified", + transform: transformAsBoolean, + encode: encodeAsBoolean, + getLabel: (value) => `artist: ${value ? "verified" : "un-verified"}`, + }, + mintProgress_eq: { + urlParam: "progress", + transform: transformDefault, + encode: encodeDefault, + getLabel: (value) => `mint progress: ${value?.toLowerCase()}`, + }, + fullyMinted_eq: { + urlParam: "fullMint", + transform: transformAsBoolean, + encode: encodeAsBoolean, + getLabel: (isFullyMinted) => + `mint: ${isFullyMinted ? "completed" : "on-going"}`, + }, + searchQuery_eq: { + urlParam: "search", + transform: transformDefault, + encode: encodeDefault, + getLabel: (value) => `search: ${value}`, + }, + activeListing_exist: { + urlParam: "hasActiveListing", + transform: transformAsBoolean, + encode: encodeAsBoolean, + getLabel: (value) => `listings: ${value ? "for sale" : "not for sale"}`, + }, } interface TagOption { @@ -41,7 +122,7 @@ export const getTagsFromFiltersObject = ( ): TTag[] => { return Object.entries(filtersObj).reduce((acc, [key, value]) => { const getTag: (value: any) => string = - tagsFilters[key as keyof ITagsFilters] + tagsFilters[key as keyof ITagsFilters]?.getLabel if (value !== undefined && getTag) { const tagLabel = getTag(value) acc.push( @@ -55,3 +136,36 @@ export const getTagsFromFiltersObject = ( return acc }, [] as TTag[]) } + +/** + * Given a record of query parameters, outputs some Listing filters + */ +export const getFiltersFromUrlQuery = ( + urlQuery: Record +) => { + const loadedFilters = {} as Filters + // go through each prop of the handler and eventually transform query param + for (const K in tagsFilters) { + const F = K as keyof Filters + const handler = tagsFilters[F as FilterKey] + if (urlQuery[handler.urlParam]) { + loadedFilters[F] = handler.transform(urlQuery[handler.urlParam]) + } + } + return loadedFilters +} + +export const getUrlQueryFromFilters = (filters: Filters) => { + const query: any = {} + + // go through each prop of the handler and eventually encode query param + for (const K in tagsFilters) { + const F = K as keyof Filters + const handler = tagsFilters[F as FilterKey] + const encoded = handler.encode(filters[F]) + if (encoded) { + query[handler.urlParam] = encoded + } + } + return query +} diff --git a/src/utils/sort.ts b/src/utils/sort.ts index fff0db3c4..fb54b9398 100644 --- a/src/utils/sort.ts +++ b/src/utils/sort.ts @@ -16,6 +16,24 @@ const sortOptionWithCustomLabel = ( label: newLabel, } } +export const getSortFromUrlQuery = ( + urlQuery: Record, + searchSortOptions: IOptions[], + defaultSortOptions: IOptions[] +) => { + const { search, sort } = urlQuery + + // if there is a sort value in the url, pre-select it in the sort input + // else, select the default value + let defaultSortValue = search ? "relevance-desc" : "createdAt-desc" + if (sort) { + let sortValues = search ? searchSortOptions : defaultSortOptions + return sortValues.map(({ value }) => value).includes(sort) + ? sort + : defaultSortValue + } + return defaultSortValue +} export const getSortOptionsWithSearchOption = ( currentSortOptions: IOptions[] @@ -115,6 +133,12 @@ export const sortOptionsMarketplace: IOptions[] = [ sortOptionWithCustomLabel(sortOptions["createdAt-asc"], "oldest listed"), ] +export const sortOptionsMarketplaceSold: IOptions[] = [ + // acceptedAt + sortOptions["price-desc"], + sortOptions["price-asc"], +] + export const sortOptionsUsers: IOptions[] = [ sortOptionWithCustomLabel( sortOptions["createdAt-desc"], From 4533efb5d5abe86077de33fdb0108f26f056d113 Mon Sep 17 00:00:00 2001 From: Geoffrey MERRAN Date: Wed, 4 Jan 2023 19:59:46 +0100 Subject: [PATCH 2/2] run lint:fix --- src/pages/marketplace/sold.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/marketplace/sold.tsx b/src/pages/marketplace/sold.tsx index 9c32af080..aac26596b 100644 --- a/src/pages/marketplace/sold.tsx +++ b/src/pages/marketplace/sold.tsx @@ -4,9 +4,9 @@ import { ClientOnlyEmpty } from "../../components/Utils/ClientOnly" import { Marketplace } from "../../containers/Marketplace" import Head from "next/head" import { MarketplaceTabs } from "../../containers/Marketplace/Tabs" -import { SectionHeader } from "../../components/Layout/SectionHeader"; -import { SectionTitle } from "../../components/Layout/SectionTitle"; -import { MarketplaceSold } from "../../containers/Marketplace/MarketplaceSold"; +import { SectionHeader } from "../../components/Layout/SectionHeader" +import { SectionTitle } from "../../components/Layout/SectionTitle" +import { MarketplaceSold } from "../../containers/Marketplace/MarketplaceSold" const MarketplacePage: NextPage = ({ query }: any) => { return (