1
+ import React from 'react' ;
2
+ import { useHistory , useParams , Link } from "react-router-dom" ;
3
+ import { Formik , Form , Field , ErrorMessage } from 'formik' ;
4
+ import * as Yup from 'yup' ;
5
+ import { useSelector , useDispatch } from 'react-redux' ;
6
+ import { useEffect } from 'react' ;
7
+ import { Table , Row , Col } from 'react-bootstrap' ;
8
+
9
+ const CreateUserSchema = Yup . object ( ) . shape ( {
10
+ userName : Yup . string ( )
11
+ . min ( 3 , 'Too Short!' )
12
+ . max ( 64 , 'Too Long!' )
13
+ . required ( 'Hey input the value!' ) ,
14
+ password : Yup . string ( )
15
+ . min ( 3 , 'Too Short!' )
16
+ . max ( 64 , 'Too Long!' )
17
+ . required ( 'Hey input the value!' )
18
+ } ) ;
19
+
20
+ const EditUserSchema = Yup . object ( ) . shape ( {
21
+ userName : Yup . string ( )
22
+ . min ( 3 , 'Too Short!' )
23
+ . max ( 64 , 'Too Long!' )
24
+ . required ( 'Hey input the value!' ) ,
25
+ } ) ;
26
+
27
+ export const UserCreate = ( ) => {
28
+
29
+ let history = useHistory ( ) ;
30
+ let dispatch = useDispatch ( ) ;
31
+
32
+ const usersContext = useSelector ( state => state . usersContext ) ;
33
+
34
+ useEffect ( ( ) => {
35
+ console . log ( 'usersContext' , usersContext ) ;
36
+ if ( usersContext . isSuccess )
37
+ history . push ( '/user-list' ) ;
38
+ } , [ usersContext . isSuccess ] ) ;
39
+
40
+ return (
41
+ < div >
42
+ < h1 > User entry</ h1 >
43
+ < Formik
44
+ enableReinitialize = { true }
45
+ setFieldValue = { ( field , value ) => console . log ( field , value ) }
46
+ initialValues = { { firstName : '' , lastName : '' , userName : '' , email : '' , phoneNumber : '' , password : '' , errors : usersContext . errors } }
47
+ validationSchema = { CreateUserSchema }
48
+ onSubmit = { ( values , { setSubmitting } ) => {
49
+ console . log ( values ) ;
50
+ dispatch ( {
51
+ type : "ADD_USER" , payload : values
52
+ } ) ;
53
+ setSubmitting ( false ) ;
54
+ } }
55
+ >
56
+ { ( { isSubmitting, values, errors } ) => {
57
+ console . log ( 'errors' , errors , values . errors ) ;
58
+ let keys = Object . keys ( values . errors ) ;
59
+ let validationErrors = [ ] ;
60
+ keys . map ( ( key ) => {
61
+ let value = values . errors [ key ] [ 0 ] ;
62
+ validationErrors . push ( { key, value } ) ;
63
+ } ) ;
64
+ return (
65
+ < Form >
66
+ < div className = "form-group row" >
67
+ < label htmlFor = "firstName" className = "col-sm-2 col-form-label" > First Name</ label >
68
+ < Field className = "col-sm-8 col-form-label" type = "text" name = "firstName" />
69
+ < ErrorMessage className = "col-sm-2 col-form-label text-danger" name = "name" component = "div" />
70
+ </ div >
71
+ < div className = "form-group row" >
72
+ < label htmlFor = "lastName" className = "col-sm-2 col-form-label" > Last Name</ label >
73
+ < Field className = "col-sm-8 col-form-label" type = "text" name = "lastName" />
74
+ < ErrorMessage className = "col-sm-2 col-form-label text-danger" name = "name" component = "div" />
75
+ </ div >
76
+ < div className = "form-group row" >
77
+ < label htmlFor = "userName" className = "col-sm-2 col-form-label" > User Name</ label >
78
+ < Field className = "col-sm-8 col-form-label" type = "text" name = "userName" />
79
+ < ErrorMessage className = "col-sm-2 col-form-label text-danger" name = "userName" component = "div" />
80
+ </ div >
81
+ < div className = "form-group row" >
82
+ < label htmlFor = "email" className = "col-sm-2 col-form-label" > Email</ label >
83
+ < Field className = "col-sm-8 col-form-label" type = "text" name = "email" />
84
+ < ErrorMessage className = "col-sm-2 col-form-label text-danger" name = "name" component = "div" />
85
+ </ div >
86
+ < div className = "form-group row" >
87
+ < label htmlFor = "phoneNumber" className = "col-sm-2 col-form-label" > Phone Number</ label >
88
+ < Field className = "col-sm-8 col-form-label" type = "text" name = "phoneNumber" />
89
+ < ErrorMessage className = "col-sm-2 col-form-label text-danger" name = "phoneNumber" component = "div" />
90
+ </ div >
91
+ < div className = "form-group row" >
92
+ < label htmlFor = "password" className = "col-sm-2 col-form-label" > Password</ label >
93
+ < Field className = "col-sm-8 col-form-label" type = "password" name = "password" />
94
+ < ErrorMessage className = "col-sm-2 col-form-label text-danger" name = "password" component = "div" />
95
+ </ div >
96
+ < div className = "form-group row" >
97
+ < label htmlFor = "errors" className = "col-sm-2 col-form-label" > </ label >
98
+ < ul >
99
+ {
100
+ validationErrors . map ( error =>
101
+ < li className = "text-danger" key = { error . key } >
102
+ { error . value }
103
+ </ li >
104
+ )
105
+ }
106
+ </ ul >
107
+ </ div >
108
+ < div className = "form-group row" >
109
+ < label htmlFor = "name" className = "col-sm-2 col-form-label" > </ label >
110
+ < button type = "submit" disabled = { isSubmitting } > Submit</ button >
111
+ </ div >
112
+ </ Form >
113
+ ) ;
114
+ } }
115
+ </ Formik >
116
+ </ div >
117
+ ) ;
118
+ } ;
119
+
120
+
121
+ export const UserEdit = ( ) => {
122
+
123
+ let history = useHistory ( ) ;
124
+ let dispatch = useDispatch ( ) ;
125
+
126
+ let { id } = useParams ( ) ;
127
+
128
+ const roleContext = useSelector ( state => {
129
+ return state . roleContext ;
130
+ } ) ;
131
+
132
+ const usersContext = useSelector ( state => state . usersContext ) ;
133
+
134
+ useEffect ( ( ) => {
135
+ console . log ( 'usersContext' , usersContext ) ;
136
+ dispatch ( { type : "FETCH_ROLE" } ) ;
137
+ dispatch ( { type : "FETCH_USER_DETAIL" , payload : id } ) ;
138
+
139
+ if ( usersContext . isSuccess )
140
+ history . push ( '/user-list' ) ;
141
+ } , [ usersContext . isSuccess ] ) ;
142
+
143
+ return (
144
+ < div >
145
+ < h1 > User entry</ h1 >
146
+ < Formik
147
+ enableReinitialize = { true }
148
+ setFieldValue = { ( field , value ) => console . log ( field , value ) }
149
+ initialValues = { {
150
+ ...usersContext . selectedUser ,
151
+ errors : usersContext . errors
152
+ } }
153
+ validationSchema = { EditUserSchema }
154
+ onSubmit = { ( values , { setSubmitting } ) => {
155
+ values . id = id ;
156
+ dispatch ( {
157
+ type : "EDIT_USER" , payload : values
158
+ } ) ;
159
+ setSubmitting ( false ) ;
160
+ } }
161
+ >
162
+ { ( { isSubmitting, values, errors } ) => {
163
+ let keys = Object . keys ( values . errors ) ;
164
+ let validationErrors = [ ] ;
165
+ keys . map ( ( key ) => {
166
+ let value = values . errors [ key ] [ 0 ] ;
167
+ validationErrors . push ( { key, value } ) ;
168
+ } ) ;
169
+ return (
170
+ < Form >
171
+ < div className = "form-group row" >
172
+ < label htmlFor = "firstName" className = "col-sm-2 col-form-label" > First name</ label >
173
+ < Field className = "col-sm-8 col-form-label" type = "text" name = "firstName" />
174
+ < ErrorMessage className = "col-sm-2 col-form-label text-danger" name = "name" component = "div" />
175
+ </ div >
176
+ < div className = "form-group row" >
177
+ < label htmlFor = "lastName" className = "col-sm-2 col-form-label" > Last name</ label >
178
+ < Field className = "col-sm-8 col-form-label" type = "text" name = "lastName" />
179
+ < ErrorMessage className = "col-sm-2 col-form-label text-danger" name = "name" component = "div" />
180
+ </ div >
181
+ < div className = "form-group row" >
182
+ < label htmlFor = "userName" className = "col-sm-2 col-form-label" > Username</ label >
183
+ < Field className = "col-sm-8 col-form-label" type = "text" name = "userName" />
184
+ < ErrorMessage className = "col-sm-2 col-form-label text-danger" name = "userName" component = "div" />
185
+ </ div >
186
+ < div className = "form-group row" >
187
+ < label htmlFor = "email" className = "col-sm-2 col-form-label" > Email</ label >
188
+ < Field className = "col-sm-8 col-form-label" type = "text" name = "email" />
189
+ < ErrorMessage className = "col-sm-2 col-form-label text-danger" name = "name" component = "div" />
190
+ </ div >
191
+ < div className = "form-group row" >
192
+ < label htmlFor = "phoneNumber" className = "col-sm-2 col-form-label" > Phone number</ label >
193
+ < Field className = "col-sm-8 col-form-label" type = "text" name = "phoneNumber" />
194
+ < ErrorMessage className = "col-sm-2 col-form-label text-danger" name = "phoneNumber" component = "div" />
195
+ </ div >
196
+ < div className = "form-group row" >
197
+ < label htmlFor = "roleId" className = "col-sm-2 col-form-label" > Roles</ label >
198
+ < Field as = "select" name = "roleId" className = "col-sm-8" >
199
+ < option value = "" key = "" > </ option >
200
+ {
201
+ roleContext . roleList . map ( ( { id, name } ) => {
202
+ return < option value = { id } key = { id } > { name } </ option > ;
203
+ } )
204
+ }
205
+ </ Field >
206
+ < ErrorMessage className = "col-sm-2 col-form-label text-danger" name = "name" component = "div" />
207
+ </ div >
208
+ < div className = "form-group row" >
209
+ < label htmlFor = "password" className = "col-sm-2 col-form-label" > Current password</ label >
210
+ < Field className = "col-sm-8 col-form-label" type = "password" name = "password" placeholder = "Leave empty if you don't want to change password" />
211
+ < ErrorMessage className = "col-sm-2 col-form-label text-danger" name = "password" component = "div" />
212
+ </ div >
213
+ < div className = "form-group row" >
214
+ < label htmlFor = "newPassword" className = "col-sm-2 col-form-label" > New password</ label >
215
+ < Field className = "col-sm-8 col-form-label" type = "password" name = "newPassword" placeholder = "Leave empty if you don't want to change password" />
216
+ < ErrorMessage className = "col-sm-2 col-form-label text-danger" name = "newPassword" component = "div" />
217
+ </ div >
218
+ < div className = "form-group row" >
219
+ < label htmlFor = "isActive" className = "col-sm-2 col-form-label" > Is active</ label >
220
+ < label > < Field type = "checkbox" name = "isActive" /> </ label >
221
+ < ErrorMessage className = "col-sm-2 col-form-label text-danger" name = "isActive" component = "div" />
222
+ </ div >
223
+ < div className = "form-group row" >
224
+ < label htmlFor = "errors" className = "col-sm-2 col-form-label" > </ label >
225
+ < ul >
226
+ {
227
+ validationErrors . map ( error =>
228
+ < li className = "text-danger" key = { error . key } >
229
+ { error . value }
230
+ </ li >
231
+ )
232
+ }
233
+ </ ul >
234
+ </ div >
235
+ < div className = "form-group row" >
236
+ < label htmlFor = "name" className = "col-sm-2 col-form-label" > </ label >
237
+ < button type = "submit" disabled = { isSubmitting } > Submit</ button >
238
+ </ div >
239
+ </ Form >
240
+ ) ;
241
+ } }
242
+ </ Formik >
243
+ </ div >
244
+ ) ;
245
+ } ;
246
+
247
+
248
+ export const UserList = ( ) => {
249
+
250
+ let dispatch = useDispatch ( ) ;
251
+
252
+ const usersContext = useSelector ( state => {
253
+ return state . usersContext ;
254
+ } ) ;
255
+
256
+ useEffect ( ( ) => {
257
+ if ( usersContext . userList . length === 0 || usersContext . shouldReload ) {
258
+ dispatch ( { type : "FETCH_USER" } ) ;
259
+ }
260
+ } , [ usersContext . shouldReload ] ) ;
261
+
262
+ return (
263
+ < >
264
+ < Row >
265
+ < h2 > User List</ h2 >
266
+ </ Row >
267
+ < Row >
268
+ < Col >
269
+ < Table striped bordered hover >
270
+ < thead >
271
+ < tr >
272
+ < th > #</ th >
273
+ < th > Username</ th >
274
+ < th > Phone Number</ th >
275
+ < th > Name</ th >
276
+ < th > Is active</ th >
277
+ < th > </ th >
278
+ </ tr >
279
+ </ thead >
280
+ < tbody >
281
+ {
282
+ usersContext . userList . map ( ( user , index ) => {
283
+ return (
284
+ < tr key = { user . id } >
285
+ < td > { index + 1 } </ td >
286
+ < td > { user . userName } </ td >
287
+ < td > { user . phoneNumber } </ td >
288
+ < td > { user . firstName } { user . lastName } </ td >
289
+ < td > { user . isActive . toString ( ) } </ td >
290
+ < td > < Link to = { `/user-edit/${ user . id } ` } className = "" > Edit</ Link > </ td >
291
+ </ tr >
292
+ )
293
+ } )
294
+ }
295
+ </ tbody >
296
+ </ Table >
297
+ </ Col >
298
+ </ Row >
299
+ </ >
300
+ ) ;
301
+ }
0 commit comments