cart display

parent 8ff8f226
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
"@types/react-dom": "^18.2.19", "@types/react-dom": "^18.2.19",
"axios": "^1.6.7", "axios": "^1.6.7",
"bootstrap": "^5.2.3", "bootstrap": "^5.2.3",
"bootstrap-icons": "^1.11.3",
"cors": "^2.8.5", "cors": "^2.8.5",
"express": "^4.18.2", "express": "^4.18.2",
"mongodb": "^6.3.0", "mongodb": "^6.3.0",
...@@ -5719,6 +5720,21 @@ ...@@ -5719,6 +5720,21 @@
"@popperjs/core": "^2.11.6" "@popperjs/core": "^2.11.6"
} }
}, },
"node_modules/bootstrap-icons": {
"version": "1.11.3",
"resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.11.3.tgz",
"integrity": "sha512-+3lpHrCw/it2/7lBL15VR0HEumaBss0+f/Lb6ZvHISn1mlK83jjFpooTLsMWbIjJMDjDjOExMsTxnXSIT4k4ww==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/twbs"
},
{
"type": "opencollective",
"url": "https://opencollective.com/bootstrap"
}
]
},
"node_modules/brace-expansion": { "node_modules/brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
"@types/react-dom": "^18.2.19", "@types/react-dom": "^18.2.19",
"axios": "^1.6.7", "axios": "^1.6.7",
"bootstrap": "^5.2.3", "bootstrap": "^5.2.3",
"bootstrap-icons": "^1.11.3",
"cors": "^2.8.5", "cors": "^2.8.5",
"express": "^4.18.2", "express": "^4.18.2",
"mongodb": "^6.3.0", "mongodb": "^6.3.0",
......
...@@ -109,23 +109,46 @@ app.patch('/updateuser/:id', (req, res) => { ...@@ -109,23 +109,46 @@ app.patch('/updateuser/:id', (req, res) => {
app.get('/cartItems/:userid', (req, res) => { app.get('/cartItems/:userid', (req, res) => {
const userid = req.params.userid const userid = req.params.userid
if(isNaN(userid)){ if(isNaN(userid)){
db.collection('cartitems').find({userId: userid}).toArray() db.collection('cartitems').findOne({userId: userid})
.then(result => { res.send(result) }) .then(result => { res.send(result) })
.catch(error => res.status(500).send(error)) .catch(error => res.status(500).send(error))
} else { } else {
res.status(500).json({ error: 'Invalid UserId' }) res.status(500).json({ error: 'Invalid UserId' })
} }
}) })
app.post('/updateCartItems/:userid', (req, res) => { app.patch('/updateCartItems/:userid', async (req, res) => {
const userid=req.params.userid const userid = req.params.userid;
const newCartItems = req.body.ObjectId const newCartItem = req.body;
console.log(req.body,userid)
// if(isNaN(userid)){ // Check if userid is a number
// db.collection('cartitems').updateOne({userId: userid},{$set:{cartItems:[newCartItems]}}) if (!isNaN(userid)) {
// .then(result => { res.send(result).status(200) }) return res.status(400).json({ error: 'Invalid UserId' });
// .catch(error => res.status(500).send(error)) }
// } else {
// res.status(500).json({ error: 'Invalid UserId' }) try {
// } const cart = await db.collection('cartitems').findOne({ userId: userid });
})
\ No newline at end of file if (!cart) {
// If cart doesn't exist, create a new one with the newCartItem
await db.collection('cartitems').insertOne({ userId: userid, cartItems: [newCartItem] });
return res.status(200).json({ message: 'Cart created with new item' });
}
// Check if the item already exists in the cart
const existingItemIndex = cart.cartItems.findIndex(item => item.id === newCartItem.id);
if (existingItemIndex !== -1) {
// If the item already exists, increase its quantity by 1
cart.cartItems[existingItemIndex].qty += 1;
} else {
// If the item doesn't exist, add it to the cart
cart.cartItems.push(newCartItem);
}
// Update the cart with the modified cartItems
await db.collection('cartitems').updateOne({ userId: userid }, { $set: { cartItems: cart.cartItems } });
return res.status(200).json({ message: 'Cart updated successfully' });
} catch (error) {
return res.status(500).json({ error: error.message });
}
});
import React, { memo } from 'react'; import React, { memo, useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { RootState } from '../../reduxstore/store';
import { fetchCartItems } from '../../reduxstore/cartSlice';
import { useNavigate } from 'react-router-dom';
const Cart = memo(() => { const Cart = memo(() => {
const dispatch=useDispatch()
const navigate=useNavigate()
const cartItems = useSelector((state: RootState) => state.cart.cartItems);
const user = useSelector((state: RootState) => state.userDetails.userDetails);
const capitalizedUserId = user && user.userId ? user.userId.charAt(0).toUpperCase() + user.userId.slice(1) : null;
const [preCartItems,setPreCartItems]=useState(cartItems);
useEffect(()=>{
if(Object.keys(user).length===0){
navigate('/login')
}else{
dispatch(fetchCartItems(user.userId))
}
},[])
const handleCartItems=()=>{
dispatch(fetchCartItems(user.userId))
}
return ( return (
<div> <div>
<div>
<button type="button" onClick={handleCartItems} className="btn btn-primary mx-2" data-bs-toggle="modal" data-bs-target="#exampleModal">
<span className='bi bi-cart'></span> Cart
</button>
<div className="modal fade" id="exampleModal" tabIndex={-1} aria-labelledby="exampleModalLabel" aria-hidden="true">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<h1 className="modal-title fs-5" id="exampleModalLabel">{capitalizedUserId}'s Cart</h1>
<button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div className="modal-body">
<table className='table table-hover'>
<thead>
<tr>
<th>Preview</th>
<th>Price</th>
<th>Quantity</th>
<th>Total</th>
</tr>
</thead>
<tbody>
{
cartItems && cartItems.map((item)=><tr key={item.id}>
<td><img src={item.image} width={100} height={100}/></td>
<td>{item.price}</td>
<td>$ {item.qty}</td>
<td>$ {item.price * item.qty}</td>
</tr>)
}
</tbody>
</table>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" className="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</div>
</div> </div>
); );
}); });
......
...@@ -2,6 +2,8 @@ import React, { memo } from 'react'; ...@@ -2,6 +2,8 @@ import React, { memo } 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 { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import Cart from '../Cart/Cart';
import Profile from '../Profile/Profile';
type NavButtonsProps = { type NavButtonsProps = {
...@@ -11,17 +13,20 @@ type NavButtonsProps = { ...@@ -11,17 +13,20 @@ type NavButtonsProps = {
const NavButtons = memo((props:NavButtonsProps) => { const NavButtons = memo((props:NavButtonsProps) => {
const user = useSelector((state: RootState) => state.userDetails.userDetails); const user = useSelector((state: RootState) => state.userDetails.userDetails);
return ( return (
<div> <div className='d-flex'>
{ user && (Object.keys(user).length===0 && user.constructor === Object) ?( { user && (Object.keys(user).length===0 && user.constructor === Object) ?(
<div className='nav-login-cart'> <div className='nav-login-cart'>
<Link to="/login"><button>Login</button></Link> <Link to="/login"><button>Login</button></Link>
<Link to="/register"> <Link to="/register">
<button>Register</button></Link> <button>Register</button></Link>
</div> </div>
): ( ): (<>
<Profile/>
<Cart/>
<Link to="/"> <Link to="/">
<button className='btn btn-danger' onClick={props.handleLogout}>Logout</button> <button className='btn btn-danger' onClick={props.handleLogout}>Logout</button>
</Link> </Link>
</>
) } ) }
</div> </div>
); );
......
import React, { memo } from 'react'; import React, { memo } from 'react';
import { useSelector } from 'react-redux';
import { RootState } from '../../reduxstore/store';
const Profile = memo(() => { const Profile = memo(() => {
const userData = useSelector((state: RootState) => state.userDetails.userDetails);
return ( return (
<div> <div>
<button type="button" className="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
<span className='bi bi-person'></span>
</button>
<div className="modal fade" id="exampleModal" tabIndex={-1} aria-labelledby="exampleModalLabel" aria-hidden="true">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<h1 className="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
<button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div className="modal-body">
...
</div>
<div className="modal-footer">
<button type="button" className="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" className="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</div> </div>
); );
}); });
......
...@@ -19,7 +19,7 @@ const Products = memo(() => { ...@@ -19,7 +19,7 @@ const Products = memo(() => {
navigate('/login'); navigate('/login');
} else { } else {
dispatch(fetchProducts()); dispatch(fetchProducts());
console.log(user) // console.log(user)
} }
} else { } else {
navigate('/login'); navigate('/login');
......
...@@ -5,6 +5,7 @@ import App from './App'; ...@@ -5,6 +5,7 @@ import App from './App';
import reportWebVitals from './reportWebVitals'; import reportWebVitals from './reportWebVitals';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css'; import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import '../node_modules/bootstrap/dist/js/bootstrap.bundle' import '../node_modules/bootstrap/dist/js/bootstrap.bundle'
import '../node_modules/bootstrap-icons/font/bootstrap-icons.css'
const root = ReactDOM.createRoot( const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement document.getElementById('root') as HTMLElement
......
...@@ -15,7 +15,7 @@ const initialState: cartStateType = { ...@@ -15,7 +15,7 @@ const initialState: cartStateType = {
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); .then(response => response.data.cartItems);
}); });
const cartSlice = createSlice({ const cartSlice = createSlice({
......
...@@ -9,7 +9,7 @@ type updateCartStateType = { ...@@ -9,7 +9,7 @@ type updateCartStateType = {
type CartItemType = { type CartItemType = {
userId:string, userId:string,
updateCartlist:any updateCartItems:any
} }
const initialState: updateCartStateType = { const initialState: updateCartStateType = {
...@@ -18,9 +18,8 @@ const initialState: updateCartStateType = { ...@@ -18,9 +18,8 @@ const initialState: updateCartStateType = {
error: '' error: ''
}; };
export const updateCartItems:any= createAsyncThunk('updatecart/updateCartItems', async ({userId,updateCartlist}:CartItemType) => { export const updateCartItems:any= createAsyncThunk('updatecart/updateCartItems', async ({userId,updateCartItems}:CartItemType) => {
console.log(updateCartlist) return await axios.patch(`http://localhost:4000/updateCartItems/${userId}`,updateCartItems)
return await axios.post(`http://localhost:4000/updateCartItems/${userId}`,updateCartlist)
.then(response => response.data); .then(response => response.data);
}); });
......
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