Search perserved by url
This commit is contained in:
parent
657d67c503
commit
3c2434a706
|
@ -14,12 +14,10 @@ import { useEffect, useLayoutEffect, useRef, useMemo, ReactNode } from 'react'
|
||||||
import { ENV, IS_PRIVATE_MANIFOLD } from 'common/envs/constants'
|
import { ENV, IS_PRIVATE_MANIFOLD } from 'common/envs/constants'
|
||||||
import { useFollows } from 'web/hooks/use-follows'
|
import { useFollows } from 'web/hooks/use-follows'
|
||||||
import {
|
import {
|
||||||
storageStore,
|
|
||||||
historyStore,
|
historyStore,
|
||||||
urlParamStore,
|
urlParamStore,
|
||||||
usePersistentState,
|
usePersistentState,
|
||||||
} from 'web/hooks/use-persistent-state'
|
} from 'web/hooks/use-persistent-state'
|
||||||
import { safeLocalStorage } from 'web/lib/util/local'
|
|
||||||
import { track, trackCallback } from 'web/lib/service/analytics'
|
import { track, trackCallback } from 'web/lib/service/analytics'
|
||||||
import ContractSearchFirestore from 'web/pages/contract-search-firestore'
|
import ContractSearchFirestore from 'web/pages/contract-search-firestore'
|
||||||
import { useMemberGroups } from 'web/hooks/use-group'
|
import { useMemberGroups } from 'web/hooks/use-group'
|
||||||
|
@ -207,7 +205,6 @@ export function ContractSearch(props: {
|
||||||
defaultFilter={defaultFilter}
|
defaultFilter={defaultFilter}
|
||||||
additionalFilter={additionalFilter}
|
additionalFilter={additionalFilter}
|
||||||
hideOrderSelector={hideOrderSelector}
|
hideOrderSelector={hideOrderSelector}
|
||||||
persistPrefix={persistPrefix ? `${persistPrefix}-controls` : undefined}
|
|
||||||
useQueryUrlParam={useQueryUrlParam}
|
useQueryUrlParam={useQueryUrlParam}
|
||||||
user={user}
|
user={user}
|
||||||
onSearchParametersChanged={onSearchParametersChanged}
|
onSearchParametersChanged={onSearchParametersChanged}
|
||||||
|
@ -236,7 +233,6 @@ function ContractSearchControls(props: {
|
||||||
additionalFilter?: AdditionalFilter
|
additionalFilter?: AdditionalFilter
|
||||||
hideOrderSelector?: boolean
|
hideOrderSelector?: boolean
|
||||||
onSearchParametersChanged: (params: SearchParameters) => void
|
onSearchParametersChanged: (params: SearchParameters) => void
|
||||||
persistPrefix?: string
|
|
||||||
useQueryUrlParam?: boolean
|
useQueryUrlParam?: boolean
|
||||||
user?: User | null
|
user?: User | null
|
||||||
noControls?: boolean
|
noControls?: boolean
|
||||||
|
@ -248,7 +244,6 @@ function ContractSearchControls(props: {
|
||||||
additionalFilter,
|
additionalFilter,
|
||||||
hideOrderSelector,
|
hideOrderSelector,
|
||||||
onSearchParametersChanged,
|
onSearchParametersChanged,
|
||||||
persistPrefix,
|
|
||||||
useQueryUrlParam,
|
useQueryUrlParam,
|
||||||
user,
|
user,
|
||||||
noControls,
|
noControls,
|
||||||
|
@ -265,17 +260,31 @@ function ContractSearchControls(props: {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const [state, setState] = usePersistentState(
|
const [sort, setSort] = usePersistentState(
|
||||||
{
|
defaultSort ?? 'score',
|
||||||
sort: defaultSort ?? 'score',
|
!useQueryUrlParam
|
||||||
filter: defaultFilter ?? 'open',
|
|
||||||
pillFilter: null as string | null,
|
|
||||||
},
|
|
||||||
!persistPrefix
|
|
||||||
? undefined
|
? undefined
|
||||||
: {
|
: {
|
||||||
key: `${persistPrefix}-params`,
|
key: 's',
|
||||||
store: storageStore(safeLocalStorage()),
|
store: urlParamStore(router),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
const [filter, setFilter] = usePersistentState(
|
||||||
|
defaultFilter ?? 'open',
|
||||||
|
!useQueryUrlParam
|
||||||
|
? undefined
|
||||||
|
: {
|
||||||
|
key: 'f',
|
||||||
|
store: urlParamStore(router),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
const [pill, setPill] = usePersistentState(
|
||||||
|
'',
|
||||||
|
!useQueryUrlParam
|
||||||
|
? undefined
|
||||||
|
: {
|
||||||
|
key: 'p',
|
||||||
|
store: urlParamStore(router),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -329,31 +338,25 @@ function ContractSearchControls(props: {
|
||||||
...additionalFilters,
|
...additionalFilters,
|
||||||
additionalFilter ? '' : 'visibility:public',
|
additionalFilter ? '' : 'visibility:public',
|
||||||
|
|
||||||
state.filter === 'open' ? 'isResolved:false' : '',
|
filter === 'open' ? 'isResolved:false' : '',
|
||||||
state.filter === 'closed' ? 'isResolved:false' : '',
|
filter === 'closed' ? 'isResolved:false' : '',
|
||||||
state.filter === 'resolved' ? 'isResolved:true' : '',
|
filter === 'resolved' ? 'isResolved:true' : '',
|
||||||
|
|
||||||
state.pillFilter &&
|
pill && pill !== 'personal' && pill !== 'your-bets'
|
||||||
state.pillFilter !== 'personal' &&
|
? `groupLinks.slug:${pill}`
|
||||||
state.pillFilter !== 'your-bets'
|
|
||||||
? `groupLinks.slug:${state.pillFilter}`
|
|
||||||
: '',
|
: '',
|
||||||
...(state.pillFilter === 'personal' ? personalFilters : []),
|
...(pill === 'personal' ? personalFilters : []),
|
||||||
state.pillFilter === 'your-bets' && user
|
pill === 'your-bets' && user
|
||||||
? // Show contracts bet on by the user
|
? // Show contracts bet on by the user
|
||||||
`uniqueBettorIds:${user.id}`
|
`uniqueBettorIds:${user.id}`
|
||||||
: '',
|
: '',
|
||||||
].filter((f) => f)
|
].filter((f) => f)
|
||||||
|
|
||||||
const openClosedFilter =
|
const openClosedFilter =
|
||||||
state.filter === 'open'
|
filter === 'open' ? 'open' : filter === 'closed' ? 'closed' : undefined
|
||||||
? 'open'
|
|
||||||
: state.filter === 'closed'
|
|
||||||
? 'closed'
|
|
||||||
: undefined
|
|
||||||
|
|
||||||
const selectPill = (pill: string | null) => () => {
|
const selectPill = (pill: string | null) => () => {
|
||||||
setState({ ...state, pillFilter: pill })
|
setPill(pill ?? '')
|
||||||
track('select search category', { category: pill ?? 'all' })
|
track('select search category', { category: pill ?? 'all' })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,25 +365,25 @@ function ContractSearchControls(props: {
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectFilter = (newFilter: filter) => {
|
const selectFilter = (newFilter: filter) => {
|
||||||
if (newFilter === state.filter) return
|
if (newFilter === filter) return
|
||||||
setState({ ...state, filter: newFilter })
|
setFilter(newFilter)
|
||||||
track('select search filter', { filter: newFilter })
|
track('select search filter', { filter: newFilter })
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectSort = (newSort: Sort) => {
|
const selectSort = (newSort: Sort) => {
|
||||||
if (newSort === state.sort) return
|
if (newSort === sort) return
|
||||||
setState({ ...state, sort: newSort })
|
setSort(newSort)
|
||||||
track('select search sort', { sort: newSort })
|
track('select search sort', { sort: newSort })
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
onSearchParametersChanged({
|
onSearchParametersChanged({
|
||||||
query: query,
|
query: query,
|
||||||
sort: state.sort,
|
sort: sort as Sort,
|
||||||
openClosedFilter: openClosedFilter,
|
openClosedFilter: openClosedFilter,
|
||||||
facetFilters: facetFilters,
|
facetFilters: facetFilters,
|
||||||
})
|
})
|
||||||
}, [query, state.sort, openClosedFilter, JSON.stringify(facetFilters)])
|
}, [query, sort, openClosedFilter, JSON.stringify(facetFilters)])
|
||||||
|
|
||||||
if (noControls) {
|
if (noControls) {
|
||||||
return <></>
|
return <></>
|
||||||
|
@ -402,7 +405,7 @@ function ContractSearchControls(props: {
|
||||||
{!query && (
|
{!query && (
|
||||||
<select
|
<select
|
||||||
className="select select-bordered"
|
className="select select-bordered"
|
||||||
value={state.filter}
|
value={filter}
|
||||||
onChange={(e) => selectFilter(e.target.value as filter)}
|
onChange={(e) => selectFilter(e.target.value as filter)}
|
||||||
>
|
>
|
||||||
<option value="open">Open</option>
|
<option value="open">Open</option>
|
||||||
|
@ -414,7 +417,7 @@ function ContractSearchControls(props: {
|
||||||
{!hideOrderSelector && !query && (
|
{!hideOrderSelector && !query && (
|
||||||
<select
|
<select
|
||||||
className="select select-bordered"
|
className="select select-bordered"
|
||||||
value={state.sort}
|
value={sort}
|
||||||
onChange={(e) => selectSort(e.target.value as Sort)}
|
onChange={(e) => selectSort(e.target.value as Sort)}
|
||||||
>
|
>
|
||||||
{SORTS.map((option) => (
|
{SORTS.map((option) => (
|
||||||
|
@ -428,16 +431,12 @@ function ContractSearchControls(props: {
|
||||||
|
|
||||||
{!additionalFilter && !query && (
|
{!additionalFilter && !query && (
|
||||||
<Row className="scrollbar-hide items-start gap-2 overflow-x-auto">
|
<Row className="scrollbar-hide items-start gap-2 overflow-x-auto">
|
||||||
<PillButton
|
<PillButton key={'all'} selected={!pill} onSelect={selectPill(null)}>
|
||||||
key={'all'}
|
|
||||||
selected={state.pillFilter === undefined}
|
|
||||||
onSelect={selectPill(null)}
|
|
||||||
>
|
|
||||||
All
|
All
|
||||||
</PillButton>
|
</PillButton>
|
||||||
<PillButton
|
<PillButton
|
||||||
key={'personal'}
|
key={'personal'}
|
||||||
selected={state.pillFilter === 'personal'}
|
selected={pill === 'personal'}
|
||||||
onSelect={selectPill('personal')}
|
onSelect={selectPill('personal')}
|
||||||
>
|
>
|
||||||
{user ? 'For you' : 'Featured'}
|
{user ? 'For you' : 'Featured'}
|
||||||
|
@ -446,7 +445,7 @@ function ContractSearchControls(props: {
|
||||||
{user && (
|
{user && (
|
||||||
<PillButton
|
<PillButton
|
||||||
key={'your-bets'}
|
key={'your-bets'}
|
||||||
selected={state.pillFilter === 'your-bets'}
|
selected={pill === 'your-bets'}
|
||||||
onSelect={selectPill('your-bets')}
|
onSelect={selectPill('your-bets')}
|
||||||
>
|
>
|
||||||
Your trades
|
Your trades
|
||||||
|
@ -457,7 +456,7 @@ function ContractSearchControls(props: {
|
||||||
return (
|
return (
|
||||||
<PillButton
|
<PillButton
|
||||||
key={slug}
|
key={slug}
|
||||||
selected={state.pillFilter === slug}
|
selected={pill === slug}
|
||||||
onSelect={selectPill(slug)}
|
onSelect={selectPill(slug)}
|
||||||
>
|
>
|
||||||
{name}
|
{name}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user