11import React , { useState } from "react" ;
22import { useSelector , useDispatch } from "react-redux" ;
33import { selectUserInfo , updateUserAsync } from "../userSlice" ;
4+ import { useForm } from "react-hook-form" ;
45
56export default function UserProfile ( ) {
67 const dispatch = useDispatch ( ) ;
78 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
925 const handleRemove = ( e , index ) => {
1026 const newUser = { ...user , addresses : [ ...user . addresses ] } ; //for shallow copy issue
1127 newUser . addresses . splice ( index , 1 ) ;
1228 dispatch ( updateUserAsync ( newUser ) ) ;
1329 } ;
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+ } ;
1442
1543 return (
1644 < div >
@@ -27,47 +55,222 @@ export default function UserProfile() {
2755 < div className = "border-t border-gray-200 px-4 py-6 sm:px-6" >
2856 < p className = "mt-0.5 text-sm text-gray-500" > Your Addresses:</ p >
2957 { 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 }
38249 </ 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 }
41252 </ p >
42253 </ 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 >
71274 </ div >
72275 </ div >
73276 ) ) }
0 commit comments