From c2ef7411e94e99279f53142504ea06ad44e53229 Mon Sep 17 00:00:00 2001 From: Saddock Kabandana Date: Mon, 22 Jul 2024 14:26:10 +0200 Subject: [PATCH 1/4] ft-mark-all-notification-as-read (#34) * [#187584881] ft-mark-all-notification-as-read * [#187584881] ft-mark-all-notification-as-read * Requested changes notifications --- package-lock.json | 2 +- src/pages/SellerDeleteItem.tsx | 34 +++++++++++++++++++++ src/store/features/product/productSlice.tsx | 27 +++++++++++++++- 3 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 src/pages/SellerDeleteItem.tsx diff --git a/package-lock.json b/package-lock.json index e837c0f3..b6ab3785 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27256,4 +27256,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/pages/SellerDeleteItem.tsx b/src/pages/SellerDeleteItem.tsx new file mode 100644 index 00000000..48792ea9 --- /dev/null +++ b/src/pages/SellerDeleteItem.tsx @@ -0,0 +1,34 @@ +import React, { useEffect } from 'react' +import { ISingleProduct } from '../utils/types/product'; +import { useAppDispatch, useAppSelector } from '../store/store'; +import { deleteItem } from '../store/features/product/productSlice'; + +interface ProductProps { + id: string; + images: string[]; + name: string; + price: string; + stock: number; + description: string; + discount: number; +} + +const SellerDeleteItem:React.FC= ({id, images, name, price}) => { + const dispatch = useAppDispatch(); + // const { product, isError, isSuccess, isLoading, message }: ISingleProduct = useAppSelector((state: any) => state.products); + + useEffect(()=>{ + dispatch(deleteItem(id)) + },[dispatch]) + + + return ( +
+

{name}

+

{price}

+ +
+ ) +} + +export default SellerDeleteItem diff --git a/src/store/features/product/productSlice.tsx b/src/store/features/product/productSlice.tsx index 663aa8f1..cf6438d7 100644 --- a/src/store/features/product/productSlice.tsx +++ b/src/store/features/product/productSlice.tsx @@ -31,6 +31,15 @@ export const searchProduct = createAsyncThunk("product } ); +export const deleteItem = createAsyncThunk("product/deleteProduct", async(id, thunkApi)=>{ + try{ + const response = await productService.deleteItem(id) + return response + } catch(error){ + return thunkApi.rejectWithValue(error) + } +}) + const productSlice = createSlice({ name: "products", initialState, @@ -69,7 +78,23 @@ const productSlice = createSlice({ state.message = action.payload; state.isSuccess = false; }) - ; + .addCase(deleteItem.pending, (state)=>{ + state.isLoading = true, + state.isError = false, + state.isSuccess = false + }) + .addCase(deleteItem.fulfilled, (state, action: PayloadAction)=>{ + state.isLoading = false, + state.isError = false, + state.products = state.products.filter(product => product.id !== action.payload.id), + state.isSuccess = true + }) + .addCase(deleteItem.rejected, (state, action: PayloadAction)=>{ + state.isLoading = false, + state.isError = true, + state.products = action.payload, + state.isSuccess = false + }); } }) From 1ec126b9ec3e3a6d7ee1c57fee739b2e14b0b5bf Mon Sep 17 00:00:00 2001 From: Solange Duhimbaze Ihirwe <159579750+solangeihirwe03@users.noreply.github.com> Date: Thu, 25 Jul 2024 13:05:34 +0200 Subject: [PATCH 2/4] [start 187584874] seller delete item --- package-lock.json | 2 +- src/App.scss | 1 + src/pages/SellerDeleteItem.tsx | 34 --------------------- src/store/features/product/productSlice.tsx | 27 +--------------- src/utils/axios/axiosInstance.ts | 2 +- 5 files changed, 4 insertions(+), 62 deletions(-) delete mode 100644 src/pages/SellerDeleteItem.tsx diff --git a/package-lock.json b/package-lock.json index b6ab3785..e837c0f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27256,4 +27256,4 @@ } } } -} \ No newline at end of file +} diff --git a/src/App.scss b/src/App.scss index fbf0a796..865a710e 100644 --- a/src/App.scss +++ b/src/App.scss @@ -43,4 +43,5 @@ @import "./assets/styles/liveChat.scss"; @import "./assets//styles/UserProfile.scss"; @import "./assets/styles/SellerSideProduct.scss"; +@import "./assets/styles/SellerDeleteItem.scss"; @import "./assets/styles/SellerDeleteItem.scss" diff --git a/src/pages/SellerDeleteItem.tsx b/src/pages/SellerDeleteItem.tsx deleted file mode 100644 index 48792ea9..00000000 --- a/src/pages/SellerDeleteItem.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React, { useEffect } from 'react' -import { ISingleProduct } from '../utils/types/product'; -import { useAppDispatch, useAppSelector } from '../store/store'; -import { deleteItem } from '../store/features/product/productSlice'; - -interface ProductProps { - id: string; - images: string[]; - name: string; - price: string; - stock: number; - description: string; - discount: number; -} - -const SellerDeleteItem:React.FC= ({id, images, name, price}) => { - const dispatch = useAppDispatch(); - // const { product, isError, isSuccess, isLoading, message }: ISingleProduct = useAppSelector((state: any) => state.products); - - useEffect(()=>{ - dispatch(deleteItem(id)) - },[dispatch]) - - - return ( -
-

{name}

-

{price}

- -
- ) -} - -export default SellerDeleteItem diff --git a/src/store/features/product/productSlice.tsx b/src/store/features/product/productSlice.tsx index cf6438d7..663aa8f1 100644 --- a/src/store/features/product/productSlice.tsx +++ b/src/store/features/product/productSlice.tsx @@ -31,15 +31,6 @@ export const searchProduct = createAsyncThunk("product } ); -export const deleteItem = createAsyncThunk("product/deleteProduct", async(id, thunkApi)=>{ - try{ - const response = await productService.deleteItem(id) - return response - } catch(error){ - return thunkApi.rejectWithValue(error) - } -}) - const productSlice = createSlice({ name: "products", initialState, @@ -78,23 +69,7 @@ const productSlice = createSlice({ state.message = action.payload; state.isSuccess = false; }) - .addCase(deleteItem.pending, (state)=>{ - state.isLoading = true, - state.isError = false, - state.isSuccess = false - }) - .addCase(deleteItem.fulfilled, (state, action: PayloadAction)=>{ - state.isLoading = false, - state.isError = false, - state.products = state.products.filter(product => product.id !== action.payload.id), - state.isSuccess = true - }) - .addCase(deleteItem.rejected, (state, action: PayloadAction)=>{ - state.isLoading = false, - state.isError = true, - state.products = action.payload, - state.isSuccess = false - }); + ; } }) diff --git a/src/utils/axios/axiosInstance.ts b/src/utils/axios/axiosInstance.ts index 171626ef..076f05c4 100644 --- a/src/utils/axios/axiosInstance.ts +++ b/src/utils/axios/axiosInstance.ts @@ -1,6 +1,6 @@ /* eslint-disable */ import axios from "axios"; -export const URL = "https://e-commerce-ninjas-platform-backend.onrender.com"; +export const URL = "http://localhost:5001" //https://e-commerce-ninjas-platform-backend.onrender.com"; const axiosInstance = axios.create({ baseURL: `${URL}`, headers: { From 84323312c64035513152495154a30fd3e8e60b10 Mon Sep 17 00:00:00 2001 From: Solange Duhimbaze Ihirwe <159579750+solangeihirwe03@users.noreply.github.com> Date: Thu, 25 Jul 2024 15:01:26 +0200 Subject: [PATCH 3/4] [finished 187584874] seller delete item --- src/utils/axios/axiosInstance.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/axios/axiosInstance.ts b/src/utils/axios/axiosInstance.ts index 076f05c4..171626ef 100644 --- a/src/utils/axios/axiosInstance.ts +++ b/src/utils/axios/axiosInstance.ts @@ -1,6 +1,6 @@ /* eslint-disable */ import axios from "axios"; -export const URL = "http://localhost:5001" //https://e-commerce-ninjas-platform-backend.onrender.com"; +export const URL = "https://e-commerce-ninjas-platform-backend.onrender.com"; const axiosInstance = axios.create({ baseURL: `${URL}`, headers: { From 4010529d1c1ab01bdcdd534a1da072980a3cb608 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 4/4] [finished 187584874] seller delete item --- src/components/product/SellerProduct.tsx | 22 +++++++++++- src/pages/seller/SellerCollection.tsx | 6 ++-- src/store/features/product/productService.tsx | 12 ++++++- .../product/sellerCollectionProductsSlice.tsx | 36 +++++++++++++++++-- 4 files changed, 68 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(false); const [updateLoading, setUpdateLoading] = useState(false); + const [showConfirm, setShowConfirm] = useState(false); + const [itemToDelete, setItemToDelete] = useState(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 (
@@ -150,7 +162,7 @@ const SellerProduct = ({ productId }: { productId: string }) => { - {!isAdd && } + {!isAdd && }
@@ -233,6 +245,14 @@ const SellerProduct = ({ productId }: { productId: string }) => { + + ${product?.name} will be permanently removed from the system. This can't be undone!`} + onConfirm={handleDelete} + onCancel={() => setShowConfirm(false)} + /> diff --git a/src/pages/seller/SellerCollection.tsx b/src/pages/seller/SellerCollection.tsx index 835555c7..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'; @@ -47,8 +47,8 @@ export default function SellerCollection() { const handleDelete = async () => { try { setShowConfirm(false) - // dispatch(removeItem(itemToDelete.id)) - // await dispatch(deleteItem(itemToDelete.id)).unwrap(); + dispatch(removeItem(itemToDelete.id)) + await dispatch(deleteItem(itemToDelete.id)).unwrap(); dispatch(fetchSellerCollectionProduct()); setItemToDelete(null) } catch (error) { 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("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) => { + state.isLoading = false, + state.isError = false, + state.isSuccess = true + state.message = action.payload.message + }) + .addCase(deleteItem.rejected, (state, action: PayloadAction) => { + 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