Make tags page filter on server side (#108)

This commit is contained in:
Marshall Polaris 2022-04-28 22:39:39 -07:00 committed by GitHub
parent 760681f958
commit 2ddd95e904
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 21 deletions

View File

@ -115,6 +115,18 @@ export async function listContracts(creatorId: string): Promise<Contract[]> {
return snapshot.docs.map((doc) => doc.data() as Contract)
}
export async function listTaggedContractsCaseInsensitive(
tag: string
): Promise<Contract[]> {
const q = query(
contractCollection,
where('lowercaseTags', 'array-contains', tag.toLowerCase()),
orderBy('createdTime', 'desc')
)
const snapshot = await getDocs(q)
return snapshot.docs.map((doc) => doc.data() as Contract)
}
export async function listAllContracts(): Promise<Contract[]> {
const q = query(contractCollection, orderBy('createdTime', 'desc'))
const snapshot = await getDocs(q)

View File

@ -1,39 +1,33 @@
import { useEffect, useState } from 'react'
import { useRouter } from 'next/router'
import { SearchableGrid } from '../../components/contract/contracts-list'
import { Page } from '../../components/page'
import { Title } from '../../components/title'
import { useContracts } from '../../hooks/use-contracts'
import { Contract, listAllContracts } from '../../lib/firebase/contracts'
export async function getStaticProps() {
const contracts = await listAllContracts().catch((_) => [])
return {
props: {
contracts,
},
revalidate: 60, // regenerate after a minute
}
}
export async function getStaticPaths() {
return { paths: [], fallback: 'blocking' }
}
import {
Contract,
listTaggedContractsCaseInsensitive,
} from '../../lib/firebase/contracts'
export default function TagPage(props: { contracts: Contract[] }) {
const router = useRouter()
const { tag } = router.query as { tag: string }
const contracts = useContracts()
// mqp: i wrote this in a panic to make the page literally work at all so if you
// want to e.g. listen for new contracts you may want to fix it up
const [contracts, setContracts] = useState<Contract[] | 'loading'>('loading')
useEffect(() => {
if (tag != null) {
listTaggedContractsCaseInsensitive(tag).then(setContracts)
}
}, [tag])
const taggedContracts = (contracts ?? props.contracts).filter((contract) =>
contract.lowercaseTags.includes(tag.toLowerCase())
)
if (contracts === 'loading') return <></>
return (
<Page>
<Title text={`#${tag}`} />
<SearchableGrid contracts={taggedContracts} />
<SearchableGrid contracts={contracts} />
</Page>
)
}