stacker.news/pages/items/[id].js

106 lines
2.3 KiB
JavaScript
Raw Normal View History

2021-04-27 00:55:48 +00:00
import Item, { ItemSkeleton } from '../../components/item'
2021-04-14 23:56:29 +00:00
import Layout from '../../components/layout'
2021-04-27 00:55:48 +00:00
import Reply, { ReplySkeleton } from '../../components/reply'
2021-04-14 23:56:29 +00:00
import Comment from '../../components/comment'
import Text from '../../components/text'
2021-04-27 00:55:48 +00:00
import Comments, { CommentsSkeleton } from '../../components/comments'
2021-04-22 22:14:32 +00:00
import { COMMENTS } from '../../fragments/comments'
import { ITEM_FIELDS } from '../../fragments/items'
2021-04-27 00:55:48 +00:00
import { gql, useQuery } from '@apollo/client'
2021-04-28 19:30:14 +00:00
import styles from '../../styles/item.module.css'
2021-07-08 00:15:27 +00:00
import Seo from '../../components/seo'
2021-07-08 17:27:52 +00:00
import ApolloClient from '../../api/client'
// ssr the item without comments so that we can populate metatags
export async function getServerSideProps ({ req, params: { id } }) {
if (isNaN(id)) {
return {
notFound: true
}
}
2021-07-08 17:27:52 +00:00
const { error, data: { item } } = await (await ApolloClient(req)).query({
query:
gql`
${ITEM_FIELDS}
{
item(id: ${id}) {
...ItemFields
text
}
}`
})
if (!item || error) {
return {
notFound: true
}
}
2021-04-14 23:56:29 +00:00
2021-04-27 21:30:58 +00:00
return {
props: {
2021-07-08 17:27:52 +00:00
item
2021-04-27 21:30:58 +00:00
}
}
}
2021-04-27 00:55:48 +00:00
2021-07-08 17:27:52 +00:00
export default function FullItem ({ item }) {
2021-04-27 00:55:48 +00:00
const query = gql`
${ITEM_FIELDS}
2021-04-22 22:14:32 +00:00
${COMMENTS}
{
2021-07-08 17:27:52 +00:00
item(id: ${item.id}) {
2021-04-27 00:55:48 +00:00
...ItemFields
text
comments {
...CommentsRecursive
}
}
2021-04-22 22:14:32 +00:00
}`
2021-04-14 23:56:29 +00:00
return (
2021-07-08 00:34:23 +00:00
<Layout noSeo>
2021-07-08 17:27:52 +00:00
<Seo item={item} />
2021-04-27 00:55:48 +00:00
<LoadItem query={query} />
</Layout>
)
}
function LoadItem ({ query }) {
const { loading, error, data } = useQuery(query)
if (error) return <div>Failed to load!</div>
if (loading) {
return (
<div>
<ItemSkeleton>
<ReplySkeleton />
</ItemSkeleton>
2021-04-28 22:52:03 +00:00
<div className={styles.comments}>
2021-04-27 00:55:48 +00:00
<CommentsSkeleton />
</div>
</div>
)
}
const { item } = data
return (
<>
2021-04-14 23:56:29 +00:00
{item.parentId
2021-04-27 00:55:48 +00:00
? <Comment item={item} replyOpen includeParent noComments />
2021-04-14 23:56:29 +00:00
: (
<>
<Item item={item}>
{item.text && <div className='mb-3'><Text>{item.text}</Text></div>}
2021-04-27 00:55:48 +00:00
<Reply parentId={item.id} />
2021-04-14 23:56:29 +00:00
</Item>
</>
)}
2021-04-28 19:30:14 +00:00
<div className={styles.comments}>
2021-04-27 00:55:48 +00:00
<Comments comments={item.comments} />
2021-04-22 22:14:32 +00:00
</div>
2021-04-27 00:55:48 +00:00
</>
2021-04-14 23:56:29 +00:00
)
}