summaryrefslogtreecommitdiff
path: root/src/lib/cart/components/Cart.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/cart/components/Cart.jsx')
-rw-r--r--src/lib/cart/components/Cart.jsx200
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>
)
}