Skip to content

Commit

Permalink
Merge pull request kirill-zhirnov#8 from stephanieg467/fix-split-orde…
Browse files Browse the repository at this point in the history
…rs-bug

fix bug in logic for splitting order by thc
  • Loading branch information
stephanieg467 authored Aug 6, 2024
2 parents 99241db + 6db2857 commit 347f240
Show file tree
Hide file tree
Showing 14 changed files with 254 additions and 183 deletions.
4 changes: 2 additions & 2 deletions @types/common.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { IMenuItem } from "./components";
import { IBasicSettings } from "./settings";
import {IMenuItem} from './components';
import {IBasicSettings} from './settings';

export enum TPublishingStatus {
published = 'published',
Expand Down
67 changes: 33 additions & 34 deletions components/cart/CartItems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,19 @@ import {
useMemo,
useRef,
useState,
} from "react";
import { useAppDispatch, useAppSelector } from "../../hooks/redux";
import { apiClient } from "../../lib/api";
import { addPromise } from "../../redux/reducers/xhr";
import { RootState } from "../../redux/store";
import debounce from "lodash/debounce";
import _cloneDeep from "lodash/cloneDeep";
import CartRow from "./CartRow";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faShoppingCart } from "@fortawesome/free-solid-svg-icons/faShoppingCart";
import { useRouter } from "next/router";
import { hideAlert, showErrorAlert } from "../../redux/reducers/alert";
import { IUseCartItems } from "../../hooks/cart";
import splitOrderByThcGrams from "../../lib/splitOrderByThcGrams";
} from 'react';
import {useAppDispatch, useAppSelector} from '../../hooks/redux';
import {apiClient} from '../../lib/api';
import {addPromise} from '../../redux/reducers/xhr';
import {RootState} from '../../redux/store';
import debounce from 'lodash/debounce';
import CartRow from './CartRow';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import {faShoppingCart} from '@fortawesome/free-solid-svg-icons/faShoppingCart';
import {useRouter} from 'next/router';
import {hideAlert, showErrorAlert} from '../../redux/reducers/alert';
import {IUseCartItems} from '../../hooks/cart';
import splitOrderByThcGrams from '../../lib/splitOrderByThcGrams';

