From a8a7daeddb0c1bf8f9551e7d8afccea92f933ee8 Mon Sep 17 00:00:00 2001 From: Mikayla Dobson <93477693+innocuous-symmetry@users.noreply.github.com> Date: Thu, 7 Jul 2022 12:58:27 -0500 Subject: [PATCH] rework of cart component --- client/src/components/Cart/Cart.tsx | 34 +++++++++++-------- client/src/components/Cart/CartItem.tsx | 14 ++++++-- client/src/components/Navbar.tsx | 2 -- .../src/components/Products/ProductCard.tsx | 8 +++-- client/src/components/Products/Products.tsx | 3 +- client/src/store/store.ts | 33 +++++++++++++----- client/src/types/main.d.ts | 1 + client/src/util/helpers.ts | 6 ---- 8 files changed, 63 insertions(+), 38 deletions(-) diff --git a/client/src/components/Cart/Cart.tsx b/client/src/components/Cart/Cart.tsx index b0c67bd..d12a19a 100644 --- a/client/src/components/Cart/Cart.tsx +++ b/client/src/components/Cart/Cart.tsx @@ -1,4 +1,5 @@ -import { useContext, useEffect, useState } from "react"; +import { useCallback, useContext, useEffect, useState } from "react"; +import { v4 } from "uuid"; import { AppContext } from "../../store/store"; import { ActionType } from "../../store/store_types"; import { Product } from '../../types/main'; @@ -8,8 +9,19 @@ import CartItem from "./CartItem"; function Cart() { const [state, dispatch] = useContext(AppContext); - const [contents, setContents] = useState(); const [data, setData] = useState(); + const [subtotal, setSubtotal] = useState('loading...'); + + // on mount + useEffect(() => { + if (!state) return; + dispatch({ type: ActionType.UPDATESUBTOTAL, payload: getSubtotal(data) }); + }, []); + + useEffect(() => { + console.log(state.cart); + setSubtotal(state.cart.subtotal); + }, [state.cart.subtotal]); useEffect(() => { if (!state.cart.contents) return; @@ -39,15 +51,10 @@ function Cart() { setData(newProducts); }, [state]); - /** - * PROBLEMATIC USEEFFECT BELOW - * LOOP BEHAVIOR ON DISPATCH - */ - - useEffect(() => { - let subtotal = getSubtotal(data); - subtotal && dispatch({ type: ActionType.UPDATESUBTOTAL, payload: subtotal }); - }, [data, getSubtotal]); + const updateQuantity = useCallback((product: Product, newQuantity: number) => { + const updated = product; + updated.quantity = newQuantity; + }, []); return ( @@ -60,12 +67,11 @@ function Cart() { }
- { data && data.map((product: Product) => ) } + { data && data.map((product: Product) => ) }
-

Subtotal:

-

{state.cart.subtotal || "Not found"}

+

Subtotal: {subtotal}

) diff --git a/client/src/components/Cart/CartItem.tsx b/client/src/components/Cart/CartItem.tsx index f627398..9561f25 100644 --- a/client/src/components/Cart/CartItem.tsx +++ b/client/src/components/Cart/CartItem.tsx @@ -1,11 +1,19 @@ +import { useEffect, useState } from "react"; import { v4 } from "uuid"; -function CartItem({ product }: any) { +function CartItem({ product, updateQuantity }: any) { + const [quantity, setQuantity] = useState(product.quantity || 0); + + useEffect(() => { + updateQuantity(product, quantity); + }, [quantity]); + return ( -
+
{product.name}

{product.price}

-

Quantity: {product.quantity || "1"}

+

Quantity: {quantity}

+ setQuantity(Number(e.target.value))}>
) } diff --git a/client/src/components/Navbar.tsx b/client/src/components/Navbar.tsx index fcfa77e..8f6a35a 100644 --- a/client/src/components/Navbar.tsx +++ b/client/src/components/Navbar.tsx @@ -23,13 +23,11 @@ function NavBar() { if (state === initialState) return; if (state.user && state.user.headers?.authenticated) { - console.log('authenticated!'); setProfText(state.user.email); setLoggedIn(true); } else if (!state.user.authenticated) { setLoggedIn(false); } - }, [state]); return ( diff --git a/client/src/components/Products/ProductCard.tsx b/client/src/components/Products/ProductCard.tsx index 45388f9..394eccd 100644 --- a/client/src/components/Products/ProductCard.tsx +++ b/client/src/components/Products/ProductCard.tsx @@ -1,6 +1,6 @@ import { useContext } from "react"; import { useNavigate } from "react-router-dom"; -import { addToCart } from "../../util/helpers"; +import { ActionType } from "../../store/store_types"; import { AppContext } from "../../store/store"; export default function ProductCard({ productData }: any) { @@ -8,6 +8,10 @@ export default function ProductCard({ productData }: any) { const [state, dispatch] = useContext(AppContext); const navigate = useNavigate(); + const addToCart = () => { + dispatch({ type: ActionType.ADDTOCART, payload: productData }); + } + return (
@@ -20,7 +24,7 @@ export default function ProductCard({ productData }: any) { { state.user.headers && state.user.headers.authenticated ? - + : } diff --git a/client/src/components/Products/Products.tsx b/client/src/components/Products/Products.tsx index 0b31d38..db8aa24 100644 --- a/client/src/components/Products/Products.tsx +++ b/client/src/components/Products/Products.tsx @@ -24,9 +24,8 @@ function Products() { useEffect(() => { if (!productData) return; - console.log(productData); - let results = productData.map((each: ProductResponse) => { + const results = productData.map((each: ProductResponse) => { return }); diff --git a/client/src/store/store.ts b/client/src/store/store.ts index 43c4fb9..51e8cfe 100644 --- a/client/src/store/store.ts +++ b/client/src/store/store.ts @@ -29,16 +29,31 @@ export const reducer = (state: appState, action: userAction) => { user: payload } case ActionType.ADDTOCART: - let updatedContents = state.cart.contents; - console.log(action.payload); - updatedContents.push(action.payload); - - return { - ...state, - cart: { - ...state.cart, - contents: updatedContents + let foundItem = state.cart.contents.find(item => item.id === action.payload.id); + if (!foundItem) { + let updatedContents = state.cart.contents; + updatedContents.push(action.payload); + return { + ...state, + cart: { + ...state.cart, + contents: updatedContents + } } + } else { + let updatedState = state; + let updatedItem = foundItem; + + if (updatedItem.quantity) { + updatedItem.quantity += 1; + } else { + updatedItem.quantity = 2; + } + + updatedState.cart.contents = updatedState.cart.contents.filter(item => item.id !== action.payload.id); + updatedState.cart.contents.push(updatedItem); + + return updatedState; } case ActionType.UPDATESUBTOTAL: return { diff --git a/client/src/types/main.d.ts b/client/src/types/main.d.ts index 0655e7d..733b0d9 100644 --- a/client/src/types/main.d.ts +++ b/client/src/types/main.d.ts @@ -28,6 +28,7 @@ export type Product = { category?: string price?: string | number, // when item is included in cart + id?: number, quantity?: number, shortDescription?: string, longDescription?: string, diff --git a/client/src/util/helpers.ts b/client/src/util/helpers.ts index b07e7c6..595343e 100644 --- a/client/src/util/helpers.ts +++ b/client/src/util/helpers.ts @@ -1,11 +1,5 @@ -import React from "react"; -import { ActionType, userAction } from "../store/store_types"; import { Product } from "../types/main"; -export const addToCart = (productData: Product, dispatch: React.Dispatch): any => { - dispatch({ type: ActionType.ADDTOCART, payload: productData }); -} - export const getSubtotal = (cartData: Product[]) => { let total = 0;