functionality for product quantity in cart, in progress subtotal calculation

This commit is contained in:
Mikayla Dobson
2022-07-04 14:13:32 -05:00
parent 8b26b622aa
commit 6e3e23faaa
7 changed files with 80 additions and 14 deletions

View File

@@ -1,22 +1,53 @@
import { useContext, useEffect, useState } from "react";
import { AppContext } from "../../store/store";
import { ActionType } from "../../store/store_types";
import { Product } from '../../types/main';
import { getSubtotal } from "../../util/helpers";
import Page from "../../util/Page";
import CartItem from "./CartItem";
function Cart() {
const [state, dispatch] = useContext(AppContext);
const [contents, setContents] = useState<JSX.Element>();
const [data, setData] = useState<any>();
useEffect(() => {
setContents(
state.cart.contents.map((product: Product) => <CartItem product={product} />)
)
}, [state, setContents]);
if (!state.cart.contents) return;
let newProducts: Array<Product> = [];
for (let item of state.cart.contents) {
const withQuantity = {
...item,
quantity: 1
}
const foundItem = newProducts.findIndex((res) => res.name === item.name);
if (foundItem === -1) {
newProducts.push(withQuantity);
} else {
// @ts-ignore
newProducts[foundItem].quantity += 1;
}
}
for (let item of newProducts) {
if (typeof item.quantity !== 'number') {
throw new Error("Quantity is possibly undefined in Cart.tsx");
}
item.quantity = item.quantity / 2;
}
setData(newProducts);
}, [state]);
/**
* PROBLEMATIC USEEFFECT BELOW
* LOOP BEHAVIOR ON DISPATCH
*/
useEffect(() => {
console.log(contents);
}, [contents]);
let subtotal = getSubtotal(data);
subtotal && dispatch({ type: ActionType.UPDATESUBTOTAL, payload: subtotal });
}, [data, getSubtotal]);
return (
<Page>
@@ -29,7 +60,12 @@ function Cart() {
}
<section id="cart-contents">
{contents || null}
{ data && data.map((product: Product) => <CartItem product={product} />) }
</section>
<section id="subtotal">
<p>Subtotal:</p>
<p>{state.cart.subtotal || "Not found"}</p>
</section>
</Page>
)

View File

@@ -1,8 +1,11 @@
import { v4 } from "uuid";
function CartItem({ product }: any) {
return (
<div className="cart-item-panel">
<div className="cart-item-panel" key={v4()}>
<strong>{product.name}</strong>
<p>{product.price}</p>
<p>Quantity: {product.quantity || "1"}</p>
</div>
)
}

View File

@@ -22,9 +22,7 @@ function NavBar() {
useEffect(() => {
if (state === initialState) return;
console.log(state.user);
if (state.user && state.user.headers.authenticated) {
if (state.user && state.user.headers?.authenticated) {
console.log('authenticated!');
setProfText(state.user.email);
setLoggedIn(true);

View File

@@ -40,6 +40,14 @@ export const reducer = (state: appState, action: userAction) => {
contents: updatedContents
}
}
case ActionType.UPDATESUBTOTAL:
return {
...state,
cart: {
...state.cart,
subtotal: action.payload
}
}
default:
return state;
}

View File

@@ -9,7 +9,8 @@ export enum ActionType {
UPDATEONE,
SEARCH,
USERLOGIN,
ADDTOCART
ADDTOCART,
UPDATESUBTOTAL
}
export interface userAction {

View File

@@ -26,7 +26,9 @@ export type Product = {
name: string,
productID?: number,
category?: string
price?: string | number
price?: string | number,
// when item is included in cart
quantity?: number,
shortDescription?: string,
longDescription?: string,
description?: string
@@ -47,7 +49,8 @@ export type Cart = {
cartID: number,
userInfo: userInfo,
checkedOut: boolean,
contents: Product[]
contents: Product[],
subTotal?: number
}
export type Order = {

View File

@@ -4,4 +4,21 @@ 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;
if (!cartData) return;
for (let item of cartData) {
if (typeof item.price === 'number') {
total += (item.price * (item.quantity || 1));
} else {
const converted = Number(item.price);
total += (converted * (item.quantity || 1));
}
}
return total;
}