From c46a7603d9a14289357f2d86c5c0b3169cbaf845 Mon Sep 17 00:00:00 2001
From: Solange Duhimbaze Ihirwe
 <159579750+solangeihirwe03@users.noreply.github.com>
Date: Thu, 25 Jul 2024 15:26:52 +0200
Subject: [PATCH] [finished 187584874] seller delete item

---
 src/components/product/SellerProduct.tsx      | 22 +++++++++-
 src/pages/seller/SellerCollection.tsx         | 43 ++++++++++++++++++-
 src/store/features/product/productService.tsx | 12 +++++-
 .../product/sellerCollectionProductsSlice.tsx | 36 ++++++++++++++--
 webpack.dev.config.ts                         |  2 +-
 5 files changed, 107 insertions(+), 8 deletions(-)

diff --git a/src/components/product/SellerProduct.tsx b/src/components/product/SellerProduct.tsx
index d04fff0f..95d0697e 100644
--- a/src/components/product/SellerProduct.tsx
+++ b/src/components/product/SellerProduct.tsx
@@ -12,6 +12,8 @@ import { PuffLoader } from 'react-spinners';
 import { Meta } from '../Meta';
 import { toast } from 'react-toastify';
 import { getErrorMessage } from '../../utils/axios/axiosInstance';
