diff options
Diffstat (limited to 'src/lib/checkout/components')
| -rw-r--r-- | src/lib/checkout/components/Checkout.jsx | 52 | ||||
| -rw-r--r-- | src/lib/checkout/components/CheckoutOld.jsx | 2 | ||||
| -rw-r--r-- | src/lib/checkout/components/CheckoutSection.jsx | 257 |
3 files changed, 293 insertions, 18 deletions
diff --git a/src/lib/checkout/components/Checkout.jsx b/src/lib/checkout/components/Checkout.jsx index 52edbd05..4aafdece 100644 --- a/src/lib/checkout/components/Checkout.jsx +++ b/src/lib/checkout/components/Checkout.jsx @@ -111,6 +111,8 @@ const Checkout = () => { const [checkoutValidation, setCheckoutValidation] = useState(false); const [loadingVoucher, setLoadingVoucher] = useState(true); const [loadingRajaOngkir, setLoadingRajaOngkir] = useState(false); + const [grandTotal, setGrandTotal] = useState(0); + const [hasFlashSale, setHasFlashSale] = useState(false); const expedisiValidation = useRef(null); @@ -223,7 +225,9 @@ const Checkout = () => { setProducts(cartCheckout?.products); setCheckWeight(cartCheckout?.hasProductWithoutWeight); setTotalWeight(cartCheckout?.totalWeight.g); + setHasFlashSale(cartCheckout?.products[0]?.hasFlashsale ? cartCheckout.products[0].hasFlashsale : false); }, [cartCheckout]); + useEffect(() => { setCheckoutValidation(false); @@ -295,6 +299,14 @@ const Checkout = () => { const [isLoading, setIsLoading] = useState(false); + useEffect(() => { + const GT = + cartCheckout?.grandTotal + + Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000; + const finalGT = GT < 0 ? 0 : GT; + setGrandTotal(finalGT); + }, [biayaKirim, cartCheckout?.grandTotal, activeVoucher]); + const checkout = async () => { const file = poFile.current.files[0]; if (typeof file !== 'undefined' && file.size > 5000000) { @@ -324,14 +336,17 @@ const Checkout = () => { quantity: product.quantity, })); let data = { - partner_shipping_id: auth.partnerId, - partner_invoice_id: auth.partnerId, + // partner_shipping_id: auth.partnerId, + // partner_invoice_id: auth.partnerId, + partner_shipping_id: selectedAddress?.shipping?.id || auth.partnerId, + partner_invoice_id: selectedAddress?.invoicing?.id || auth.partnerId, user_id: auth.id, order_line: JSON.stringify(productOrder), delivery_amount: biayaKirim, carrier_id: selectedCarrierId, estimated_arrival_days: splitDuration(etd), delivery_service_type: selectedExpedisiService, + flash_sale : hasFlashSale, // dibuat negasi untuk ngetest kebalikan nilai false voucher: activeVoucher, type: 'sale_order', }; @@ -347,16 +362,25 @@ const Checkout = () => { 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; + if (grandTotal > 0) { + 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; + } else { + window.location.href = `${ + process.env.NEXT_PUBLIC_SELF_HOST + }/shop/checkout/success?order_id=${isCheckouted.name.replace( + /\//g, + '-' + )}`; + } }; gtag('event', 'conversion', { @@ -913,10 +937,7 @@ const Checkout = () => { <div className='flex gap-x-2 justify-between mb-4'> <div>Grand Total</div> <div className='font-semibold text-gray_r-12'> - {currencyFormat( - cartCheckout?.grandTotal + - Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000 - )} + {currencyFormat(grandTotal)} </div> </div> )} @@ -1208,10 +1229,7 @@ const Checkout = () => { <div className='flex gap-x-2 justify-between mb-4'> <div>Grand Total</div> <div className='font-semibold text-gray_r-12'> - {currencyFormat( - cartCheckout?.grandTotal + - Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000 - )} + {currencyFormat(grandTotal)} </div> </div> )} @@ -1442,7 +1460,7 @@ const SectionExpedisi = ({ dengan menghubungi admin melalui{' '} <a className='text-danger-500 inline' - href='https://api.whatsapp.com/send?phone=628128080622' + href='https://api.whatsapp.com/send?phone=6281717181922' > tautan ini </a> diff --git a/src/lib/checkout/components/CheckoutOld.jsx b/src/lib/checkout/components/CheckoutOld.jsx index d57fbd66..e2c45ce6 100644 --- a/src/lib/checkout/components/CheckoutOld.jsx +++ b/src/lib/checkout/components/CheckoutOld.jsx @@ -696,7 +696,7 @@ const SectionExpedisi = ({ address, listExpedisi, setSelectedExpedisi, checkWeig diatur beratnya. Mohon atur berat barang dengan menghubungi admin melalui{' '} <a className='text-danger-500 inline' - href='https://api.whatsapp.com/send?phone=628128080622' + href='https://api.whatsapp.com/send?phone=6281717181922' > tautan ini </a> diff --git a/src/lib/checkout/components/CheckoutSection.jsx b/src/lib/checkout/components/CheckoutSection.jsx new file mode 100644 index 00000000..affe6138 --- /dev/null +++ b/src/lib/checkout/components/CheckoutSection.jsx @@ -0,0 +1,257 @@ +import Link from 'next/link'; +import BottomPopup from '@/core/components/elements/Popup/BottomPopup'; +import { AnimatePresence, motion } from 'framer-motion'; +import { Divider, Spinner } from '@chakra-ui/react'; + +export const SectionAddress = ({ address, label, url }) => { + return ( + <div className='p-4'> + <div className='flex justify-between items-center'> + <div className='font-medium'>{label}</div> + <Link className='text-caption-1' href={url}> + Pilih Alamat Lain + </Link> + </div> + + {address && ( + <div className='mt-4 text-caption-1'> + <div className='badge-red mb-2'> + {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> + <p className='mt-1 text-gray_r-11'> + {address.street}, {address?.city?.name} + </p> + </div> + )} + </div> + ); +}; + +export const SectionValidation = ({ address }) => + address?.rajaongkirCityId == 0 && ( + <BottomPopup active={true} title='Update Alamat'> + <div className='leading-7 text-gray_r-12/80'> + Mohon untuk memperbarui alamat Anda dengan mengklik tombol di bawah ini.{' '} + </div> + <div className='flex justify-center mt-6 gap-x-4'> + <Link + className='btn-solid-red w-full md:w-fit text-white' + href={`/my/address/${address?.id}/edit`} + > + Update Alamat + </Link> + </div> + </BottomPopup> + ); + +export const SectionExpedisi = ({ + address, + listExpedisi, + setSelectedExpedisi, + checkWeigth, + checkoutValidation, + expedisiValidation, + loadingRajaOngkir, +}) => + address?.rajaongkirCityId > 0 && ( + <div className='p-4' ref={expedisiValidation}> + <div className='flex justify-between items-center'> + <div className='font-medium'>Pilih Ekspedisi: </div> + <div className='w-[250px]'> + <div className='flex items-center gap-x-4'> + <select + className={`form-input ${ + checkoutValidation ? 'border-red-500 shake' : '' + }`} + onChange={(e) => setSelectedExpedisi(e.target.value)} + required + > + <option value='0,0'>Pilih Pengiriman</option> + <option value='1,32'>SELF PICKUP</option> + {checkWeigth != true && + listExpedisi.map((expedisi) => ( + <option + disabled={checkWeigth} + value={expedisi.label + ',' + expedisi.carrierId} + key={expedisi.value} + > + {' '} + {expedisi.label.toUpperCase()}{' '} + </option> + ))} + </select> + + <AnimatePresence> + {loadingRajaOngkir && ( + <motion.div + initial={{ opacity: 0, width: 0 }} + animate={{ opacity: 1, width: '28px' }} + exit={{ opacity: 0, width: 0 }} + transition={{ + duration: 0.25, + }} + className='overflow-hidden' + > + <Spinner thickness='3px' speed='0.5s' color='red.500' /> + </motion.div> + )} + </AnimatePresence> + </div> + {checkoutValidation && ( + <span className='text-sm text-red-500'> + *silahkan pilih expedisi + </span> + )} + </div> + <style jsx>{` + .shake { + animation: shake 0.4s ease-in-out; + } + `}</style> + </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{' '} + <a + className='text-danger-500 inline' + href='https://api.whatsapp.com/send?phone=6281717181922' + > + tautan ini + </a> + </p> + )} + </div> + ); + +export const SectionListService = ({ + listserviceExpedisi, + setSelectedServiceType, +}) => + listserviceExpedisi?.length > 0 && ( + <> + <div className='p-4'> + <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)} + > + {listserviceExpedisi.map((service) => ( + <option + value={ + service.cost[0].value + + ',' + + service.description + + '-' + + service.service + + ',' + + extractDuration(service.cost[0].etd) + } + key={service.service} + > + {' '} + {service.description} - {service.service.toUpperCase()} + {extractDuration(service.cost[0].etd) && + ` (Estimasi Tiba ${extractDuration( + service.cost[0].etd + )} Hari)`} + </option> + ))} + </select> + </div> + </div> + </div> + <Divider /> + </> + ); + +export const PickupAddress = ({ label }) => ( + <div className='p-4'> + <div className='flex justify-between items-center'> + <div className='font-medium'>{label}</div> + </div> + <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 + </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> +); + +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 ''; +}; + +export 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 ''; +} + +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}`; +} + +export function splitDuration(duration) { + if (duration) { + let estimationDate = null; + if (duration.includes('-')) { + estimationDate = duration.split('-'); + estimationDate = parseInt(estimationDate[1]); + } else { + estimationDate = parseInt(duration); + } + + return estimationDate; + } + + return ''; +}
\ No newline at end of file |
