2023-07-24 18:35:05 +00:00
|
|
|
import Container from 'react-bootstrap/Container'
|
2022-01-26 21:43:18 +00:00
|
|
|
import styles from './search.module.css'
|
2022-09-22 15:26:02 +00:00
|
|
|
import SearchIcon from '../svgs/search-line.svg'
|
2023-09-11 23:11:47 +00:00
|
|
|
import { useEffect, useRef, useState } from 'react'
|
2023-10-04 19:44:06 +00:00
|
|
|
import { Form, Input, Select, DatePicker, SubmitButton } from './form'
|
2022-01-27 19:18:48 +00:00
|
|
|
import { useRouter } from 'next/router'
|
2022-01-26 21:43:18 +00:00
|
|
|
|
2022-02-17 17:23:43 +00:00
|
|
|
export default function Search ({ sub }) {
|
2022-01-27 19:18:48 +00:00
|
|
|
const router = useRouter()
|
2022-10-20 22:44:44 +00:00
|
|
|
const [q, setQ] = useState(router.query.q || '')
|
2023-09-11 23:11:47 +00:00
|
|
|
const inputRef = useRef(null)
|
2022-01-27 19:18:48 +00:00
|
|
|
|
|
|
|
useEffect(() => {
|
2023-09-11 23:11:47 +00:00
|
|
|
inputRef.current?.focus()
|
2022-01-27 19:18:48 +00:00
|
|
|
}, [])
|
|
|
|
|
2022-10-20 22:44:44 +00:00
|
|
|
const search = async values => {
|
|
|
|
let prefix = ''
|
|
|
|
if (sub) {
|
|
|
|
prefix = `/~${sub}`
|
|
|
|
}
|
2022-10-25 17:13:06 +00:00
|
|
|
|
2022-10-20 22:44:44 +00:00
|
|
|
if (values.q?.trim() !== '') {
|
2023-07-09 17:37:12 +00:00
|
|
|
if (values.what === 'stackers') {
|
2022-10-25 17:13:06 +00:00
|
|
|
await router.push({
|
2023-07-09 17:37:12 +00:00
|
|
|
pathname: '/stackers/search',
|
|
|
|
query: { q, what: 'stackers' }
|
2023-07-23 15:08:43 +00:00
|
|
|
}, {
|
|
|
|
pathname: '/stackers/search',
|
|
|
|
query: { q }
|
2022-10-25 17:13:06 +00:00
|
|
|
})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-07-25 20:29:45 +00:00
|
|
|
if (values.what === '' || values.what === 'all') delete values.what
|
2023-09-11 23:11:47 +00:00
|
|
|
if (values.sort === '' || values.sort === 'zaprank') delete values.sort
|
2023-07-25 20:29:45 +00:00
|
|
|
if (values.when === '' || values.when === 'forever') delete values.when
|
2023-10-04 19:44:06 +00:00
|
|
|
if (values.when !== 'custom') { delete values.from; delete values.to }
|
2022-10-20 22:44:44 +00:00
|
|
|
await router.push({
|
|
|
|
pathname: prefix + '/search',
|
|
|
|
query: values
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-01 20:58:30 +00:00
|
|
|
const filter = sub !== 'jobs'
|
2023-07-25 20:29:45 +00:00
|
|
|
const what = router.pathname.startsWith('/stackers') ? 'stackers' : router.query.what || 'all'
|
2023-09-11 23:11:47 +00:00
|
|
|
const sort = router.query.sort || 'zaprank'
|
2023-07-25 20:29:45 +00:00
|
|
|
const when = router.query.when || 'forever'
|
2023-10-04 19:44:06 +00:00
|
|
|
const from = router.query.from || new Date().toISOString()
|
|
|
|
const to = router.query.to || new Date().toISOString()
|
|
|
|
|
|
|
|
const [datePicker, setDatePicker] = useState(when === 'custom')
|
|
|
|
// The following state is needed for the date picker (and driven by the date picker).
|
|
|
|
// Substituting router.query or formik values would cause network lag and/or timezone issues.
|
|
|
|
const [range, setRange] = useState({ start: new Date(from), end: new Date(to) })
|
2023-07-25 20:29:45 +00:00
|
|
|
|
2022-01-26 21:43:18 +00:00
|
|
|
return (
|
|
|
|
<>
|
2023-09-11 23:11:47 +00:00
|
|
|
<div className={styles.searchSection}>
|
2023-10-04 19:44:06 +00:00
|
|
|
<Container className={`px-md-0 ${styles.searchContainer}`}>
|
2023-09-11 23:11:47 +00:00
|
|
|
<Form
|
2023-10-04 19:44:06 +00:00
|
|
|
initial={{ q, what, sort, when, from, to }}
|
2023-09-11 23:11:47 +00:00
|
|
|
onSubmit={search}
|
|
|
|
>
|
|
|
|
<div className={`${styles.active} my-3`}>
|
|
|
|
<Input
|
|
|
|
name='q'
|
|
|
|
required
|
|
|
|
autoFocus
|
|
|
|
groupClassName='me-3 mb-0 flex-grow-1'
|
|
|
|
className='flex-grow-1'
|
|
|
|
clear
|
|
|
|
innerRef={inputRef}
|
|
|
|
overrideValue={q}
|
|
|
|
onChange={async (formik, e) => {
|
|
|
|
setQ(e.target.value?.trim())
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
<SubmitButton variant='primary' className={styles.search}>
|
|
|
|
<SearchIcon width={22} height={22} />
|
|
|
|
</SubmitButton>
|
|
|
|
</div>
|
|
|
|
{filter &&
|
2023-10-04 19:44:06 +00:00
|
|
|
<div className='text-muted fw-bold d-flex align-items-center flex-wrap pb-2'>
|
|
|
|
<div className='text-muted fw-bold d-flex align-items-center pb-2'>
|
|
|
|
<Select
|
|
|
|
groupClassName='me-2 mb-0'
|
|
|
|
onChange={(formik, e) => search({ ...formik?.values, what: e.target.value })}
|
|
|
|
name='what'
|
|
|
|
size='sm'
|
|
|
|
overrideValue={what}
|
|
|
|
items={['all', 'posts', 'comments', 'stackers']}
|
|
|
|
/>
|
|
|
|
{what !== 'stackers' &&
|
|
|
|
<>
|
|
|
|
by
|
|
|
|
<Select
|
|
|
|
groupClassName='mx-2 mb-0'
|
|
|
|
onChange={(formik, e) => search({ ...formik?.values, sort: e.target.value })}
|
|
|
|
name='sort'
|
|
|
|
size='sm'
|
|
|
|
overrideValue={sort}
|
|
|
|
items={['zaprank', 'match', 'recent', 'comments', 'sats']}
|
|
|
|
/>
|
|
|
|
for
|
|
|
|
<Select
|
|
|
|
groupClassName='mb-0 mx-2'
|
|
|
|
onChange={(formik, e) => {
|
|
|
|
search({ ...formik?.values, when: e.target.value, from: from || new Date().toISOString(), to: to || new Date().toISOString() })
|
|
|
|
setDatePicker(e.target.value === 'custom')
|
|
|
|
if (e.target.value === 'custom') setRange({ start: new Date(), end: new Date() })
|
|
|
|
}}
|
|
|
|
name='when'
|
|
|
|
size='sm'
|
|
|
|
overrideValue={when}
|
|
|
|
items={['custom', 'forever', 'day', 'week', 'month', 'year']}
|
|
|
|
/>
|
|
|
|
</>}
|
|
|
|
</div>
|
|
|
|
{datePicker &&
|
|
|
|
<DatePicker
|
|
|
|
fromName='from' toName='to'
|
|
|
|
className='form-control p-0 px-2 mb-2 text-center'
|
|
|
|
onMount={() => {
|
|
|
|
setRange({ start: new Date(from), end: new Date(to) })
|
|
|
|
return [from, to]
|
|
|
|
}}
|
|
|
|
onChange={(formik, [start, end], e) => {
|
|
|
|
setRange({ start, end })
|
|
|
|
search({ ...formik?.values, from: start && start.toISOString(), to: end && end.toISOString() })
|
|
|
|
}}
|
|
|
|
selected={range.start}
|
|
|
|
startDate={range.start} endDate={range.end}
|
|
|
|
selectsRange
|
|
|
|
dateFormat='MM/dd/yy'
|
|
|
|
maxDate={new Date()}
|
|
|
|
minDate={new Date('2021-05-01')}
|
|
|
|
/>}
|
2023-09-11 23:11:47 +00:00
|
|
|
</div>}
|
|
|
|
</Form>
|
2022-01-26 21:43:18 +00:00
|
|
|
</Container>
|
|
|
|
</div>
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
}
|