Skip to content

Commit dd85b34

Browse files
committed
feat: 12.CartUseReducer: setup
1 parent 3cf6ced commit dd85b34

File tree

9 files changed

+513
-2
lines changed

9 files changed

+513
-2
lines changed

src/App.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@
88
// import Navbar from './projects/8.Navbar'
99
// import SidebarModal from './projects/9.Sidebar-Modal'
1010
// import StripeMenu from './projects/10.StripeMenu'
11-
import Cart from './projects/11.Cart'
11+
// import Cart from './projects/11.Cart'
12+
import CartUseReducer from './projects/12.CartUseReducer'
1213
function App() {
1314
return (
14-
<Cart/>
15+
<CartUseReducer/>
1516
);
1617
}
1718

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import React from 'react'
2+
import CartItem from './CartItem'
3+
import { useGlobalContext } from './context'
4+
5+
const CartContainer = () => {
6+
const { cart, clearCart, totalPrice } = useGlobalContext()
7+
if (cart.length === 0) {
8+
return (
9+
<section className='cart'>
10+
{/* cart header */}
11+
<header>
12+
<h2>your bag</h2>
13+
<h4 className='empty-cart'>is currently empty</h4>
14+
</header>
15+
</section>
16+
)
17+
}
18+
return (
19+
<section className='cart'>
20+
{/* cart header */}
21+
<header>
22+
<h2>your bag</h2>
23+
</header>
24+
{/* cart items */}
25+
<div>
26+
{cart.map((item) => {
27+
return <CartItem key={item.id} {...item} />
28+
})}
29+
</div>
30+
{/* cart footer */}
31+
<footer>
32+
<hr />
33+
<div className='cart-total'>
34+
<h4>
35+
total <span>${totalPrice}</span>
36+
</h4>
37+
</div>
38+
<button
39+
className='btn clear-btn'
40+
onClick={clearCart}
41+
>
42+
clear cart
43+
</button>
44+
</footer>
45+
</section>
46+
)
47+
}
48+
49+
export default CartContainer
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import React from 'react'
2+
import { useGlobalContext } from './context'
3+
4+
const CartItem = ({ id, img, title, price, amount }) => {
5+
const {updateAmount, removeItem} = useGlobalContext()
6+
return (
7+
<article className='cart-item'>
8+
<img src={img} alt={title} />
9+
<div>
10+
<h4>{title}</h4>
11+
<h4 className='item-price'>${price}</h4>
12+
{/* remove button */}
13+
<button
14+
className='remove-btn'
15+
onClick={() => removeItem(id)}
16+
>
17+
remove
18+
</button>
19+
</div>
20+
<div>
21+
{/* increase amount */}
22+
<button className='amount-btn' onClick={() => updateAmount(id, 1)}>
23+
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'>
24+
<path d='M10.707 7.05L10 6.343 4.343 12l1.414 1.414L10 9.172l4.243 4.242L15.657 12z' />
25+
</svg>
26+
</button>
27+
{/* amount */}
28+
<p className='amount'>{amount}</p>
29+
{/* decrease amount */}
30+
<button className='amount-btn' onClick={() => updateAmount(id, -1)}>
31+
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'>
32+
<path d='M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z' />
33+
</svg>
34+
</button>
35+
</div>
36+
</article>
37+
)
38+
}
39+
40+
export default CartItem
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import React from 'react'
2+
import { useGlobalContext } from './context'
3+
const Navbar = () => {
4+
const {totalItems} = useGlobalContext()
5+
return (
6+
<nav>
7+
<div className='nav-center'>
8+
<h3>useReducer</h3>
9+
<div className='nav-container'>
10+
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'>
11+
<path d='M16 6v2h2l2 12H0L2 8h2V6a6 6 0 1 1 12 0zm-2 0a4 4 0 1 0-8 0v2h8V6zM4 10v2h2v-2H4zm10 0v2h2v-2h-2z' />
12+
</svg>
13+
<div className='amount-container'>
14+
<p className='total-amount'>{totalItems}</p>
15+
</div>
16+
</div>
17+
</div>
18+
</nav>
19+
)
20+
}
21+
22+
export default Navbar
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import React, { useState, useContext, useReducer, useEffect } from 'react'
2+
import cartItems from './data'
3+
import reducer from './reducer'
4+
5+
6+
const url = 'https://course-api.com/react-useReducer-cart-project'
7+
8+
const AppContext = React.createContext()
9+
10+
const AppProvider = ({ children }) => {
11+
const [cart, setCart] = useState(cartItems)
12+
const [totalItems, setTotalItems] = useState(cart.length)
13+
const [totalPrice, setTotalPrice] = useState(0)
14+
15+
// Function that clear all the items of the cart
16+
const clearCart = () =>{
17+
setCart([])
18+
}
19+
20+
// Function that update the amount of items in the cart
21+
const updateAmount = (id, amount) => {
22+
23+
const cartItem = cart.find(item => item.id === id) //Get the item with the given id
24+
const newAmount = cartItem.amount + amount // calculate the new amount
25+
26+
// If the number of items is 0 remove the item from the cart
27+
if(newAmount ===0) {
28+
setCart(cart.filter(item => item.id !== id))
29+
} else {
30+
setCart(cart.map(item => (item.id === id ? { ...item, amount: newAmount } : item)))
31+
}
32+
// update the total amount of items
33+
setTotalItems(prevTotalItems => prevTotalItems + amount)
34+
}
35+
36+
// Function that calculate the totlal price of the items in the cart
37+
const calculateTotalPrice = () => {
38+
let total = 0
39+
cart.forEach(item => total += item.price * item.amount)
40+
setTotalPrice(total.toFixed(2))
41+
}
42+
43+
// Function that remove an item from the cart
44+
const removeItem = (id) => {
45+
const item = cart.find(item => item.id === id)
46+
setTotalItems(prevTotalItems => prevTotalItems - item.amount)
47+
setCart(cart.filter(item => item.id !== id))
48+
}
49+
50+
// Use Effect to update the total price everytime the cart, total items is updated
51+
useEffect(() => {
52+
calculateTotalPrice()
53+
}, [cart, totalItems])
54+
55+
return (
56+
<AppContext.Provider
57+
value={{
58+
cart,
59+
clearCart,
60+
totalItems,
61+
updateAmount,
62+
totalPrice,
63+
removeItem
64+
}}
65+
>
66+
{children}
67+
</AppContext.Provider>
68+
)
69+
}
70+
// make sure use
71+
export const useGlobalContext = () => {
72+
return useContext(AppContext)
73+
}
74+
75+
export { AppProvider }
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
const cartItems= [
2+
{
3+
id: 1,
4+
title: 'Samsung Galaxy S7',
5+
price: 599.99,
6+
img:
7+
'https://res.cloudinary.com/diqqf3eq2/image/upload/v1583368215/phone-2_ohtt5s.png',
8+
amount: 1,
9+
},
10+
{
11+
id: 2,
12+
title: 'google pixel ',
13+
price: 499.99,
14+
img:
15+
'https://res.cloudinary.com/diqqf3eq2/image/upload/v1583371867/phone-1_gvesln.png',
16+
amount: 1,
17+
},
18+
{
19+
id: 3,
20+
title: 'Xiaomi Redmi Note 2',
21+
price: 699.99,
22+
img:
23+
'https://res.cloudinary.com/diqqf3eq2/image/upload/v1583368224/phone-3_h2s6fo.png',
24+
amount: 1,
25+
},
26+
]
27+
28+
export default cartItems

0 commit comments

Comments
 (0)