cart operations updated

parent 78645351
...@@ -127,26 +127,27 @@ app.patch('/updateCartItems/:userid', async (req, res) => { ...@@ -127,26 +127,27 @@ app.patch('/updateCartItems/:userid', async (req, res) => {
} }
try { try {
const cart = await db.collection('cartitems').findOne({ userId: userid }); // const cart = await db.collection('cartitems').findOne({ userId: userid });
if (!cart) { // if (!cart) {
// If cart doesn't exist, create a new one with the newCartItem // // If cart doesn't exist, create a new one with the newCartItem
await db.collection('cartitems').insertOne({ userId: userid, cartItems: [newCartItem] }); // await db.collection('cartitems').insertOne({ userId: userid, cartItems: [newCartItem] });
return res.status(200).json({ message: 'Cart created with new item' }); // return res.status(200).json({ message: 'Cart created with new item' });
} // }
// Check if the item already exists in the cart // // Check if the item already exists in the cart
const existingItemIndex = cart.cartItems.findIndex(item => item.id === newCartItem.id); // const existingItemIndex = cart.cartItems.findIndex(item => item.id === newCartItem.id);
if (existingItemIndex !== -1) { // if (existingItemIndex !== -1) {
// If the item already exists, increase its quantity by 1 // // If the item already exists, increase its quantity by 1
cart.cartItems[existingItemIndex].qty += 1; // cart.cartItems[existingItemIndex].qty += 1;
} else { // } else {
// If the item doesn't exist, add it to the cart // // If the item doesn't exist, add it to the cart
cart.cartItems.push(newCartItem); // cart.cartItems.push(newCartItem);
} // }
// Update the cart with the modified cartItems // // Update the cart with the modified cartItems
await db.collection('cartitems').updateOne({ userId: userid }, { $set: { cartItems: cart.cartItems } }); // await db.collection('cartitems').updateOne({ userId: userid }, { $set: { cartItems: cart.cartItems } });
await db.collection('cartitems').updateOne({ userId: userid }, { $set: { cartItems: newCartItem} });
return res.status(200).json({ message: 'Cart updated successfully' }); return res.status(200).json({ message: 'Cart updated successfully' });
} catch (error) { } catch (error) {
return res.status(500).json({ error: error.message }); return res.status(500).json({ error: error.message });
......
import React, { memo, useEffect, useState } from 'react'; import React, { memo,useMemo, useCallback, useEffect} from 'react';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { RootState } from '../../reduxstore/store'; import { RootState } from '../../reduxstore/store';
import { fetchCartItems } from '../../reduxstore/cartSlice'; import { fetchCartItems, updateCartItems, removeFromCart, clearCart, incrementQuantity, decrementQuantity } from '../../reduxstore/cartSlice';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
const Cart = memo(() => { const Cart = memo(() => {
const dispatch=useDispatch() const dispatch = useDispatch()
const navigate=useNavigate() const navigate = useNavigate()
const cartItems = useSelector((state: RootState) => state.cart.cartItems); const cartItems = useSelector((state: RootState) => state.cart.cartItems);
const user = useSelector((state: RootState) => state.userDetails.userDetails); const user = useSelector((state: RootState) => state.userDetails.userDetails);
const capitalizedUserId = user && user.userId ? user.userId.charAt(0).toUpperCase() + user.userId.slice(1) : null; const capitalizedUserId = user && user.userId ? user.userId.charAt(0).toUpperCase() + user.userId.slice(1) : null;
// const [preCartItems,setPreCartItems]=useState(cartItems);
useEffect(()=>{ useEffect(() => {
if(Object.keys(user).length===0){ if (Object.keys(user).length === 0) {
navigate('/login') navigate('/login')
}else{ } else {
dispatch(fetchCartItems(user.userId)) dispatch(fetchCartItems(user.userId))
} }
},[]) }, [user])
const handleCartItems=()=>{ const handleCartChanges = () => {
dispatch(fetchCartItems(user.userId)) dispatch(updateCartItems({ userId: user.userId, updateCartItems: cartItems }))
} }
const totalPay=useMemo(()=>{
return cartItems.reduce((acc,curr)=>{
return acc=acc+ (parseInt(curr.price) * parseInt(curr.qty));
},0)
},[cartItems])
return ( return (
<div> <div>
<div> <div>
<button type="button" onClick={handleCartItems} className="btn btn-primary mx-2" data-bs-toggle="modal" data-bs-target="#cartModal"> <button type="button" className="btn btn-primary mx-2" data-bs-toggle="modal" data-bs-target="#cartModal">
<span className='bi bi-cart'></span> Cart <span className='bi bi-cart'></span> Cart
</button> </button>
<div className="modal fade" id="cartModal" tabIndex={-1} aria-labelledby="cartModalLabel" aria-hidden="true"> <div className="modal fade" id="cartModal" tabIndex={-1} aria-labelledby="cartModalLabel" aria-hidden="true">
<div className="modal-dialog"> <div className="modal-dialog">
...@@ -36,31 +42,45 @@ const Cart = memo(() => { ...@@ -36,31 +42,45 @@ const Cart = memo(() => {
<button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> <button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div> </div>
<div className="modal-body"> <div className="modal-body">
<table className='table table-hover'> <table className='table table-hover m-0'>
<thead> <thead>
<tr> <tr>
<th>Preview</th> <th>Preview</th>
<th>Price</th> <th>Price</th>
<th>Quantity</th> <th>Quantity</th>
<th>Total</th> <th>Total</th>
<th>Remove</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{ {
cartItems && cartItems.map((item)=><tr key={item.id}> cartItems.length > 0 && cartItems.map((item) => <tr key={item.id}>
<td><img src={item.image} width={100} height={100}/></td> <td><img src={item.image} width={50} height={50} /></td>
<td>{item.price}</td> <td>{item.price}</td>
<td>$ {item.qty}</td> <td>
<td>$ {item.price * item.qty}</td> <span className='d-flex justify-content-start align-items-center'>
<button onClick={()=>{dispatch(decrementQuantity(item))}} className='btn btn-tranparent fw-bolder d-flex justify-content-center align-items-center' style={{ height: "15px", width: "15px" }}>-</button>
<span> {item.qty} </span>
<button onClick={()=>{dispatch(incrementQuantity(item))}} className='btn btn-tranparent fw-bolder d-flex justify-content-center align-items-center' style={{ height: "10px", width: "8px" }}>+</button>
</span>
</td>
<td>$ {(item.price * item.qty).toFixed()}</td>
<td><button onClick={() => dispatch(removeFromCart(item))} className='bi bi-trash text-danger bg-transparent border-0'></button></td>
</tr>) </tr>)
} }
</tbody> </tbody>
<tfoot>
<tr>
<td colSpan={3} align='right'>Total:</td>
<td colSpan={2}>{`${totalPay}`}</td>
</tr>
</tfoot>
</table> </table>
</div> </div>
{/* <div className="modal-footer"> <div className="modal-footer">
<button type="button" className="btn btn-secondary" data-bs-dismiss="modal">Close</button> <button type="button" className="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" className="btn btn-primary">Save changes</button> <button type="button" className="btn btn-primary" onClick={handleCartChanges}>Save Changes</button>
</div> */} </div>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -5,7 +5,6 @@ import { RootState } from '../../reduxstore/store'; ...@@ -5,7 +5,6 @@ import { RootState } from '../../reduxstore/store';
const Profile = memo(() => { const Profile = memo(() => {
const userData = useSelector((state: RootState) => state.userDetails.userDetails); const userData = useSelector((state: RootState) => state.userDetails.userDetails);
useEffect(()=>{console.log(userData)},[userData])
return ( return (
<div> <div>
......
import React, { memo } from 'react'; import React, { memo } from 'react';
import { useDispatch,useSelector } from 'react-redux'; import { useDispatch,useSelector } from 'react-redux';
import { updateCartItems } from '../../reduxstore/updatecartSlice';
import { RootState } from '../../reduxstore/store'; import { RootState } from '../../reduxstore/store';
import { addToCart } from '../../reduxstore/cartSlice';
type ProductType = { type ProductType = {
_id:string _id:string
...@@ -27,7 +27,8 @@ const Product = memo((props: ProductPropsType) => { ...@@ -27,7 +27,8 @@ const Product = memo((props: ProductPropsType) => {
const handleAddtoCart=()=>{ const handleAddtoCart=()=>{
if(Object.keys(user).length!=0){ if(Object.keys(user).length!=0){
dispatch(updateCartItems({userId:user.userId,updateCartItems:props.product})) // dispatch(updateCartItems({userId:user.userId,updateCartItems:props.product}))
dispatch(addToCart(props.product))
} }
} }
......
...@@ -19,7 +19,6 @@ const Products = memo(() => { ...@@ -19,7 +19,6 @@ const Products = memo(() => {
navigate('/login'); navigate('/login');
} else { } else {
dispatch(fetchProducts()); dispatch(fetchProducts());
// console.log(user)
} }
} else { } else {
navigate('/login'); navigate('/login');
...@@ -27,7 +26,7 @@ const Products = memo(() => { ...@@ -27,7 +26,7 @@ const Products = memo(() => {
}, [user]) }, [user])
if (products.loading) { return <div className="text-center mt-5">Loading...</div> } if (products.loading) { return <div className="text-center mt-5">Loading...</div> }
else if(products.error!=="") { return <h1>{products.error}</h1>} else if(products.loading && products.error!="") { return <h1>{products.error}</h1>}
else { else {
return ( return (
<div className='row d-flex justify-content-evenly bg-dark'> <div className='row d-flex justify-content-evenly bg-dark'>
......
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios'; import axios from 'axios';
type cartStateType = { type cartStateType = {
loading: boolean; loading: boolean;
cartItems: any[]; cartItems: any[];
error: string | undefined; error: string | undefined;
}; };
type CartItemType = {
userId: string,
updateCartItems: any
}
const initialState: cartStateType = { const initialState: cartStateType = {
loading: false, loading: false,
...@@ -13,19 +18,72 @@ const initialState: cartStateType = { ...@@ -13,19 +18,72 @@ const initialState: cartStateType = {
error: '' error: ''
}; };
export const fetchCartItems:any= createAsyncThunk('cart/fetchCartItems', async (userid) => { export const fetchCartItems: any = createAsyncThunk('cart/fetchCartItems', async (userid) => {
return await axios.get(`http://localhost:4000/cartItems/${userid}`) return await axios.get(`http://localhost:4000/cartItems/${userid}`)
.then(response => response.data.cartItems); .then(response => response.data.cartItems);
}); });
export const updateCartItems: any = createAsyncThunk('updatecart/updateCartItems', async ({ userId, updateCartItems }: CartItemType) => {
return await axios.patch(`http://localhost:4000/updateCartItems/${userId}`, updateCartItems)
.then(response => {
console.log(response.data);
return response.data
});
});
const cartSlice = createSlice({ const cartSlice = createSlice({
name: 'cartItems', name: 'cartItems',
initialState, initialState,
reducers: {}, reducers: {
addToCart: (state, action) => {
state.loading = true;
let prevCartItems = state.cartItems
const newItem = action.payload;
if (prevCartItems.find((item) => item.id === newItem.id)) {
const index = prevCartItems.indexOf(prevCartItems.find((item) => item.id === newItem.id));
let updatedItem = { ...prevCartItems[index], qty: prevCartItems[index].qty + 1 };
prevCartItems[index] = updatedItem;
state.cartItems = [...prevCartItems];
} else {
prevCartItems.push(newItem);
}
},
removeFromCart: (state, action) => {
state.loading = true;
const removeItem = action.payload;
console.log(removeItem)
const filteredItems = state.cartItems.filter((item) => item.id !== removeItem.id);
state.cartItems = filteredItems;
},
clearCart: (state) => (
{ ...state, cartItems: [] }
),
incrementQuantity: (state, action) => {
let prevCartItems = state.cartItems
const index = prevCartItems.findIndex((item) => item.id === action.payload.id);
if (index !== -1) {
let updatedItem = { ...prevCartItems[index], qty: prevCartItems[index].qty + 1 };
prevCartItems[index] = updatedItem;
state.cartItems = [...prevCartItems];
}
},
decrementQuantity: (state, action) => {
let prevCartItems = state.cartItems
if (action.payload.qty != 1) {
const index = prevCartItems.findIndex((item) => item.id === action.payload.id);
if (index !== -1) {
const updatedItem = { ...prevCartItems[index], qty: prevCartItems[index].qty - 1 };
prevCartItems[index] = updatedItem;
state.cartItems = [...prevCartItems];
}
}
}
},
extraReducers: builder => { extraReducers: builder => {
builder.addCase(fetchCartItems.pending, (state) => { builder.addCase(fetchCartItems.pending, (state) => {
state.loading = true; state.loading = true;
state.error="pending" state.error = "pending"
}); });
builder.addCase(fetchCartItems.fulfilled, (state, action) => { builder.addCase(fetchCartItems.fulfilled, (state, action) => {
state.loading = false; state.loading = false;
...@@ -42,3 +100,4 @@ const cartSlice = createSlice({ ...@@ -42,3 +100,4 @@ const cartSlice = createSlice({
export default cartSlice.reducer; export default cartSlice.reducer;
export type CartStateType = ReturnType<typeof cartSlice.reducer>; export type CartStateType = ReturnType<typeof cartSlice.reducer>;
export const { addToCart, removeFromCart, clearCart, incrementQuantity, decrementQuantity } = cartSlice.actions;
...@@ -3,12 +3,12 @@ import cartReducer,{CartStateType} from './cartSlice' ...@@ -3,12 +3,12 @@ import cartReducer,{CartStateType} from './cartSlice'
import productsReducer,{ProductsStateType} from './productsSlice' import productsReducer,{ProductsStateType} from './productsSlice'
import usersReducer,{UsersStateType} from './usersSlice' import usersReducer,{UsersStateType} from './usersSlice'
import userDetailsslice,{UserDetailsType} from './userDetailsslice' import userDetailsslice,{UserDetailsType} from './userDetailsslice'
import storage from 'redux-persist/lib/storage'; import sessionStorage from 'redux-persist/es/storage/session'
import { persistReducer, persistStore } from 'redux-persist'; import { persistReducer, persistStore } from 'redux-persist';
const persistConfig={ const persistConfig={
key: "root", key: "root",
storage storage:sessionStorage
} }
export type RootState= { export type RootState= {
products:ProductsStateType; products:ProductsStateType;
......
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';
type updateCartStateType = {
loading: boolean;
cartItems: any[];
error: string | undefined;
};
type CartItemType = {
userId:string,
updateCartItems:any
}
const initialState: updateCartStateType = {
loading: false,
cartItems: [],
error: ''
};
export const updateCartItems:any= createAsyncThunk('updatecart/updateCartItems', async ({userId,updateCartItems}:CartItemType) => {
return await axios.patch(`http://localhost:4000/updateCartItems/${userId}`,updateCartItems)
.then(response => response.data);
});
const updatecartSlice = createSlice({
name: 'updatecartItems',
initialState,
reducers: {},
extraReducers: builder => {
builder.addCase(updateCartItems.pending, (state) => {
state.loading = true;
state.error="pending"
});
builder.addCase(updateCartItems.fulfilled, (state, action) => {
state.loading = false;
state.cartItems = action.payload;
state.error = '';
});
builder.addCase(updateCartItems.rejected, (state, action) => {
state.loading = false;
state.cartItems = [];
state.error = action.error || 'Something went wrong!';
});
}
});
export default updatecartSlice.reducer;
export type UpdateCartStateType = ReturnType<typeof updatecartSlice.reducer>;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment