Skip to content

Commit beab140

Browse files
edit/remove address functionality in my profile page
1 parent 9a7f78d commit beab140

File tree

2 files changed

+246
-42
lines changed

2 files changed

+246
-42
lines changed

data.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1916,13 +1916,14 @@
19161916
"password": "Murtaza123",
19171917
"addresses": [
19181918
{
1919-
"name": "Murtaza Tankiwala",
1919+
"name": "Murtaza ",
19201920
"email": "murtazashabbir14@gmail.com",
1921-
"phone": "07869558609",
1921+
"phone": "7869558609",
19221922
"street": "1109 - Noorani Nagar - Near M.Shabbir bhai Khergonewala",
19231923
"city": "Indore",
19241924
"state": "Madhya Pradesh",
1925-
"pinCode": "452002"
1925+
"pinCode": "452002",
1926+
"address": "Indore"
19261927
}
19271928
]
19281929
},

src/features/user/components/UserProfile.js

Lines changed: 242 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,44 @@
11
import React, { useState } from "react";
22
import { useSelector, useDispatch } from "react-redux";
33
import { selectUserInfo, updateUserAsync } from "../userSlice";
4+
import { useForm } from "react-hook-form";
45

56
export 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

Comments
 (0)