diff options
| author | Rafi Zadanly <zadanlyr@gmail.com> | 2023-02-20 10:49:35 +0700 |
|---|---|---|
| committer | Rafi Zadanly <zadanlyr@gmail.com> | 2023-02-20 10:49:35 +0700 |
| commit | d22df6bd30b8ed4bcfa938dcbbedc5fc376c2304 (patch) | |
| tree | 8d86213da671f07a57f78bd5d6ac0cce80ffe970 /src/lib/cart/components | |
| parent | 71ca8757d549c62e7b2925793689815f4ab771ad (diff) | |
cart refactor
Diffstat (limited to 'src/lib/cart/components')
| -rw-r--r-- | src/lib/cart/components/Cart.jsx | 200 |
1 files changed, 190 insertions, 10 deletions
diff --git a/src/lib/cart/components/Cart.jsx b/src/lib/cart/components/Cart.jsx index 5f9ae1c0..3dd54429 100644 --- a/src/lib/cart/components/Cart.jsx +++ b/src/lib/cart/components/Cart.jsx @@ -1,28 +1,208 @@ import Link from "@/core/components/elements/Link/Link" import useCart from "../hooks/useCart" import Image from "@/core/components/elements/Image/Image" +import currencyFormat from "@/core/utils/currencyFormat" +import { useEffect, useState } from "react" +import { getItemCart, updateItemCart } from "@/core/utils/cart" +import { CheckIcon, RectangleGroupIcon } from "@heroicons/react/24/outline" +import { createSlug } from "@/core/utils/slug" +import { useRouter } from "next/router" const Cart = () => { - const { cart } = useCart() + const router = useRouter() + const [ products, setProducts ] = useState(null) + const { cart } = useCart({ enabled: !products }) + + const [ totalPriceBeforeTax, setTotalPriceBeforeTax ] = useState(0) + const [ totalTaxAmount, setTotalTaxAmount ] = useState(0) + const [ totalDiscountAmount, setTotalDiscountAmount ] = useState(0) + + useEffect(() => { + if (cart.data && !products) { + const productsWithQuantity = cart.data.map((product) => { + const productInCart = getItemCart({ productId: product.id }) + if (!productInCart) return + return { + ...product, + quantity: productInCart.quantity, + selected: productInCart.selected + } + }) + setProducts(productsWithQuantity) + } + }, [cart, products]) + + useEffect(() => { + if (!products) return + + let calculateTotalPriceBeforeTax = 0 + let calculateTotalTaxAmount = 0 + let calculateTotalDiscountAmount = 0 + for (const product of products) { + if (product.quantity == '') continue + updateItemCart({ + productId: product.id, + quantity: product.quantity, + selected: product.selected + }) + + if (!product.selected) continue + let priceBeforeTax = product.price.price / 1.11 + calculateTotalPriceBeforeTax += priceBeforeTax * product.quantity + calculateTotalTaxAmount += (product.price.price - priceBeforeTax) * product.quantity + calculateTotalDiscountAmount += (product.price.price - product.price.priceDiscount) * product.quantity + } + setTotalPriceBeforeTax(calculateTotalPriceBeforeTax) + setTotalTaxAmount(calculateTotalTaxAmount) + setTotalDiscountAmount(calculateTotalDiscountAmount) + }, [products]) + + const updateQuantity = (value, productId, operation = '') => { + let productIndex = products.findIndex((product) => product.id == productId) + if (productIndex < 0) return + + let productsToUpdate = products + let quantity = productsToUpdate[productIndex].quantity + if (value != '' && isNaN(parseInt(value))) return + value = value != '' ? parseInt(value) : '' + switch (operation) { + case 'PLUS': + quantity += value + break + case 'MINUS': + if ((quantity - value) < 1) return + quantity -= value + break + case 'BLUR': + if (value != '') return + quantity = 1 + break + default: + quantity = value + break + } + productsToUpdate[productIndex].quantity = quantity + setProducts([ ...productsToUpdate ]) + } + + const toggleSelected = (productId) => { + let productIndex = products.findIndex((product) => product.id == productId) + if (productIndex < 0) return + + let productsToUpdate = products + productsToUpdate[productIndex].selected = !productsToUpdate[productIndex].selected + setProducts([ ...productsToUpdate ]) + } + + const selectedProduct = () => { + if (!products) return [] + return products.filter((product) => product.selected == true) + } return ( - <div className="p-4"> - <div className="flex justify-between mb-4"> + <div className="pt-6"> + <div className="flex justify-between mb-4 px-4"> <h1 className="font-semibold">Daftar Produk Belanja</h1> <Link href="/">Cari Produk Lain</Link> </div> - <div className="flex flex-col gap-y-4"> - { cart.data?.map((product) => ( + <div className="flex flex-col gap-y-4 px-4"> + { products?.map((product) => ( <div key={product.id} className="flex"> - <div className="w-4/12"> - <Image src={product?.parent?.image} alt={product?.name} className="object-contain object-center border border-gray_r-6 h-32 w-full rounded-md" /> - </div> - <div className="flex-1 px-2"> - <div>{ product?.parent?.name }</div> + <button + type="button" + className="flex items-center mr-2" + onClick={() => toggleSelected(product.id)} + > + { !product.selected && ( + <div className="w-5 h-5 border border-gray_r-11 rounded" /> + ) } + { product.selected && ( + <CheckIcon className="border bg-red_r-10 w-5 text-white" /> + ) } + </button> + <Link + href={createSlug('/shop/product/', product.parent.name, product.parent.id)} + className="w-3/12 flex-shrink-0" + > + <Image src={product?.parent?.image} alt={product?.name} className="object-contain object-center border border-gray_r-6 h-40 w-full rounded-md" /> + </Link> + <div className="flex-1 px-2 text-caption-1"> + <Link + href={createSlug('/shop/product/', product.parent.name, product.parent.id)} + className="line-clamp-2 leading-6 !text-gray_r-12 font-normal" + > + { product?.parent?.name } + </Link> + <div className="text-gray_r-11 mt-1">{ product.code }</div> + { product?.price?.discountPercentage > 0 && ( + <div className="flex gap-x-1 items-center mt-3"> + <div className="text-gray_r-11 line-through text-caption-2"> + {currencyFormat(product?.price?.price)} + </div> + <div className="badge-solid-red"> + {product?.price?.discountPercentage}% + </div> + </div> + ) } + <div className="font-normal mt-1"> + { currencyFormat(product?.price?.priceDiscount) } + </div> + <div className="flex justify-between items-center mt-1"> + <div className="text-red_r-11 font-medium"> + { currencyFormat(product?.price?.priceDiscount * product.quantity) } + </div> + <div className="flex gap-x-2"> + <button + type="button" + className="btn-light px-2 py-1" + onClick={() => updateQuantity(1, product.id, 'MINUS')} + > + - + </button> + <input + className="form-input w-10 border-0 border-b rounded-none py-1 px-0 text-center" + value={product.quantity} + onChange={(e) => updateQuantity(e.target.value, product.id)} + onBlur={(e) => updateQuantity(e.target.value, product.id, 'BLUR')} + /> + <button + type="button" + className="btn-light px-2 py-1" + onClick={() => updateQuantity(1, product.id, 'PLUS')} + > + + + </button> + </div> + </div> </div> </div> )) } </div> + <div className="sticky bottom-0 left-0 w-full p-4 mt-6 border-t border-gray_r-6 bg-white"> + <div className="flex justify-between mb-4"> + <div className="text-gray_r-11"> + Total: <span className="text-red_r-11 font-semibold">{ currencyFormat(totalPriceBeforeTax - totalDiscountAmount + totalTaxAmount) }</span> + </div> + </div> + <div className="flex gap-x-3"> + <button + type="button" + className="btn-yellow flex-1" + disabled={selectedProduct().length == 0} + onClick={() => router.push('/shop/quotation')} + > + Quotation + </button> + <button + type="button" + className="btn-solid-red flex-1" + disabled={selectedProduct().length == 0} + onClick={() => router.push('/shop/checkout')} + > + Checkout + </button> + </div> + </div> </div> ) } |
