1 | import React, { useState, useContext, useEffect, useRef } from 'react';
|
---|
2 | import { useNavigate } from 'react-router-dom';
|
---|
3 | import styles from '../../css/ShoppingCartCss/shopping-cart-style.module.css';
|
---|
4 | import { FaShoppingCart } from "react-icons/fa";
|
---|
5 | import { CartContext } from './CartContext';
|
---|
6 | import { OrderContext } from './OrderContext';
|
---|
7 | import ErrorModal from './ErrorModal';
|
---|
8 |
|
---|
9 | const ShoppingCart = ({ ingredients, hideIngredients }) => {
|
---|
10 | const { cart, setCart, addToCart, removeFromCart } = useContext(CartContext);
|
---|
11 | const { isOrderInProgress } = useContext(OrderContext);
|
---|
12 | const [showCart, setShowCart] = useState(false);
|
---|
13 | const [showIngredients, setShowIngredients] = useState(false);
|
---|
14 | const [showModal, setShowModal] = useState(false);
|
---|
15 | const navigate = useNavigate();
|
---|
16 | const cartRef = useRef(null);
|
---|
17 |
|
---|
18 | useEffect(() => {
|
---|
19 | if (isOrderInProgress) {
|
---|
20 | const storedCart = localStorage.getItem('cart');
|
---|
21 | if (storedCart) {
|
---|
22 | const parsedCart = JSON.parse(storedCart);
|
---|
23 | setCart(parsedCart);
|
---|
24 | }
|
---|
25 | }
|
---|
26 | }, [isOrderInProgress, setCart]);
|
---|
27 |
|
---|
28 | const toggleCart = () => {
|
---|
29 | setShowCart(!showCart);
|
---|
30 | if (!hideIngredients) {
|
---|
31 | setShowIngredients(true);
|
---|
32 | }
|
---|
33 | };
|
---|
34 |
|
---|
35 | const toggleIngredients = () => {
|
---|
36 | setShowIngredients(!showIngredients);
|
---|
37 | };
|
---|
38 |
|
---|
39 | const handleCheckboxChange = (ingredient) => {
|
---|
40 | if (isOrderInProgress) return;
|
---|
41 | const isInCart = cart.some(item => item.id === ingredient.id);
|
---|
42 | if (isInCart) {
|
---|
43 | removeFromCart(ingredient);
|
---|
44 | } else {
|
---|
45 | addToCart(ingredient);
|
---|
46 | }
|
---|
47 | };
|
---|
48 |
|
---|
49 | const handleProceedToCheckout = () => {
|
---|
50 | const token = localStorage.getItem('token');
|
---|
51 | if (!token) {
|
---|
52 | setShowModal(true);
|
---|
53 | } else {
|
---|
54 | navigate("/checkout");
|
---|
55 | }
|
---|
56 | };
|
---|
57 |
|
---|
58 | const closeModal = () => {
|
---|
59 | setShowModal(false);
|
---|
60 | };
|
---|
61 |
|
---|
62 | const handleLoginRedirect = () => {
|
---|
63 | navigate('/login');
|
---|
64 | };
|
---|
65 |
|
---|
66 | const isIngredientInCart = (ingredient) => {
|
---|
67 | return cart.some(item => item.id === ingredient.id);
|
---|
68 | };
|
---|
69 |
|
---|
70 | useEffect(() => {
|
---|
71 | const handleClickOutside = (event) => {
|
---|
72 | if (cartRef.current && !cartRef.current.contains(event.target)) {
|
---|
73 | setShowCart(false);
|
---|
74 | }
|
---|
75 | };
|
---|
76 |
|
---|
77 | if (showCart) {
|
---|
78 | document.addEventListener('mousedown', handleClickOutside);
|
---|
79 | } else {
|
---|
80 | document.removeEventListener('mousedown', handleClickOutside);
|
---|
81 | }
|
---|
82 |
|
---|
83 | return () => {
|
---|
84 | document.removeEventListener('mousedown', handleClickOutside);
|
---|
85 | };
|
---|
86 | }, [showCart]);
|
---|
87 |
|
---|
88 | return (
|
---|
89 | <div className={styles.shoppingCart}>
|
---|
90 | <div className={styles.cartIcon} onClick={toggleCart}>
|
---|
91 | <FaShoppingCart />
|
---|
92 | {cart.length > 0 && <span className={styles.cartCount}>{cart.length}</span>}
|
---|
93 | </div>
|
---|
94 |
|
---|
95 | {showCart && (
|
---|
96 | <div className={styles.cartPopup} ref={cartRef}>
|
---|
97 | <h4>Shopping Cart</h4>
|
---|
98 | {cart.length === 0 ? (
|
---|
99 | <p>No items in cart</p>
|
---|
100 | ) : (
|
---|
101 | <div className={styles.cartItems}>
|
---|
102 | {cart.map((item, index) => (
|
---|
103 | <div className={styles.cartItemCard} key={index}>
|
---|
104 | <p>{item.name}</p>
|
---|
105 | <p className={styles.gramsText}>
|
---|
106 | {item.grams > 0 ? `${item.grams} grams` : ''}
|
---|
107 | </p>
|
---|
108 | {item.grams <= 0 && (
|
---|
109 | <button
|
---|
110 | className={styles.removeButton}
|
---|
111 | onClick={() => removeFromCart(item)}
|
---|
112 | disabled={isOrderInProgress}
|
---|
113 | >
|
---|
114 | ×
|
---|
115 | </button>
|
---|
116 | )}
|
---|
117 | </div>
|
---|
118 | ))}
|
---|
119 | </div>
|
---|
120 | )}
|
---|
121 | <button
|
---|
122 | className={styles.checkoutButton}
|
---|
123 | onClick={handleProceedToCheckout}
|
---|
124 | disabled={isOrderInProgress}
|
---|
125 | >
|
---|
126 | {isOrderInProgress ? 'Order in Progress' : 'Proceed to Checkout'}
|
---|
127 | </button>
|
---|
128 | </div>
|
---|
129 | )}
|
---|
130 |
|
---|
131 | {!hideIngredients && (
|
---|
132 | <div>
|
---|
133 | <h3 className={styles.toggleTitle} onClick={toggleIngredients}>
|
---|
134 | {showIngredients ? 'Get Them Delivered' : 'Missing Ingredients?'}
|
---|
135 | </h3>
|
---|
136 |
|
---|
137 | <div className={`${styles.ingredientList} ${showIngredients ? styles.show : styles.hide}`}>
|
---|
138 | <ul>
|
---|
139 | {ingredients.map((ingredient, index) => (
|
---|
140 | <li key={index}>
|
---|
141 | <label>
|
---|
142 | <input
|
---|
143 | type="checkbox"
|
---|
144 | checked={isIngredientInCart(ingredient)}
|
---|
145 | onChange={() => handleCheckboxChange(ingredient)}
|
---|
146 | disabled={isOrderInProgress}
|
---|
147 | />
|
---|
148 | {ingredient.name}
|
---|
149 | </label>
|
---|
150 | </li>
|
---|
151 | ))}
|
---|
152 | </ul>
|
---|
153 | </div>
|
---|
154 | </div>
|
---|
155 | )}
|
---|
156 |
|
---|
157 | {showModal && (
|
---|
158 | <ErrorModal
|
---|
159 | message="You must log in to proceed to checkout."
|
---|
160 | onClose={closeModal}
|
---|
161 | onLogin={handleLoginRedirect}
|
---|
162 | />
|
---|
163 | )}
|
---|
164 | </div>
|
---|
165 | );
|
---|
166 | };
|
---|
167 |
|
---|
168 | export default ShoppingCart;
|
---|