1
- import React from 'react' ;
1
+ import React , { useState } from 'react' ;
2
+ import { Comment } from '../types/Comment' ;
3
+ import classNames from 'classnames' ;
4
+ import { Post } from '../types/Post' ;
5
+ import { createComment } from '../api/fetchPosts' ;
6
+
7
+ interface Props {
8
+ post : Post | null ;
9
+ setCommentsList : ( value : ( prev : Comment [ ] ) => Comment [ ] ) => void ;
10
+ setIsError : ( value : boolean ) => void ;
11
+ commentsList : Comment [ ] ;
12
+ }
13
+
14
+ export const NewCommentForm : React . FC < Props > = ( {
15
+ post,
16
+ setCommentsList,
17
+ commentsList,
18
+ setIsError,
19
+ } ) => {
20
+ const [ nameInput , setNameInput ] = useState ( '' ) ;
21
+ const [ emailInput , setEmailInput ] = useState ( '' ) ;
22
+ const [ bodyInput , setBodyInput ] = useState ( '' ) ;
23
+ const [ isLoading , setIsLoading ] = useState ( false ) ;
24
+ const [ nameError , setNameError ] = useState ( false ) ;
25
+ const [ emailError , setEmailError ] = useState ( false ) ;
26
+ const [ bodyError , setBodyError ] = useState ( false ) ;
27
+
28
+ const resetFormAfterSuccesSubmit = ( ) => {
29
+ setNameInput ( nameInput ) ;
30
+ setEmailInput ( emailInput ) ;
31
+ setBodyInput ( '' ) ;
32
+ } ;
33
+
34
+ const resetForm = ( ) => {
35
+ setNameInput ( '' ) ;
36
+ setEmailInput ( '' ) ;
37
+ setBodyInput ( '' ) ;
38
+ setNameError ( false ) ;
39
+ setEmailError ( false ) ;
40
+ setBodyError ( false ) ;
41
+ } ;
42
+
43
+ const submitForm = async ( ) => {
44
+ if ( ! nameInput ) {
45
+ setNameError ( true ) ;
46
+ }
47
+
48
+ if ( ! emailInput ) {
49
+ setEmailError ( true ) ;
50
+ }
51
+
52
+ if ( ! bodyInput ) {
53
+ setBodyError ( true ) ;
54
+ }
55
+
56
+ if ( ! post ?. id ) {
57
+ setIsError ( true ) ;
58
+
59
+ return ;
60
+ }
61
+
62
+ if ( ! nameInput || ! emailInput || ! bodyInput ) {
63
+ return ;
64
+ }
65
+
66
+ setIsLoading ( true ) ;
67
+
68
+ const newComment = {
69
+ postId : post ?. id ,
70
+ name : nameInput ,
71
+ email : emailInput ,
72
+ body : bodyInput ,
73
+ } ;
74
+
75
+ try {
76
+ await createComment ( newComment ) ;
77
+ setCommentsList ( prev => [
78
+ ...prev ,
79
+ { ...newComment , id : commentsList . length + 1 } ,
80
+ ] ) ;
81
+ resetFormAfterSuccesSubmit ( ) ;
82
+ } catch {
83
+ setIsError ( true ) ;
84
+ } finally {
85
+ setIsLoading ( false ) ;
86
+ }
87
+ } ;
2
88
3
- export const NewCommentForm : React . FC = ( ) => {
4
89
return (
5
- < form data-cy = "NewCommentForm" >
90
+ < form
91
+ data-cy = "NewCommentForm"
92
+ onSubmit = { e => {
93
+ e . preventDefault ( ) ;
94
+ submitForm ( ) ;
95
+ } }
96
+ onReset = { resetForm }
97
+ >
6
98
< div className = "field" data-cy = "NameField" >
7
99
< label className = "label" htmlFor = "comment-author-name" >
8
100
Author Name
9
101
</ label >
10
102
11
103
< div className = "control has-icons-left has-icons-right" >
12
104
< input
105
+ value = { nameInput }
13
106
type = "text"
14
107
name = "name"
15
108
id = "comment-author-name"
16
109
placeholder = "Name Surname"
17
- className = "input is-danger"
110
+ className = { classNames ( 'input' , {
111
+ 'is-danger' : nameError && ! nameInput ,
112
+ } ) }
113
+ onChange = { e => {
114
+ setNameInput ( e . target . value ) ;
115
+ setNameError ( false ) ;
116
+ } }
18
117
/>
19
118
20
119
< span className = "icon is-small is-left" >
21
120
< i className = "fas fa-user" />
22
121
</ span >
23
122
24
- < span
25
- className = "icon is-small is-right has-text-danger"
26
- data-cy = "ErrorIcon"
27
- >
28
- < i className = "fas fa-exclamation-triangle" />
29
- </ span >
123
+ { nameError && ! nameInput && (
124
+ < span
125
+ className = "icon is-small is-right has-text-danger"
126
+ data-cy = "ErrorIcon"
127
+ >
128
+ < i className = "fas fa-exclamation-triangle" />
129
+ </ span >
130
+ ) }
30
131
</ div >
31
132
32
- < p className = "help is-danger" data-cy = "ErrorMessage" >
33
- Name is required
34
- </ p >
133
+ { nameError && ! nameInput && (
134
+ < p className = "help is-danger" data-cy = "ErrorMessage" >
135
+ Name is required
136
+ </ p >
137
+ ) }
35
138
</ div >
36
139
37
140
< div className = "field" data-cy = "EmailField" >
@@ -41,28 +144,39 @@ export const NewCommentForm: React.FC = () => {
41
144
42
145
< div className = "control has-icons-left has-icons-right" >
43
146
< input
147
+ value = { emailInput }
44
148
type = "text"
45
149
name = "email"
46
150
id = "comment-author-email"
47
151
48
- className = "input is-danger"
152
+ className = { classNames ( 'input' , {
153
+ 'is-danger' : emailError ,
154
+ } ) }
155
+ onChange = { e => {
156
+ setEmailInput ( e . target . value ) ;
157
+ setEmailError ( false ) ;
158
+ } }
49
159
/>
50
160
51
161
< span className = "icon is-small is-left" >
52
162
< i className = "fas fa-envelope" />
53
163
</ span >
54
164
55
- < span
56
- className = "icon is-small is-right has-text-danger"
57
- data-cy = "ErrorIcon"
58
- >
59
- < i className = "fas fa-exclamation-triangle" />
60
- </ span >
165
+ { emailError && ! emailInput && (
166
+ < span
167
+ className = "icon is-small is-right has-text-danger"
168
+ data-cy = "ErrorIcon"
169
+ >
170
+ < i className = "fas fa-exclamation-triangle" />
171
+ </ span >
172
+ ) }
61
173
</ div >
62
174
63
- < p className = "help is-danger" data-cy = "ErrorMessage" >
64
- Email is required
65
- </ p >
175
+ { emailError && ! emailInput && (
176
+ < p className = "help is-danger" data-cy = "ErrorMessage" >
177
+ Email is required
178
+ </ p >
179
+ ) }
66
180
</ div >
67
181
68
182
< div className = "field" data-cy = "BodyField" >
@@ -72,23 +186,38 @@ export const NewCommentForm: React.FC = () => {
72
186
73
187
< div className = "control" >
74
188
< textarea
189
+ value = { bodyInput }
75
190
id = "comment-body"
76
191
name = "body"
77
192
placeholder = "Type comment here"
78
- className = "textarea is-danger"
193
+ className = { classNames ( 'textarea' , {
194
+ 'is-danger' : bodyError && ! bodyInput ,
195
+ } ) }
196
+ onChange = { e => {
197
+ setBodyInput ( e . target . value ) ;
198
+ setBodyError ( false ) ;
199
+ } }
79
200
/>
80
201
</ div >
81
202
82
- < p className = "help is-danger" data-cy = "ErrorMessage" >
83
- Enter some text
84
- </ p >
203
+ { bodyError && ! bodyInput && (
204
+ < p className = "help is-danger" data-cy = "ErrorMessage" >
205
+ Enter some text
206
+ </ p >
207
+ ) }
85
208
</ div >
86
209
87
210
< div className = "field is-grouped" >
88
211
< div className = "control" >
89
- < button type = "submit" className = "button is-link is-loading" >
212
+ < button
213
+ type = "submit"
214
+ className = { classNames ( 'button is-link' , {
215
+ 'is-loading' : isLoading ,
216
+ } ) }
217
+ >
90
218
Add
91
219
</ button >
220
+ { /* */ }
92
221
</ div >
93
222
94
223
< div className = "control" >
0 commit comments