+import { deleteItem } from '../../store/features/product/sellerCollectionProductsSlice';
+import ConfirmModal from './ConfirmModal';
 
 const initialProductState: ISingleProduct = {
     id: "",
@@ -43,6 +45,8 @@ const SellerProduct = ({ productId }: { productId: string }) => {
     const [isThereAnyUpdate, setIsThereAnyUpdate] = useState<boolean>(false);
 
     const [updateLoading, setUpdateLoading] = useState(false);
+    const [showConfirm, setShowConfirm] = useState(false);
+    const [itemToDelete, setItemToDelete] = useState<string | null>(null);
 
     useEffect(() => {
         if (!isAdd) {
@@ -123,6 +127,14 @@ const SellerProduct = ({ productId }: { productId: string }) => {
         }
     };
 
+    const handleDelete = async () => {
+        if (updatedProduct) {
+            await dispatch(deleteItem(itemToDelete)); 
+            setShowConfirm(false);
+            navigate('/seller/products'); 
+        }
+    };
+
     if (isLoading) {
         return (
             <div className="loader">
@@ -150,7 +162,7 @@ const SellerProduct = ({ productId }: { productId: string }) => {
                         <button disabled={(!isThereAnyUpdate && !isImagesUpdated) || updateLoading} className={`edit-btn ${!isThereAnyUpdate && !isImagesUpdated && 'disabled'}`} onClick={handleSaveOrAdd}>
                             <FaSave /> {isAdd ? "ADD" : "UPDATE"}{updateLoading && "ING..."}
                         </button>
-                        {!isAdd && <button className='delete-btn'><FaTrash /> Delete</button>}
+                        {!isAdd && <button className='delete-btn' onClick={() => { setShowConfirm(true); setItemToDelete(productId); }}><FaTrash /> Delete</button>}
                     </div>
                 </div>
 
@@ -233,6 +245,14 @@ const SellerProduct = ({ productId }: { productId: string }) => {
                             </ContentCard>
                         </ContentCard>
                     </div>
+
+                    <ConfirmModal
+                isOpen={showConfirm}
+                title="Are you sure"
+                message={`Deleting this product <i>${product?.name}</i> will be permanently removed from the system. This can't be undone!`}
+                onConfirm={handleDelete}
+                onCancel={() => setShowConfirm(false)}
+            />
                 </div>
             </div>
         </>
diff --git a/src/pages/seller/SellerCollection.tsx b/src/pages/seller/SellerCollection.tsx
index 8b310752..dd28a92c 100644
--- a/src/pages/seller/SellerCollection.tsx
+++ b/src/pages/seller/SellerCollection.tsx
@@ -2,7 +2,7 @@
 import React, { useEffect, useState } from 'react'
 import Table from '../../components/table/Table';
 import { useAppDispatch, useAppSelector } from '../../store/store';
-import { fetchSellerCollectionProduct } from '../../store/features/product/sellerCollectionProductsSlice';
+import { fetchSellerCollectionProduct, deleteItem, removeItem } from '../../store/features/product/sellerCollectionProductsSlice';
 import Zoom from '@mui/material/Zoom';
 import Tooltip from '@mui/material/Tooltip';
 import DeleteIcon from '@mui/icons-material/Delete';
@@ -22,6 +22,13 @@ import { FaEye, FaPlusCircle } from 'react-icons/fa';
 import { ISingleProductInitialResponse } from '../../utils/types/store';
 import { resetUpdateState, updateSellerProductStatus } from '../../store/features/product/sellerProductSlice';
 import { toast } from 'react-toastify';
+import ConfirmModal from '../../components/product/ConfirmModal';
+
+interface DeleteItemState {
+    id: any;
+    name: string;
+}
+
 export default function SellerCollection() {
     const navigate = useNavigate()
     const dispatch = useAppDispatch();
@@ -33,6 +40,26 @@ export default function SellerCollection() {
         dispatch(fetchSellerCollectionProduct())
     }, [dispatch]);
 
+    const [showConfirm, setShowConfirm] = useState(false);
+    const [itemToDelete, setItemToDelete] = useState<DeleteItemState | null>(null);
+
+
+    const handleDelete = async () => {
+        try {
+            setShowConfirm(false)
+            dispatch(removeItem(itemToDelete.id))
+            await dispatch(deleteItem(itemToDelete.id)).unwrap();
+            dispatch(fetchSellerCollectionProduct());
+            setItemToDelete(null)
+        } catch (error) {
+            console.error('Error deleting item:', error);
+        }finally{
+            if(isSuccess)
+            toast.success(message)
+        }
+    };
+
+
     useEffect(() => {
         if (isUpdate && isUpdateSuccess) {
             toast.success(updateMessage);
@@ -69,7 +96,7 @@ export default function SellerCollection() {
                     </IconButton>
                 </Tooltip>
                 <Tooltip TransitionComponent={Zoom} title="Delete" arrow>
-                    <IconButton>
+                    <IconButton onClick={() => { setShowConfirm(true); setItemToDelete({ id: product.id, name: product.name }); }}>
                         <DeleteIcon className='icon__delete' />
                     </IconButton>
                 </Tooltip>
@@ -102,6 +129,8 @@ export default function SellerCollection() {
         setOpen(false);
     };
 
+    const popupMessage = `Deleting this product <i>${itemToDelete?.name}</i> will be permanently removed from the system. This can't be undone!`;
+
     return (
         <div className='seller__main__container'>
             <Meta title={`Seller Products`} />
@@ -162,6 +191,16 @@ export default function SellerCollection() {
                     </Button>
                 </DialogActions>
             </Dialog>
+
+            {showConfirm && (
+                <ConfirmModal
+                    isOpen={showConfirm}
+                    title="Are you sure?"
+                    message={popupMessage}
+                    onConfirm={handleDelete}
+                    onCancel={() => setShowConfirm(false)}
+                />
+            )}
         </div>
     )
 }
diff --git a/src/store/features/product/productService.tsx b/src/store/features/product/productService.tsx
index ed625f8c..504d824e 100644
--- a/src/store/features/product/productService.tsx
+++ b/src/store/features/product/productService.tsx
@@ -97,6 +97,15 @@ const sellerGetOrderHistory = async () => {
   return response.data;
 }
 
+const SellerDeleteItem = async(id: string)=>{
+  try{
+    const response = await axiosInstance.delete(`api/shop/seller-delete-product/${id}`);
+    return response.data
+  }catch(error){
+    throw new Error("failed to delete product")
+  }
+}
+
 const productService = {
   fetchProducts,
   fetchSingleProduct,
@@ -109,6 +118,7 @@ const productService = {
   addSellerProduct,
   updateSellerProductStatus,
   sellerGetAllProducts,
- sellerGetOrderHistory
+ sellerGetOrderHistory,
+ SellerDeleteItem
 }
 export default productService;
\ No newline at end of file
diff --git a/src/store/features/product/sellerCollectionProductsSlice.tsx b/src/store/features/product/sellerCollectionProductsSlice.tsx
index a14d4290..b0916d18 100644
--- a/src/store/features/product/sellerCollectionProductsSlice.tsx
+++ b/src/store/features/product/sellerCollectionProductsSlice.tsx
@@ -43,10 +43,24 @@ export const sellerGetOrderHistory = createAsyncThunk('seller/seller-get-orderHi
     }
 })
 
+export const deleteItem = createAsyncThunk<ISellerCollectionProductInitialResponse, string>("product/deleteProduct", async (id, thunkApi) => {
+    try {
+        const response = await productService.SellerDeleteItem(id)
+        return response
+    } catch (error) {
+        return thunkApi.rejectWithValue(error)
+    }
+})
+
 const sellerCollectionProductsSlice = createSlice({
     name: "sellerCollectionProducts",
     initialState,
-    reducers: {},
+    reducers: {
+        removeItem: (state, action: any) => {
+            const itemId = action.payload
+            state.data.products = state.data?.products.filter((item) =>item.id !== itemId)
+        }
+    },
     extraReducers: (builder) => {
         builder
             .addCase(fetchSellerCollectionProduct.pending, (state) => {
@@ -96,8 +110,24 @@ const sellerCollectionProductsSlice = createSlice({
                 state.isError = false;
                 state.isSuccess = false;
                 state.message = action.payload.message || null
-            });
+            })
+            .addCase(deleteItem.pending, (state) => {
+                state.isError = false,
+                    state.isSuccess = false
+            })
+            .addCase(deleteItem.fulfilled, (state, action: PayloadAction<any>) => {
+                state.isLoading = false,
+                state.isError = false,
+                state.isSuccess = true
+                state.message = action.payload.message
+            })
+            .addCase(deleteItem.rejected, (state, action: PayloadAction<any>) => {
+                state.isLoading = false,
+                    state.isError = true,
+                    state.message = action.payload,
+                    state.isSuccess = false
+            });;
     }
 })
-
+export const {removeItem} = sellerCollectionProductsSlice.actions
 export default sellerCollectionProductsSlice.reducer;
\ No newline at end of file
diff --git a/webpack.dev.config.ts b/webpack.dev.config.ts
index ffb303f6..1b684fa0 100644
--- a/webpack.dev.config.ts
+++ b/webpack.dev.config.ts
@@ -97,7 +97,7 @@ const config: Configuration = {
     historyApiFallback: {
       disableDotRule: true,
     },
-    port: 5000,
+    port: 9000,
     open: true,
     hot: true,
   },