From 105f40b2b52f051ae7026a91412cc5d852423382 Mon Sep 17 00:00:00 2001 From: jahooma Date: Sun, 2 Jan 2022 16:43:38 -0600 Subject: [PATCH] Search and query url params! --- web/components/contracts-list.tsx | 45 +++++++++++-------------- web/hooks/use-sort-and-query-params.tsx | 40 ++++++++++++++++++++++ web/pages/landing-page.tsx | 10 +++++- web/pages/markets.tsx | 29 +++------------- web/pages/tag/[tag].tsx | 13 ++++++- 5 files changed, 86 insertions(+), 51 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 1af18641..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,22 +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[] - sort?: Sort + query: string + setQuery: (query: string) => void + sort: Sort setSort: (sort: Sort) => void byOneCreator?: boolean }) { - const { contracts, sort, setSort, byOneCreator } = props - const [query, setQuery] = useState('') - // const [sort, setSort] = useState( - // defaultSort || (byOneCreator ? 'pool' : 'creator') - // ) - - // useEffect(() => { - // if (defaultSort) setSort(defaultSort) - // }, [defaultSort]) + const { contracts, query, setQuery, sort, setSort, byOneCreator } = props function check(corpus: String) { return corpus.toLowerCase().includes(query.toLowerCase()) @@ -180,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) } @@ -218,8 +207,8 @@ export function SearchableGrid(props: { )} - - + + @@ -239,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 @@ -252,8 +245,10 @@ export function CreatorContractsList(props: { creator: User }) { {}} + query={query} + setQuery={setQuery} + sort={sort} + setSort={setSort} /> ) } 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 025e22b8..96f3c7a4 100644 --- a/web/pages/markets.tsx +++ b/web/pages/markets.tsx @@ -1,7 +1,7 @@ -import { useRouter } from 'next/router' 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() { @@ -18,34 +18,15 @@ export async function getStaticProps() { export default function Markets(props: { contracts: Contract[] }) { const contracts = useContracts() - - const router = useRouter() - const { tag, creator, newest, mostTraded } = router.query as { - tag?: string - creator?: string - newest?: string - mostTraded?: string - } - const sort = - tag === '' - ? 'tag' - : creator === '' - ? 'creator' - : newest === '' - ? 'createdTime' - : mostTraded === '' - ? 'pool' - : undefined - - const setSort = () => { - router.push(router.pathname, '?tag') - } + const { query, setQuery, sort, setSort } = useQueryAndSortParams() return ( - {(props.contracts || contracts !== 'loading') && router.isReady && ( + {(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> )