1
1
import React , { useState } from "react" ;
2
2
import { useSelector , useDispatch } from "react-redux" ;
3
3
import { selectUserInfo , updateUserAsync } from "../userSlice" ;
4
+ import { useForm } from "react-hook-form" ;
4
5
5
6
export default function UserProfile ( ) {
6
7
const dispatch = useDispatch ( ) ;
7
8
const user = useSelector ( selectUserInfo ) ;
8
- const handleEdit = ( ) => { } ;
9
+ const [ selectedEditIndex , setSelectedEditIndex ] = useState ( - 1 ) ;
10
+ const {
11
+ register,
12
+ handleSubmit,
13
+ reset,
14
+ setValue,
15
+ formState : { errors } ,
16
+ } = useForm ( ) ;
17
+ // to edit existing form data
18
+ const handleEdit = ( addressUpdate , index ) => {
19
+ const newUser = { ...user , addresses : [ ...user . addresses ] } ; //for shallow copy issue
20
+ newUser . addresses . splice ( index , 1 , addressUpdate ) ;
21
+ dispatch ( updateUserAsync ( newUser ) ) ;
22
+ setSelectedEditIndex ( - 1 ) ;
23
+ } ;
24
+ // to remove existing address
9
25
const handleRemove = ( e , index ) => {
10
26
const newUser = { ...user , addresses : [ ...user . addresses ] } ; //for shallow copy issue
11
27
newUser . addresses . splice ( index , 1 ) ;
12
28
dispatch ( updateUserAsync ( newUser ) ) ;
13
29
} ;
30
+ // to show and edit form values....
31
+ const handleEditForm = ( index ) => {
32
+ setSelectedEditIndex ( index ) ;
33
+ const address = user . addresses [ index ] ; // to grab address according to index...
34
+ setValue ( "name" , address . name ) ;
35
+ setValue ( "email" , address . email ) ;
36
+ setValue ( "phone" , address . phone ) ;
37
+ setValue ( "street" , address . street ) ;
38
+ setValue ( "address" , address . city ) ;
39
+ setValue ( "state" , address . state ) ;
40
+ setValue ( "pinCode" , address . pinCode ) ;
41
+ } ;
14
42
15
43
return (
16
44
< div >
@@ -27,47 +55,222 @@ export default function UserProfile() {
27
55
< div className = "border-t border-gray-200 px-4 py-6 sm:px-6" >
28
56
< p className = "mt-0.5 text-sm text-gray-500" > Your Addresses:</ p >
29
57
{ user . addresses . map ( ( address , index ) => (
30
- < div className = "flex justify-between gap-x-6 px-5 py-5 border-solid border-2 border-gray-200" >
31
- < div className = "flex gap-x-4" >
32
- < div className = "min-w-0 flex-auto" >
33
- < p className = "text-sm font-semibold leading-6 text-gray-900" >
34
- { address . name }
35
- </ p >
36
- < p className = "mt-1 truncate text-xs leading-5 text-gray-500" >
37
- { address . street }
58
+ < div >
59
+ { selectedEditIndex === index ? (
60
+ < form
61
+ className = "bg-white px-5 py-12 mt-12"
62
+ noValidate
63
+ onSubmit = { handleSubmit ( ( data ) => {
64
+ console . log ( data ) ;
65
+ handleEdit ( data , index ) ;
66
+ reset ( ) ;
67
+ } ) }
68
+ >
69
+ < div className = "space-y-12" >
70
+ < div className = "border-b border-gray-900/10 pb-12" >
71
+ < h2 className = "text-2xl font-semibold leading-7 text-gray-900" >
72
+ Personal Information
73
+ </ h2 >
74
+ < p className = "mt-1 text-sm leading-6 text-gray-600" >
75
+ Use a permanent address where you can receive mail.
76
+ </ p >
77
+
78
+ < div className = "mt-10 grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6" >
79
+ < div className = "sm:col-span-4" >
80
+ < label
81
+ htmlFor = "name"
82
+ className = "block text-sm font-medium leading-6 text-gray-900"
83
+ >
84
+ Full Name
85
+ </ label >
86
+ < div className = "mt-2" >
87
+ < input
88
+ type = "text"
89
+ { ...register ( "name" , {
90
+ required : "name is required" ,
91
+ } ) }
92
+ id = "name"
93
+ className = "block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
94
+ />
95
+ </ div >
96
+ </ div >
97
+
98
+ < div className = "sm:col-span-4" >
99
+ < label
100
+ htmlFor = "email"
101
+ className = "block text-sm font-medium leading-6 text-gray-900"
102
+ >
103
+ Email address
104
+ </ label >
105
+ < div className = "mt-2" >
106
+ < input
107
+ id = "email"
108
+ { ...register ( "email" , {
109
+ required : "email is required" ,
110
+ } ) }
111
+ type = "email"
112
+ className = "block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
113
+ />
114
+ </ div >
115
+ </ div >
116
+
117
+ < div className = "sm:col-span-3" >
118
+ < label
119
+ htmlFor = "Phone"
120
+ className = "block text-sm font-medium leading-6 text-gray-900"
121
+ >
122
+ Phone
123
+ </ label >
124
+ < div className = "mt-2" >
125
+ < input
126
+ id = "email"
127
+ { ...register ( "phone" , {
128
+ required : "phone is required" ,
129
+ } ) }
130
+ type = "tel"
131
+ className = "block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
132
+ />
133
+ </ div >
134
+ </ div >
135
+
136
+ < div className = "col-span-full" >
137
+ < label
138
+ htmlFor = "street-address"
139
+ className = "block text-sm font-medium leading-6 text-gray-900"
140
+ >
141
+ Street address
142
+ </ label >
143
+ < div className = "mt-2" >
144
+ < input
145
+ type = "text"
146
+ { ...register ( "street" , {
147
+ required : "street is required" ,
148
+ } ) }
149
+ id = "street-address"
150
+ className = "block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
151
+ />
152
+ </ div >
153
+ </ div >
154
+
155
+ < div className = "sm:col-span-2 sm:col-start-1" >
156
+ < label
157
+ htmlFor = "city"
158
+ className = "block text-sm font-medium leading-6 text-gray-900"
159
+ >
160
+ City
161
+ </ label >
162
+ < div className = "mt-2" >
163
+ < input
164
+ type = "text"
165
+ { ...register ( "city" , {
166
+ required : "city is required" ,
167
+ } ) }
168
+ id = "city"
169
+ className = "block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
170
+ />
171
+ </ div >
172
+ </ div >
173
+
174
+ < div className = "sm:col-span-2" >
175
+ < label
176
+ htmlFor = "state"
177
+ className = "block text-sm font-medium leading-6 text-gray-900"
178
+ >
179
+ State / Province
180
+ </ label >
181
+ < div className = "mt-2" >
182
+ < input
183
+ type = "text"
184
+ { ...register ( "state" , {
185
+ required : "state is required" ,
186
+ } ) }
187
+ id = "state"
188
+ className = "block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
189
+ />
190
+ </ div >
191
+ </ div >
192
+
193
+ < div className = "sm:col-span-2" >
194
+ < label
195
+ htmlFor = "pinCode"
196
+ className = "block text-sm font-medium leading-6 text-gray-900"
197
+ >
198
+ ZIP / Postal code
199
+ </ label >
200
+ < div className = "mt-2" >
201
+ < input
202
+ type = "text"
203
+ { ...register ( "pinCode" , {
204
+ required : "pinCode is required" ,
205
+ } ) }
206
+ id = "pinCode"
207
+ className = "block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
208
+ />
209
+ </ div >
210
+ </ div >
211
+ </ div >
212
+ </ div >
213
+
214
+ < div className = "mt-6 flex items-center justify-end gap-x-6" >
215
+ < button
216
+ onClick = { ( e ) => setSelectedEditIndex ( - 1 ) }
217
+ type = "submit"
218
+ className = "rounded-md px-3 py-2 text-sm font-semibold text-grey shadow-sm hover:bg-grey-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
219
+ >
220
+ Cancle
221
+ </ button >
222
+ < button
223
+ type = "submit"
224
+ className = "rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
225
+ >
226
+ Edit Address
227
+ </ button >
228
+ </ div >
229
+ </ div >
230
+ </ form >
231
+ ) : null }
232
+ < div className = "flex justify-between gap-x-6 px-5 py-5 border-solid border-2 border-gray-200" >
233
+ < div className = "flex gap-x-4" >
234
+ < div className = "min-w-0 flex-auto" >
235
+ < p className = "text-sm font-semibold leading-6 text-gray-900" >
236
+ { address . name }
237
+ </ p >
238
+ < p className = "mt-1 truncate text-xs leading-5 text-gray-500" >
239
+ { address . street }
240
+ </ p >
241
+ < p className = "mt-1 truncate text-xs leading-5 text-gray-500" >
242
+ { address . pinCode }
243
+ </ p >
244
+ </ div >
245
+ </ div >
246
+ < div className = "hidden sm:flex sm:flex-col sm:items-end" >
247
+ < p className = "text-sm leading-6 text-gray-900" >
248
+ Phone: { address . phone }
38
249
</ p >
39
- < p className = "mt-1 truncate text-xs leading-5 text-gray-500" >
40
- { address . pinCode }
250
+ < p className = "text-sm leading-6 text-gray-500" >
251
+ { address . city }
41
252
</ p >
42
253
</ div >
43
- </ div >
44
- < div className = "hidden sm:flex sm:flex-col sm:items-end" >
45
- < p className = "text-sm leading-6 text-gray-900" >
46
- Phone: { address . phone }
47
- </ p >
48
- < p className = "text-sm leading-6 text-gray-500" >
49
- { address . city }
50
- </ p >
51
- </ div >
52
- < div className = "hidden sm:flex sm:flex-col sm:items-end" >
53
- < button
54
- onClick = { ( e ) => {
55
- handleEdit ( e , address . id ) ;
56
- } }
57
- type = "button"
58
- className = "font-medium text-indigo-600 hover:text-indigo-500"
59
- >
60
- Edit
61
- </ button >
62
- < button
63
- onClick = { ( e ) => {
64
- handleRemove ( e , index ) ;
65
- } }
66
- type = "button"
67
- className = "font-medium text-indigo-600 hover:text-indigo-500"
68
- >
69
- Remove
70
- </ button >
254
+ < div className = "hidden sm:flex sm:flex-col sm:items-end" >
255
+ < button
256
+ onClick = { ( e ) => {
257
+ handleEditForm ( index ) ;
258
+ } }
259
+ type = "button"
260
+ className = "font-medium text-indigo-600 hover:text-indigo-500"
261
+ >
262
+ Edit
263
+ </ button >
264
+ < button
265
+ onClick = { ( e ) => {
266
+ handleRemove ( e , index ) ;
267
+ } }
268
+ type = "button"
269
+ className = "font-medium text-indigo-600 hover:text-indigo-500"
270
+ >
271
+ Remove
272
+ </ button >
273
+ </ div >
71
274
</ div >
72
275
</ div >
73
276
) ) }
0 commit comments