export default function CartItems({
items,
Expand Down Expand Up @@ -49,7 +48,7 @@ export default function CartItems({

const rmItem = (itemId: number) => {
if (!cartId) return;
if (!confirm("Are you sure?")) return;
if (!confirm('Are you sure?')) return;

setSubmitting(true);
const promise = apiClient.cart
Expand Down Expand Up @@ -108,7 +107,7 @@ export default function CartItems({
if (totalThcGrams !== null && totalThcGrams > 30) {
dispatch(
showErrorAlert({
text: "Note: due to federal regulations limiting the quantity of cannabis products to 30 grams per order your order will be split into multiple packages.",
text: 'Note: due to federal regulations limiting the quantity of cannabis products to 30 grams per order your order will be split into multiple packages.',
})
);
} else {
Expand All @@ -117,22 +116,22 @@ export default function CartItems({
}, [totalThcGrams]);

useEffect(() => {
setSplitOrders(splitOrderByThcGrams({ items, totalThcGrams }));
setSplitOrders(splitOrderByThcGrams({items, totalThcGrams}));
}, [items, totalThcGrams]);

return (
<>
<div className="cart-items">
<div className="cart-items__thead row">
<div className="cart-items__thead-cell col-md-4"></div>
<div className="cart-items__thead-cell col-md-2">Price</div>
<div className="cart-items__thead-cell col-md-2">Qty</div>
<div className="cart-items__thead-cell col-md-2">Total</div>
<div className="cart-items__thead-cell col-md-2"></div>
<div className='cart-items'>
<div className='cart-items__thead row'>
<div className='cart-items__thead-cell col-md-4'></div>
<div className='cart-items__thead-cell col-md-2'>Price</div>
<div className='cart-items__thead-cell col-md-2'>Qty</div>
<div className='cart-items__thead-cell col-md-2'>Total</div>
<div className='cart-items__thead-cell col-md-2'></div>
</div>
{splitOrders.map((cartItems, index) => (
<>
{splitOrders.length > 1 && <div className="cart-items__split-order">Package {index + 1}</div>}
{splitOrders.length > 1 && <div className='cart-items__split-order'>Package {index + 1}</div>}
{cartItems.map((item) => (
<CartRow
item={item}
Expand All @@ -143,25 +142,25 @@ export default function CartItems({
))}
</>
))}
<div className="cart-items__total-row row">
<div className="cart-items__total-cell cart-items__total-cell_title col-md-6">
<div className='cart-items__total-row row'>
<div className='cart-items__total-cell cart-items__total-cell_title col-md-6'>
Order Total:
</div>
<div className="cart-items__total-cell col-md-2">
<span className="cart-items__label">Qty: </span>
<div className='cart-items__total-cell col-md-2'>
<span className='cart-items__label'>Qty: </span>
{total.qty}
</div>
<div className="cart-items__total-cell col-md-2">
<span className="cart-items__label">Price: </span>
<div className='cart-items__total-cell col-md-2'>
<span className='cart-items__label'>Price: </span>
{total.price}
</div>
</div>
</div>
<div className="cart-items__actions">
<div className='cart-items__actions'>
<button
className="btn btn-action btn-lg btn-anim"
className='btn btn-action btn-lg btn-anim'
disabled={submitting}
onClick={() => router.push("/checkout")}
onClick={() => router.push('/checkout')}
>
Proceed to checkout <FontAwesomeIcon icon={faShoppingCart} />
</button>
Expand Down
21 changes: 16 additions & 5 deletions components/cart/CartRow.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {ICartItem} from 'boundless-api-client';
import Link from 'next/link';
import {getCartImg} from '../../lib/imgs';
import {getProductUrl} from '../../lib/urls';
import NoImage from '../NoImage';
import {TThumbRatio} from 'boundless-api-client';
import {calcTotalPrice} from '../../lib/calculator';
import useFormatCurrency from '../../hooks/useFormatCurrency';
import {IUseCartItems} from '../../hooks/cart';

export default function CartRow({item, rmItem, onQtyChange}: ICartRowProps) {
const {formatCurrency} = useFormatCurrency();
Expand Down Expand Up @@ -45,8 +45,19 @@ export default function CartRow({item, rmItem, onQtyChange}: ICartRowProps) {
className='btn btn-outline-secondary text-center'
type='button'
style={{width: 25}}
disabled={item.qty < 2}
onClick={() => onQtyChange(item.qty - 1)}
onClick={() => {
if (item.qty === 1) {
// Split items will have an originalQty in which case we don't want to remove the entire item.
if (item?.originalQty) {
onQtyChange(item.originalQty - 1);
} else {
rmItem();
}
} else {
onQtyChange(item?.originalQty ? item.originalQty - 1 : item.qty - 1);
}
}
}
><>&ndash;</></button>
<input
type='number'
Expand All @@ -60,7 +71,7 @@ export default function CartRow({item, rmItem, onQtyChange}: ICartRowProps) {
className='btn btn-outline-secondary text-center'
type='button'
style={{width: 25}}
onClick={() => onQtyChange(item.qty + 1)}
onClick={() => onQtyChange(item?.originalQty ? item.originalQty + 1 : item.qty + 1)}
>+</button>
</div>
</div>
Expand All @@ -81,7 +92,7 @@ export default function CartRow({item, rmItem, onQtyChange}: ICartRowProps) {
}

interface ICartRowProps {
item: ICartItem;
item: IUseCartItems;
rmItem: () => void;
onQtyChange: (qty: number) => void
}
64 changes: 32 additions & 32 deletions components/footer/FooterMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,92 +1,92 @@
import clsx from "clsx";
import Link from "next/link";
import { IMenuItem } from "../../@types/components";
import clsx from 'clsx';
import Link from 'next/link';
import {IMenuItem} from '../../@types/components';

export default function FooterMenu() {
const boundlessBaseUrl = process.env.BOUNDLESS_BASE_URL || "";
const shopBaseUrl = process.env.SHOP_BASE_URL || "";
const boundlessBaseUrl = process.env.BOUNDLESS_BASE_URL || '';
const shopBaseUrl = process.env.SHOP_BASE_URL || '';

const menuListmenuList: IMenuItem[] = [
{
title: "Home",
title: 'Home',
url: boundlessBaseUrl,
isActive: false,
},
{
title: "Shop",
title: 'Shop',
url: shopBaseUrl,
isActive: true,
},
{
title: "Blog",
url: boundlessBaseUrl + "/blog",
title: 'Blog',
url: boundlessBaseUrl + '/blog',
isActive: false,
},
{
title: "About",
url: boundlessBaseUrl + "/about",
title: 'About',
url: boundlessBaseUrl + '/about',
isActive: false,
},
];

const menuListSecondary: IMenuItem[] = [
{
title: "Privacy",
url: shopBaseUrl + "/privacy-policy",
title: 'Privacy',
url: '/privacy-policy',
isActive: false,
},
{
title: "Refund",
url: shopBaseUrl + "/refund",
title: 'Refund',
url: '/refund',
isActive: false,
},
{
title: "Terms of Service",
url: shopBaseUrl + "/terms-of-service",
title: 'Terms of Service',
url: '/terms-of-service',
isActive: false,
},
];

return (
<>
<ul
className="page-footer-menu list-unstyled"
className='page-footer-menu list-unstyled'
itemScope
itemType="//schema.org/ItemList"
itemType='//schema.org/ItemList'
>
{menuListmenuList.map((item, i) => (
<li
className={clsx("page-footer-menu__list-element", {
className={clsx('page-footer-menu__list-element', {
active: item.isActive,
})}
key={item.title + i}
>
<div
itemProp="itemListElement"
itemProp='itemListElement'
itemScope
itemType="//schema.org/ListItem"
itemType='//schema.org/ListItem'
>
<ListElement item={item} position={i} />
</div>
</li>
))}
</ul>
<ul
className="page-footer-menu list-unstyled"
className='page-footer-menu list-unstyled'
itemScope
itemType="//schema.org/ItemList"
itemType='//schema.org/ItemList'
>
{menuListSecondary.map((item, i) => (
<li
className={clsx("page-footer-menu__list-element", {
className={clsx('page-footer-menu__list-element', {
active: item.isActive,
})}
key={item.title + i}
>
<div
itemProp="itemListElement"
itemProp='itemListElement'
itemScope
itemType="//schema.org/ListItem"
itemType='//schema.org/ListItem'
>
<ListElement item={item} position={i} />
</div>
Expand All @@ -109,23 +109,23 @@ function ListElement({
<>
<Link
href={item.url}
className={clsx("page-footer-menu__element is-link", {
className={clsx('page-footer-menu__element is-link', {
active: item.isActive,
})}
>
<span className="title" itemProp="name">
<span className='title' itemProp='name'>
{item.title}
</span>
</Link>
<meta itemProp="position" content={String(position + 1)} />
<meta itemProp='position' content={String(position + 1)} />
</>
);

return (
<div
className={clsx("page-footer-menu__element", { active: item.isActive })}
className={clsx('page-footer-menu__element', {active: item.isActive})}
>
<span className="page-footer-menu__text-title">{item.title}</span>
<span className='page-footer-menu__text-title'>{item.title}</span>
</div>
);
}
28 changes: 14 additions & 14 deletions hooks/cart.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { useAppDispatch, useAppSelector } from "./redux";
import { RootState } from "../redux/store";
import { initCart } from "../redux/actions/cart";
import { ICartItem } from "boundless-api-client";
import { useCallback, useEffect, useMemo, useState } from "react";
import { setCartTotal, setCartTotalThcGrams, setInitStatus, TCartInited } from "../redux/reducers/cart";
import {useAppDispatch, useAppSelector} from './redux';
import {RootState} from '../redux/store';
import {initCart} from '../redux/actions/cart';
import {ICartItem} from 'boundless-api-client';
import {useCallback, useEffect, useMemo, useState} from 'react';
import {setCartTotal, setCartTotalThcGrams, setInitStatus, TCartInited} from '../redux/reducers/cart';
import {
calcThcGramsTotal,
calcTotal,
calcTotalPrice,
itemThcGrams,
} from "../lib/calculator";
import { apiClient } from "../lib/api";
} from '../lib/calculator';
import {apiClient} from '../lib/api';

export function useCart() {
const cart = useAppSelector((state: RootState) => state.cart);
Expand All @@ -30,18 +30,19 @@ export function useCart() {

export interface IUseCartItems extends ICartItem {
thcGrams?: number;
originalQty?: number;
}
export const useCartItems = () => {
const dispatch = useAppDispatch();
const { id: cartId } = useCart();
const {id: cartId} = useCart();
const [items, setItems] = useState<Array<IUseCartItems>>([]);
const [loading, setLoading] = useState(false);
const totalThcGrams = useAppSelector(
(state: RootState) => state.cart.totalThcGrams
);

const calculateThcTotal = useMemo(async () => {
const total = await calcThcGramsTotal(items);
const calculateThcTotal = useMemo(() => {
const total = calcThcGramsTotal(items);
dispatch(setCartTotalThcGrams(total));
}, [items, dispatch]);

Expand All @@ -54,16 +55,15 @@ export const useCartItems = () => {

try {
const {cart, items} = await apiClient.cart.getCartItems(cartId);
// items.length ? await calculateThcTotal : 0;

const itemsPromises = items.map(item => itemThcGrams(item).then(thcGrams => ({...item, thcGrams})));
const results = await Promise.allSettled(itemsPromises);
const itemsWithThcGrams = results.filter(result => result.status === 'fulfilled').map(result => (result as PromiseFulfilledResult<IUseCartItems>).value);

calculateThcTotal;

setItems(itemsWithThcGrams);
dispatch(setInitStatus(TCartInited.processing));

await calculateThcTotal;
dispatch(setInitStatus(TCartInited.yes));
dispatch(setCartTotal(cart.total));
} catch (err) {
Expand Down
Loading

0 comments on commit 347f240

Please sign in to comment.