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 { 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 checkoutApi from '../api/checkoutApi' 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 imageNext from 'next/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 { createSlug } from '@/core/utils/slug' 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' const SELF_PICKUP_ID = 32 const { checkoutApi } = require('../api/checkoutApi') const { getProductsCheckout } = require('../api/checkoutApi') const Checkout = () => { const router = useRouter() const auth = useAuth() const [activeVoucher, SetActiveVoucher] = useState(null) const { data: cartCheckout } = useQuery('cartCheckout-' + activeVoucher, () => getProductsCheckout(activeVoucher) ) const [selectedAddress, setSelectedAddress] = useState({ shipping: null, invoicing: null }) const [addresses, setAddresses] = useState(null) useEffect(() => { if (!auth) return const getAddresses = async () => { const dataAddresses = await addressesApi() setAddresses(dataAddresses) } getAddresses() }, [auth]) useEffect(() => { if (!addresses) return const matchAddress = (key) => { const addressToMatch = getItemAddress(key) const foundAddress = addresses.filter((address) => address.id == addressToMatch) if (foundAddress.length > 0) { return foundAddress[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 [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 expedisiValidation = useRef(null) const voucher = async () => { try { let dataVoucher = await getVoucher(auth?.id) SetListVoucher(dataVoucher) } finally { setLoadingVoucher(false) } } const VoucherCode = async (code) => { let dataVoucher = await findVoucher(code, auth.id) if (dataVoucher.length <= 0) { SetFindVoucher(1) return } let addNewLine = dataVoucher[0] let checkList = listVouchers.findIndex((voucher) => voucher.code == addNewLine.code) if (checkList >= 0) { if (listVouchers[checkList].canApply) { ToggleSwitch(code) SetCodeVoucher(null) } else { SetSelisihHargaCode(listVouchers[checkList].differenceToApply) SetFindVoucher(2) } return } if (cartCheckout?.subtotal < addNewLine.minPurchaseAmount) { SetSelisihHargaCode(currencyFormat(addNewLine.minPurchaseAmount - cartCheckout?.subtotal)) SetFindVoucher(2) return } else { SetFindVoucher(3) SetButtonTerapkan(true) } SetListVoucher((prevList) => [addNewLine, ...prevList]) SetActiveVoucher(addNewLine.code) } useEffect(() => { SetFindVoucher(null) }, [bottomPopup]) useEffect(() => { const loadExpedisi = async () => { let dataExpedisi = await ExpedisiList() dataExpedisi = dataExpedisi.map((expedisi) => ({ value: expedisi.id, label: expedisi.name, carrierId: expedisi.deliveryCarrierId })) setExpedisi(dataExpedisi) } loadExpedisi() // voucher() }, []) const hitungDiscountVoucher = (code) => { let dataVoucherIndex = listVouchers.findIndex((voucher) => voucher.code == code) let dataActiveVoucher = listVouchers[dataVoucherIndex] let countDiscount = dataActiveVoucher.discountVoucher /*if (dataActiveVoucher.discountType === 'percentage') { countDiscount = cartCheckout?.subtotal * (dataActiveVoucher.discountAmount / 100) if ( dataActiveVoucher.maxDiscountAmount > 0 && countDiscount > dataActiveVoucher.maxDiscountAmount ) { countDiscount = dataActiveVoucher.maxDiscountAmount } } else { countDiscount = dataActiveVoucher.discountAmount }*/ return countDiscount } useEffect(() => { if (!listVouchers) return if (!activeVoucher) return const countDiscount = hitungDiscountVoucher(activeVoucher) SetDiscountVoucher(countDiscount) }, [activeVoucher, listVouchers]) useEffect(() => { setProducts(cartCheckout?.products) setCheckWeight(cartCheckout?.hasProductWithoutWeight) setTotalWeight(cartCheckout?.totalWeight.g) }, [cartCheckout]) useEffect(() => { setCheckoutValidation(false) const loadServiceRajaOngkir = async () => { 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)) setListServiceExpedisi(dataService.data[0].costs) if (dataService.data[0].costs[0]) { 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') } else { toast.error('Maaf, layanan tidak tersedia. Mohon pilih expedisi lain.') } } if (selectedCarrier != 0 && selectedCarrier != 1 && totalWeight > 0) { loadServiceRajaOngkir() } else { setListServiceExpedisi() setBiayaKirim(0) setselectedExpedisiService() setEtd() } }, [selectedCarrier, selectedAddress, totalWeight]) useEffect(() => { if (selectedServiceType) { let serviceType = selectedServiceType.split(',') setBiayaKirim(serviceType[0]) setselectedExpedisiService(serviceType[1]) setEtd(serviceType[2]) } }, [selectedServiceType]) useEffect(() => { if (etd) setEtdFix(calculateEstimatedArrival(etd)) }, [etd]) useEffect(() => { if (selectedExpedisi) { let serviceType = selectedExpedisi.split(',') if (serviceType[0] === 0) { setSelectedExpedisi(0) } setselectedCarrier(serviceType[0]) setselectedCarrierId(serviceType[1]) setListServiceExpedisi([]) } }, [selectedExpedisi]) const poNumber = useRef(null) const poFile = useRef(null) const [isLoading, setIsLoading] = useState(false) const checkout = async () => { const file = poFile.current.files[0] if (typeof file !== 'undefined' && file.size > 5000000) { toast.error('Maksimal ukuran file adalah 5MB', { position: 'bottom-center' }) return } if (selectedExpedisi === 0) { setCheckoutValidation(true) if (expedisiValidation.current) { const position = expedisiValidation.current.getBoundingClientRect() window.scrollTo({ top: position.top - 300 + window.pageYOffset, behavior: 'smooth' }) } return } if (selectedCarrier != 1 && biayaKirim == 0) { toast.error('Maaf, layanan tidak tersedia. Mohon pilih expedisi lain.') return } setIsLoading(true) const productOrder = products.map((product) => ({ product_id: product.id, quantity: product.quantity })) let data = { partner_shipping_id: auth.partnerId, partner_invoice_id: auth.partnerId, user_id: auth.id, order_line: JSON.stringify(productOrder), delivery_amount: biayaKirim, carrier_id: selectedCarrierId, delivery_service_type: selectedExpedisiService, voucher: activeVoucher, type: 'sale_order' } 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 }) if (!isCheckouted?.id) { toast.error('Gagal melakukan transaksi, terjadi kesalahan internal') return } gtagPurchase(products, biayaKirim, isCheckouted.name) const midtrans = async () => { 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 } gtag('event', 'conversion', { send_to: 'AW-954540379/nDymCL3BhaQYENvClMcD', value: cartCheckout?.grandTotal + Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000, currency: 'IDR', transaction_id: isCheckouted.id, event_callback: midtrans }) } const handlingActivateCode = async () => { VoucherCode(codeVoucher) } const handleUseVoucher = async (code, isCheck) => { if (isCheck) { if (code === activeVoucher) { SetActiveVoucher(null) SetDiscountVoucher(0) } else { SetActiveVoucher(code) SetFindVoucher(null) document.getElementById('uniqCode').value = '' SetButtonTerapkan(false) } } else { SetActiveVoucher(code) SetFindVoucher(null) document.getElementById('uniqCode').value = '' SetButtonTerapkan(false) } } const onChangeCodeVoucher = async (e) => { SetCodeVoucher(e.target.value) SetButtonTerapkan(false) } const [isChecked, setIsChecked] = useState(false) const ToggleSwitch = (code) => { setIsChecked(!isChecked) handleUseVoucher(code, !isChecked) } // const taxTotal = (totalAmount - totalDiscountAmount - discountVoucher) * 0.11 return ( <> SetBottomPopup(false)} title='Gunakan Promo' >
onChangeCodeVoucher(e)} />
{findCodeVoucher === 3 && activeVoucher === codeVoucher && (
Voucher berhasil ditambahkan{' '}
)} {findCodeVoucher === 1 && (
Kode voucher salah / sudah tidak berlaku lagi. Coba voucher lainnya, ya.
)} {findCodeVoucher === 2 && (
Tambah {selisihHargaCode} untuk pakai promo ini
)}
{!loadingVoucher && !listVouchers ? (

Tidak ada voucher tersedia

Maaf, saat ini tidak ada voucher yang tersedia.

) : (

Promo Khusus Untuk {auth?.name}

)} {loadingVoucher && ( <>
)} {!loadingVoucher && listVouchers?.map((item) => (
{item.canApply === false && (
)}
{item.name}

{item.name}

{item.description}

Kode Voucher :{' '} {item.code}

{activeVoucher === item.code && ( Voucher digunakan )}

{!item.canApply && item.applyStatus === 'MPA' && item.manufactureNames != '' && (

Tambah produk{' '} {item.manufactureNames} senilai{' '} {currencyFormat(item.differenceToApply)} {' '} untuk pakai promo ini

)} {!item.canApply && item.applyStatus === 'MPA' && item.manufactureNames === '' && (

Tambah{' '} {currencyFormat(item.differenceToApply)} {' '} untuk pakai promo ini{' '}

)} {!item.canApply && item.applyStatus === 'UM' && (

Tambah produk{' '} {item.manufactureNames} senilai{' '} {currencyFormat(item.minPurchaseAmount)} {' '} untuk pakai promo ini

)} {item.canApply && (

Potensi potongan sebesar{' '} {currencyFormat(item.discountVoucher)}

)} {/* {item.canApply === false ? 'Tambah ' + currencyFormat(item.differenceToApply) + ' untuk pakai promo ini' : 'Potensi potongan sebesar ' + currencyFormat(hitungDiscountVoucher(item.code))} */}


Berakhir dalam {item.remainingTime}{' '} lagi{' '}
))}
Jika mengalami kesulitan dalam melakukan pembelian di website Indoteknik. Hubungi kami disini
{selectedCarrierId == SELF_PICKUP_ID && } {selectedCarrierId != SELF_PICKUP_ID && ( <> )}
{products && }
Ringkasan Pesanan
{products?.length} Barang

{!cartCheckout ? (
) : (
Total Belanja
{currencyFormat(cartCheckout?.totalPurchase)}
Diskon Produk
- {currencyFormat(cartCheckout?.totalDiscount)}
{activeVoucher && (
Diskon Voucher
- {currencyFormat(discountVoucher)}
)}
Subtotal
{currencyFormat(cartCheckout?.subtotal)}
PPN 11%
{currencyFormat(cartCheckout?.tax)}
Biaya Kirim

{etdFix}

{currencyFormat(Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000)}
)}
{!cartCheckout ? (
{' '}
) : (
Grand Total
{currencyFormat( cartCheckout?.grandTotal + Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000 )}
)}
{/*

*) Belum termasuk biaya pengiriman

*/}

Dengan melakukan pembelian melalui website Indoteknik, saya menyetujui{' '} Syarat & Ketentuan {' '} yang berlaku

Purchase Order

Ukuran dokumen PO Maksimal 5MB

{priceCheck && (
*) Terdapat produk yang belum memiliki harga,{' '} Hubungi Kami untuk meminta harga.
)}
{selectedCarrierId == SELF_PICKUP_ID && } {selectedCarrierId != SELF_PICKUP_ID && ( <> )}
Detail Pesanan
{!products ? ( ) : ( products?.map((product) => ( <> {product.program && product.program.items && product.program.items.map((item) => ( <> ))} )) )}
Nama Produk Jumlah Harga Subtotal
{product?.name}
{product?.parent?.name}
{product?.code}{' '} {product?.attributes.length > 0 ? `| ${product?.attributes.join(', ')}` : ''}
Berat item : {product?.weight} Kg
{product?.price?.discountPercentage > 0 && (
{currencyFormat(product?.price?.price)}
{product?.price?.discountPercentage}%
)}
{product.price.priceDiscount > 0 ? currencyFormat(product?.price?.priceDiscount) : 'Call For Price'}
{product.price.priceDiscount > 0 ? ( currencyFormat(product?.price?.priceDiscount * product?.quantity) ) : ( Call For Price{' '} )}
{item.name}
{product.program.type.label}
{item.name}
{item?.price?.discountPercentage > 0 && (
{currencyFormat(product?.price?.price)}
)}
{item?.price.priceDiscount > 0 ? 'Gratis' : ''}
{item.price.priceDiscount > 0 ? 'Gratis' : ''}
Ringkasan Pesanan
{products?.length} Barang

{!cartCheckout ? (
) : (
Total Belanja
{currencyFormat(cartCheckout?.totalPurchase)}
Diskon Produk
- {currencyFormat(cartCheckout?.totalDiscount)}
{activeVoucher && (
Diskon Voucher
- {currencyFormat(discountVoucher)}
)}
Subtotal
{currencyFormat(cartCheckout?.subtotal)}
PPN 11%
{currencyFormat(cartCheckout?.tax)}
Biaya Kirim

{etdFix}

{currencyFormat(Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000)}
)}
{!cartCheckout ? (
{' '}
) : (
Grand Total
{currencyFormat( cartCheckout?.grandTotal + Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000 )}
)}

Dengan melakukan pembelian melalui website Indoteknik, saya menyetujui{' '} Syarat & Ketentuan {' '} yang berlaku


Purchase Order (Opsional)

Ukuran dokumen PO Maksimal 5MB


{priceCheck && (
*) Terdapat produk yang belum memiliki harga,{' '} Hubungi Kami untuk meminta harga.
)}
) } const SectionAddress = ({ address, label, url }) => (
{label}
Pilih Alamat Lain
{address && (
{address.type.charAt(0).toUpperCase() + address.type.slice(1) + ' Address'}

{address.name}

{address.mobile}

{address.street}, {address?.city?.name}

)}
) const SectionValidation = ({ address }) => address?.rajaongkirCityId == 0 && (
Mohon untuk memperbarui alamat Anda dengan mengklik tombol di bawah ini.{' '}
Update Alamat
) const SectionExpedisi = ({ address, listExpedisi, setSelectedExpedisi, checkWeigth, checkoutValidation, expedisiValidation }) => address?.rajaongkirCityId > 0 && (
Pilih Expedisi :
{checkoutValidation && ( *silahkan pilih expedisi )}
{checkWeigth == true && (

Mohon maaf, pengiriman hanya tersedia untuk self pickup karena terdapat barang yang belum diatur beratnya. Mohon atur berat barang dengan menghubungi admin melalui{' '} tautan ini

)}
) const SectionListService = ({ listserviceExpedisi, setSelectedServiceType }) => listserviceExpedisi?.length > 0 && ( <>
Service Type Expedisi :
) function addDays(date, days) { 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}` } 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 etdText = `*Estimasi tiba ${formatDate(from)}` if (estimationDate[1] > estimationDate[0]) { etdText += ` - ${formatDate(to)}` } return etdText } return '' } const extractDuration = (text) => { 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]) if (min === max) { return min.toString() } return matches[0] } return '' } const PickupAddress = ({ label }) => (
{label}

Indoteknik

Jl. Bandengan Utara Raya No.85, RT.3/RW.16, Penjaringan, Kec. Penjaringan, Kota Jkt Utara, Daerah Khusus Ibukota Jakarta, Indonesia Kodepos : 14440

Telp : 021-2933 8828/29

Mobile : 0813 9000 7430

) export default Checkout