stacker.news/pages/index.js

130 lines
3.0 KiB
JavaScript
Raw Normal View History

2021-04-12 18:05:09 +00:00
import { useQuery, gql, useMutation } from '@apollo/client'
import { useState } from 'react'
import { useSession } from 'next-auth/client'
import styles from '../styles/index.module.css'
import Layout from '../components/layout'
2021-03-22 20:36:10 +00:00
2021-04-12 18:05:09 +00:00
function Users () {
const { loading, error, data } = useQuery(gql`{ users { id, name } }`)
2021-03-25 19:29:24 +00:00
if (error) return <div>Failed to load</div>
2021-04-12 18:05:09 +00:00
if (loading) return <div>Loading...</div>
2021-03-25 19:29:24 +00:00
const { users } = data
return (
<div>
2021-04-12 18:05:09 +00:00
{users.map(user => (
<div key={user.id}>{user.name}</div>
2021-03-25 19:29:24 +00:00
))}
2021-03-22 20:36:10 +00:00
</div>
)
}
2021-04-12 18:05:09 +00:00
function NewItem ({ parentId }) {
const [session] = useSession()
const [createItem] = useMutation(
gql`
mutation CreateItem($text: String!, $parentId: ID) {
createItem(text: $text, parentId: $parentId) {
id
}
}`, {
update (cache, { data: { createItem } }) {
cache.modify({
fields: {
items (existingItems = [], { readField }) {
const newItemRef = cache.writeFragment({
data: createItem,
fragment: gql`
fragment NewItem on Item {
id
user {
name
}
text
depth
}
`
})
for (let i = 0; i < existingItems.length; i++) {
if (readField('id', existingItems[i]) === parentId) {
return [...existingItems.slice(0, i), newItemRef, ...existingItems.slice(i)]
}
}
return [newItemRef, ...existingItems]
}
}
})
}
})
const [open, setOpen] = useState(false)
if (!session) return null
if (!open) {
return (
<div onClick={() => setOpen(true)}>
{parentId ? 'reply' : 'submit'}
</div>
)
}
let text
return (
<form
style={{ marginLeft: '5px' }}
onSubmit={e => {
e.preventDefault()
createItem({ variables: { text: text.value, parentId } })
setOpen(false)
text.value = ''
}}
>
<textarea
ref={node => {
text = node
}}
/>
<button type='submit'>Submit</button>
</form>
)
}
function Items () {
const { loading, error, data } = useQuery(
gql`
{ items {
id
user {
name
}
text
depth
} }`
)
if (error) return <div>Failed to load</div>
if (loading) return <div>Loading...</div>
const { items } = data
return (
<>
<NewItem />
<div>
{items.map(item => (
<div key={item.id} style={{ marginLeft: `${5 * item.depth}px` }}>
<div>{item.user.name} : {item.text}</div>
<NewItem parentId={item.id} />
</div>
))}
</div>
</>
)
}
export default function Index () {
return (
<Layout>
<div className={`${styles.box} flashit`} />
<Users />
<Items />
</Layout>
)
}