Date doc individual page
This commit is contained in:
parent
5ef5dc15ff
commit
3495a667ca
|
@ -6,13 +6,15 @@ export const linkClass =
|
|||
'z-10 break-anywhere hover:underline hover:decoration-indigo-400 hover:decoration-2'
|
||||
|
||||
export const SiteLink = (props: {
|
||||
href: string
|
||||
href: string | undefined
|
||||
children?: ReactNode
|
||||
onClick?: () => void
|
||||
className?: string
|
||||
}) => {
|
||||
const { href, children, onClick, className } = props
|
||||
|
||||
if (!href) return <>{children}</>
|
||||
|
||||
return (
|
||||
<MaybeLink href={href}>
|
||||
<a
|
||||
|
|
|
@ -8,6 +8,7 @@ import {
|
|||
} from 'firebase/firestore'
|
||||
import { DateDoc, Post } from 'common/post'
|
||||
import { coll, getValue, getValues, listenForValue } from './utils'
|
||||
import { getUserByUsername } from './users'
|
||||
|
||||
export const posts = coll<Post>('posts')
|
||||
|
||||
|
@ -49,3 +50,17 @@ export async function getDateDocs() {
|
|||
const q = query(posts, where('type', '==', 'date-doc'))
|
||||
return getValues<DateDoc>(q)
|
||||
}
|
||||
|
||||
export async function getDateDoc(username: string) {
|
||||
const user = await getUserByUsername(username)
|
||||
if (!user) return null
|
||||
|
||||
const q = query(
|
||||
posts,
|
||||
where('type', '==', 'date-doc'),
|
||||
where('creatorId', '==', user.id)
|
||||
)
|
||||
const docs = await getValues<DateDoc>(q)
|
||||
const post = docs.length === 0 ? null : docs[0]
|
||||
return { post, user }
|
||||
}
|
||||
|
|
98
web/pages/date-docs/[username].tsx
Normal file
98
web/pages/date-docs/[username].tsx
Normal file
|
@ -0,0 +1,98 @@
|
|||
import { getDateDoc } from 'web/lib/firebase/posts'
|
||||
import { Page } from 'web/components/page'
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
import { DateDoc } from 'common/post'
|
||||
import { Spacer } from 'web/components/layout/spacer'
|
||||
import { Content } from 'web/components/editor'
|
||||
import { Col } from 'web/components/layout/col'
|
||||
import { Row } from 'web/components/layout/row'
|
||||
import { SiteLink } from 'web/components/site-link'
|
||||
import { User } from 'web/lib/firebase/users'
|
||||
import { DOMAIN } from 'common/envs/constants'
|
||||
import Custom404 from '../404'
|
||||
|
||||
export async function getStaticProps(props: { params: { username: string } }) {
|
||||
const { username } = props.params
|
||||
const { user, post } = (await getDateDoc(username)) ?? {
|
||||
user: null,
|
||||
post: null,
|
||||
}
|
||||
|
||||
return {
|
||||
props: {
|
||||
user,
|
||||
post,
|
||||
},
|
||||
revalidate: 5, // regenerate after five seconds
|
||||
}
|
||||
}
|
||||
|
||||
export async function getStaticPaths() {
|
||||
return { paths: [], fallback: 'blocking' }
|
||||
}
|
||||
|
||||
export default function DateDocPage(props: {
|
||||
user: User | null
|
||||
post: DateDoc | null
|
||||
}) {
|
||||
const { user, post } = props
|
||||
|
||||
if (!user || !post) return <Custom404 />
|
||||
|
||||
return (
|
||||
<Page>
|
||||
<div className="mx-auto w-full max-w-xl">
|
||||
<DateDocPost dateDoc={post} creator={user} />
|
||||
</div>
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
|
||||
export function DateDocPost(props: {
|
||||
dateDoc: DateDoc
|
||||
creator: User
|
||||
link?: boolean
|
||||
}) {
|
||||
const { dateDoc, creator } = props
|
||||
const { content, birthday, photoUrl, contractSlug } = dateDoc
|
||||
const { name, username } = creator
|
||||
|
||||
const age = dayjs().diff(birthday, 'year')
|
||||
const marketUrl = `https://${DOMAIN}/${username}/${contractSlug}`
|
||||
|
||||
return (
|
||||
<Col className="rounded-lg bg-white px-6 py-6">
|
||||
<SiteLink
|
||||
href={props.link ? `/date-docs/${creator.username}` : undefined}
|
||||
>
|
||||
<Col className="gap-2 self-center">
|
||||
<Row>
|
||||
<img
|
||||
className="w-full max-w-lg rounded-lg object-cover"
|
||||
src={photoUrl}
|
||||
alt={name}
|
||||
/>
|
||||
</Row>
|
||||
<Row className="gap-4 text-2xl">
|
||||
<div>
|
||||
{name}, {age}
|
||||
</div>
|
||||
</Row>
|
||||
</Col>
|
||||
</SiteLink>
|
||||
<Spacer h={6} />
|
||||
<Content content={content} />
|
||||
<Spacer h={6} />
|
||||
<div className="mt-10 w-full max-w-lg self-center rounded-xl bg-gradient-to-r from-blue-200 via-purple-200 to-indigo-300 p-5">
|
||||
<iframe
|
||||
height="405"
|
||||
src={marketUrl}
|
||||
title=""
|
||||
frameBorder="0"
|
||||
className="w-full rounded-xl bg-white p-10"
|
||||
></iframe>
|
||||
</div>
|
||||
</Col>
|
||||
)
|
||||
}
|
|
@ -1,19 +1,17 @@
|
|||
import { Page } from 'web/components/page'
|
||||
import { PlusCircleIcon } from '@heroicons/react/outline'
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
import { getDateDocs } from 'web/lib/firebase/posts'
|
||||
import { DateDoc } from 'common/post'
|
||||
import type { DateDoc } from 'common/post'
|
||||
import { Title } from 'web/components/title'
|
||||
import { Spacer } from 'web/components/layout/spacer'
|
||||
import { Content } from 'web/components/editor'
|
||||
import { Col } from 'web/components/layout/col'
|
||||
import { useUser } from 'web/hooks/use-user'
|
||||
import { Row } from 'web/components/layout/row'
|
||||
import { Button } from 'web/components/button'
|
||||
import { SiteLink } from 'web/components/site-link'
|
||||
import { getUser, User } from 'web/lib/firebase/users'
|
||||
import { DOMAIN } from 'common/envs/constants'
|
||||
import { DateDocPost } from './[username]'
|
||||
|
||||
export async function getStaticProps() {
|
||||
const dateDocs = await getDateDocs()
|
||||
|
@ -42,7 +40,7 @@ export default function DatePage(props: {
|
|||
|
||||
return (
|
||||
<Page>
|
||||
<div className="mx-auto w-full max-w-3xl">
|
||||
<div className="mx-auto w-full max-w-xl">
|
||||
<Row className="items-center justify-between">
|
||||
<Title className="!my-0 px-2 text-blue-500" text="Date docs" />
|
||||
{!hasDoc && (
|
||||
|
@ -60,10 +58,11 @@ export default function DatePage(props: {
|
|||
<Spacer h={6} />
|
||||
<Col className="gap-4">
|
||||
{dateDocs.map((dateDoc, i) => (
|
||||
<DateDoc
|
||||
<DateDocPost
|
||||
key={dateDoc.id}
|
||||
dateDoc={dateDoc}
|
||||
creator={docCreators[i]}
|
||||
link
|
||||
/>
|
||||
))}
|
||||
</Col>
|
||||
|
@ -71,43 +70,3 @@ export default function DatePage(props: {
|
|||
</Page>
|
||||
)
|
||||
}
|
||||
|
||||
function DateDoc(props: { dateDoc: DateDoc; creator: User }) {
|
||||
const { dateDoc, creator } = props
|
||||
const { content, birthday, photoUrl, contractSlug } = dateDoc
|
||||
const { name, username } = creator
|
||||
|
||||
const age = dayjs().diff(birthday, 'year')
|
||||
const marketUrl = `https://${DOMAIN}/${username}/${contractSlug}`
|
||||
|
||||
return (
|
||||
<Col className="rounded-lg bg-white px-6 py-6">
|
||||
<Col className="gap-2 self-center">
|
||||
<Row>
|
||||
<img
|
||||
className="w-full max-w-lg rounded-lg object-cover"
|
||||
src={photoUrl}
|
||||
alt={name}
|
||||
/>
|
||||
</Row>
|
||||
<Row className="gap-4 text-2xl">
|
||||
<div>
|
||||
{name}, {age}
|
||||
</div>
|
||||
</Row>
|
||||
</Col>
|
||||
<Spacer h={6} />
|
||||
<Content content={content} />
|
||||
<Spacer h={6} />
|
||||
<div className="mt-10 w-full max-w-lg self-center rounded-xl bg-gradient-to-r from-blue-200 via-purple-200 to-indigo-300 p-5">
|
||||
<iframe
|
||||
height="405"
|
||||
src={marketUrl}
|
||||
title=""
|
||||
frameBorder="0"
|
||||
className="w-full rounded-xl bg-white p-10"
|
||||
></iframe>
|
||||
</div>
|
||||
</Col>
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user