Skip to content

Commit 66fa507

Browse files
committed
done cart reducer
1 parent 69a0eeb commit 66fa507

File tree

9 files changed

+165
-27
lines changed

9 files changed

+165
-27
lines changed

13-cart/src/App.js

+14-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
1-
import React from 'react'
1+
import React, { useEffect } from 'react'
2+
import { useDispatch, useSelector } from 'react-redux'
3+
import CartContainer from './components/CartContainer'
4+
import Navbar from './components/Navbar'
5+
import { calculateTotals } from './features/cart/cartSlice'
26

37
function App() {
8+
const dispatch = useDispatch()
9+
const { cartItems } = useSelector((store) => store.cart)
10+
11+
useEffect(() => {
12+
dispatch(calculateTotals())
13+
}, [cartItems])
14+
415
// if (loading) {
516
// return (
617
// <div className='loading'>
@@ -10,7 +21,8 @@ function App() {
1021
// }
1122
return (
1223
<main>
13-
<p>hiii</p>
24+
<Navbar />
25+
<CartContainer />
1426
</main>
1527
)
1628
}

13-cart/src/CartContainer.js

Whitespace-only changes.

13-cart/src/CartItem.js

Whitespace-only changes.

13-cart/src/Navbar.js

-21
This file was deleted.
+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import React from 'react'
2+
import { useDispatch, useSelector } from 'react-redux'
3+
import { clearCart } from '../features/cart/cartSlice'
4+
import CartItem from './CartItem'
5+
6+
const CartContainer = () => {
7+
const { cartItems, total, amount } = useSelector((store) => store.cart)
8+
const dispatch = useDispatch()
9+
10+
if (amount < 1) {
11+
return (
12+
<section className='cart'>
13+
<header>
14+
<h2>your bag</h2>
15+
<h4 className='empty-cart'>is currently empty</h4>
16+
</header>
17+
</section>
18+
)
19+
}
20+
21+
return (
22+
<section className='cart'>
23+
<header>
24+
<h2>your bag</h2>
25+
</header>
26+
<div>
27+
{cartItems.map((item) => {
28+
return <CartItem key={item.id} {...item} />
29+
})}
30+
</div>
31+
<footer>
32+
<hr />
33+
<div className='cart-total'>
34+
<h4>
35+
total <span>${total.toFixed(2)}</span>
36+
</h4>
37+
</div>
38+
<button className='btn clear-btn' onClick={() => dispatch(clearCart())}>
39+
clear cart
40+
</button>
41+
</footer>
42+
</section>
43+
)
44+
}
45+
46+
export default CartContainer

13-cart/src/components/CartItem.js

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import React from 'react'
2+
import { useDispatch } from 'react-redux'
3+
import { removeItem, increase, decrease } from '../features/cart/cartSlice'
4+
import { ChevronDown, ChevronUp } from '../icons'
5+
6+
const CartItem = ({ title, price, img, amount, id }) => {
7+
const dispatch = useDispatch()
8+
9+
return (
10+
<article className='cart-item'>
11+
<img src={img} alt={title} />
12+
<div>
13+
<h4>{title}</h4>
14+
<h4 className='item-price'>${price}</h4>
15+
<button className='remove-btn' onClick={() => dispatch(removeItem(id))}>
16+
remove
17+
</button>
18+
</div>
19+
<div>
20+
<button
21+
className='amount-btn'
22+
onClick={() => dispatch(increase({ id }))}
23+
>
24+
<ChevronUp />
25+
</button>
26+
<p className='amount'>{amount}</p>
27+
<button
28+
className='amount-btn'
29+
onClick={() => {
30+
if (amount === 1) {
31+
dispatch(removeItem(id))
32+
return
33+
}
34+
dispatch(decrease({ id }))
35+
}}
36+
>
37+
<ChevronDown />
38+
</button>
39+
</div>
40+
</article>
41+
)
42+
}
43+
44+
export default CartItem

13-cart/src/components/Navbar.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import React from 'react'
2+
import { useSelector } from 'react-redux'
3+
import { CartIcon } from '../icons'
4+
5+
const Navbar = () => {
6+
const { amount } = useSelector((store) => store.cart)
7+
8+
return (
9+
<nav>
10+
<div className='nav-center'>
11+
<h3>Shopping</h3>
12+
<div className='nav-container'>
13+
<CartIcon />
14+
<div className='amount-container'>
15+
<p className='total-amount'>{amount}</p>
16+
</div>
17+
</div>
18+
</div>
19+
</nav>
20+
)
21+
}
22+
23+
export default Navbar

13-cart/src/data.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
// eslint-disable-next-line import/no-anonymous-default-export
12
export default [
23
{
34
id: 1,
45
title: 'Samsung Galaxy S7',
56
price: 599.99,
67
img: 'https://dl.airtable.com/.attachments/91ee456448cef47deec553a2ea3fa8ad/b08bec68/phone-2_ohtt5s.png',
7-
amount: 1,
8+
amount: 4,
89
},
910
{
1011
id: 2,
@@ -20,4 +21,4 @@ export default [
2021
img: 'https://dl.airtable.com/.attachments/bae9208dc34f35128749ecda5b999e84/337c285d/phone-3_h2s6fo.png',
2122
amount: 1,
2223
},
23-
];
24+
]

13-cart/src/features/cart/cartSlice.js

+35-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { createSlice } from '@reduxjs/toolkit'
22
import data from '../../data'
33

44
const initialState = {
5-
cartItems: [],
5+
cartItems: data,
66
amount: 4,
77
total: 0,
88
isLoading: true,
@@ -11,7 +11,40 @@ const initialState = {
1111
const cartSlice = createSlice({
1212
name: 'cart',
1313
initialState,
14-
reducers: {},
14+
reducers: {
15+
clearCart: (state) => {
16+
state.cartItems = []
17+
},
18+
19+
removeItem: (state, action) => {
20+
state.cartItems = state.cartItems.filter(
21+
(item) => item.id !== action.payload
22+
)
23+
},
24+
25+
increase: (state, { payload }) => {
26+
const cartItem = state.cartItems.find((item) => item.id === payload.id)
27+
cartItem.amount = cartItem.amount + 1
28+
},
29+
30+
decrease: (state, { payload }) => {
31+
const cartItem = state.cartItems.find((item) => item.id === payload.id)
32+
cartItem.amount = cartItem.amount - 1
33+
},
34+
35+
calculateTotals: (state) => {
36+
let amount = 0
37+
let total = 0
38+
state.cartItems.forEach((item) => {
39+
amount += item.amount
40+
total += item.amount * item.price
41+
})
42+
state.amount = amount
43+
state.total = total
44+
},
45+
},
1546
})
1647

48+
export const { clearCart, removeItem, increase, decrease, calculateTotals } =
49+
cartSlice.actions
1750
export default cartSlice.reducer

0 commit comments

Comments
 (0)