feat: recent unpaid bounties selection (#1589)

* feat: recent unpaid bounties selection

* chore: added checkbox on recent header

* chore: active bounties selection made through a checkbox

* chore: renamed function for better clarity

* chore: fixed active bounties only checkbox alignment

* chore: active-only option passed as query param

* chores: variablesFunc refactoring

* chore: removed type mapping function from recent header

* chore: router replace instead of push

* chore: router retrieved by hook instead of argument

* chore: checkbox starts checked based on url's query param

* more idiomatic react + push instead of replace

---------

Co-authored-by: ekzyis <ek@stacker.news>
Co-authored-by: Keyan <34140557+huumn@users.noreply.github.com>
Co-authored-by: k00b <k00b@stacker.news>
This commit is contained in:
Lorenzo 2024-11-29 01:47:01 +01:00 committed by GitHub
parent 8ce2e46519
commit 7cb2aed9db
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 56 additions and 14 deletions

View File

@ -300,6 +300,8 @@ function typeClause (type) {
return ['"Item".bio = true', '"Item"."parentId" IS NULL']
case 'bounties':
return ['"Item".bounty IS NOT NULL', '"Item"."parentId" IS NULL']
case 'bounties_active':
return ['"Item".bounty IS NOT NULL', '"Item"."parentId" IS NULL', '"Item"."bountyPaidTo" IS NULL']
case 'comments':
return '"Item"."parentId" IS NOT NULL'
case 'freebies':

View File

@ -1,10 +1,33 @@
import { ITEM_TYPES, ITEM_TYPES_UNIVERSAL } from '@/lib/constants'
import BootstrapForm from 'react-bootstrap/Form'
import { Select } from './form'
import { useRouter } from 'next/router'
export default function RecentHeader ({ type, sub }) {
function ActiveBountiesCheckbox ({ prefix }) {
const router = useRouter()
const onChange = (e) => {
if (e.target.checked) {
router.push(prefix + '/recent/bounties?' + new URLSearchParams({ active: true }).toString())
} else {
router.push(prefix + '/recent/bounties')
}
}
return (
<div className='mx-2 mb-2'>
<BootstrapForm.Check
inline
checked={router.query.active === 'true'}
label='active only'
onChange={onChange}
/>
</div>
)
}
export default function RecentHeader ({ type, sub }) {
const router = useRouter()
const prefix = sub ? `/~${sub.name}` : ''
const items = sub
@ -14,18 +37,22 @@ export default function RecentHeader ({ type, sub }) {
: ITEM_TYPES
type ||= router.query.type || type || 'posts'
return (
<div className='text-muted fw-bold my-1 d-flex justify-content-start align-items-center'>
<Select
groupClassName='mb-2'
className='w-auto'
name='type'
size='sm'
value={type}
items={items}
noForm
onChange={(_, e) => router.push(prefix + (e.target.value === 'posts' ? '/recent' : `/recent/${e.target.value}`))}
/>
<div className='flex-wrap'>
<div className='text-muted fw-bold my-1 d-flex justify-content-start align-items-center'>
<Select
groupClassName='mb-2'
className='w-auto'
name='type'
size='sm'
value={type}
items={items}
noForm
onChange={(_, e) => router.push(prefix + (e.target.value === 'posts' ? '/recent' : `/recent/${e.target.value}`))}
/>
{type === 'bounties' && <ActiveBountiesCheckbox prefix={prefix} />}
</div>
</div>
)
}

View File

@ -9,8 +9,21 @@ import { useQuery } from '@apollo/client'
import PageLoading from '@/components/page-loading'
const staticVariables = { sort: 'recent' }
const variablesFunc = vars =>
({ includeComments: COMMENT_TYPE_QUERY.includes(vars.type), ...staticVariables, ...vars })
function variablesFunc (vars) {
let type = vars?.type || ''
if (type === 'bounties' && vars?.active) {
type = 'bounties_active'
}
return ({
includeComments: COMMENT_TYPE_QUERY.includes(vars.type),
...staticVariables,
...vars,
type
})
}
export const getServerSideProps = getGetServerSideProps({
query: SUB_ITEMS,