From f99e0aba70efad0deb907d8e27f09fc9f527c8a4 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Fri, 17 Feb 2023 17:07:50 +0700 Subject: Refactor --- src2/pages/shop/cart.js | 282 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 282 insertions(+) create mode 100644 src2/pages/shop/cart.js (limited to 'src2/pages/shop/cart.js') diff --git a/src2/pages/shop/cart.js b/src2/pages/shop/cart.js new file mode 100644 index 00000000..1178781b --- /dev/null +++ b/src2/pages/shop/cart.js @@ -0,0 +1,282 @@ +import { useEffect, useState } from "react"; +import { toast } from "react-hot-toast"; +import { + TrashIcon, + PlusIcon, + MinusIcon, + ExclamationCircleIcon, +} from "@heroicons/react/24/solid"; +import { ExclamationTriangleIcon } from "@heroicons/react/24/outline"; +import { useRouter } from "next/router"; + +// Helpers +import { + createOrUpdateItemCart, + deleteItemCart, + getCart +} from "@/core/utils/cart"; +import { createSlug } from "@/core/utils/slug"; +import apiOdoo from "@/core/utils/apiOdoo"; +import currencyFormat from "@/core/utils/currencyFormat"; + +// Components +import Image from "@/components/elements/Image"; +import Layout from "@/components/layouts/Layout"; +import Link from "@/components/elements/Link"; +import Alert from "@/components/elements/Alert"; +import Spinner from "@/components/elements/Spinner"; +import AppBar from "@/components/layouts/AppBar"; +import ProgressBar from "@/components/elements/ProgressBar"; +import LineDivider from "@/components/elements/LineDivider"; +import useConfirmAlert from "@/lib/elements/hooks/useConfirmAlert"; + +export default function Cart() { + const router = useRouter(); + const [isLoadingProducts, setIsLoadingProducts] = useState(true); + const [products, setProducts] = useState([]); + const [totalPriceBeforeTax, setTotalPriceBeforeTax] = useState(0); + const [totalTaxAmount, setTotalTaxAmount] = useState(0); + const [totalDiscountAmount, setTotalDiscountAmount] = useState(0); + + useEffect(() => { + const getProducts = async () => { + let cart = getCart(); + let productIds = Object.keys(cart); + if (productIds.length > 0) { + productIds = productIds.join(','); + let dataProducts = await apiOdoo('GET', `/api/v1/product_variant/${productIds}`); + dataProducts = dataProducts.map((product) => ({ + ...product, + quantity: cart[product.id].quantity, + selected: cart[product.id].selected, + })); + setProducts(dataProducts); + } + setIsLoadingProducts(false); + } + getProducts(); + }, []); + + useEffect(() => { + for (const product of products) { + if (product.quantity != '') createOrUpdateItemCart(product.id, product.quantity, product.selected); + } + const productsSelected = products.filter((product) => product.selected == true); + let calculateTotalPriceBeforeTax = 0; + let calculateTotalTaxAmount = 0; + let calculateTotalDiscountAmount = 0; + productsSelected.forEach(product => { + let priceBeforeTax = product.price.price / 1.11; + calculateTotalPriceBeforeTax += priceBeforeTax * product.quantity; + calculateTotalTaxAmount += (product.price.price - priceBeforeTax) * product.quantity; + calculateTotalDiscountAmount += (product.price.price - product.price.price_discount) * product.quantity; + }); + setTotalPriceBeforeTax(calculateTotalPriceBeforeTax); + setTotalTaxAmount(calculateTotalTaxAmount); + setTotalDiscountAmount(calculateTotalDiscountAmount); + }, [products]); + + const getProductsSelected = () => { + return products.filter((product) => product.selected == true); + } + + const updateCart = (productId, quantity) => { + let productIndexToUpdate = products.findIndex((product) => product.id == productId); + let productsToUpdate = products; + productsToUpdate[productIndexToUpdate].quantity = quantity; + setProducts([...productsToUpdate]); + }; + + const blurQuantity = (productId, quantity) => { + quantity = quantity == ('' || 0) ? 1 : parseInt(quantity); + if (typeof quantity === 'number') { + quantity = parseInt(quantity); + quantity = Math.floor(quantity); + } + updateCart(productId, quantity); + }; + + const updateQuantity = (productId, quantity) => { + quantity = quantity == '' ? '' : parseInt(quantity); + updateCart(productId, quantity); + }; + + const plusQuantity = (productId) => { + let productIndexToUpdate = products.findIndex((product) => product.id == productId); + let quantity = products[productIndexToUpdate].quantity + 1; + updateCart(productId, quantity); + } + + const minusQuantity = (productId) => { + let productIndexToUpdate = products.findIndex((product) => product.id == productId); + let quantity = products[productIndexToUpdate].quantity - 1; + updateCart(productId, quantity); + } + + const toggleProductSelected = (productId) => { + let productIndexToUpdate = products.findIndex((product) => product.id == productId); + let productsToUpdate = products; + productsToUpdate[productIndexToUpdate].selected = !productsToUpdate[productIndexToUpdate].selected; + setProducts([...productsToUpdate]); + } + + const deleteItem = (productId) => { + let productIndexToUpdate = products.findIndex((product) => product.id == productId); + let productsToUpdate = products; + productsToUpdate.splice(productIndexToUpdate, 1); + setProducts([...productsToUpdate]); + deleteItemCart(productId); + toast.success('Berhasil menghapus 1 barang dari keranjang', { duration: 1500 }); + } + + const { + openConfirmAlert, + ConfirmAlert + } = useConfirmAlert({ + title: 'Hapus barang dari keranjang', + caption:'Apakah anda yakin menghapus barang dari keranjang?', + closeText: 'Batal', + submitText: 'Hapus', + onSubmit: deleteItem + }) + + return ( + <> + { ConfirmAlert } + + + + + {isLoadingProducts && ( +
+ +
+ ) } + + { !isLoadingProducts && products.length == 0 && ( +
+ +

Keranjang belanja anda masih kosong.

+ Mulai Belanja +
+ ) } + + { !isLoadingProducts && products.length > 0 && ( + <> + + + + +
+ +
+ +
+ Mohon dicek kembali & pastikan pesanan kamu sudah sesuai dengan yang kamu butuhkan. Atau bisa hubungi kami. +
+
+ + + +
+
+

Daftar Produk Belanja

+ Cari Produk Lain +
+ {products.map((product, index) => ( +
+
toggleProductSelected(product.id)}> + + {product.parent.name} +
+
+ + {product.parent.name} + +

+ {product.code || '-'} + {product.attributes.length > 0 ? ` | ${product.attributes.join(', ')}` : ''} +

+
+ {product.price.discount_percentage > 0 && ( + <> +

{currencyFormat(product.price.price)}

+ {product.price.discount_percentage}% + + )} +

{currencyFormat(product.price.price_discount)}

+
+
+

{currencyFormat(product.quantity * product.price.price_discount)}

+
+ + + blurQuantity(product.id, e.target.value)} + onChange={(e) => updateQuantity(product.id, e.target.value)} + value={product.quantity} + /> + +
+
+
+
+ ))} +
+ +
+
+

Total

+

{getProductsSelected().length > 0 && ( + <>({ getProductsSelected().length } Barang) + )}

+

{currencyFormat(totalPriceBeforeTax + totalTaxAmount - totalDiscountAmount)}

+
+ +
+ + +
+
+ + ) } +
+ + ); +} \ No newline at end of file -- cgit v1.2.3