Skip to content

Commit

Permalink
refactor cart and add total price (#112)
Browse files Browse the repository at this point in the history
  • Loading branch information
dogfrogfog authored Jul 14, 2024
1 parent a650913 commit c78c548
Show file tree
Hide file tree
Showing 12 changed files with 210 additions and 102 deletions.
71 changes: 56 additions & 15 deletions src/actions/cart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,63 @@ import {
getCookieCart,
updateCookieCartProduct,
removeCookieCartProduct,
changeCookieCartProductQuanity,
getCartProductKey,
} from "@/lib/utils/cart";

export const GRBPWR_CART = "grbpwr-cart";

export async function addCartProduct(slug: string, size: string) {
export async function addCartProduct({
slug,
size,
price,
}: {
slug: string;
size: string;
price: number;
}) {
"use server";

const cartData = getCookieCart();

try {
if (!cartData) {
createCookieCartProduct(slug, size);
createCookieCartProduct({ productSlug: slug, size, price });

return;
}

const productKey = getCartProductKey(slug, size);
const cartProduct = cartData.products[productKey];
let newProductQuanity;
const newProduct = {
quanity: 0,
price: 0,
};

if (cartProduct) {
newProductQuanity = cartProduct.quanity + 1;
newProduct.quanity = cartProduct.quanity + 1;
newProduct.price = cartProduct.price + price;
} else {
newProductQuanity = 1;
newProduct.quanity = 1;
newProduct.price = price;
}

updateCookieCartProduct(slug, size, newProductQuanity);
updateCookieCartProduct({ productSlug: slug, size, data: newProduct });
} catch (error) {
console.log("failed to parse cart", error);
}
}

export async function removeCartProduct(slug: string, size: string) {
export async function removeCartProduct({
productSlug,
size,
}: {
productSlug: string;
size: string;
}) {
"use server";

try {
removeCookieCartProduct(slug, size);
removeCookieCartProduct(productSlug, size);
} catch (error) {
console.log("failed to parse cart", error);
}
Expand All @@ -51,25 +69,48 @@ export async function changeCartProductQuanity({
slug,
size,
operation,
price,
}: {
slug: string;
price: number;
size: string;
operation: "increase" | "decrease";
}) {
"use server";
const cartData = getCookieCart();

try {
const cartData = getCookieCart();
if (
operation === "decrease" &&
cartData?.products[getCartProductKey(slug, size)]?.quanity === 1
) {
if (!cartData) return;

const productKey = getCartProductKey(slug, size);
const cartProduct = cartData.products[productKey];

if (operation === "decrease" && cartProduct.quanity === 1) {
removeCookieCartProduct(slug, size);

return;
}

changeCookieCartProductQuanity(slug, size, operation);
const newProduct = {
quanity: cartProduct.quanity,
price: cartProduct.price,
};

if (operation === "decrease") {
newProduct.quanity = cartProduct.quanity - 1;
newProduct.price = cartProduct.price - price;
}

if (operation === "increase") {
newProduct.quanity = cartProduct.quanity + 1;
newProduct.price = cartProduct.price + price;
}

updateCookieCartProduct({
productSlug: slug,
size,
data: newProduct,
});
} catch (error) {
console.log("failed to parse cart", error);
}
Expand Down
8 changes: 5 additions & 3 deletions src/app/cart/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import { CartProductsSkeleton } from "@/components/ui/Skeleton";
import Button from "@/components/ui/Button";
import { ButtonStyle } from "@/components/ui/Button/styles";
import Link from "next/link";
import TotalPrice from "@/components/cart/TotalPrice";

export const dynamic = "force-dynamic";

export default async function Page() {
export default async function CartPage() {
return (
<CoreLayout>
<div className="relative flex gap-32">
Expand All @@ -24,8 +25,9 @@ export default async function Page() {
</div>
<div className="relative grow">
<div className="sticky top-20">
<p className="mb-8 text-sm">total:</p>
<p className="mb-2 text-lg">170$</p>
{/* <p className="mb-8 text-sm">total:</p>
<p className="mb-2 text-lg">170$</p> */}
<TotalPrice />

<Button asChild style={ButtonStyle.simpleButton}>
<Link href="/cart/checkout">checkout</Link>
Expand Down
20 changes: 12 additions & 8 deletions src/app/product/[...productParams]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ export default async function ProductPage({ params }: ProductPageProps) {
id: parseInt(id),
});

console.log("product22");
console.log(product);
const baseCurrencyPrice =
product?.product?.productDisplay?.productBody?.price?.value;

return (
<CoreLayout hideForm>
Expand All @@ -76,12 +76,16 @@ export default async function ProductPage({ params }: ProductPageProps) {
{product?.product?.productDisplay?.productBody?.description}
</div>
<div className="mt-4">measurements</div>
<AddToCartForm
handleSubmit={addCartProduct}
slug={product?.product?.slug || ""}
// price={0}
sizes={product?.sizes || []}
/>
{baseCurrencyPrice &&
product?.product?.slug &&
product?.sizes?.length && (
<AddToCartForm
handleSubmit={addCartProduct}
slug={product.product.slug}
price={parseInt(baseCurrencyPrice)}
sizes={product.sizes}
/>
)}
</div>
</div>
</CoreLayout>
Expand Down
16 changes: 10 additions & 6 deletions src/components/cart/CartItemRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export default function CartItemRow({
if (!product) return null;

const { product: p } = product;
const basicCurrencyValue = p?.productDisplay?.productBody?.price?.value;

return (
<div className="flex justify-between gap-6 text-textColor">
Expand All @@ -34,12 +35,15 @@ export default function CartItemRow({
</div>
</div>
<div className="flex w-1/2 whitespace-nowrap text-sm">
<ProductAmountButtons
slug={p?.slug || ""}
size={size}
removeProduct={removeCartProduct}
changeProductAmount={changeCartProductQuanity}
/>
{p?.slug && basicCurrencyValue && (
<ProductAmountButtons
slug={p?.slug || ""}
size={size}
price={parseInt(basicCurrencyValue)}
removeProduct={removeCartProduct}
changeProductAmount={changeCartProductQuanity}
/>
)}
<div className="font-bold">quanity: {quanity}</div>
</div>
<div className="flex w-1/2 flex-col items-end space-y-2">
Expand Down
27 changes: 12 additions & 15 deletions src/components/cart/CartPopup.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
"use client";

import Button from "@/components/ui/Button";
import { useState } from "react";
import { ButtonStyle } from "../ui/Button/styles";
import Link from "next/link";
import { cn } from "@/lib/utils";
import { useClickAway } from "@uidotdev/usehooks";
import Button from "@/components/ui/Button";
import { cn } from "@/lib/utils";
import { ButtonStyle } from "../ui/Button/styles";

export default function CartPopup({ children }: { children: React.ReactNode }) {
export default function CartPopup({
children,
itemsQuanity,
}: {
children: React.ReactNode;
itemsQuanity?: number;
}) {
const [open, setOpenStatus] = useState(false);

const ref = useClickAway<HTMLDivElement>(() => {
Expand All @@ -21,7 +27,7 @@ export default function CartPopup({ children }: { children: React.ReactNode }) {
onClick={() => setOpenStatus(!open)}
style={ButtonStyle.underlinedButton}
>
cart
cart {itemsQuanity ? `(${itemsQuanity})` : ""}
</Button>
<div className="blueTheme">
<div
Expand All @@ -33,16 +39,7 @@ export default function CartPopup({ children }: { children: React.ReactNode }) {
)}
>
<div className="mb-6 text-textColor">added to cart {"[06]"}</div>
<div className="relative">
<div className="no-scroll-bar relative max-h-[800px] space-y-5 overflow-y-scroll pb-5">
{children}
</div>
<div className="absolute bottom-0 left-0 h-28 w-full bg-gradient-to-t from-bgColor"></div>
</div>
<div className="mb-3 flex justify-between border-t border-dashed border-textColor pt-5 text-textColor">
<span>total:</span>
<span>170$</span>
</div>
{children}
<div className="flex justify-end gap-2">
<Button asChild style={ButtonStyle.simpleButton}>
<Link href="/cart">cart</Link>
Expand Down
4 changes: 3 additions & 1 deletion src/components/cart/CartProductsList.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import CartItemRow from "@/components/cart/CartItemRow";
import Button from "@/components/ui/Button";
import { serviceClient } from "@/lib/api";
import { getProductPrice } from "@/lib/utils";
import {
getCartProductSlugAndSizeFromKey,
getCookieCart,
Expand All @@ -11,6 +10,9 @@ import Link from "next/link";
export default async function CartProductsList() {
const cartData = getCookieCart();

console.log("cartData");
console.log(cartData);

if (!cartData || !cartData.products) return null;

const productsPromises = Object.entries(cartData.products).map(
Expand Down
34 changes: 26 additions & 8 deletions src/components/cart/ProductAmountButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,31 @@ type Props = {
slug,
size,
operation,
price,
}: {
slug: string;
size: string;
price: number;
operation: "increase" | "decrease";
}) => void;
removeProduct: (slug: string, size: string) => void;
removeProduct: ({
productSlug,
size,
}: {
productSlug: string;
size: string;
}) => void;
slug: string;
size: string;
price: number;
};

export default function ProductAmountButtons({
changeProductAmount,
removeProduct,
slug,
size,
price,
}: Props) {
// todo: check if product is in stock

Expand All @@ -31,23 +41,31 @@ export default function ProductAmountButtons({
<div className="flex ">
<Button
style={ButtonStyle.default}
onClick={() =>
changeProductAmount({ slug, size, operation: "increase" })
}
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();

changeProductAmount({ slug, size, operation: "increase", price });
}}
>
[+]
</Button>
<Button
style={ButtonStyle.default}
onClick={() =>
changeProductAmount({ slug, size, operation: "decrease" })
}
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();

changeProductAmount({ slug, size, operation: "decrease", price });
}}
>
[-]
</Button>
<Button
style={ButtonStyle.default}
onClick={() => removeProduct(slug, size)}
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();

removeProduct({ productSlug: slug, size });
}}
>
[x]
</Button>
Expand Down
21 changes: 21 additions & 0 deletions src/components/cart/TotalPrice/SelectedCurrency.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"use client";

import { useHeroContext } from "@/components/contexts/HeroContext";

export default function SelectedCurrency({
baseCurrencyTotal,
}: {
baseCurrencyTotal: number;
}) {
const { selectedCurrency } = useHeroContext();

return (
<div>
<div>total</div>
<div> base currency: {baseCurrencyTotal}</div>
<div>
todo: convert to {selectedCurrency}: {baseCurrencyTotal}
</div>
</div>
);
}
19 changes: 19 additions & 0 deletions src/components/cart/TotalPrice/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { getCookieCart } from "@/lib/utils/cart";
import SelectedCurrency from "./SelectedCurrency";

export default function TotalPrice() {
const cartData = getCookieCart();

if (!cartData) return;

const total = Object.values(cartData.products).reduce(
(acc, p) => acc + p.price,
0,
);

return (
<div>
<SelectedCurrency baseCurrencyTotal={total} />
</div>
);
}
Loading

0 comments on commit c78c548

Please sign in to comment.