From 67398e6f10d6f7729d8f1ace7005ef13d32c5ddd Mon Sep 17 00:00:00 2001
From: Rafi Zadanly <zadanlyr@gmail.com>
Date: Thu, 4 Jan 2024 10:05:25 +0700
Subject: Update promotion program feature

---
 src/lib/checkout/components/Checkout.jsx | 930 +++++++++++++++----------------
 1 file changed, 440 insertions(+), 490 deletions(-)

(limited to 'src/lib/checkout/components/Checkout.jsx')

diff --git a/src/lib/checkout/components/Checkout.jsx b/src/lib/checkout/components/Checkout.jsx
index 9a799010..eb31b9dc 100644
--- a/src/lib/checkout/components/Checkout.jsx
+++ b/src/lib/checkout/components/Checkout.jsx
@@ -1,191 +1,199 @@
-import Alert from '@/core/components/elements/Alert/Alert'
-import Divider from '@/core/components/elements/Divider/Divider'
-import Link from '@/core/components/elements/Link/Link'
-import useAuth from '@/core/hooks/useAuth'
-import { getItemAddress } from '@/core/utils/address'
-import addressesApi from '@/lib/address/api/addressesApi'
+import Alert from '@/core/components/elements/Alert/Alert';
+import Divider from '@/core/components/elements/Divider/Divider';
+import Link from '@/core/components/elements/Link/Link';
+import useAuth from '@/core/hooks/useAuth';
+import { getItemAddress } from '@/core/utils/address';
+import addressesApi from '@/lib/address/api/addressesApi';
 import {
   BanknotesIcon,
   ChevronLeftIcon,
   ClockIcon,
-  ExclamationCircleIcon
-} from '@heroicons/react/24/outline'
-import React, { useEffect, useRef, useState } from 'react'
-import _ from 'lodash'
-import { deleteItemCart, getCartApi } from '@/core/utils/cart'
-import currencyFormat from '@/core/utils/currencyFormat'
-import { toast } from 'react-hot-toast'
-import getFileBase64 from '@/core/utils/getFileBase64'
-import { useRouter } from 'next/router'
-import VariantGroupCard from '@/lib/variant/components/VariantGroupCard'
-import axios from 'axios'
-import Image from '@/core/components/elements/Image/Image'
-import MobileView from '@/core/components/views/MobileView'
-import DesktopView from '@/core/components/views/DesktopView'
-import ExpedisiList from '../api/ExpedisiList'
-import whatsappUrl from '@/core/utils/whatsappUrl'
-import BottomPopup from '@/core/components/elements/Popup/BottomPopup'
-import { useQuery } from 'react-query'
-import { gtagPurchase } from '@/core/utils/googleTag'
-import { findVoucher, getVoucher } from '../api/getVoucher'
-import CardProdcuctsList from '@/core/components/elements/Product/cartProductsList'
-import { Spinner } from '@chakra-ui/react'
-import { AnimatePresence, motion } from 'framer-motion'
-
-const SELF_PICKUP_ID = 32
-
-const { checkoutApi } = require('../api/checkoutApi')
-const { getProductsCheckout } = require('../api/checkoutApi')
+  ExclamationCircleIcon,
+} from '@heroicons/react/24/outline';
+import React, { useEffect, useRef, useState } from 'react';
+import _ from 'lodash';
+import { deleteItemCart } from '@/core/utils/cart';
+import currencyFormat from '@/core/utils/currencyFormat';
+import { toast } from 'react-hot-toast';
+import getFileBase64 from '@/core/utils/getFileBase64';
+import { useRouter } from 'next/router';
+import axios from 'axios';
+import Image from '@/core/components/elements/Image/Image';
+import MobileView from '@/core/components/views/MobileView';
+import DesktopView from '@/core/components/views/DesktopView';
+import ExpedisiList from '../api/ExpedisiList';
+import whatsappUrl from '@/core/utils/whatsappUrl';
+import BottomPopup from '@/core/components/elements/Popup/BottomPopup';
+import { useQuery } from 'react-query';
+import { gtagPurchase } from '@/core/utils/googleTag';
+import { findVoucher, getVoucher } from '../api/getVoucher';
+import { Spinner } from '@chakra-ui/react';
+import { AnimatePresence, motion } from 'framer-motion';
+import snakecaseKeys from 'snakecase-keys';
+import CartItem from '~/modules/cart/components/Item.tsx';
+
+const SELF_PICKUP_ID = 32;
+
+const { checkoutApi } = require('../api/checkoutApi');
+const { getProductsCheckout } = require('../api/checkoutApi');
 
 const Checkout = () => {
-  const router = useRouter()
-  const query = router.query.source ?? null
-  const auth = useAuth()
+  const router = useRouter();
+  const query = router.query.source ?? null;
+  const auth = useAuth();
 
-  const [activeVoucher, SetActiveVoucher] = useState(null)
+  const [activeVoucher, SetActiveVoucher] = useState(null);
 
   const { data: cartCheckout } = useQuery('cartCheckout-' + activeVoucher, () =>
     getProductsCheckout(activeVoucher, query)
-  )
+  );
 
   const [selectedAddress, setSelectedAddress] = useState({
     shipping: null,
-    invoicing: null
-  })
-  const [addresses, setAddresses] = useState(null)
+    invoicing: null,
+  });
+  const [addresses, setAddresses] = useState(null);
 
   useEffect(() => {
-    if (!auth) return
+    if (!auth) return;
 
     const getAddresses = async () => {
-      const dataAddresses = await addressesApi()
-      setAddresses(dataAddresses)
-    }
+      const dataAddresses = await addressesApi();
+      setAddresses(dataAddresses);
+    };
 
-    getAddresses()
-  }, [auth])
+    getAddresses();
+  }, [auth]);
 
   useEffect(() => {
-    if (!addresses) return
+    if (!addresses) return;
 
     const matchAddress = (key) => {
-      const addressToMatch = getItemAddress(key)
-      const foundAddress = addresses.filter((address) => address.id == addressToMatch)
+      const addressToMatch = getItemAddress(key);
+      const foundAddress = addresses.filter(
+        (address) => address.id == addressToMatch
+      );
       if (foundAddress.length > 0) {
-        return foundAddress[0]
+        return foundAddress[0];
       }
-      return addresses[0]
-    }
+      return addresses[0];
+    };
 
     setSelectedAddress({
       shipping: matchAddress('shipping'),
-      invoicing: matchAddress('invoicing')
-    })
-  }, [addresses])
-
-  const [products, setProducts] = useState(null)
-  const [totalWeight, setTotalWeight] = useState(0)
-  const [priceCheck, setPriceCheck] = useState(false)
-  const [listExpedisi, setExpedisi] = useState([])
-  const [listserviceExpedisi, setListServiceExpedisi] = useState([])
-  const [selectedExpedisi, setSelectedExpedisi] = useState(0)
-  const [selectedCarrierId, setselectedCarrierId] = useState(0)
-  const [selectedCarrier, setselectedCarrier] = useState(0)
-  const [biayaKirim, setBiayaKirim] = useState(0)
-  const [checkWeigth, setCheckWeight] = useState(false)
-  const [selectedServiceType, setSelectedServiceType] = useState(null)
-  const [selectedExpedisiService, setselectedExpedisiService] = useState(null)
-  const [etd, setEtd] = useState(null)
-  const [etdFix, setEtdFix] = useState(null)
-  const [bottomPopup, SetBottomPopup] = useState(null)
-  const [bottomPopupTnC, SetBottomPopupTnC] = useState(null)
-  const [itemTnC, setItemTnC] = useState(null)
-  const [listVouchers, SetListVoucher] = useState(null)
-  const [discountVoucher, SetDiscountVoucher] = useState(0)
-  const [codeVoucher, SetCodeVoucher] = useState(null)
-  const [findCodeVoucher, SetFindVoucher] = useState(null)
-  const [selisihHargaCode, SetSelisihHargaCode] = useState(null)
-  const [buttonTerapkan, SetButtonTerapkan] = useState(false)
-  const [checkoutValidation, setCheckoutValidation] = useState(false)
-  const [loadingVoucher, setLoadingVoucher] = useState(true)
-  const [loadingRajaOngkir, setLoadingRajaOngkir] = useState(false)
-
-  const expedisiValidation = useRef(null)
+      invoicing: matchAddress('invoicing'),
+    });
+  }, [addresses]);
+
+  const [products, setProducts] = useState(null);
+  const [totalWeight, setTotalWeight] = useState(0);
+  const [priceCheck, setPriceCheck] = useState(false);
+  const [listExpedisi, setExpedisi] = useState([]);
+  const [listserviceExpedisi, setListServiceExpedisi] = useState([]);
+  const [selectedExpedisi, setSelectedExpedisi] = useState(0);
+  const [selectedCarrierId, setselectedCarrierId] = useState(0);
+  const [selectedCarrier, setselectedCarrier] = useState(0);
+  const [biayaKirim, setBiayaKirim] = useState(0);
+  const [checkWeigth, setCheckWeight] = useState(false);
+  const [selectedServiceType, setSelectedServiceType] = useState(null);
+  const [selectedExpedisiService, setselectedExpedisiService] = useState(null);
+  const [etd, setEtd] = useState(null);
+  const [etdFix, setEtdFix] = useState(null);
+  const [bottomPopup, SetBottomPopup] = useState(null);
+  const [bottomPopupTnC, SetBottomPopupTnC] = useState(null);
+  const [itemTnC, setItemTnC] = useState(null);
+  const [listVouchers, SetListVoucher] = useState(null);
+  const [discountVoucher, SetDiscountVoucher] = useState(0);
+  const [codeVoucher, SetCodeVoucher] = useState(null);
+  const [findCodeVoucher, SetFindVoucher] = useState(null);
+  const [selisihHargaCode, SetSelisihHargaCode] = useState(null);
+  const [buttonTerapkan, SetButtonTerapkan] = useState(false);
+  const [checkoutValidation, setCheckoutValidation] = useState(false);
+  const [loadingVoucher, setLoadingVoucher] = useState(true);
+  const [loadingRajaOngkir, setLoadingRajaOngkir] = useState(false);
+
+  const expedisiValidation = useRef(null);
 
   const voucher = async () => {
     if (!listVouchers) {
       try {
-        let dataVoucher = await getVoucher(auth?.id, query)
-        SetListVoucher(dataVoucher)
+        let dataVoucher = await getVoucher(auth?.id, query);
+        SetListVoucher(dataVoucher);
       } finally {
-        setLoadingVoucher(false)
+        setLoadingVoucher(false);
       }
     }
-  }
+  };
   const VoucherCode = async (code) => {
-    let dataVoucher = await findVoucher(code, auth.id, query)
+    let dataVoucher = await findVoucher(code, auth.id, query);
     if (dataVoucher.length <= 0) {
-      SetFindVoucher(1)
-      return
+      SetFindVoucher(1);
+      return;
     }
 
-    let addNewLine = dataVoucher[0]
-    let checkList = listVouchers.findIndex((voucher) => voucher.code == addNewLine.code)
+    let addNewLine = dataVoucher[0];
+    let checkList = listVouchers.findIndex(
+      (voucher) => voucher.code == addNewLine.code
+    );
     if (checkList >= 0) {
       if (listVouchers[checkList].canApply) {
-        ToggleSwitch(code)
-        SetCodeVoucher(null)
+        ToggleSwitch(code);
+        SetCodeVoucher(null);
       } else {
-        SetSelisihHargaCode(listVouchers[checkList].differenceToApply)
-        SetFindVoucher(2)
+        SetSelisihHargaCode(listVouchers[checkList].differenceToApply);
+        SetFindVoucher(2);
       }
-      return
+      return;
     }
     if (cartCheckout?.subtotal < addNewLine.minPurchaseAmount) {
-      SetSelisihHargaCode(currencyFormat(addNewLine.minPurchaseAmount - cartCheckout?.subtotal))
-      SetFindVoucher(2)
-      return
+      SetSelisihHargaCode(
+        currencyFormat(addNewLine.minPurchaseAmount - cartCheckout?.subtotal)
+      );
+      SetFindVoucher(2);
+      return;
     } else {
-      SetFindVoucher(3)
-      SetButtonTerapkan(true)
+      SetFindVoucher(3);
+      SetButtonTerapkan(true);
     }
-    SetListVoucher((prevList) => [addNewLine, ...prevList])
-    SetActiveVoucher(addNewLine.code)
-  }
+    SetListVoucher((prevList) => [addNewLine, ...prevList]);
+    SetActiveVoucher(addNewLine.code);
+  };
 
   useEffect(() => {
-    SetFindVoucher(null)
-  }, [bottomPopup])
+    SetFindVoucher(null);
+  }, [bottomPopup]);
 
   useEffect(() => {
     const loadExpedisi = async () => {
-      let dataExpedisi = await ExpedisiList()
+      let dataExpedisi = await ExpedisiList();
       dataExpedisi = dataExpedisi.map((expedisi) => ({
         value: expedisi.id,
         label: expedisi.name,
-        carrierId: expedisi.deliveryCarrierId
-      }))
-      setExpedisi(dataExpedisi)
-    }
-    loadExpedisi()
+        carrierId: expedisi.deliveryCarrierId,
+      }));
+      setExpedisi(dataExpedisi);
+    };
+    loadExpedisi();
 
     const handlePopState = () => {
-      router.push('/shop/cart')
-    }
+      router.push('/shop/cart');
+    };
 
-    window.onpopstate = handlePopState
+    window.onpopstate = handlePopState;
 
     return () => {
-      window.onpopstate = null
-    }
+      window.onpopstate = null;
+    };
     // voucher()
-  }, [])
+  }, []);
 
   const hitungDiscountVoucher = (code) => {
-    let dataVoucherIndex = listVouchers.findIndex((voucher) => voucher.code == code)
-    let dataActiveVoucher = listVouchers[dataVoucherIndex]
+    let dataVoucherIndex = listVouchers.findIndex(
+      (voucher) => voucher.code == code
+    );
+    let dataActiveVoucher = listVouchers[dataVoucherIndex];
 
-    let countDiscount = dataActiveVoucher.discountVoucher
+    let countDiscount = dataActiveVoucher.discountVoucher;
 
     /*if (dataActiveVoucher.discountType === 'percentage') {
       countDiscount = cartCheckout?.subtotal * (dataActiveVoucher.discountAmount / 100)
@@ -199,116 +207,122 @@ const Checkout = () => {
       countDiscount = dataActiveVoucher.discountAmount
     }*/
 
-    return countDiscount
-  }
+    return countDiscount;
+  };
 
   useEffect(() => {
-    if (!listVouchers) return
-    if (!activeVoucher) return
+    if (!listVouchers) return;
+    if (!activeVoucher) return;
 
-    const countDiscount = hitungDiscountVoucher(activeVoucher)
+    const countDiscount = hitungDiscountVoucher(activeVoucher);
 
-    SetDiscountVoucher(countDiscount)
-  }, [activeVoucher, listVouchers])
+    SetDiscountVoucher(countDiscount);
+  }, [activeVoucher, listVouchers]);
 
   useEffect(() => {
-    setProducts(cartCheckout?.products)
-    setCheckWeight(cartCheckout?.hasProductWithoutWeight)
-    setTotalWeight(cartCheckout?.totalWeight.g)
-  }, [cartCheckout])
+    setProducts(cartCheckout?.products);
+    setCheckWeight(cartCheckout?.hasProductWithoutWeight);
+    setTotalWeight(cartCheckout?.totalWeight.g);
+  }, [cartCheckout]);
 
   useEffect(() => {
-    setCheckoutValidation(false)
+    setCheckoutValidation(false);
     const loadServiceRajaOngkir = async () => {
-      setLoadingRajaOngkir(true)
+      setLoadingRajaOngkir(true);
       const body = {
         origin: 2127,
         destination: selectedAddress.shipping.rajaongkirCityId,
         weight: totalWeight,
         courier: selectedCarrier,
         originType: 'subdistrict',
-        destinationType: 'subdistrict'
-      }
-      setBiayaKirim(0)
-      const dataService = await axios('/api/rajaongkir-service?body=' + JSON.stringify(body))
-      setLoadingRajaOngkir(false)
-      setListServiceExpedisi(dataService.data[0].costs)
+        destinationType: 'subdistrict',
+      };
+      setBiayaKirim(0);
+      const dataService = await axios(
+        '/api/rajaongkir-service?body=' + JSON.stringify(body)
+      );
+      setLoadingRajaOngkir(false);
+      setListServiceExpedisi(dataService.data[0].costs);
       if (dataService.data[0].costs[0]) {
-        setBiayaKirim(dataService.data[0].costs[0]?.cost[0].value)
+        setBiayaKirim(dataService.data[0].costs[0]?.cost[0].value);
         setselectedExpedisiService(
-          dataService.data[0].costs[0]?.description + '-' + dataService.data[0].costs[0]?.service
-        )
-        setEtd(dataService.data[0].costs[0]?.cost[0].etd)
-        toast.success('Harap pilih tipe layanan pengiriman')
+          dataService.data[0].costs[0]?.description +
+            '-' +
+            dataService.data[0].costs[0]?.service
+        );
+        setEtd(dataService.data[0].costs[0]?.cost[0].etd);
+        toast.success('Harap pilih tipe layanan pengiriman');
       } else {
-        toast.error('Maaf, layanan tidak tersedia. Mohon pilih expedisi lain.')
+        toast.error('Maaf, layanan tidak tersedia. Mohon pilih expedisi lain.');
       }
-    }
+    };
     if (selectedCarrier != 0 && selectedCarrier != 1 && totalWeight > 0) {
-      loadServiceRajaOngkir()
+      loadServiceRajaOngkir();
     } else {
-      setListServiceExpedisi()
-      setBiayaKirim(0)
-      setselectedExpedisiService()
-      setEtd()
+      setListServiceExpedisi();
+      setBiayaKirim(0);
+      setselectedExpedisiService();
+      setEtd();
     }
-  }, [selectedCarrier, selectedAddress, totalWeight])
+  }, [selectedCarrier, selectedAddress, totalWeight]);
 
   useEffect(() => {
     if (selectedServiceType) {
-      let serviceType = selectedServiceType.split(',')
-      setBiayaKirim(serviceType[0])
-      setselectedExpedisiService(serviceType[1])
-      setEtd(serviceType[2])
+      let serviceType = selectedServiceType.split(',');
+      setBiayaKirim(serviceType[0]);
+      setselectedExpedisiService(serviceType[1]);
+      setEtd(serviceType[2]);
     }
-  }, [selectedServiceType])
+  }, [selectedServiceType]);
 
   useEffect(() => {
-    if (etd) setEtdFix(calculateEstimatedArrival(etd))
-  }, [etd])
+    if (etd) setEtdFix(calculateEstimatedArrival(etd));
+  }, [etd]);
 
   useEffect(() => {
     if (selectedExpedisi) {
-      let serviceType = selectedExpedisi.split(',')
-      if (serviceType[0] === 0) return
+      let serviceType = selectedExpedisi.split(',');
+      if (serviceType[0] === 0) return;
 
-      setselectedCarrier(serviceType[0])
-      setselectedCarrierId(serviceType[1])
-      setListServiceExpedisi([])
+      setselectedCarrier(serviceType[0]);
+      setselectedCarrierId(serviceType[1]);
+      setListServiceExpedisi([]);
     }
-  }, [selectedExpedisi])
+  }, [selectedExpedisi]);
 
-  const poNumber = useRef(null)
-  const poFile = useRef(null)
+  const poNumber = useRef(null);
+  const poFile = useRef(null);
 
-  const [isLoading, setIsLoading] = useState(false)
+  const [isLoading, setIsLoading] = useState(false);
 
   const checkout = async () => {
-    const file = poFile.current.files[0]
+    const file = poFile.current.files[0];
     if (typeof file !== 'undefined' && file.size > 5000000) {
-      toast.error('Maksimal ukuran file adalah 5MB', { position: 'bottom-center' })
-      return
+      toast.error('Maksimal ukuran file adalah 5MB', {
+        position: 'bottom-center',
+      });
+      return;
     }
     if (selectedExpedisi === 0) {
-      setCheckoutValidation(true)
+      setCheckoutValidation(true);
       if (expedisiValidation.current) {
-        const position = expedisiValidation.current.getBoundingClientRect()
+        const position = expedisiValidation.current.getBoundingClientRect();
         window.scrollTo({
           top: position.top - 300 + window.pageYOffset,
-          behavior: 'smooth'
-        })
+          behavior: 'smooth',
+        });
       }
-      return
+      return;
     }
     if (selectedCarrier != 1 && biayaKirim == 0) {
-      toast.error('Maaf, layanan tidak tersedia. Mohon pilih expedisi lain.')
-      return
+      toast.error('Maaf, layanan tidak tersedia. Mohon pilih expedisi lain.');
+      return;
     }
-    setIsLoading(true)
+    setIsLoading(true);
     const productOrder = products.map((product) => ({
       product_id: product.id,
-      quantity: product.quantity
-    }))
+      quantity: product.quantity,
+    }));
     let data = {
       partner_shipping_id: auth.partnerId,
       partner_invoice_id: auth.partnerId,
@@ -319,80 +333,82 @@ const Checkout = () => {
       estimated_arrival_days: splitDuration(etd),
       delivery_service_type: selectedExpedisiService,
       voucher: activeVoucher,
-      type: 'sale_order'
-    }
+      type: 'sale_order',
+    };
 
     if (query) {
-      data.source = 'buy'
+      data.source = 'buy';
     }
-    if (poNumber.current.value) data.po_number = poNumber.current.value
-    if (typeof file !== 'undefined') data.po_file = await getFileBase64(file)
+    if (poNumber.current.value) data.po_number = poNumber.current.value;
+    if (typeof file !== 'undefined') data.po_file = await getFileBase64(file);
 
-    const isCheckouted = await checkoutApi({ data })
+    const isCheckouted = await checkoutApi({ data });
     if (!isCheckouted?.id) {
-      toast.error('Gagal melakukan transaksi, terjadi kesalahan internal')
-      return
+      toast.error('Gagal melakukan transaksi, terjadi kesalahan internal');
+      return;
     }
 
-    gtagPurchase(products, biayaKirim, isCheckouted.name)
+    gtagPurchase(products, biayaKirim, isCheckouted.name);
 
     const midtrans = async () => {
-      for (const product of products) deleteItemCart({ productId: product.id })
+      for (const product of products) deleteItemCart({ productId: product.id });
       const payment = await axios.post(
         `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/midtrans-payment?transactionId=${isCheckouted.id}`
-      )
-      setIsLoading(false)
-      window.location.href = payment.data.redirectUrl
-    }
+      );
+      setIsLoading(false);
+      window.location.href = payment.data.redirectUrl;
+    };
 
     gtag('event', 'conversion', {
       send_to: 'AW-954540379/nDymCL3BhaQYENvClMcD',
-      value: cartCheckout?.grandTotal + Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000,
+      value:
+        cartCheckout?.grandTotal +
+        Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000,
       currency: 'IDR',
       transaction_id: isCheckouted.id,
-      event_callback: midtrans
-    })
-  }
+      event_callback: midtrans,
+    });
+  };
 
   const handlingActivateCode = async () => {
-    VoucherCode(codeVoucher)
-  }
+    VoucherCode(codeVoucher);
+  };
 
   const handleUseVoucher = async (code, isCheck) => {
     if (isCheck) {
       if (code === activeVoucher) {
-        SetActiveVoucher(null)
-        SetDiscountVoucher(0)
+        SetActiveVoucher(null);
+        SetDiscountVoucher(0);
       } else {
-        SetActiveVoucher(code)
-        SetFindVoucher(null)
-        document.getElementById('uniqCode').value = ''
-        SetButtonTerapkan(false)
+        SetActiveVoucher(code);
+        SetFindVoucher(null);
+        document.getElementById('uniqCode').value = '';
+        SetButtonTerapkan(false);
       }
     } else {
-      SetActiveVoucher(code)
-      SetFindVoucher(null)
-      document.getElementById('uniqCode').value = ''
-      SetButtonTerapkan(false)
+      SetActiveVoucher(code);
+      SetFindVoucher(null);
+      document.getElementById('uniqCode').value = '';
+      SetButtonTerapkan(false);
     }
-  }
+  };
 
   const onChangeCodeVoucher = async (e) => {
-    SetCodeVoucher(e.target.value)
-    SetButtonTerapkan(false)
-  }
+    SetCodeVoucher(e.target.value);
+    SetButtonTerapkan(false);
+  };
 
