From bad7a2b54331df91e40f4fafe4c9d711db7df843 Mon Sep 17 00:00:00 2001 From: James Grugett Date: Sun, 2 Jan 2022 16:46:04 -0600 Subject: [PATCH] Sort & query url params (#17) * Sort query in progress * Search and query url params! --- web/components/contracts-list.tsx | 47 ++++++++++++++----------- web/hooks/use-sort-and-query-params.tsx | 40 +++++++++++++++++++++ web/pages/landing-page.tsx | 10 +++++- web/pages/markets.tsx | 6 ++++ web/pages/tag/[tag].tsx | 13 ++++++- 5 files changed, 94 insertions(+), 22 deletions(-) create mode 100644 web/hooks/use-sort-and-query-params.tsx diff --git a/web/components/contracts-list.tsx b/web/components/contracts-list.tsx index 715a7ffe..69908523 100644 --- a/web/components/contracts-list.tsx +++ b/web/components/contracts-list.tsx @@ -3,17 +3,13 @@ import Link from 'next/link' import clsx from 'clsx' import { useEffect, useState } from 'react' -import { - compute, - Contract, - listContracts, - path, -} from '../lib/firebase/contracts' +import { compute, Contract, listContracts } from '../lib/firebase/contracts' import { User } from '../lib/firebase/users' import { Col } from './layout/col' import { SiteLink } from './site-link' import { parseTags } from '../lib/util/parse' import { ContractCard } from './contract-card' +import { Sort, useQueryAndSortParams } from '../hooks/use-sort-and-query-params' function ContractsGrid(props: { contracts: Contract[] }) { const [resolvedContracts, activeContracts] = _.partition( @@ -61,7 +57,7 @@ function CreatorContractsGrid(props: { contracts: Contract[] }) { const { creatorUsername, creatorName } = byCreator[creatorId][0] return ( - + {creatorName} @@ -116,7 +112,7 @@ function TagContractsGrid(props: { contracts: Contract[] }) { {tags.map((tag) => { return ( - + #{tag} @@ -152,17 +148,15 @@ function TagContractsGrid(props: { contracts: Contract[] }) { const MAX_CONTRACTS_DISPLAYED = 99 -type Sort = 'creator' | 'tag' | 'createdTime' | 'pool' | 'resolved' | 'all' export function SearchableGrid(props: { contracts: Contract[] - defaultSort?: Sort + query: string + setQuery: (query: string) => void + sort: Sort + setSort: (sort: Sort) => void byOneCreator?: boolean }) { - const { contracts, defaultSort, byOneCreator } = props - const [query, setQuery] = useState('') - const [sort, setSort] = useState( - defaultSort || (byOneCreator ? 'pool' : 'creator') - ) + const { contracts, query, setQuery, sort, setSort, byOneCreator } = props function check(corpus: String) { return corpus.toLowerCase().includes(query.toLowerCase()) @@ -175,9 +169,9 @@ export function SearchableGrid(props: { check(c.creatorUsername) ) - if (sort === 'createdTime' || sort === 'resolved' || sort === 'all') { + if (sort === 'newest' || sort === 'resolved' || sort === 'all') { matches.sort((a, b) => b.createdTime - a.createdTime) - } else if (sort === 'pool' || sort === 'creator' || sort === 'tag') { + } else if (sort === 'most-traded' || sort === 'creator' || sort === 'tag') { matches.sort((a, b) => compute(b).truePool - compute(a).truePool) } @@ -213,8 +207,8 @@ export function SearchableGrid(props: { )} - - + + @@ -234,6 +228,10 @@ export function CreatorContractsList(props: { creator: User }) { const { creator } = props const [contracts, setContracts] = useState('loading') + const { query, setQuery, sort, setSort } = useQueryAndSortParams({ + defaultSort: 'all', + }) + useEffect(() => { if (creator?.id) { // TODO: stream changes from firestore @@ -243,5 +241,14 @@ export function CreatorContractsList(props: { creator: User }) { if (contracts === 'loading') return <> - return + return ( + + ) } diff --git a/web/hooks/use-sort-and-query-params.tsx b/web/hooks/use-sort-and-query-params.tsx new file mode 100644 index 00000000..ee0db506 --- /dev/null +++ b/web/hooks/use-sort-and-query-params.tsx @@ -0,0 +1,40 @@ +import { useRouter } from 'next/router' + +export type Sort = + | 'creator' + | 'tag' + | 'newest' + | 'most-traded' + | 'resolved' + | 'all' + +export function useQueryAndSortParams(options?: { defaultSort: Sort }) { + const router = useRouter() + + const { s: sort, q: query } = router.query as { + q?: string + s?: Sort + } + + const setSort = (sort: Sort | undefined) => { + router.query.s = sort + router.push(router, undefined, { shallow: true }) + } + + const setQuery = (query: string | undefined) => { + if (query) { + router.query.q = query + } else { + delete router.query.q + } + + router.push(router, undefined, { shallow: true }) + } + + return { + sort: sort ?? options?.defaultSort ?? 'creator', + query: query ?? '', + setSort, + setQuery, + } +} diff --git a/web/pages/landing-page.tsx b/web/pages/landing-page.tsx index f983a6ac..13d209b6 100644 --- a/web/pages/landing-page.tsx +++ b/web/pages/landing-page.tsx @@ -13,6 +13,7 @@ import { SearchableGrid } from '../components/contracts-list' import { Col } from '../components/layout/col' import { NavBar } from '../components/nav-bar' import Link from 'next/link' +import { useQueryAndSortParams } from '../hooks/use-sort-and-query-params' export default function LandingPage() { return ( @@ -159,13 +160,20 @@ function FeaturesSection() { function ExploreMarketsSection() { const contracts = useContracts() + const { query, setQuery, sort, setSort } = useQueryAndSortParams() return (

Explore our markets

- +
) } diff --git a/web/pages/markets.tsx b/web/pages/markets.tsx index f14a1906..96f3c7a4 100644 --- a/web/pages/markets.tsx +++ b/web/pages/markets.tsx @@ -1,6 +1,7 @@ import { SearchableGrid } from '../components/contracts-list' import { Page } from '../components/page' import { useContracts } from '../hooks/use-contracts' +import { useQueryAndSortParams } from '../hooks/use-sort-and-query-params' import { Contract, listAllContracts } from '../lib/firebase/contracts' export async function getStaticProps() { @@ -17,12 +18,17 @@ export async function getStaticProps() { export default function Markets(props: { contracts: Contract[] }) { const contracts = useContracts() + const { query, setQuery, sort, setSort } = useQueryAndSortParams() return ( {(props.contracts || contracts !== 'loading') && ( )} diff --git a/web/pages/tag/[tag].tsx b/web/pages/tag/[tag].tsx index 7f15748a..ae56f1c5 100644 --- a/web/pages/tag/[tag].tsx +++ b/web/pages/tag/[tag].tsx @@ -3,6 +3,7 @@ import { SearchableGrid } from '../../components/contracts-list' import { Page } from '../../components/page' import { Title } from '../../components/title' import { useContracts } from '../../hooks/use-contracts' +import { useQueryAndSortParams } from '../../hooks/use-sort-and-query-params' export default function TagPage() { const router = useRouter() @@ -18,13 +19,23 @@ export default function TagPage() { ) } + const { query, setQuery, sort, setSort } = useQueryAndSortParams({ + defaultSort: 'most-traded', + }) + return ( {contracts === 'loading' ? ( <></> ) : ( - <SearchableGrid contracts={contracts} /> + <SearchableGrid + contracts={contracts} + query={query} + setQuery={setQuery} + sort={sort} + setSort={setSort} + /> )} </Page> )