more progress
This commit is contained in:
parent
bc5d4d4808
commit
28ed42fc29
28
api/client.js
Normal file
28
api/client.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { ApolloClient, InMemoryCache } from '@apollo/client'
|
||||||
|
import { SchemaLink } from '@apollo/client/link/schema'
|
||||||
|
import { mergeSchemas } from 'graphql-tools'
|
||||||
|
import { getSession } from 'next-auth/client'
|
||||||
|
import resolvers from './resolvers'
|
||||||
|
import typeDefs from './typeDefs'
|
||||||
|
import models from './models'
|
||||||
|
|
||||||
|
const client = new ApolloClient({
|
||||||
|
ssrMode: true,
|
||||||
|
// Instead of "createHttpLink" use SchemaLink here
|
||||||
|
link: new SchemaLink({
|
||||||
|
schema: mergeSchemas({
|
||||||
|
schemas: typeDefs,
|
||||||
|
resolvers: resolvers
|
||||||
|
}),
|
||||||
|
context: async ({ req }) => {
|
||||||
|
const session = await getSession({ req })
|
||||||
|
return {
|
||||||
|
models,
|
||||||
|
me: session ? session.user : null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
cache: new InMemoryCache()
|
||||||
|
})
|
||||||
|
|
||||||
|
export default client
|
@ -30,6 +30,21 @@ const createItem = async (parent, { title, text, url, parentId }, { me, models }
|
|||||||
export default {
|
export default {
|
||||||
Query: {
|
Query: {
|
||||||
items: async (parent, args, { models }) => {
|
items: async (parent, args, { models }) => {
|
||||||
|
return await models.$queryRaw(`
|
||||||
|
SELECT id, "created_at" as "createdAt", title, url, text, "userId", ltree2text("path") AS "path"
|
||||||
|
FROM "Item"
|
||||||
|
WHERE "parentId" IS NULL
|
||||||
|
ORDER BY "path"`)
|
||||||
|
},
|
||||||
|
item: async (parent, { id }, { models }) => {
|
||||||
|
const res = await models.$queryRaw(`
|
||||||
|
SELECT id, "created_at" as "createdAt", title, url, text, "parentId", "userId", ltree2text("path") AS "path"
|
||||||
|
FROM "Item"
|
||||||
|
WHERE id = ${id}
|
||||||
|
ORDER BY "path"`)
|
||||||
|
return res.length ? res[0] : null
|
||||||
|
},
|
||||||
|
ncomments: async (parent, { parentId }, { models }) => {
|
||||||
return await models.$queryRaw(`
|
return await models.$queryRaw(`
|
||||||
SELECT id, "created_at" as "createdAt", title, url, text, "userId", ltree2text("path") AS "path"
|
SELECT id, "created_at" as "createdAt", title, url, text, "userId", ltree2text("path") AS "path"
|
||||||
FROM "Item"
|
FROM "Item"
|
||||||
@ -62,7 +77,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!parentId) {
|
if (!parentId) {
|
||||||
throw new UserInputError('Comment must have text', { argumentName: 'text' })
|
throw new UserInputError('Comment must have parent', { argumentName: 'text' })
|
||||||
}
|
}
|
||||||
|
|
||||||
return await createItem(parent, { text, parentId }, { me, models })
|
return await createItem(parent, { text, parentId }, { me, models })
|
||||||
@ -85,7 +100,13 @@ export default {
|
|||||||
|
|
||||||
return path.split('.').length - 1
|
return path.split('.').length - 1
|
||||||
},
|
},
|
||||||
comments: () => 0,
|
ncomments: async (item, args, { models }) => {
|
||||||
|
const [{ count }] = await models.$queryRaw`
|
||||||
|
SELECT count(*)
|
||||||
|
FROM "Item"
|
||||||
|
WHERE path <@ text2ltree(${item.id}) AND id != ${item.id}`
|
||||||
|
return count
|
||||||
|
},
|
||||||
sats: () => 0
|
sats: () => 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@ import { gql } from 'apollo-server-micro'
|
|||||||
export default gql`
|
export default gql`
|
||||||
extend type Query {
|
extend type Query {
|
||||||
items: [Item!]!
|
items: [Item!]!
|
||||||
|
item(id: ID!): Item
|
||||||
|
ncomments(id: ID!): [Item!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
extend type Mutation {
|
extend type Mutation {
|
||||||
@ -17,9 +19,10 @@ export default gql`
|
|||||||
title: String
|
title: String
|
||||||
url: String
|
url: String
|
||||||
text: String
|
text: String
|
||||||
|
parentId: Int
|
||||||
user: User!
|
user: User!
|
||||||
depth: Int!
|
depth: Int!
|
||||||
sats: Int!
|
sats: Int!
|
||||||
comments: Int!
|
ncomments: Int!
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
70
components/comment.js
Normal file
70
components/comment.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import itemStyles from './item.module.css'
|
||||||
|
import styles from './comment.module.css'
|
||||||
|
import UpVote from '../svgs/lightning-arrow.svg'
|
||||||
|
import Text from './text'
|
||||||
|
import Link from 'next/link'
|
||||||
|
import Reply from './reply'
|
||||||
|
import { useState } from 'react'
|
||||||
|
|
||||||
|
function timeSince (timeStamp) {
|
||||||
|
const now = new Date()
|
||||||
|
const secondsPast = (now.getTime() - timeStamp) / 1000
|
||||||
|
if (secondsPast < 60) {
|
||||||
|
return parseInt(secondsPast) + 's'
|
||||||
|
}
|
||||||
|
if (secondsPast < 3600) {
|
||||||
|
return parseInt(secondsPast / 60) + 'm'
|
||||||
|
}
|
||||||
|
if (secondsPast <= 86400) {
|
||||||
|
return parseInt(secondsPast / 3600) + 'h'
|
||||||
|
}
|
||||||
|
if (secondsPast > 86400) {
|
||||||
|
const day = timeStamp.getDate()
|
||||||
|
const month = timeStamp.toDateString().match(/ [a-zA-Z]*/)[0].replace(' ', '')
|
||||||
|
const year = timeStamp.getFullYear() === now.getFullYear() ? '' : ' ' + timeStamp.getFullYear()
|
||||||
|
return day + ' ' + month + year
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Comment ({ item, children }) {
|
||||||
|
const [reply, setReply] = useState(false)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className={`${itemStyles.item} ${styles.item}`}>
|
||||||
|
<UpVote width={24} height={24} className={`${itemStyles.upvote} ${styles.upvote}`} />
|
||||||
|
<div className={itemStyles.hunk}>
|
||||||
|
<div className={itemStyles.other}>
|
||||||
|
<Link href={`/@${item.user.name}`} passHref>
|
||||||
|
<a>@{item.user.name}</a>
|
||||||
|
</Link>
|
||||||
|
<span> </span>
|
||||||
|
<span>{timeSince(new Date(item.createdAt))}</span>
|
||||||
|
<span> \ </span>
|
||||||
|
<span>{item.sats} sats</span>
|
||||||
|
<span> \ </span>
|
||||||
|
<span>{item.ncomments} replies</span>
|
||||||
|
</div>
|
||||||
|
<div className={styles.text}>
|
||||||
|
<Text>{item.text}</Text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={`${itemStyles.children} ${styles.children}`}>
|
||||||
|
<div
|
||||||
|
className={`${itemStyles.other} ${styles.reply}`}
|
||||||
|
onClick={() => setReply(!reply)}
|
||||||
|
>
|
||||||
|
{reply ? 'cancel' : 'reply'}
|
||||||
|
</div>
|
||||||
|
{reply && <Reply parentId={item.id} />}
|
||||||
|
{children}
|
||||||
|
{item.comments
|
||||||
|
? item.comments.map((item) => (
|
||||||
|
<Comment key={item.id} item={item} />
|
||||||
|
))
|
||||||
|
: null}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
21
components/comment.module.css
Normal file
21
components/comment.module.css
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
.item {
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upvote {
|
||||||
|
margin-top: .3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
margin-top: .1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply {
|
||||||
|
font-weight: bold;
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.children {
|
||||||
|
margin-top: .4rem;
|
||||||
|
}
|
@ -62,6 +62,7 @@ export function Form ({
|
|||||||
<Formik
|
<Formik
|
||||||
initialValues={initial}
|
initialValues={initial}
|
||||||
validationSchema={schema}
|
validationSchema={schema}
|
||||||
|
validateOnBlur={false}
|
||||||
onSubmit={(...args) =>
|
onSubmit={(...args) =>
|
||||||
onSubmit(...args).catch(e => setError(e.message))}
|
onSubmit(...args).catch(e => setError(e.message))}
|
||||||
>
|
>
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import Link from 'next/link'
|
||||||
import UpVote from '../svgs/lightning-arrow.svg'
|
import UpVote from '../svgs/lightning-arrow.svg'
|
||||||
import styles from './item.module.css'
|
import styles from './item.module.css'
|
||||||
|
|
||||||
@ -21,27 +22,41 @@ function timeSince (timeStamp) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Item ({ item }) {
|
export default function Item ({ item, children }) {
|
||||||
return (
|
return (
|
||||||
<div className='d-flex justify-content-start align-items-center'>
|
<>
|
||||||
<UpVote width={32} height={32} className={styles.upvote} />
|
<div className={styles.item}>
|
||||||
<div>
|
<UpVote width={24} height={24} className={styles.upvote} />
|
||||||
<div>
|
<div className={styles.hunk}>
|
||||||
<span>
|
<div className={`${styles.main} flex-wrap flex-md-nowrap`}>
|
||||||
<span className={styles.title}>{item.title}</span>
|
<Link href={`/items/${item.id}`} passHref>
|
||||||
<a className={styles.link} href={item.url}>{item.url.replace(/(^\w+:|^)\/\//, '')}</a>
|
<a className={`${styles.title} text-reset flex-md-fill flex-md-shrink-0 mr-2`}>{item.title}</a>
|
||||||
</span>
|
</Link>
|
||||||
</div>
|
{item.url && <a className={styles.link} href={item.url}>{item.url.replace(/(^\w+:|^)\/\//, '')}</a>}
|
||||||
<div className={styles.other}>
|
</div>
|
||||||
<span>{item.sats} sats</span>
|
<div className={styles.other}>
|
||||||
<span> \ </span>
|
<span>{item.sats} sats</span>
|
||||||
<span>{item.comments} comments</span>
|
<span> \ </span>
|
||||||
<span> </span>
|
<span>{item.ncomments} comments</span>
|
||||||
<a href='/satoshi'>@{item.user.name}</a>
|
<span> \ </span>
|
||||||
<span> </span>
|
<Link href={`/@${item.user.name}`} passHref>
|
||||||
<span>{timeSince(new Date(item.createdAt))}</span>
|
<a>@{item.user.name}</a>
|
||||||
|
</Link>
|
||||||
|
<span> </span>
|
||||||
|
<span>{timeSince(new Date(item.createdAt))}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{children && (
|
||||||
|
<div className={styles.children}>
|
||||||
|
{children}
|
||||||
|
{item.comments
|
||||||
|
? item.comments.map((item) => (
|
||||||
|
<Item key={item.id} item={item} />
|
||||||
|
))
|
||||||
|
: null}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
.upvote {
|
.upvote {
|
||||||
fill: grey;
|
fill: grey;
|
||||||
margin-right: .25rem;
|
min-width: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
.upvote:hover {
|
.upvote:hover {
|
||||||
@ -10,14 +10,39 @@
|
|||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
white-space: normal;
|
||||||
|
margin-right: .5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.link {
|
.link {
|
||||||
font-size: 80%;
|
font-size: 80%;
|
||||||
margin-left: .5rem;
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
.other {
|
.other {
|
||||||
font-size: 70%;
|
font-size: 70%;
|
||||||
color: grey;
|
color: grey;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hunk {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.children {
|
||||||
|
margin-top: 1rem;
|
||||||
|
margin-left: 24px;
|
||||||
}
|
}
|
36
components/items.js
Normal file
36
components/items.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { gql, useQuery } from '@apollo/client'
|
||||||
|
import React from 'react'
|
||||||
|
import Item from './item'
|
||||||
|
import styles from './items.module.css'
|
||||||
|
|
||||||
|
export default function Items () {
|
||||||
|
const { loading, error, data } = useQuery(
|
||||||
|
gql`
|
||||||
|
{ items {
|
||||||
|
id
|
||||||
|
createdAt
|
||||||
|
title
|
||||||
|
url
|
||||||
|
user {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
sats
|
||||||
|
ncomments
|
||||||
|
} }`
|
||||||
|
)
|
||||||
|
if (error) return <div>Failed to load</div>
|
||||||
|
if (loading) return <div>Loading...</div>
|
||||||
|
const { items } = data
|
||||||
|
return (
|
||||||
|
<div className={styles.grid}>
|
||||||
|
{items.map((item, i) => (
|
||||||
|
<React.Fragment key={item.id}>
|
||||||
|
<div className={styles.rank} key={item.id}>
|
||||||
|
{i + 1}
|
||||||
|
</div>
|
||||||
|
<Item item={item} />
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
12
components/items.module.css
Normal file
12
components/items.module.css
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rank {
|
||||||
|
font-weight: 600;
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
color: grey;
|
||||||
|
font-size: 90%;
|
||||||
|
}
|
@ -1,10 +1,17 @@
|
|||||||
import Header from './header'
|
import Header from './header'
|
||||||
|
import Container from 'react-bootstrap/Container'
|
||||||
|
|
||||||
export default function Layout ({ children }) {
|
export default function Layout ({ noContain, children }) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Header />
|
<Header />
|
||||||
{children}
|
{noContain
|
||||||
|
? children
|
||||||
|
: (
|
||||||
|
<Container className='my-2 py-2 px-sm-0'>
|
||||||
|
{children}
|
||||||
|
</Container>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
50
components/reply.js
Normal file
50
components/reply.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import { Form, Input, SubmitButton } from '../components/form'
|
||||||
|
import * as Yup from 'yup'
|
||||||
|
import { gql, useMutation } from '@apollo/client'
|
||||||
|
import styles from './reply.module.css'
|
||||||
|
|
||||||
|
export const CommentSchema = Yup.object({
|
||||||
|
text: Yup.string().required('required').trim()
|
||||||
|
})
|
||||||
|
|
||||||
|
export default function Reply ({ parentId }) {
|
||||||
|
const [createComment] = useMutation(
|
||||||
|
gql`
|
||||||
|
mutation createComment($text: String!, $parentId: ID!) {
|
||||||
|
createComment(text: $text, parentId: $parentId) {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.reply}>
|
||||||
|
<Form
|
||||||
|
initial={{
|
||||||
|
text: ''
|
||||||
|
}}
|
||||||
|
schema={CommentSchema}
|
||||||
|
onSubmit={async (values) => {
|
||||||
|
const {
|
||||||
|
data: {
|
||||||
|
createComment: { id }
|
||||||
|
},
|
||||||
|
error
|
||||||
|
} = await createComment({ variables: { ...values, parentId } })
|
||||||
|
if (error) {
|
||||||
|
throw new Error({ message: error.toString() })
|
||||||
|
}
|
||||||
|
console.log('success!', id)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
name='text'
|
||||||
|
as='textarea'
|
||||||
|
rows={4}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<SubmitButton variant='secondary' className='mt-1'>reply</SubmitButton>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
4
components/reply.module.css
Normal file
4
components/reply.module.css
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
.reply {
|
||||||
|
max-width: 600px;
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
9
components/text.js
Normal file
9
components/text.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import styles from './text.module.css'
|
||||||
|
|
||||||
|
export default function Text ({ children }) {
|
||||||
|
return (
|
||||||
|
<pre className={styles.text}>
|
||||||
|
{children}
|
||||||
|
</pre>
|
||||||
|
)
|
||||||
|
}
|
7
components/text.module.css
Normal file
7
components/text.module.css
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
.text {
|
||||||
|
font-size: 90%;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-break: break-word;
|
||||||
|
font-family: inherit;
|
||||||
|
margin: 0;
|
||||||
|
}
|
3
pages/[username].js
Normal file
3
pages/[username].js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export default function User () {
|
||||||
|
return <div>hi</div>
|
||||||
|
}
|
@ -11,7 +11,7 @@ const apolloServer = new ApolloServer({
|
|||||||
const session = await getSession({ req })
|
const session = await getSession({ req })
|
||||||
return {
|
return {
|
||||||
models,
|
models,
|
||||||
me: session ? session.user : await models.user.findUnique({ where: { name: 'k00b' } })
|
me: session ? session.user : null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import { useQuery, gql } from '@apollo/client'
|
|
||||||
// import styles from '../styles/index.module.css'
|
|
||||||
import Layout from '../components/layout'
|
import Layout from '../components/layout'
|
||||||
import Item from '../components/item'
|
import React from 'react'
|
||||||
import Container from 'react-bootstrap/Container'
|
import Items from '../components/items'
|
||||||
|
|
||||||
// function Users () {
|
// function Users () {
|
||||||
// const { loading, error, data } = useQuery(gql`{ users { id, name } }`)
|
// const { loading, error, data } = useQuery(gql`{ users { id, name } }`)
|
||||||
@ -88,42 +86,6 @@ import Container from 'react-bootstrap/Container'
|
|||||||
// )
|
// )
|
||||||
// }
|
// }
|
||||||
|
|
||||||
function Items () {
|
|
||||||
const { loading, error, data } = useQuery(
|
|
||||||
gql`
|
|
||||||
{ items {
|
|
||||||
id
|
|
||||||
createdAt
|
|
||||||
title
|
|
||||||
url
|
|
||||||
user {
|
|
||||||
name
|
|
||||||
}
|
|
||||||
sats
|
|
||||||
comments
|
|
||||||
} }`
|
|
||||||
)
|
|
||||||
if (error) return <div>Failed to load</div>
|
|
||||||
if (loading) return <div>Loading...</div>
|
|
||||||
const { items } = data
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Container className='my-1 py-2 px-sm-0'>
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
{items.map((item, i) => (
|
|
||||||
<tr className='align-items-center' key={item.id}>
|
|
||||||
<td align='right' className='font-weight-bold text-muted mr-1'>{i + 1}</td>
|
|
||||||
<td><Item item={item} /></td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</Container>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Index () {
|
export default function Index () {
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
|
59
pages/items/[id].js
Normal file
59
pages/items/[id].js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import gql from 'graphql-tag'
|
||||||
|
import Item from '../../components/item'
|
||||||
|
import Layout from '../../components/layout'
|
||||||
|
import ApolloClient from '../../api/client'
|
||||||
|
import Reply from '../../components/reply'
|
||||||
|
import Comment from '../../components/comment'
|
||||||
|
import Text from '../../components/text'
|
||||||
|
|
||||||
|
export async function getServerSideProps ({ params }) {
|
||||||
|
const { error, data: { item } } = await ApolloClient.query({
|
||||||
|
query:
|
||||||
|
gql`{
|
||||||
|
item(id: ${params.id}) {
|
||||||
|
id
|
||||||
|
createdAt
|
||||||
|
title
|
||||||
|
url
|
||||||
|
text
|
||||||
|
parentId
|
||||||
|
user {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
sats
|
||||||
|
ncomments
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!item || error) {
|
||||||
|
return {
|
||||||
|
notFound: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
item: item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function FullItem ({ item }) {
|
||||||
|
return (
|
||||||
|
<Layout>
|
||||||
|
{item.parentId
|
||||||
|
? (
|
||||||
|
<Comment item={item} />
|
||||||
|
)
|
||||||
|
: (
|
||||||
|
<>
|
||||||
|
<Item item={item}>
|
||||||
|
{item.text && <Text>{item.text}</Text>}
|
||||||
|
<Reply parentId={item.id} />
|
||||||
|
</Item>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Layout>
|
||||||
|
)
|
||||||
|
}
|
@ -1,13 +0,0 @@
|
|||||||
import Container from "react-bootstrap/Container";
|
|
||||||
import Item from "../../../components/item";
|
|
||||||
import Layout from "../../../components/layout";
|
|
||||||
|
|
||||||
export default function AnItem () {
|
|
||||||
return (
|
|
||||||
<Layout>
|
|
||||||
<Container className='my-4'>
|
|
||||||
<Item />
|
|
||||||
</Container>
|
|
||||||
</Layout>
|
|
||||||
)
|
|
||||||
}
|
|
@ -127,7 +127,7 @@ export function PostForm () {
|
|||||||
|
|
||||||
export default function Post () {
|
export default function Post () {
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout noContain>
|
||||||
<div className={styles.page}>
|
<div className={styles.page}>
|
||||||
<div className={styles.post}>
|
<div className={styles.post}>
|
||||||
<PostForm />
|
<PostForm />
|
||||||
|
@ -34,7 +34,6 @@ $container-max-widths: (
|
|||||||
sm: 540px,
|
sm: 540px,
|
||||||
md: 720px,
|
md: 720px,
|
||||||
lg: 900px,
|
lg: 900px,
|
||||||
xl: 900px
|
|
||||||
) !default;
|
) !default;
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,10 +2,4 @@
|
|||||||
width: 100px;
|
width: 100px;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
background-color: grey;
|
background-color: grey;
|
||||||
}
|
|
||||||
|
|
||||||
.grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: auto auto auto;
|
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user