From 12a44971e7339893a61e6c21d1aef3fb9ac911dd Mon Sep 17 00:00:00 2001 From: nasnik Date: Thu, 18 May 2023 19:10:10 -0700 Subject: [PATCH] updated cart component, header, and added OrderSummary --- .idea/.gitignore | 5 + .idea/client-5-6-23.iml | 12 ++ .idea/modules.xml | 8 + .idea/vcs.xml | 6 + src/App.js | 43 ++--- src/components/Cart/Cart.js | 109 ++++-------- src/components/Cart/CartItem.js | 37 ++++ src/components/Cart/OrderSummary.js | 189 ++++++++++++++++++++- src/components/Cart/cart.svg | 3 + src/components/Cart/delete.svg | 52 ++++++ src/components/Cart/useLocalStorageCart.js | 19 +++ src/components/Header/HeaderButtons.js | 54 ++++++ src/components/withCart.js | 56 +++++- src/index.js | 27 +-- 14 files changed, 499 insertions(+), 121 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/client-5-6-23.iml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 src/components/Cart/CartItem.js create mode 100644 src/components/Cart/cart.svg create mode 100644 src/components/Cart/delete.svg create mode 100644 src/components/Cart/useLocalStorageCart.js diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/client-5-6-23.iml b/.idea/client-5-6-23.iml new file mode 100644 index 0000000..24643cc --- /dev/null +++ b/.idea/client-5-6-23.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..9df5f3c --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/App.js b/src/App.js index e7bd7d9..6fafb06 100644 --- a/src/App.js +++ b/src/App.js @@ -1,9 +1,9 @@ import './App.css'; -import { Route, BrowserRouter as Router, Routes } from 'react-router-dom'; +import {Route, BrowserRouter as Router, Routes, BrowserRouter} from 'react-router-dom'; import AdminRoutes from './components/Admin/AdminRoutes'; -import { CartProvider } from "./components/withCart"; +import {CartProvider} from "./components/withCart"; import Header from "./components/Header/Header"; import React from "react"; import Restaurant from "./components/Restaurants/Restaurant"; @@ -11,27 +11,30 @@ import Restaurants from "./components/Restaurants/Restaurants"; import SignInRoute from "./routes/SignInRoute"; import SignUpRoute from "./routes/SignUpRoute"; import UserMenuRoute from "./routes/UserMenuRoute"; +import Checkout from "./components/Cart/OrderSummary"; +import OrderSummary from "./components/Cart/OrderSummary"; +import Cart from "./components/Cart/Cart"; function App() { - const isAdmin = true; // Add Redux states here + const isAdmin = true; // Add Redux states here - return ( - - -
- - } /> - - } /> - } /> - } /> - } /> - } /> - {/* Other routes */} - - - - ); + return ( + + +
+ + }/> + }/> + }/> + }/> + }/> + }/> + }/> + {/* Other routes */} + + + + ); } export default App; diff --git a/src/components/Cart/Cart.js b/src/components/Cart/Cart.js index 9deb9e4..6714384 100644 --- a/src/components/Cart/Cart.js +++ b/src/components/Cart/Cart.js @@ -1,87 +1,42 @@ import React, {useEffect, useState} from 'react'; +import {useCart} from "../withCart"; +import {Offcanvas, Stack} from "react-bootstrap"; +import CartItem from "./CartItem"; +import Button from "react-bootstrap/Button"; +import {Link, useNavigate} from "react-router-dom"; -const Cart = ({cartItems, setCartItems}) => { - // console.log('basket is', cartItems); - const [totalPrice, setTotalPrice] = useState(0) - const totalPrices = () => { - let total = 0; - cartItems.map(el => - (total += el.price * el.count)) - setTotalPrice(total) - } - useEffect(() => { - // eslint-disable-next-line react-hooks/exhaustive-deps - totalPrices() - }) +const Cart = ({isOpen}) => { - const plusCount = (id) => { - setCartItems(cartItems.map(el => { - if (el.id === id) { - el.count++; - } - return el; - })) - } - const minusCount = (id, count) => { - if (count < 2) { - removeProduct(id); - } else { - setCartItems( - cartItems.map(el => { - if (el.id === id) { - el.count--; - } - return el - }) - ) - } - } - const removeProduct = (id) => { - setCartItems(cartItems.filter(el => - el.id !== id)) - } - return ( -
-

Shopping Cart

- {cartItems.length > 0 && - - - - - - - - - - - - {cartItems.map(el=> - - - - - - - + return ( + + + +

Shopping Cart

+
+
+ + + {cartItems.map((item, index) => ( + + ))} +
+ Total:{' $'}{ + cartItems.reduce((total, cartItem) => { + return total + (cartItem?.dish.price || 0) * cartItem.quantity + }, 0) + } - )} -
-

Total order $ {totalPrice}

-
-
ProductPriceQuantityTotal Price
{el.name}{el.price} - - {el.count} - + const {closeCart, cartItems} = useCart(); - {el.price * el.count} - -
- } -

Delivery address

-

Payment details

-
+
+ Checkout +
+ + + + ); }; diff --git a/src/components/Cart/CartItem.js b/src/components/Cart/CartItem.js new file mode 100644 index 0000000..f756ced --- /dev/null +++ b/src/components/Cart/CartItem.js @@ -0,0 +1,37 @@ +import React from 'react'; +import {useCart} from "../withCart"; +import {Stack} from "react-bootstrap"; +import Button from "react-bootstrap/Button"; +import BinIcon from "./delete.svg"; + + +const CartItem = ({item, id}) => { + const{removeFromCart, increaseItemQuantity, decreaseItemQuantity} = useCart(); + + return ( + + +
+
{item.dish.name}{" "} + {item.quantity > 1 &&( + x{item.quantity} + + )}
+
${item.dish.price}
+
${item.dish.price * item.quantity}
+ + + {item.quantity} + +
+
+ ); +}; + +export default CartItem; \ No newline at end of file diff --git a/src/components/Cart/OrderSummary.js b/src/components/Cart/OrderSummary.js index e6f904b..1faa04b 100644 --- a/src/components/Cart/OrderSummary.js +++ b/src/components/Cart/OrderSummary.js @@ -1,11 +1,190 @@ -import React from 'react'; +import React, { useContext, useState } from 'react'; +import { CartContext } from '../withCart'; +import CartItem from "./CartItem"; +import signInForm from "../auth/SignInForm"; +import {Link} from "react-router-dom"; -const OrderSummary = () => { +const Checkout = () => { + const { cartItems, clearCart } = useContext(CartContext); + const [deliveryInfo, setDeliveryInfo] = useState({ + name: '', + address: '', + phone: '', + }); + const isLoggedIn = localStorage.getItem('isLoggedIn') === 'true'; + const userName = localStorage.getItem('userName'); + + const handleInputChange = (e) => { + setDeliveryInfo((prevInfo) => ({ + ...prevInfo, + [e.target.name]: e.target.value, + })); + }; + + // Here goes PlaceOrderButton function + const handleSubmit = (e) => { + e.preventDefault(); + // Process the order and clear the cart + console.log('Order submitted:', deliveryInfo); + clearCart(); + }; + if (isLoggedIn) { return ( -
- +
+

Checkout

+
+ +
+

Account Information

+

Hello, {userName}!

+

Some information

+

Delivery Information

+
+
+ + +
+
+ + +
+
+ + +
+

Payment Details

+
+ + +
+ +
+
+
+

Order Summary

+ {cartItems.length === 0 ? ( +

Your cart is empty.

+ ) : ( + <> + {cartItems.map((item, index)=> ( + + ))} +
+ Total:{' $'}{ + cartItems.reduce((total, cartItem) => { + return total + (cartItem?.dish.price || 0)* cartItem.quantity + }, 0) + } +
+ + )} +
+
); + } else { + return ( +
+

Checkout

+ {' '} +
+ +
+

Account Information

+
+ + Log In + + + Sign Up + + {" "} +
+

Delivery Information

+
+
+ + +
+
+ + +
+
+ + +
+

Payment Details

+
+ + +
+ +
+
+
+

Order Summary

+ {cartItems.length === 0 ? ( +

Your cart is empty.

+ ) : ( + <> + {cartItems.map((item, index)=> ( + + ))} +
+ Total:{' $'}{ + cartItems.reduce((total, cartItem) => { + return total + (cartItem?.dish.price || 0)* cartItem.quantity + }, 0) + } +
+ + )} +
+
+
+ ); + } }; -export default OrderSummary; \ No newline at end of file +export default Checkout; \ No newline at end of file diff --git a/src/components/Cart/cart.svg b/src/components/Cart/cart.svg new file mode 100644 index 0000000..3f93ced --- /dev/null +++ b/src/components/Cart/cart.svg @@ -0,0 +1,3 @@ + + \ No newline at end of file diff --git a/src/components/Cart/delete.svg b/src/components/Cart/delete.svg new file mode 100644 index 0000000..1c78f27 --- /dev/null +++ b/src/components/Cart/delete.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/Cart/useLocalStorageCart.js b/src/components/Cart/useLocalStorageCart.js new file mode 100644 index 0000000..876d201 --- /dev/null +++ b/src/components/Cart/useLocalStorageCart.js @@ -0,0 +1,19 @@ +import React, {useEffect, useState} from 'react'; + +const useLocalStorageCart = (key, initialValue) => { + const[value, setValue] = useState(()=>{ + const jsonValue =localStorage.getItem(key); + if(jsonValue !== null) { + return JSON.parse(jsonValue); + }else{ + return initialValue; + } + + }); + useEffect(() => { + localStorage.setItem(key, JSON.stringify(value)) + }, [key, value]); + return [value, setValue]; +}; + +export default useLocalStorageCart; \ No newline at end of file diff --git a/src/components/Header/HeaderButtons.js b/src/components/Header/HeaderButtons.js index 9f0bbeb..b046121 100644 --- a/src/components/Header/HeaderButtons.js +++ b/src/components/Header/HeaderButtons.js @@ -1,6 +1,10 @@ import { Link } from 'react-router-dom'; +import Button from "react-bootstrap/Button"; +import CartIcon from "../Cart/cart.svg"; +import {useCart} from "../withCart"; function HeaderButtons({ isLoggedIn, isAdmin, onLogout }) { + const {openCart, cartQuantity} = useCart(); if (isLoggedIn) { return (
@@ -15,6 +19,31 @@ function HeaderButtons({ isLoggedIn, isAdmin, onLogout }) { Log Out + {cartQuantity > 0 && ( + )}
); } else { @@ -26,6 +55,31 @@ function HeaderButtons({ isLoggedIn, isAdmin, onLogout }) { Sign Up + {cartQuantity > 0 && ( + )}
); } diff --git a/src/components/withCart.js b/src/components/withCart.js index f8b468d..d4556be 100644 --- a/src/components/withCart.js +++ b/src/components/withCart.js @@ -1,9 +1,20 @@ -import React, { createContext, useContext, useState } from "react"; +import React, {createContext, useContext, useEffect, useState} from "react"; +import Cart from "./Cart/Cart"; +import useLocalStorageCart from "./Cart/useLocalStorageCart"; -const CartContext = createContext(); +export const CartContext = createContext(); const CartProvider = ({ children }) => { - const [cartItems, setCartItems] = useState([]); + const [cartItems, setCartItems] = useLocalStorageCart('cartItems', []); + const [isOpen, setIsOpen] = useState(false); + + + const cartQuantity = cartItems.reduce((quantity, item) => item.quantity + quantity, 0); + const openCart = ()=> setIsOpen(true); + const closeCart = ()=> setIsOpen(false); + function getItemQuantity(id) { + return cartItems.find(item => item.id === id)?.quantity || 0 + } const addToCart = (newItem) => { const existedDishIndex = cartItems.findIndex((item) => { @@ -20,18 +31,51 @@ const CartProvider = ({ children }) => { }; const removeFromCart = (itemId) => { - setCartItems(cartItems.filter((item) => item.id !== itemId)); - }; + setCartItems(cartItems.filter((item, index) => index !== itemId)); + }; const clearCart = () => { setCartItems([]); }; + function increaseItemQuantity(id) { + setCartItems(currentItems => { + if (currentItems.find((item, index) => index === id) == null) { + return [...currentItems, {id, quantity: 1}] + } else { + return currentItems.map((item, index) => { + return index === id ? {...item, quantity: item.quantity + 1} : item; + }) + } + }) + } + function decreaseItemQuantity(id) { + setCartItems(currentItems => { + if (currentItems.find((item, index) => index === id)?.quantity === 1) { + return currentItems.filter((item, index) => index !== id) + } else { + return currentItems.map((item, index) => { + return index === id ? {...item, quantity: item.quantity - 1} : item; + }) + } + }) + } return ( {children} + ); }; diff --git a/src/index.js b/src/index.js index fd1492b..6381e1e 100644 --- a/src/index.js +++ b/src/index.js @@ -3,24 +3,25 @@ import "bootstrap/dist/css/bootstrap.css"; import App from "./App"; import React from "react"; import ReactDOM from "react-dom/client"; +import {BrowserRouter, Router} from "react-router-dom"; if ('serviceWorker' in navigator) { - window.addEventListener('load', () => { - navigator.serviceWorker - .register('service-worker.js') - .then((registration) => { - console.log('Service Worker registered: ', registration); - }) - .catch((error) => { - console.error('Service Worker registration failed: ', error); - }); - }); + window.addEventListener('load', () => { + navigator.serviceWorker + .register('service-worker.js') + .then((registration) => { + console.log('Service Worker registered: ', registration); + }) + .catch((error) => { + console.error('Service Worker registration failed: ', error); + }); + }); } const root = ReactDOM.createRoot(document.getElementById("root")); root.render( - - - + + + );