rework of cart component

This commit is contained in:
Mikayla Dobson
2022-07-07 12:58:27 -05:00
parent ec8a070e1f
commit a8a7daeddb
8 changed files with 63 additions and 38 deletions

View File

@@ -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<JSX.Element>();
const [data, setData] = useState<any>();
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 (
<Page>
@@ -60,12 +67,11 @@ function Cart() {
}
<section id="cart-contents">
{ data && data.map((product: Product) => <CartItem product={product} />) }
{ data && data.map((product: Product) => <CartItem key={v4()} updateQuantity={updateQuantity} product={product} />) }
</section>
<section id="subtotal">
<p>Subtotal:</p>
<p>{state.cart.subtotal || "Not found"}</p>
<p>Subtotal: {subtotal}</p>
</section>
</Page>
)

View File

@@ -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 (
<div className="cart-item-panel" key={v4()}>
<div className="cart-item-panel">
<strong>{product.name}</strong>
<p>{product.price}</p>
<p>Quantity: {product.quantity || "1"}</p>
<p>Quantity: {quantity}</p>
<input type="number" min="0" value={quantity} onChange={(e) => setQuantity(Number(e.target.value))}></input>
</div>
)
}

View File

@@ -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 (

View File

@@ -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 (
<div className="card product-card" key={`product-id-${id}`}>
<div className="product-photo"></div>
@@ -20,7 +24,7 @@ export default function ProductCard({ productData }: any) {
{
state.user.headers && state.user.headers.authenticated ?
<button onClick={() => addToCart(productData, dispatch)}>Add to Cart</button>
<button onClick={addToCart}>Add to Cart</button>
:
<button onClick={() => navigate('/login')}>Login to add to your cart</button>
}

View File

@@ -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 <ProductCard key={each.id} productData={each} />
});

View File

@@ -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 {

View File

@@ -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,

View File

@@ -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<userAction>): any => {
dispatch({ type: ActionType.ADDTOCART, payload: productData });
}
export const getSubtotal = (cartData: Product[]) => {
let total = 0;