Post.tsx 3.01 KB
Newer Older
Yogi's avatar
Yogi committed
1
import { gql, useMutation } from '@apollo/client'
Yogi's avatar
Yogi committed
2
import Attachments from '@components/Post/SinglePost/Attachments'
Yogi's avatar
Yogi committed
3
4
5
6
7
import { Button } from '@components/UI/Button'
import { ErrorMessage } from '@components/UI/ErrorMessage'
import { Form, useZodForm } from '@components/UI/Form'
import { Spinner } from '@components/UI/Spinner'
import { TextArea } from '@components/UI/TextArea'
Yogi's avatar
Yogi committed
8
9
10
11
import {
  CreatePostMutation,
  CreatePostMutationVariables
} from '@graphql/types.generated'
Yogi's avatar
Yogi committed
12
import { PencilAltIcon } from '@heroicons/react/outline'
Yogi's avatar
Yogi committed
13
import { useRouter } from 'next/router'
Yogi's avatar
Yogi committed
14
import React, { useState } from 'react'
Yogi's avatar
Yogi committed
15
import toast from 'react-hot-toast'
Yogi's avatar
Yogi committed
16
import { object, string } from 'zod'
Yogi's avatar
Yogi committed
17
18

import Attachment from '../Attachment'
Yogi's avatar
Yogi committed
19
import SelectTarget from '../SelectTarget'
Yogi's avatar
Yogi committed
20
21

const newPostSchema = object({
Yogi's avatar
Yogi committed
22
23
24
  body: string()
    .min(1, { message: '馃摐 Post should not be empty' })
    .max(10000, { message: '馃摐 Post should not exceed 10000 characters' })
Yogi's avatar
Yogi committed
25
26
27
})

const PostType: React.FC = () => {
Yogi's avatar
Yogi committed
28
  const router = useRouter()
Yogi's avatar
Yogi committed
29
  const [attachments, setAttachments] = useState<string[]>([])
Yogi's avatar
Yogi committed
30
31
32
33
  const [selectedTarget, setSelectedTarget] = useState({
    targetId: '',
    targetType: ''
  })
Yogi's avatar
Yogi committed
34
  const [createPost, createPostResult] = useMutation<
Yogi's avatar
Yogi committed
35
36
    CreatePostMutation,
    CreatePostMutationVariables
Yogi's avatar
Yogi committed
37
38
  >(
    gql`
Yogi's avatar
Yogi committed
39
      mutation CreatePost($input: CreatePostInput!) {
Yogi's avatar
Yogi committed
40
41
42
43
44
45
46
        createPost(input: $input) {
          id
          body
        }
      }
    `,
    {
Yogi's avatar
Yogi committed
47
      onCompleted(data) {
Yogi's avatar
Yogi committed
48
        setAttachments([])
Yogi's avatar
Yogi committed
49
        form.reset()
Yogi's avatar
Yogi committed
50
        toast.success('Post has been created successfully!')
Yogi's avatar
Yogi committed
51
        router.push(`/posts/${data?.createPost?.id}`)
Yogi's avatar
Yogi committed
52
53
54
55
56
57
58
59
60
61
62
63
      }
    }
  )

  const form = useZodForm({
    schema: newPostSchema
  })

  return (
    <Form
      form={form}
      className="space-y-1"
Yogi's avatar
Yogi committed
64
      onSubmit={({ body }) =>
Yogi's avatar
Yogi committed
65
66
67
68
69
        createPost({
          variables: {
            input: {
              body,
              type: 'POST',
Yogi's avatar
Yogi committed
70
71
              attachments:
                attachments.length > 0 ? JSON.stringify(attachments) : null,
Yogi's avatar
Yogi committed
72
73
              targetId: selectedTarget.targetId,
              targetType: selectedTarget.targetType
Yogi's avatar
Yogi committed
74
75
76
            }
          }
        })
Yogi's avatar
Yogi committed
77
      }
Yogi's avatar
Yogi committed
78
    >
79
      <ErrorMessage error={createPostResult.error} className="mb-1" />
Yogi's avatar
Yogi committed
80
81
      <TextArea {...form.register('body')} placeholder="What's on your mind?" />
      <div className="flex items-center justify-between">
Yogi's avatar
Yogi committed
82
83
84
85
86
        <div className="flex space-x-2">
          <Attachment
            attachments={attachments}
            setAttachments={setAttachments}
          />
Yogi's avatar
Yogi committed
87
          <SelectTarget setSelectedTarget={setSelectedTarget} />
Yogi's avatar
Yogi committed
88
        </div>
Yogi's avatar
Yogi committed
89
90
91
92
93
94
95
96
97
98
99
        <Button
          type="submit"
          icon={
            form.formState.isSubmitting ? (
              <Spinner size="xs" />
            ) : (
              <PencilAltIcon className="h-4 w-4" />
            )
          }
        >
          Post
Yogi's avatar
Yogi committed
100
101
102
103
104
105
106
107
108
109
110
111
        </Button>
      </div>
      <Attachments
        attachments={attachments}
        setAttachments={setAttachments}
        isNew
      />
    </Form>
  )
}

export default PostType