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 { useContext, useEffect, useState } from "react";
import { AppContext } from "../../store/store"; import { AppContext } from "../../store/store";
import { ActionType } from "../../store/store_types";
import { Product } from '../../types/main'; import { Product } from '../../types/main';
import { getSubtotal } from "../../util/helpers";
import Page from "../../util/Page"; import Page from "../../util/Page";
import CartItem from "./CartItem"; import CartItem from "./CartItem";
function Cart() { function Cart() {
const [state, dispatch] = useContext(AppContext); const [state, dispatch] = useContext(AppContext);
const [contents, setContents] = useState<JSX.Element>(); const [contents, setContents] = useState<JSX.Element>();
const [data, setData] = useState<any>();
useEffect(() => { useEffect(() => {
setContents( if (!state.cart.contents) return;
state.cart.contents.map((product: Product) => <CartItem product={product} />)
)
}, [state, setContents]);
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(() => { useEffect(() => {
console.log(contents); let subtotal = getSubtotal(data);
}, [contents]); subtotal && dispatch({ type: ActionType.UPDATESUBTOTAL, payload: subtotal });
}, [data, getSubtotal]);
return ( return (
<Page> <Page>
@@ -29,7 +60,12 @@ function Cart() {
} }
<section id="cart-contents"> <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> </section>
</Page> </Page>
) )

View File

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

View File

@@ -22,9 +22,7 @@ function NavBar() {
useEffect(() => { useEffect(() => {
if (state === initialState) return; 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!'); console.log('authenticated!');
setProfText(state.user.email); setProfText(state.user.email);
setLoggedIn(true); setLoggedIn(true);

View File

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

View File

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

View File

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

View File

@@ -4,4 +4,21 @@ import { Product } from "../types/main";
export const addToCart = (productData: Product, dispatch: React.Dispatch<userAction>): any => { export const addToCart = (productData: Product, dispatch: React.Dispatch<userAction>): any => {
dispatch({ type: ActionType.ADDTOCART, payload: productData }); 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;
} }