stacker.news/components/user-header.js

138 lines
4.0 KiB
JavaScript
Raw Normal View History

2021-05-21 22:32:21 +00:00
import { Button } from 'react-bootstrap'
2021-04-22 22:14:32 +00:00
import Link from 'next/link'
import { useRouter } from 'next/router'
import Nav from 'react-bootstrap/Nav'
2021-05-21 22:32:21 +00:00
import { useState } from 'react'
import { Form, Input, SubmitButton } from './form'
import InputGroup from 'react-bootstrap/InputGroup'
import * as Yup from 'yup'
2021-05-22 00:09:11 +00:00
import { gql, useApolloClient, useMutation } from '@apollo/client'
2021-05-25 00:08:56 +00:00
import styles from './user-header.module.css'
import { useMe } from './me'
2021-05-21 22:32:21 +00:00
const NAME_QUERY =
gql`
query nameAvailable($name: String!) {
nameAvailable(name: $name)
}
`
2021-04-22 22:14:32 +00:00
2021-05-22 00:09:11 +00:00
const NAME_MUTATION =
gql`
mutation setName($name: String!) {
setName(name: $name)
}
`
2021-04-22 22:14:32 +00:00
export default function UserHeader ({ user }) {
2021-05-21 22:32:21 +00:00
const [editting, setEditting] = useState(false)
const me = useMe()
2021-04-22 22:14:32 +00:00
const router = useRouter()
2021-05-21 22:32:21 +00:00
const client = useApolloClient()
2021-05-22 00:09:11 +00:00
const [setName] = useMutation(NAME_MUTATION)
2021-05-21 22:32:21 +00:00
2021-09-23 17:42:00 +00:00
const Satistics = () => <h1 className='mb-0'><small className='text-success'>{user.sats} sats \ {user.stacked} stacked</small></h1>
2021-05-21 22:32:21 +00:00
const UserSchema = Yup.object({
name: Yup.string()
.required('required')
.matches(/^[\w_]+$/, 'only letters, numbers, and _')
.max(32, 'too long')
.test({
name: 'name',
test: async name => {
if (!name || !name.length) return false
const { data } = await client.query({ query: NAME_QUERY, variables: { name } })
return data.nameAvailable
},
message: 'taken'
})
})
2021-04-22 22:14:32 +00:00
return (
<>
2021-09-23 17:42:00 +00:00
<div>
{editting
? (
<Form
schema={UserSchema}
initial={{
name: user.name
}}
validateImmediately
onSubmit={async ({ name }) => {
if (name === user.name) {
setEditting(false)
return
}
const { error } = await setName({ variables: { name } })
if (error) {
throw new Error({ message: error.toString() })
}
router.replace(`/${name}`)
2021-09-07 13:25:19 +00:00
2021-09-23 17:42:00 +00:00
client.writeFragment({
id: `User:${user.id}`,
fragment: gql`
2021-09-07 13:25:19 +00:00
fragment CurUser on User {
name
}
`,
2021-09-23 17:42:00 +00:00
data: {
name
}
})
2021-09-07 13:25:19 +00:00
2021-09-23 17:42:00 +00:00
setEditting(false)
}}
>
2021-09-24 21:28:21 +00:00
<div className='d-flex align-items-center'>
<Input
prepend=<InputGroup.Text>@</InputGroup.Text>
name='name'
autoFocus
groupClassName={`mb-0 ${styles.username}`}
showValid
/>
<SubmitButton variant='link' onClick={() => setEditting(true)}>save</SubmitButton>
</div>
2021-09-23 17:42:00 +00:00
</Form>
)
: (
<div className='d-flex align-items-center'>
<h2 className='mb-0'>@{user.name}</h2>
{me?.name === user.name &&
2021-09-23 17:42:00 +00:00
<Button variant='link' onClick={() => setEditting(true)}>edit nym</Button>}
</div>
)}
<Satistics user={user} />
</div>
2021-04-22 22:14:32 +00:00
<Nav
2021-09-23 17:42:00 +00:00
className={styles.nav}
2021-04-22 22:14:32 +00:00
activeKey={router.asPath}
>
<Nav.Item>
<Link href={'/' + user.name} passHref>
2021-09-23 17:42:00 +00:00
<Nav.Link>bio</Nav.Link>
</Link>
</Nav.Item>
<Nav.Item>
<Link href={'/' + user.name + '/posts'} passHref>
2021-04-22 22:14:32 +00:00
<Nav.Link>{user.nitems} posts</Nav.Link>
</Link>
</Nav.Item>
<Nav.Item>
<Link href={'/' + user.name + '/comments'} passHref>
<Nav.Link>{user.ncomments} comments</Nav.Link>
</Link>
</Nav.Item>
2021-05-11 15:52:50 +00:00
{/* <Nav.Item>
2021-04-22 22:14:32 +00:00
<Link href={'/' + user.name + '/sativity'} passHref>
2021-09-23 17:42:00 +00:00
<Nav.Link>satistics</Nav.Link>
2021-04-22 22:14:32 +00:00
</Link>
2021-05-11 15:52:50 +00:00
</Nav.Item> */}
2021-04-22 22:14:32 +00:00
</Nav>
</>
)
}