-  const [isChecked, setIsChecked] = useState(false)
+  const [isChecked, setIsChecked] = useState(false);
 
   const ToggleSwitch = (code) => {
-    setIsChecked(!isChecked)
-    handleUseVoucher(code, !isChecked)
-  }
+    setIsChecked(!isChecked);
+    handleUseVoucher(code, !isChecked);
+  };
 
   const handlingTnC = async (item) => {
-    setItemTnC(item)
-    SetBottomPopupTnC(true)
-  }
+    setItemTnC(item);
+    SetBottomPopupTnC(true);
+  };
   // const taxTotal = (totalAmount - totalDiscountAmount - discountVoucher) * 0.11
 
   return (
@@ -401,13 +417,17 @@ const Checkout = () => {
         className='w-full md:!w-[40%] !min-h-[90vh]'
         active={bottomPopupTnC}
         close={() => {
-          SetBottomPopupTnC(false)
-          SetBottomPopup(false)
+          SetBottomPopupTnC(false);
+          SetBottomPopup(false);
         }}
         title={
           <div>
-            <button className='flex gap-x-2 items-center' onClick={() => SetBottomPopupTnC(false)}>
-              <ChevronLeftIcon class='h- w-5 text-black' /> <span className='text-lg'>Voucher</span>
+            <button
+              className='flex gap-x-2 items-center'
+              onClick={() => SetBottomPopupTnC(false)}
+            >
+              <ChevronLeftIcon class='h- w-5 text-black' />{' '}
+              <span className='text-lg'>Voucher</span>
             </button>{' '}
           </div>
         }
@@ -420,13 +440,17 @@ const Checkout = () => {
               <span className='text-sm'>
                 {' '}
                 Berakhir dalam :{' '}
-                <span className='text-sm text-red-500'>{itemTnC?.remainingTime} lagi</span>
+                <span className='text-sm text-red-500'>
+                  {itemTnC?.remainingTime} lagi
+                </span>
               </span>
             </div>
             <div className='flex items-center gap-x-1'>
               <BanknotesIcon class='h-6 w-6 text-green-500' />
               <span className='text-sm'> Kode Voucher : </span>
-              <span className='text-red-500 font-semibold'>{itemTnC?.code}</span>
+              <span className='text-red-500 font-semibold'>
+                {itemTnC?.code}
+              </span>
             </div>
           </div>
           <div>
@@ -441,6 +465,7 @@ const Checkout = () => {
           </div>
         </div>
       </BottomPopup>
+
       <BottomPopup
         className='w-full md:!w-[40%] !min-h-[350px]'
         active={bottomPopup}
@@ -448,8 +473,8 @@ const Checkout = () => {
         title='Gunakan Promo'
       >
         <div className='row'>
-          <div className='flex justify-between items-center'>
-            <div className='flex md:w-[70%]'>
+          <div className='flex justify-between items-center gap-x-4'>
+            <div className='flex flex-1 md:w-[70%]'>
               <input
                 type='text'
                 id='uniqCode'
@@ -481,15 +506,16 @@ const Checkout = () => {
           {findCodeVoucher === 1 && (
             <div className='mt-2'>
               <span className='text-caption-1 mt-2 text-red-600'>
-                Kode voucher salah / sudah tidak berlaku lagi. Coba voucher lainnya, ya.
+                Kode voucher salah / sudah tidak berlaku lagi. Coba voucher
+                lainnya, ya.
               </span>
             </div>
           )}
           {findCodeVoucher === 2 && (
             <div className='mt-2'>
               <span className='text-caption-1 mt-2 text-red-600'>
-                Tambah <span className='text-red-600'>{selisihHargaCode}</span> untuk pakai promo
-                ini
+                Tambah <span className='text-red-600'>{selisihHargaCode}</span>{' '}
+                untuk pakai promo ini
               </span>
             </div>
           )}
@@ -500,15 +526,21 @@ const Checkout = () => {
               <div className='flex items-center justify-center mt-4 mb-4'>
                 <div className='text-center'>
                   <h1 className='font-bold mb-4'>Tidak ada voucher tersedia</h1>
-                  <p className='text-gray-500'>Maaf, saat ini tidak ada voucher yang tersedia.</p>
+                  <p className='text-gray-500'>
+                    Maaf, saat ini tidak ada voucher yang tersedia.
+                  </p>
                 </div>
               </div>
             ) : (
-              <h3 className='font-semibold mb-4'>Promo Khusus Untuk {auth?.name}</h3>
+              <h3 className='font-semibold mb-4'>
+                Promo Khusus Untuk {auth?.name}
+              </h3>
             )}
             {loadingVoucher && (
               <>
-                <div className={`border border-solid  w-full hover:cursor-pointer  p-2`}>
+                <div
+                  className={`border border-solid  w-full hover:cursor-pointer  p-2`}
+                >
                   <div class='flex items-center space-x-3'>
                     <div class='flex items-center justify-center h-28 w-48 mb-4 bg-gray-300 rounded dark:bg-gray-700'>
                       <svg
@@ -529,7 +561,9 @@ const Checkout = () => {
                     </div>
                   </div>
                 </div>
-                <div className={`border border-solid  w-full hover:cursor-pointer  p-2`}>
+                <div
+                  className={`border border-solid  w-full hover:cursor-pointer  p-2`}
+                >
                   <div class='flex items-center space-x-3'>
                     <div class='flex items-center justify-center h-28 w-48 mb-4 bg-gray-300 rounded dark:bg-gray-700'>
                       <svg
@@ -579,7 +613,9 @@ const Checkout = () => {
                       >
                         <p>
                           Voucher tidak bisa di gunakan,{' '}
-                          <span className='text-red font-bold'>Baca Selengkapnya !</span>
+                          <span className='text-red font-bold'>
+                            Baca Selengkapnya !
+                          </span>
                         </p>
                       </div>
                     )}
@@ -589,14 +625,20 @@ const Checkout = () => {
                         <div className='absolute w-full h-full bg-gray_r-3/40 top-0 left-0 z-50' />
                       )}
                       <div className='hidden md:w-[250px] md:block'>
-                        <Image src={item.image} alt={item.name} className={`object-cover`} />
+                        <Image
+                          src={item.image}
+                          alt={item.name}
+                          className={`object-cover`}
+                        />
                       </div>
                       <div className='w-full'>
                         <div className='flex justify-between gap-x-2 mb-1 items-center'>
                           <div className=''>
                             <h3 className='font-semibold'>{item.name}</h3>
                             <div className='mt-1'>
-                              <span className='text-sm line-clamp-3'>{item.description} </span>
+                              <span className='text-sm line-clamp-3'>
+                                {item.description}{' '}
+                              </span>
                             </div>
                           </div>
                           <div className='flex justify-end'>
@@ -605,7 +647,9 @@ const Checkout = () => {
                                 type='checkbox'
                                 value=''
                                 class='sr-only peer'
-                                checked={activeVoucher === item.code ? true : false}
+                                checked={
+                                  activeVoucher === item.code ? true : false
+                                }
                                 onChange={() => ToggleSwitch(item.code)}
                               />
                               <div class="w-11 h-6 bg-gray-200 rounded-full peer dark:bg-gray-700 peer-focus:ring-4 peer-focus:ring-green-300 dark:peer-focus:ring-green-800 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-green-600"></div>
@@ -616,11 +660,15 @@ const Checkout = () => {
                         <div className='flex justify-between items-center'>
                           <p className='text-justify text-sm md:text-xs'>
                             Kode Voucher :{' '}
-                            <span className='text-red-500 font-semibold'>{item.code}</span>
+                            <span className='text-red-500 font-semibold'>
+                              {item.code}
+                            </span>
                           </p>
                           <p className='text-sm md:text-xs'>
                             {activeVoucher === item.code && (
-                              <span className=' text-green-600'>Voucher digunakan </span>
+                              <span className=' text-green-600'>
+                                Voucher digunakan{' '}
+                              </span>
                             )}
                           </p>
                         </div>
@@ -642,7 +690,10 @@ const Checkout = () => {
                           <div className='flex justify-between items-center'>
                             <div className='text-left ml-3 text-sm '>
                               Berakhir dalam{' '}
-                              <span className='text-red-600'>{item.remainingTime}</span> lagi,{' '}
+                              <span className='text-red-600'>
+                                {item.remainingTime}
+                              </span>{' '}
+                              lagi,{' '}
                             </div>
                             <div
                               className='text-sm ml-2 text-red-600'
@@ -670,6 +721,7 @@ const Checkout = () => {
           </div>
         </div>
       </BottomPopup>
+
       <MobileView>
         <div className='p-4'>
           <Alert type='info' className='text-caption-2 flex gap-x-3'>
@@ -677,8 +729,8 @@ const Checkout = () => {
               <ExclamationCircleIcon className='w-7 text-blue-700' />
             </div>
             <span className='leading-5'>
-              Jika mengalami kesulitan dalam melakukan pembelian di website Indoteknik. Hubungi kami
-              disini
+              Jika mengalami kesulitan dalam melakukan pembelian di website
+              Indoteknik. Hubungi kami disini
             </span>
           </Alert>
         </div>
@@ -701,14 +753,17 @@ const Checkout = () => {
               </svg>
               <span class='sr-only'>Info</span>
               <div className='text-justify'>
-                Fitur Self Pickup, hanya berlaku untuk customer di area jakarta. Apa bila memilih
-                fitur ini, anda akan dihubungi setelah barang siap diambil.
+                Fitur Self Pickup, hanya berlaku untuk customer di area jakarta.
+                Apa bila memilih fitur ini, anda akan dihubungi setelah barang
+                siap diambil.
               </div>
             </div>
           </div>
         )}
 
-        {selectedCarrierId == SELF_PICKUP_ID && <PickupAddress label='Alamat Pickup' />}
+        {selectedCarrierId == SELF_PICKUP_ID && (
+          <PickupAddress label='Alamat Pickup' />
+        )}
         {selectedCarrierId != SELF_PICKUP_ID && (
           <>
             <SectionAddress
@@ -742,7 +797,10 @@ const Checkout = () => {
         />
 
         <div className='p-4 flex flex-col gap-y-4'>
-          {products && <VariantGroupCard openOnClick={false} variants={products} />}
+          {!!products &&
+            snakecaseKeys(products).map((item, index) => (
+              <CartItem key={index} item={item} editable={false} />
+            ))}
         </div>
 
         <Divider />
@@ -750,7 +808,6 @@ const Checkout = () => {
         <div className='p-4'>
           <div className='flex justify-between items-center'>
             <div className='font-medium'>Ringkasan Pesanan</div>
-            <div className='text-gray_r-11 text-caption-1'>{products?.length} Barang</div>
           </div>
           <hr className='my-4 border-gray_r-6' />
           {!cartCheckout ? (
@@ -804,7 +861,9 @@ const Checkout = () => {
               {activeVoucher && (
                 <div className='flex gap-x-2 justify-between'>
                   <div className='text-gray_r-11'>Diskon Voucher</div>
-                  <div className='text-danger-500'>- {currencyFormat(discountVoucher)}</div>
+                  <div className='text-danger-500'>
+                    - {currencyFormat(discountVoucher)}
+                  </div>
                 </div>
               )}
               <div className='flex gap-x-2 justify-between'>
@@ -819,7 +878,11 @@ const Checkout = () => {
                 <div className='text-gray_r-11'>
                   Biaya Kirim <p className='text-xs mt-3'>{etdFix}</p>
                 </div>
-                <div>{currencyFormat(Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000)}</div>
+                <div>
+                  {currencyFormat(
+                    Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000
+                  )}
+                </div>
               </div>
             </div>
           )}
@@ -840,7 +903,8 @@ const Checkout = () => {
               <div>Grand Total</div>
               <div className='font-semibold text-gray_r-12'>
                 {currencyFormat(
-                  cartCheckout?.grandTotal + Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000
+                  cartCheckout?.grandTotal +
+                    Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000
                 )}
               </div>
             </div>
@@ -852,8 +916,8 @@ const Checkout = () => {
             <button
               type='button'
               onClick={() => {
-                SetBottomPopup(true)
-                voucher()
+                SetBottomPopup(true);
+                voucher();
               }}
               className='text-gray-900 p-4 flex items-center justify-between  rounded-lg bg-white border font-medium border-gray-300  hover:bg-gray-100 py-2.5 h-[50px] w-[100%]'
             >
@@ -886,7 +950,8 @@ const Checkout = () => {
           </div>
           {/* <p className='text-caption-2 text-gray_r-10 mb-2'>*) Belum termasuk biaya pengiriman</p> */}
           <p className='text-caption-2 text-gray_r-10 leading-5'>
-            Dengan melakukan pembelian melalui website Indoteknik, saya menyetujui{' '}
+            Dengan melakukan pembelian melalui website Indoteknik, saya
+            menyetujui{' '}
             <Link href='/syarat-ketentuan' className='inline font-normal'>
               Syarat & Ketentuan
             </Link>{' '}
@@ -911,10 +976,16 @@ const Checkout = () => {
             </div>
             <div className='w-6/12'>
               <label className='form-label font-normal'>Nomor PO</label>
-              <input type='text' className='form-input mt-2 h-12' ref={poNumber} />
+              <input
+                type='text'
+                className='form-input mt-2 h-12'
+                ref={poNumber}
+              />
             </div>
           </div>
-          <p className='text-caption-2 text-gray_r-11 mt-2'>Ukuran dokumen PO Maksimal 5MB</p>
+          <p className='text-caption-2 text-gray_r-11 mt-2'>
+            Ukuran dokumen PO Maksimal 5MB
+          </p>
         </div>
 
         <Divider />
@@ -923,7 +994,9 @@ const Checkout = () => {
           <button
             className='flex-1 btn-yellow'
             onClick={checkout}
-            disabled={isLoading || !products || products?.length == 0 || priceCheck}
+            disabled={
+              isLoading || !products || products?.length == 0 || priceCheck
+            }
           >
             {isLoading ? 'Loading...' : 'Lanjut Pembayaran'}
           </button>
@@ -957,8 +1030,9 @@ const Checkout = () => {
               </svg>
               <span class='sr-only'>Info</span>
               <div>
-                Fitur Self Pickup, hanya berlaku untuk customer di area jakarta. Apa bila memilih
-                fitur ini, anda akan dihubungi setelah barang siap diambil.
+                Fitur Self Pickup, hanya berlaku untuk customer di area jakarta.
+                Apa bila memilih fitur ini, anda akan dihubungi setelah barang
+                siap diambil.
               </div>
             </div>
           )}
@@ -966,7 +1040,9 @@ const Checkout = () => {
           <div className='flex'>
             {' '}
             <div className='w-3/4 border border-gray_r-6 rounded bg-white'>
-              {selectedCarrierId == SELF_PICKUP_ID && <PickupAddress label='Alamat Pickup' />}
+              {selectedCarrierId == SELF_PICKUP_ID && (
+                <PickupAddress label='Alamat Pickup' />
+              )}
               {selectedCarrierId != SELF_PICKUP_ID && (
                 <>
                   <SectionAddress
@@ -1000,170 +1076,13 @@ const Checkout = () => {
               />
 
               <div className='p-4'>
-                <div className='font-medium'>Detail Pesanan</div>
-                <CardProdcuctsList isLoading={isLoading} products={products} />
-
-                {/* <table className='table-checkout'>
-                  <thead>
-                    <tr>
-                      <th>Nama Produk</th>
-                      <th>Jumlah</th>
-                      <th>Harga</th>
-                      <th>Subtotal</th>
-                    </tr>
-                  </thead>
-                  <tbody>
-                    {!products ? (
-                      <tr>
-                        <td colSpan={4}>
-                          <div className='container my-4'>
-                            <div class='h-2.5 bg-gray-200 rounded-full dark:bg-gray-700 w-48 mb-4'></div>
-                            <div class='h-2 bg-gray-200 rounded-full dark:bg-gray-700 mb-2.5'></div>
-                            <div class='h-2 bg-gray-200 rounded-full dark:bg-gray-700 mb-2.5'></div>
-                            <div class='h-2 bg-gray-200 rounded-full dark:bg-gray-700'></div>
-                          </div>
-                        </td>
-                      </tr>
-                    ) : (
-                      products?.map((product) => (
-                        <>
-                          <tr
-                            key={product.id}
-                            className={`${product.program ? '!border-t-0 !border-b-0' : ''}`}
-                          >
-                            <td className='flex'>
-                              <div className='w-[20%] 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'
-                                />
-                              </div>
-                              <div className='px-2 text-left'>
-                                <div className='line-clamp-2 leading-6 !text-gray_r-12 font-normal'>
-                                  {product?.parent?.name}
-                                </div>
-                                <div className='text-gray_r-11 mt-2'>
-                                  {product?.code}{' '}
-                                  {product?.attributes.length > 0
-                                    ? `| ${product?.attributes.join(', ')}`
-                                    : ''}
-                                </div>
-                                <div className='text-gray_r-11 mt-2'>
-                                  Berat item : {product?.weight} Kg
-                                </div>
-                              </div>
-                            </td>
-                            <td>
-                              <input
-                                className='form-input w-16 py-2 text-center bg-gray_r-1'
-                                type='number'
-                                value={product?.quantity}
-                                disabled
-                              />
-                            </td>
-                            <td>
-                              {product?.hasFlashsale ? (
-                                <>
-                                  <div className='flex gap-x-1 items-center justify-center mt-3'>
-                                    <div className='text-gray_r-11 line-through text-caption-1'>
-                                      {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='font-normal mt-1'>
-                                  {product.price.priceDiscount > 0
-                                    ? currencyFormat(product?.price?.priceDiscount)
-                                    : 'Call for Inquiry'}
-                                </div>
-                              )}
-                            </td>
-                            <td>
-                              <div className='text-danger-500 font-medium'>
-                                {product.price.priceDiscount > 0 ? (
-                                  currencyFormat(product?.price?.priceDiscount * product?.quantity)
-                                ) : (
-                                  <a
-                                    href={whatsappUrl('product', {
-                                      name: product.name,
-                                      url: createSlug(
-                                        '/shop/product/',
-                                        product.name,
-                                        product.id,
-                                        true
-                                      )
-                                    })}
-                                    className='underline'
-                                  >
-                                    Call for Inquiry{' '}
-                                  </a>
-                                )}
-                              </div>
-                            </td>
-                          </tr>
-                          {product.program &&
-                            product.program.items &&
-                            product.program.items.map((item) => (
-                              <>
-                                <tr key={product?.program?.id} className='!border-t-0'>
-                                  <td className='flex'>
-                                    <div className='w-[20%] flex-shrink-0'>
-                                      <Image
-                                        src={item.parent.image}
-                                        alt={item.name}
-                                        className='object-contain object-center border border-gray_r-6 h-40 w-full rounded-md'
-                                      />
-                                    </div>
-                                    <div className='px-2 text-left'>
-                                      <div className=''>
-                                        <span className='border border-solid border-red-600 rounded-md p-1 text-red-600'>
-                                          {product.program.type.label}
-                                        </span>
-                                      </div>
-                                      <div className='mt-2 line-clamp-2 leading-6'>{item.name}</div>
-                                    </div>
-                                  </td>
-                                  <td>
-                                    <input
-                                      className='form-input w-16 py-2 text-center bg-gray_r-1'
-                                      type='number'
-                                      value={1}
-                                      disabled
-                                    />
-                                  </td>
-                                  <td>
-                                    {item?.price?.discountPercentage > 0 && (
-                                      <div className='flex gap-x-1 items-center justify-center mt-3'>
-                                        <div className='text-gray_r-11 line-through text-caption-1'>
-                                          {currencyFormat(product?.price?.price)}
-                                        </div>
-                                      </div>
-                                    )}
-                                    <div className='font-normal mt-1'>
-                                      {item?.price.priceDiscount > 0 ? 'Gratis' : ''}
-                                    </div>
-                                  </td>
-                                  <td>
-                                    <div className='text-danger-500 font-medium'>
-                                      {item.price.priceDiscount > 0 ? 'Gratis' : ''}
-                                    </div>
-                                  </td>
-                                  <td></td>
-                                </tr>
-                              </>
-                            ))}
-                        </>
-                      ))
-                    )}
-                  </tbody>
-                </table> */}
+                <div className='font-medium mb-6'>Detail Pesanan</div>
+                <div className='flex flex-col gap-y-8 border-t border-gray-300 pt-8'>
+                  {!!products &&
+                    snakecaseKeys(products).map((item, index) => (
+                      <CartItem key={index} item={item} editable={false} />
+                    ))}
+                </div>
               </div>
             </div>
             <div className='w-1/4 pl-4'>
@@ -1171,7 +1090,8 @@ const Checkout = () => {
                 <div className='flex justify-between items-center'>
                   <div className='font-medium'>Ringkasan Pesanan</div>
                   <div className='text-gray_r-11 text-caption-1'>
-                    {products?.length} Barang - {cartCheckout?.totalWeight.kg} Kg
+                    {cartCheckout?.totalWeight.kg}{' '}
+                    Kg
                   </div>
                 </div>
 
@@ -1227,7 +1147,9 @@ const Checkout = () => {
                     {activeVoucher && (
                       <div className='flex gap-x-2 justify-between'>
                         <div className='text-gray_r-11'>Diskon Voucher</div>
-                        <div className='text-danger-500'>- {currencyFormat(discountVoucher)}</div>
+                        <div className='text-danger-500'>
+                          - {currencyFormat(discountVoucher)}
+                        </div>
                       </div>
                     )}
                     <div className='flex gap-x-2 justify-between'>
@@ -1244,7 +1166,9 @@ const Checkout = () => {
                         <p className='text-xs mt-3'>{etdFix}</p>
                       </div>
                       <div>
-                        {currencyFormat(Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000)}
+                        {currencyFormat(
+                          Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000
+                        )}
                       </div>
                     </div>
                   </div>
@@ -1279,8 +1203,8 @@ const Checkout = () => {
                   <button
                     type='button'
                     onClick={() => {
-                      SetBottomPopup(true)
-                      voucher()
+                      SetBottomPopup(true);
+                      voucher();
                     }}
                     className='text-gray-900 p-3 flex items-center justify-between  rounded-lg bg-white border font-medium border-gray-300  hover:bg-gray-100 py-2.5 h-[50px] w-[100%]'
                   >
@@ -1312,7 +1236,8 @@ const Checkout = () => {
                 </div>
 
                 <p className='text-caption-2 text-gray_r-11 leading-5'>
-                  Dengan melakukan pembelian melalui website Indoteknik, saya menyetujui{' '}
+                  Dengan melakukan pembelian melalui website Indoteknik, saya
+                  menyetujui{' '}
                   <Link href='/syarat-ketentuan' className='inline font-normal'>
                     Syarat & Ketentuan
                   </Link>{' '}
@@ -1322,7 +1247,8 @@ const Checkout = () => {
                 <hr className='my-4 border-gray_r-6' />
 
                 <div className='font-medium mt-4'>
-                  Purchase Order <span className='font-normal text-gray_r-11'>(Opsional)</span>
+                  Purchase Order{' '}
+                  <span className='font-normal text-gray_r-11'>(Opsional)</span>
                 </div>
 
                 <div className='mt-4 flex gap-x-3'>
@@ -1337,17 +1263,28 @@ const Checkout = () => {
                   </div>
                   <div className='w-6/12'>
                     <label className='form-label font-normal'>Nomor PO</label>
-                    <input type='text' className='form-input mt-2 h-12' ref={poNumber} />
+                    <input
+                      type='text'
+                      className='form-input mt-2 h-12'
+                      ref={poNumber}
+                    />
                   </div>
                 </div>
-                <p className='text-caption-2 text-gray_r-11 mt-2'>Ukuran dokumen PO Maksimal 5MB</p>
+                <p className='text-caption-2 text-gray_r-11 mt-2'>
+                  Ukuran dokumen PO Maksimal 5MB
+                </p>
 
                 <hr className='my-4 border-gray_r-6' />
 
                 <button
                   className='w-full btn-yellow mt-4'
                   onClick={checkout}
-                  disabled={isLoading || !products || products?.length == 0 || priceCheck}
+                  disabled={
+                    isLoading ||
+                    !products ||
+                    products?.length == 0 ||
+                    priceCheck
+                  }
                 >
                   {isLoading ? 'Loading...' : 'Lanjut Pembayaran'}
                 </button>
@@ -1367,8 +1304,8 @@ const Checkout = () => {
         </div>
       </DesktopView>
     </>
-  )
-}
+  );
+};
 
 const SectionAddress = ({ address, label, url }) => (
   <div className='p-4'>
@@ -1382,7 +1319,9 @@ const SectionAddress = ({ address, label, url }) => (
     {address && (
       <div className='mt-4 text-caption-1'>
         <div className='badge-red mb-2'>
-          {address.type.charAt(0).toUpperCase() + address.type.slice(1) + ' Address'}
+          {address.type.charAt(0).toUpperCase() +
+            address.type.slice(1) +
+            ' Address'}
         </div>
         <p className='font-medium'>{address.name}</p>
         <p className='mt-2 text-gray_r-11'>{address.mobile}</p>
@@ -1392,7 +1331,7 @@ const SectionAddress = ({ address, label, url }) => (
       </div>
     )}
   </div>
-)
+);
 
 const SectionValidation = ({ address }) =>
   address?.rajaongkirCityId == 0 && (
@@ -1409,7 +1348,7 @@ const SectionValidation = ({ address }) =>
         </Link>
       </div>
     </BottomPopup>
-  )
+  );
 
 const SectionExpedisi = ({
   address,
@@ -1418,7 +1357,7 @@ const SectionExpedisi = ({
   checkWeigth,
   checkoutValidation,
   expedisiValidation,
-  loadingRajaOngkir
+  loadingRajaOngkir,
 }) =>
   address?.rajaongkirCityId > 0 && (
     <div className='p-4' ref={expedisiValidation}>
@@ -1427,7 +1366,9 @@ const SectionExpedisi = ({
         <div className='w-[250px]'>
           <div className='flex items-center gap-x-4'>
             <select
-              className={`form-input ${checkoutValidation ? 'border-red-500 shake' : ''}`}
+              className={`form-input ${
+                checkoutValidation ? 'border-red-500 shake' : ''
+              }`}
               onChange={(e) => setSelectedExpedisi(e.target.value)}
               required
             >
@@ -1453,7 +1394,7 @@ const SectionExpedisi = ({
                   animate={{ opacity: 1, width: '28px' }}
                   exit={{ opacity: 0, width: 0 }}
                   transition={{
-                    duration: 0.25
+                    duration: 0.25,
                   }}
                   className='overflow-hidden'
                 >
@@ -1463,7 +1404,9 @@ const SectionExpedisi = ({
             </AnimatePresence>
           </div>
           {checkoutValidation && (
-            <span className='text-sm text-red-500'>*silahkan pilih expedisi</span>
+            <span className='text-sm text-red-500'>
+              *silahkan pilih expedisi
+            </span>
           )}
         </div>
         <style jsx>{`
@@ -1474,8 +1417,9 @@ const SectionExpedisi = ({
       </div>
       {checkWeigth == true && (
         <p className='mt-4 text-gray_r-11 leading-6'>
-          Mohon maaf, pengiriman hanya tersedia untuk self pickup karena terdapat barang yang belum
-          diatur beratnya. Mohon atur berat barang dengan menghubungi admin melalui{' '}
+          Mohon maaf, pengiriman hanya tersedia untuk self pickup karena
+          terdapat barang yang belum diatur beratnya. Mohon atur berat barang
+          dengan menghubungi admin melalui{' '}
           <a
             className='text-danger-500 inline'
             href='https://api.whatsapp.com/send?phone=628128080622'
@@ -1485,7 +1429,7 @@ const SectionExpedisi = ({
         </p>
       )}
     </div>
-  )
+  );
 
 const SectionListService = ({ listserviceExpedisi, setSelectedServiceType }) =>
   listserviceExpedisi?.length > 0 && (
@@ -1494,7 +1438,10 @@ const SectionListService = ({ listserviceExpedisi, setSelectedServiceType }) =>
         <div className='flex justify-between items-center'>
           <div className='font-medium'>Tipe Layanan Ekspedisi: </div>
           <div>
-            <select className='form-input' onChange={(e) => setSelectedServiceType(e.target.value)}>
+            <select
+              className='form-input'
+              onChange={(e) => setSelectedServiceType(e.target.value)}
+            >
               {listserviceExpedisi.map((service) => (
                 <option
                   value={
@@ -1511,7 +1458,9 @@ const SectionListService = ({ listserviceExpedisi, setSelectedServiceType }) =>
                   {' '}
                   {service.description} - {service.service.toUpperCase()}
                   {extractDuration(service.cost[0].etd) &&
-                    ` (Estimasi Tiba ${extractDuration(service.cost[0].etd)} Hari)`}
+                    ` (Estimasi Tiba ${extractDuration(
+                      service.cost[0].etd
+                    )} Hari)`}
                 </option>
               ))}
             </select>
@@ -1520,73 +1469,73 @@ const SectionListService = ({ listserviceExpedisi, setSelectedServiceType }) =>
       </div>
       <Divider />
     </>
-  )
+  );
 
 function addDays(date, days) {
-  const result = new Date(date)
-  result.setDate(result.getDate() + days)
-  return result
+  const result = new Date(date);
+  result.setDate(result.getDate() + days);
+  return result;
 }
 
 function formatDate(date) {
-  const day = date.getDate()
-  const month = date.toLocaleString('default', { month: 'short' })
-  return `${day} ${month}`
+  const day = date.getDate();
+  const month = date.toLocaleString('default', { month: 'short' });
+  return `${day} ${month}`;
 }
 
 function calculateEstimatedArrival(duration) {
   if (duration) {
-    let estimationDate = duration.split('-')
-    estimationDate[0] = parseInt(estimationDate[0])
-    estimationDate[1] = parseInt(estimationDate[1])
-    const from = addDays(new Date(), estimationDate[0] + 3)
-    const to = addDays(new Date(), estimationDate[1] + 3)
+    let estimationDate = duration.split('-');
+    estimationDate[0] = parseInt(estimationDate[0]);
+    estimationDate[1] = parseInt(estimationDate[1]);
+    const from = addDays(new Date(), estimationDate[0] + 3);
+    const to = addDays(new Date(), estimationDate[1] + 3);
 
-    let etdText = `*Estimasi tiba ${formatDate(from)}`
+    let etdText = `*Estimasi tiba ${formatDate(from)}`;
 
     if (estimationDate[1] > estimationDate[0]) {
-      etdText += ` - ${formatDate(to)}`
+      etdText += ` - ${formatDate(to)}`;
     }
 
-    return etdText
+    return etdText;
   }
 
-  return ''
+  return '';
 }
 
 function splitDuration(duration) {
   if (duration) {
-    let estimationDate = null
+    let estimationDate = null;
     if (duration.includes('-')) {
-      estimationDate = duration.split('-')
-      estimationDate = parseInt(estimationDate[1])
+      estimationDate = duration.split('-');
+      estimationDate = parseInt(estimationDate[1]);
     } else {
-      estimationDate = parseInt(duration)
+      estimationDate = parseInt(duration);
     }
 
-    return estimationDate
+    return estimationDate;
   }
 
-  return ''
+  return '';
 }
 
 const extractDuration = (text) => {
-  const matches = text.match(/\d+(?:-\d+)?/g)
+  const matches = text.match(/\d+(?:-\d+)?/g);
 
   if (matches && matches.length === 1) {
-    const parts = matches[0].split('-')
-    const min = parseInt(parts[0])
-    const max = parseInt(parts[1])
+    const parts = matches[0].split('-');
+    const min = parseInt(parts[0]);
+    const max = parseInt(parts[1]);
 
     if (min === max) {
-      return min.toString()
+      return min.toString();
     }
 
-    return matches[0]
+    return matches[0];
   }
 
-  return ''
-}
+  return '';
+};
 
 const PickupAddress = ({ label }) => (
   <div className='p-4'>
@@ -1596,13 +1545,14 @@ const PickupAddress = ({ label }) => (
     <div className='mt-4 text-caption-1'>
       <p className='font-medium'>Indoteknik</p>
       <p className='mt-2 mb-2 text-gray_r-11 leading-6'>
-        Jl. Bandengan Utara Raya No.85, RT.3/RW.16, Penjaringan, Kec. Penjaringan, Kota Jkt Utara,
-        Daerah Khusus Ibukota Jakarta, Indonesia Kodepos : 14440
+        Jl. Bandengan Utara Raya No.85, RT.3/RW.16, Penjaringan, Kec.
+        Penjaringan, Kota Jkt Utara, Daerah Khusus Ibukota Jakarta, Indonesia
+        Kodepos : 14440
       </p>
       <p className='mt-1 text-gray_r-11'>Telp : 021-2933 8828/29</p>
       <p className='mt-1 text-gray_r-11'>Mobile : 0813 9000 7430</p>
     </div>
   </div>
-)
+);
 
-export default Checkout
+export default Checkout;
-- 
cgit v1.2.3

