Client-side render pages that need auth

These pages are now client-side rendered:
- /home
- /leaderboards
- /market/...
- /fold/...
This commit is contained in:
Austin Chen 2022-03-01 16:32:31 -08:00
parent eef35cd7d0
commit 20d18f3588
6 changed files with 74 additions and 8 deletions

View File

@ -29,7 +29,7 @@ export const useContractWithPreload = (
useEffect(() => { useEffect(() => {
if (contractId) return listenForContract(contractId, setContract) if (contractId) return listenForContract(contractId, setContract)
if (contractId !== null) if (contractId !== null && slug)
getContractFromSlug(slug).then((c) => setContractId(c?.id || null)) getContractFromSlug(slug).then((c) => setContractId(c?.id || null))
}, [contractId, slug]) }, [contractId, slug])

30
web/hooks/use-propz.ts Normal file
View File

@ -0,0 +1,30 @@
import _ from 'lodash'
import { useRouter } from 'next/router'
import { useState, useEffect } from 'react'
type PropzProps = {
params: any
}
// getStaticPropz should exactly match getStaticProps
// This allows us to client-side render the page for authenticated users.
// TODO: Could cache the result using stale-while-revalidate: https://swr.vercel.app/
export function usePropz(
getStaticPropz: (props?: PropzProps) => Promise<any>,
// Dynamic routes will need the query params from the router
needParams?: boolean
) {
// Get params from router
const router = useRouter()
const params = router.query
const [propz, setPropz] = useState<any>(undefined)
useEffect(() => {
if (needParams && _.isEmpty(params)) {
return
}
// @ts-ignore
getStaticPropz({ params }).then((result) => setPropz(result.props))
}, [params])
return propz
}

View File

@ -29,8 +29,9 @@ import { useFoldsWithTags } from '../../hooks/use-fold'
import { listAllAnswers } from '../../lib/firebase/answers' import { listAllAnswers } from '../../lib/firebase/answers'
import { Answer } from '../../../common/answer' import { Answer } from '../../../common/answer'
import { AnswersPanel } from '../../components/answers/answers-panel' import { AnswersPanel } from '../../components/answers/answers-panel'
import { usePropz } from '../../hooks/use-propz'
export async function getStaticProps(props: { export async function getStaticPropz(props: {
params: { username: string; contractSlug: string } params: { username: string; contractSlug: string }
}) { }) {
const { username, contractSlug } = props.params const { username, contractSlug } = props.params
@ -64,7 +65,7 @@ export async function getStaticProps(props: {
} }
} }
export async function getStaticPaths() { export async function getStaticPathz() {
return { paths: [], fallback: 'blocking' } return { paths: [], fallback: 'blocking' }
} }
@ -77,6 +78,16 @@ export default function ContractPage(props: {
slug: string slug: string
folds: Fold[] folds: Fold[]
}) { }) {
// @ts-ignore
props = usePropz(getStaticPropz, true) ?? {
contract: null,
username: '',
comments: [],
answers: [],
bets: [],
slug: '',
folds: [],
}
const user = useUser() const user = useUser()
const contract = useContractWithPreload(props.slug, props.contract) const contract = useContractWithPreload(props.slug, props.contract)

View File

@ -40,8 +40,9 @@ import FeedCreate from '../../../components/feed-create'
import { SEO } from '../../../components/SEO' import { SEO } from '../../../components/SEO'
import { useTaggedContracts } from '../../../hooks/use-contracts' import { useTaggedContracts } from '../../../hooks/use-contracts'
import { Linkify } from '../../../components/linkify' import { Linkify } from '../../../components/linkify'
import { usePropz } from '../../../hooks/use-propz'
export async function getStaticProps(props: { params: { slugs: string[] } }) { export async function getStaticPropz(props: { params: { slugs: string[] } }) {
const { slugs } = props.params const { slugs } = props.params
const fold = await getFoldBySlug(slugs[0]) const fold = await getFoldBySlug(slugs[0])
@ -124,7 +125,7 @@ async function toTopUsers(userScores: { [userId: string]: number }) {
return topUsers.filter((user) => user) return topUsers.filter((user) => user)
} }
export async function getStaticPaths() { export async function getStaticPathz() {
return { paths: [], fallback: 'blocking' } return { paths: [], fallback: 'blocking' }
} }
const foldSubpages = [undefined, 'activity', 'markets', 'leaderboards'] as const const foldSubpages = [undefined, 'activity', 'markets', 'leaderboards'] as const
@ -141,6 +142,19 @@ export default function FoldPage(props: {
creatorScores: { [userId: string]: number } creatorScores: { [userId: string]: number }
topCreators: User[] topCreators: User[]
}) { }) {
// @ts-ignore
props = usePropz(getStaticPropz, true) ?? {
fold: null,
curator: null,
contracts: [],
activeContracts: [],
activeContractBets: [],
activeContractComments: [],
traderScores: {},
topTraders: [],
creatorScores: {},
topCreators: [],
}
const { const {
curator, curator,
activeContractBets, activeContractBets,
@ -154,7 +168,7 @@ export default function FoldPage(props: {
const router = useRouter() const router = useRouter()
const { slugs } = router.query as { slugs: string[] } const { slugs } = router.query as { slugs: string[] }
const page = (slugs[1] ?? 'activity') as typeof foldSubpages[number] const page = (slugs?.[1] ?? 'activity') as typeof foldSubpages[number]
const fold = useFold(props.fold?.id) ?? props.fold const fold = useFold(props.fold?.id) ?? props.fold

View File

@ -20,8 +20,9 @@ import {
useFindActiveContracts, useFindActiveContracts,
} from '../hooks/use-active-contracts' } from '../hooks/use-active-contracts'
import { useGetRecentBets } from '../hooks/use-bets' import { useGetRecentBets } from '../hooks/use-bets'
import { usePropz } from '../hooks/use-propz'
export async function getStaticProps() { export async function getStaticPropz() {
const contractInfo = await getAllContractInfo() const contractInfo = await getAllContractInfo()
return { return {
@ -36,6 +37,11 @@ const Home = (props: {
recentBets: Bet[] recentBets: Bet[]
recentComments: Comment[] recentComments: Comment[]
}) => { }) => {
props = usePropz(getStaticPropz) ?? {
contracts: [],
folds: [],
recentComments: [],
}
const { contracts, folds, recentComments } = props const { contracts, folds, recentComments } = props
const user = useUser() const user = useUser()

View File

@ -5,8 +5,9 @@ import { Leaderboard } from '../components/leaderboard'
import { Page } from '../components/page' import { Page } from '../components/page'
import { getTopCreators, getTopTraders, User } from '../lib/firebase/users' import { getTopCreators, getTopTraders, User } from '../lib/firebase/users'
import { formatMoney } from '../../common/util/format' import { formatMoney } from '../../common/util/format'
import { usePropz } from '../hooks/use-propz'
export async function getStaticProps() { export async function getStaticPropz() {
const [topTraders, topCreators] = await Promise.all([ const [topTraders, topCreators] = await Promise.all([
getTopTraders().catch((_) => {}), getTopTraders().catch((_) => {}),
getTopCreators().catch((_) => {}), getTopCreators().catch((_) => {}),
@ -26,6 +27,10 @@ export default function Leaderboards(props: {
topTraders: User[] topTraders: User[]
topCreators: User[] topCreators: User[]
}) { }) {
props = usePropz(getStaticPropz) ?? {
topTraders: [],
topCreators: [],
}
const { topTraders, topCreators } = props const { topTraders, topCreators } = props
return ( return (