|
1 | 1 | import { useDispatch, useSelector } from "react-redux"; |
2 | 2 | import { |
| 3 | + clearSelectedProduct, |
3 | 4 | createProductAsync, |
| 5 | + fetchProductByIdAsync, |
4 | 6 | selectBrands, |
5 | 7 | selectCategories, |
| 8 | + selectProductById, |
| 9 | + updateProductAsync, |
6 | 10 | } from "../../product/productSlice"; |
7 | 11 | import { PhotoIcon, UserCircleIcon } from "@heroicons/react/24/solid"; |
8 | 12 | import { useForm } from "react-hook-form"; |
| 13 | +import { useEffect } from "react"; |
| 14 | +import { useParams } from "react-router-dom"; |
9 | 15 | function ProductForm() { |
10 | 16 | const categories = useSelector(selectCategories); |
11 | 17 | const brands = useSelector(selectBrands); |
12 | 18 | const dispatch = useDispatch(); |
| 19 | + const params = useParams(); |
| 20 | + const selectedProduct = useSelector(selectProductById); |
13 | 21 | const { |
14 | 22 | register, |
15 | 23 | handleSubmit, |
| 24 | + setValue, |
| 25 | + reset, |
16 | 26 | formState: { errors }, |
17 | 27 | } = useForm(); |
18 | 28 |
|
| 29 | + useEffect(() => { |
| 30 | + if (params.id) { |
| 31 | + dispatch(fetchProductByIdAsync(params.id)); |
| 32 | + } else { |
| 33 | + dispatch(clearSelectedProduct()); |
| 34 | + } |
| 35 | + }, [params.id, dispatch]); |
| 36 | + |
| 37 | + useEffect(() => { |
| 38 | + if (selectedProduct && params.id) { |
| 39 | + setValue("title", selectedProduct.title); |
| 40 | + setValue("description", selectedProduct.description); |
| 41 | + setValue("brand", selectedProduct.brand); |
| 42 | + setValue("category", selectedProduct.category); |
| 43 | + setValue("price", selectedProduct.price); |
| 44 | + setValue("discountPercentage", selectedProduct.discountPercentage); |
| 45 | + setValue("stock", selectedProduct.stock); |
| 46 | + setValue("thumbnail", selectedProduct.thumbnail); |
| 47 | + setValue("image", selectedProduct.images[0]); |
| 48 | + } |
| 49 | + }, [setValue, params.id, selectedProduct]); |
| 50 | + |
| 51 | + const handleDelete = () => { |
| 52 | + const product = { ...selectedProduct }; |
| 53 | + product.deleted = true; |
| 54 | + dispatch(updateProductAsync(product)); |
| 55 | + }; |
19 | 56 | return ( |
20 | 57 | <form |
21 | 58 | noValidate |
22 | 59 | onSubmit={handleSubmit((data) => { |
23 | 60 | console.log(data); |
24 | 61 | const product = { ...data }; |
25 | | - product.images = [ |
26 | | - product.image1, |
27 | | - product.image2, |
28 | | - product.image3, |
29 | | - product.thumbnail, |
30 | | - ]; |
| 62 | + product.images = [product.image, product.thumbnail]; |
| 63 | + delete product["image"]; |
31 | 64 | product.rating = 0; |
32 | | - delete product["image1"]; |
33 | | - delete product["image2"]; |
34 | | - delete product["image3"]; |
| 65 | + |
| 66 | + product.price = +product.price; |
| 67 | + |
| 68 | + product.discountPercentage = +product.discountPercentage; |
| 69 | + product.stock = +product.stock; |
| 70 | + product.discount = +product.discount; |
35 | 71 | console.log(product); |
36 | | - dispatch(createProductAsync(product)); |
| 72 | + |
| 73 | + if (params.id) { |
| 74 | + product.id = params.id; |
| 75 | + product.rating = selectedProduct.rating || 0; |
| 76 | + dispatch(updateProductAsync(product)); |
| 77 | + reset(); |
| 78 | + } else { |
| 79 | + dispatch(createProductAsync(product)); |
| 80 | + reset(); |
| 81 | + } |
37 | 82 | })} |
38 | 83 | > |
39 | 84 | <div className="space-y-12 bg-white p-12"> |
@@ -214,59 +259,19 @@ function ProductForm() { |
214 | 259 |
|
215 | 260 | <div className="sm:col-span-6"> |
216 | 261 | <label |
217 | | - htmlFor="image1" |
218 | | - className="block text-sm font-medium leading-6 text-gray-900" |
219 | | - > |
220 | | - Image1 |
221 | | - </label> |
222 | | - <div className="mt-2"> |
223 | | - <div className="flex rounded-md shadow-sm ring-1 ring-inset ring-gray-300 focus-within:ring-2 focus-within:ring-inset focus-within:ring-indigo-600"> |
224 | | - <input |
225 | | - type="text" |
226 | | - {...register("image1", { |
227 | | - required: "image1 is required", |
228 | | - })} |
229 | | - id="image1" |
230 | | - className="block flex-1 border-0 bg-transparent py-1.5 pl-1 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6" |
231 | | - /> |
232 | | - </div> |
233 | | - </div> |
234 | | - </div> |
235 | | - <div className="sm:col-span-6"> |
236 | | - <label |
237 | | - htmlFor="image2" |
238 | | - className="block text-sm font-medium leading-6 text-gray-900" |
239 | | - > |
240 | | - Image2 |
241 | | - </label> |
242 | | - <div className="mt-2"> |
243 | | - <div className="flex rounded-md shadow-sm ring-1 ring-inset ring-gray-300 focus-within:ring-2 focus-within:ring-inset focus-within:ring-indigo-600"> |
244 | | - <input |
245 | | - type="text" |
246 | | - {...register("image2", { |
247 | | - required: "image2 is required", |
248 | | - })} |
249 | | - id="image2" |
250 | | - className="block flex-1 border-0 bg-transparent py-1.5 pl-1 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6" |
251 | | - /> |
252 | | - </div> |
253 | | - </div> |
254 | | - </div> |
255 | | - <div className="sm:col-span-6"> |
256 | | - <label |
257 | | - htmlFor="image3" |
| 262 | + htmlFor="image" |
258 | 263 | className="block text-sm font-medium leading-6 text-gray-900" |
259 | 264 | > |
260 | | - Image3 |
| 265 | + Image |
261 | 266 | </label> |
262 | 267 | <div className="mt-2"> |
263 | 268 | <div className="flex rounded-md shadow-sm ring-1 ring-inset ring-gray-300 focus-within:ring-2 focus-within:ring-inset focus-within:ring-indigo-600"> |
264 | 269 | <input |
265 | 270 | type="text" |
266 | | - {...register("image3", { |
267 | | - required: "image3 is required", |
| 271 | + {...register("image", { |
| 272 | + required: "image is required", |
268 | 273 | })} |
269 | | - id="image3" |
| 274 | + id="image" |
270 | 275 | className="block flex-1 border-0 bg-transparent py-1.5 pl-1 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6" |
271 | 276 | /> |
272 | 277 | </div> |
@@ -360,6 +365,14 @@ function ProductForm() { |
360 | 365 | > |
361 | 366 | Cancel |
362 | 367 | </button> |
| 368 | + {selectedProduct && ( |
| 369 | + <button |
| 370 | + onClick={handleDelete} |
| 371 | + className="rounded-md bg-red-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600" |
| 372 | + > |
| 373 | + Delete |
| 374 | + </button> |
| 375 | + )} |
363 | 376 | <button |
364 | 377 | type="submit" |
365 | 378 | 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" |
|
0 commit comments