summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/components/elements/Navbar/NavbarDesktop.jsx10
-rw-r--r--src/core/components/elements/Popup/BottomPopup.jsx6
-rw-r--r--src/lib/cart/components/Cart.jsx2
-rw-r--r--src/lib/checkout/components/Checkout.jsx53
-rw-r--r--src/lib/invoice/components/Invoice.jsx10
-rw-r--r--src/lib/product/components/Product/ProductDesktop.jsx18
-rw-r--r--src/lib/product/components/ProductSearch.jsx12
-rw-r--r--src/lib/product/components/Skeleton/ProductSearchSkeleton.jsx6
-rw-r--r--src/lib/quotation/components/Quotation.jsx37
-rw-r--r--src/lib/transaction/components/Transaction.jsx14
-rw-r--r--src/pages/api/shop/midtrans-payment.js20
-rw-r--r--src/pages/shop/quotation/finish.jsx47
12 files changed, 122 insertions, 113 deletions
diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx
index db281e9a..7e66a234 100644
--- a/src/core/components/elements/Navbar/NavbarDesktop.jsx
+++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx
@@ -67,7 +67,7 @@ const NavbarDesktop = () => {
<a href='https://wa.me/628' className='flex items-center gap-x-1 !text-gray_r-12/80'>
<Image src='/images/socials/Whatsapp-2.png' alt='Whatsapp' width={48} height={48} />
<div>
- <div className='font-semibold'>Order Via WA</div>
+ <div className='font-semibold'>Whatsapp</div>
0812 8080 622 (Chat)
</div>
</a>
@@ -92,19 +92,13 @@ const NavbarDesktop = () => {
</button>
<div className='w-6/12 flex gap-x-1 px-1 bg-gray_r-1'>
<Link
- href='/'
- className='p-4 flex-1 flex justify-center items-center !text-gray_r-12/80 bg-gray_r-2 hover:bg-gray_r-4 border border-gray_r-6 idt-transition'
- >
- Promo Produk
- </Link>
- <Link
href='/shop/brands'
className='p-4 flex-1 flex justify-center items-center !text-gray_r-12/80 bg-gray_r-2 hover:bg-gray_r-4 border border-gray_r-6 idt-transition'
>
Semua Brand
</Link>
<Link
- href='/'
+ href='/shop/search?orderBy=stock'
className='p-4 flex-1 flex justify-center items-center !text-gray_r-12/80 bg-gray_r-2 hover:bg-gray_r-4 border border-gray_r-6 idt-transition'
>
Ready Stock
diff --git a/src/core/components/elements/Popup/BottomPopup.jsx b/src/core/components/elements/Popup/BottomPopup.jsx
index 5828d222..1fc77932 100644
--- a/src/core/components/elements/Popup/BottomPopup.jsx
+++ b/src/core/components/elements/Popup/BottomPopup.jsx
@@ -3,6 +3,7 @@ import { AnimatePresence, motion } from 'framer-motion'
import { useEffect } from 'react'
import MobileView from '../../views/MobileView'
import DesktopView from '../../views/DesktopView'
+import ReactDOM from 'react-dom'
const transition = { ease: 'linear', duration: 0.2 }
@@ -15,7 +16,7 @@ const BottomPopup = ({ children, active = false, title, close }) => {
}
}, [active])
- return (
+ return ReactDOM.createPortal(
<>
<AnimatePresence>
{active && (
@@ -66,7 +67,8 @@ const BottomPopup = ({ children, active = false, title, close }) => {
</>
)}
</AnimatePresence>
- </>
+ </>,
+ document.querySelector('body')
)
}
diff --git a/src/lib/cart/components/Cart.jsx b/src/lib/cart/components/Cart.jsx
index 7ebee14b..8d995103 100644
--- a/src/lib/cart/components/Cart.jsx
+++ b/src/lib/cart/components/Cart.jsx
@@ -115,7 +115,7 @@ const Cart = () => {
const selectedProduct = () => {
if (!products) return []
- return products?.filter((product) => product.selected == true)
+ return products?.filter((product) => product?.selected == true)
}
const deleteProduct = (productId) => {
diff --git a/src/lib/checkout/components/Checkout.jsx b/src/lib/checkout/components/Checkout.jsx
index 048bb24e..ffb33eb7 100644
--- a/src/lib/checkout/components/Checkout.jsx
+++ b/src/lib/checkout/components/Checkout.jsx
@@ -78,7 +78,7 @@ const Checkout = () => {
}
const dataProducts = await CartApi({ variantIds })
- const productsWithQuantity = dataProducts.map(async (product) => {
+ const productsWithQuantity = dataProducts?.map(async (product) => {
const productPrice = await variantPriceApi({ id: product.id })
return {
...product,
@@ -87,12 +87,16 @@ const Checkout = () => {
discountPercentage: productPrice.discount,
priceDiscount: productPrice.priceExcludeAfterDiscount
},
- quantity: query.quantity ? query.quantity : getItemCart({ productId: product.id }).quantity
+ quantity: query.quantity
+ ? query.quantity
+ : getItemCart({ productId: product.id }).quantity
}
})
- Promise.all(productsWithQuantity).then((resolvedProducts) => {
- setProducts(resolvedProducts)
- })
+ if (productsWithQuantity) {
+ Promise.all(productsWithQuantity).then((resolvedProducts) => {
+ setProducts(resolvedProducts)
+ })
+ }
}
loadProducts()
}, [router])
@@ -150,6 +154,8 @@ const Checkout = () => {
window.location.href = payment.data.redirectUrl
}
+ const taxTotal = (totalAmount - totalDiscountAmount) * 0.11
+
return (
<>
<MobileView>
@@ -202,14 +208,14 @@ const Checkout = () => {
</div>
<div className='flex gap-x-2 justify-between'>
<div className='text-gray_r-11'>PPN 11% (Incl.)</div>
- <div>{currencyFormat((totalAmount - totalDiscountAmount) * 0.11)}</div>
+ <div>{currencyFormat(taxTotal)}</div>
</div>
</div>
<hr className='my-4 border-gray_r-6' />
<div className='flex gap-x-2 justify-between mb-4'>
<div>Grand Total</div>
<div className='font-semibold text-gray_r-12'>
- {currencyFormat(totalAmount - totalDiscountAmount)}
+ {currencyFormat(totalAmount - totalDiscountAmount + taxTotal)}
</div>
</div>
<p className='text-caption-2 text-gray_r-10 mb-2'>*) Belum termasuk biaya pengiriman</p>
@@ -233,31 +239,6 @@ const Checkout = () => {
<Divider />
<div className='p-4'>
- <div className='font-medium mb-4'>Metode Pembayaran</div>
- <div className='flex flex-col gap-y-3'>
- <div
- className={`p-2 idt-transition border rounded text-gray_r-12/80 ${
- paymentMethod == 'manual' ? 'border-yellow_r-8 bg-yellow_r-2' : 'border-gray_r-6'
- }`}
- onClick={() => setPaymentMethod('manual')}
- >
- Bank BCA (PT. Indoteknik Dotcom)
- <div className='mt-1'>8870-4000-81</div>
- </div>
- <div
- className={`p-2 idt-transition border rounded ${
- paymentMethod == 'midtrans' ? 'border-yellow_r-8 bg-yellow_r-2' : 'border-gray_r-6'
- }`}
- onClick={() => setPaymentMethod('midtrans')}
- >
- <Image src='/images/payments/midtrans.jpg' alt='Midtrans Payment' />
- </div>
- </div>
- </div>
-
- <Divider />
-
- <div className='p-4'>
<div className='font-medium'>Purchase Order</div>
<div className='mt-4 flex gap-x-3'>
@@ -286,7 +267,7 @@ const Checkout = () => {
onClick={checkout}
disabled={isLoading || !products || products?.length == 0}
>
- {isLoading ? 'Loading...' : 'Bayar'}
+ {isLoading ? 'Loading...' : 'Lanjut Pembayaran'}
</button>
</div>
</MobileView>
@@ -402,8 +383,8 @@ const Checkout = () => {
<div>{currencyFormat(totalAmount - totalDiscountAmount)}</div>
</div>
<div className='flex gap-x-2 justify-between'>
- <div className='text-gray_r-11'>PPN 11% (Incl.)</div>
- <div>{currencyFormat((totalAmount - totalDiscountAmount) * 0.11)}</div>
+ <div className='text-gray_r-11'>PPN 11%</div>
+ <div>{currencyFormat(taxTotal)}</div>
</div>
</div>
@@ -412,7 +393,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(totalAmount - totalDiscountAmount)}
+ {currencyFormat(totalAmount - totalDiscountAmount + taxTotal)}
</div>
</div>
<p className='text-caption-2 text-gray_r-11 mb-2'>
diff --git a/src/lib/invoice/components/Invoice.jsx b/src/lib/invoice/components/Invoice.jsx
index 211d1ae1..6012e4ea 100644
--- a/src/lib/invoice/components/Invoice.jsx
+++ b/src/lib/invoice/components/Invoice.jsx
@@ -152,9 +152,7 @@ const Invoice = ({ id }) => {
<div>: {invoice?.data?.invoiceDate}</div>
<div>Purchase Order</div>
- <div>
- : {invoice?.data?.purchaseOrderName || '-'}
- </div>
+ <div>: {invoice?.data?.purchaseOrderName || '-'}</div>
<div>Ketentuan Pembayaran</div>
<div>: {invoice?.data?.paymentTerm}</div>
@@ -252,13 +250,13 @@ const Invoice = ({ id }) => {
{currencyFormat(-totalDiscountAmount)}
</div>
- <div className='text-right'>PPN 11% (Incl.)</div>
- <div className='text-right font-medium'>{currencyFormat(totalAmount * 0.11)}</div>
-
<div className='text-right'>Grand Total</div>
<div className='text-right font-medium text-gray_r-12'>
{currencyFormat(invoice.data?.amountTotal)}
</div>
+
+ <div className='text-right'>PPN 11% (Incl.)</div>
+ <div className='text-right font-medium'>{currencyFormat(totalAmount * 0.11)}</div>
</div>
</div>
</div>
diff --git a/src/lib/product/components/Product/ProductDesktop.jsx b/src/lib/product/components/Product/ProductDesktop.jsx
index 2f73d124..79e7bb45 100644
--- a/src/lib/product/components/Product/ProductDesktop.jsx
+++ b/src/lib/product/components/Product/ProductDesktop.jsx
@@ -11,8 +11,10 @@ import { updateItemCart } from '@/core/utils/cart'
import useVariantPrice from '@/lib/variant/hooks/useVariantPrice'
import useProductPrice from '../../hooks/useProductPrice'
import PriceSkeleton from '@/core/components/elements/Skeleton/PriceSkeleton'
+import { useRouter } from 'next/router'
const ProductDesktop = ({ product, wishlist, toggleWishlist }) => {
+ const router = useRouter()
const { productPrice } = useProductPrice({ id: product.id })
const [informationTab, setInformationTab] = useState(informationTabOptions[0].value)
@@ -41,6 +43,12 @@ const ProductDesktop = ({ product, wishlist, toggleWishlist }) => {
toast.success('Berhasil menambahkan ke keranjang')
}
+ const handleBuy = (variantId) => {
+ const quantity = variantQuantityRefs.current[variantId].value
+ if (!validQuantity(quantity)) return
+ router.push(`/shop/checkout?productId=${variantId}&quantity=${quantity}`)
+ }
+
const variantSectionRef = useRef(null)
const goToVariantSection = () => {
if (variantSectionRef.current) {
@@ -193,7 +201,11 @@ const ProductDesktop = ({ product, wishlist, toggleWishlist }) => {
>
Keranjang
</button>
- <button type='button' className='flex-1 py-2 btn-solid-red'>
+ <button
+ type='button'
+ onClick={() => handleBuy(variant.id)}
+ className='flex-1 py-2 btn-solid-red'
+ >
Beli
</button>
</td>
@@ -264,7 +276,9 @@ const VariantPrice = ({ id }) => {
{variantPrice?.data?.priceExcludeAfterDiscount > 0 ? (
currencyFormat(variantPrice?.data?.priceExcludeAfterDiscount)
) : (
- <a href='https://wa.me/' className='text-red_r-11'>Call for price</a>
+ <a href='https://wa.me/' className='text-red_r-11'>
+ Call for price
+ </a>
)}
</>
)
diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx
index b5d7c974..b00d68a4 100644
--- a/src/lib/product/components/ProductSearch.jsx
+++ b/src/lib/product/components/ProductSearch.jsx
@@ -41,11 +41,6 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null }) => {
}
)
- const [open, setOpen] = useState(1)
-
- const handleOpen = (value) => {
- setOpen(open === value ? 0 : value)
- }
const orderOptions = [
{ value: 'price-asc', label: 'Harga Terendah' },
{ value: 'price-desc', label: 'Harga Tertinggi' },
@@ -69,13 +64,10 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null }) => {
}
}, [query, products, productSearch])
- if (productSearch.isLoading) {
- return <ProductSearchSkeleton />
- }
-
return (
<>
<MobileView>
+ {productSearch.isLoading && <ProductSearchSkeleton />}
<div className='p-4'>
<h1 className='mb-2 font-semibold text-h-sm'>Produk</h1>
@@ -178,6 +170,7 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null }) => {
<select
name='urutan'
className='form-input mt-2'
+ value={router.query?.orderBy || ''}
onChange={(e) => handleOrderBy(e)}
>
<option value=''>Urutkan</option>
@@ -191,6 +184,7 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null }) => {
</div>
</div>
</div>
+ {productSearch.isLoading && <ProductSearchSkeleton />}
<div className='grid grid-cols-5 gap-x-3 gap-y-6'>
{products &&
products.map((product) => <ProductCard product={product} key={product.id} />)}
diff --git a/src/lib/product/components/Skeleton/ProductSearchSkeleton.jsx b/src/lib/product/components/Skeleton/ProductSearchSkeleton.jsx
index fa1e175d..3447df79 100644
--- a/src/lib/product/components/Skeleton/ProductSearchSkeleton.jsx
+++ b/src/lib/product/components/Skeleton/ProductSearchSkeleton.jsx
@@ -1,7 +1,11 @@
import ProductCardSkeleton from '@/core/components/elements/Skeleton/ProductCardSkeleton'
const ProductSearchSkeleton = () => (
- <div className='p-4 grid grid-cols-2 gap-4'>
+ <div className='p-4 grid grid-cols-2 md:grid-cols-5 gap-4'>
+ <ProductCardSkeleton />
+ <ProductCardSkeleton />
+ <ProductCardSkeleton />
+ <ProductCardSkeleton />
<ProductCardSkeleton />
<ProductCardSkeleton />
<ProductCardSkeleton />
diff --git a/src/lib/quotation/components/Quotation.jsx b/src/lib/quotation/components/Quotation.jsx
index 3054616c..a95a149a 100644
--- a/src/lib/quotation/components/Quotation.jsx
+++ b/src/lib/quotation/components/Quotation.jsx
@@ -15,6 +15,7 @@ import VariantGroupCard from '@/lib/variant/components/VariantGroupCard'
import MobileView from '@/core/components/views/MobileView'
import DesktopView from '@/core/components/views/DesktopView'
import Image from '@/core/components/elements/Image/Image'
+import variantPriceApi from '@/lib/variant/api/variantPriceApi'
const Quotation = () => {
const router = useRouter()
@@ -31,11 +32,23 @@ const Quotation = () => {
.map((o) => o.productId)
.join(',')
const dataProducts = await CartApi({ variantIds })
- const dataProductsQuantity = _.map(dataProducts, (o) => ({
- ...o,
- quantity: getItemCart({ productId: o.id }).quantity
- }))
- setProducts(dataProductsQuantity)
+ const productsWithQuantity = dataProducts?.map(async (product) => {
+ const productPrice = await variantPriceApi({ id: product.id })
+ return {
+ ...product,
+ price: {
+ price: productPrice.priceExclude,
+ discountPercentage: productPrice.discount,
+ priceDiscount: productPrice.priceExcludeAfterDiscount
+ },
+ quantity: getItemCart({ productId: product.id }).quantity
+ }
+ })
+ if (productsWithQuantity) {
+ Promise.all(productsWithQuantity).then((resolvedProducts) => {
+ setProducts(resolvedProducts)
+ })
+ }
}
loadProducts()
}, [])
@@ -78,6 +91,8 @@ const Quotation = () => {
toast.error('Gagal melakukan transaksi, terjadi kesalahan internal')
}
+ const taxTotal = (totalAmount - totalDiscountAmount) * 0.11
+
return (
<>
<MobileView>
@@ -121,15 +136,15 @@ const Quotation = () => {
<div>{currencyFormat(totalAmount - totalDiscountAmount)}</div>
</div>
<div className='flex gap-x-2 justify-between'>
- <div className='text-gray_r-11'>PPN 11% (Incl.)</div>
- <div>{currencyFormat((totalAmount - totalDiscountAmount) * 0.11)}</div>
+ <div className='text-gray_r-11'>PPN 11%</div>
+ <div>{currencyFormat(taxTotal)}</div>
</div>
</div>
<hr className='my-4 border-gray_r-6' />
<div className='flex gap-x-2 justify-between mb-4'>
<div>Grand Total</div>
<div className='font-semibold text-gray_r-12'>
- {currencyFormat(totalAmount - totalDiscountAmount)}
+ {currencyFormat(totalAmount - totalDiscountAmount + taxTotal)}
</div>
</div>
<p className='text-caption-2 text-gray_r-10 mb-2'>*) Belum termasuk biaya pengiriman</p>
@@ -244,8 +259,8 @@ const Quotation = () => {
<div>{currencyFormat(totalAmount - totalDiscountAmount)}</div>
</div>
<div className='flex gap-x-2 justify-between'>
- <div className='text-gray_r-11'>PPN 11% (Incl.)</div>
- <div>{currencyFormat((totalAmount - totalDiscountAmount) * 0.11)}</div>
+ <div className='text-gray_r-11'>PPN 11%</div>
+ <div>{currencyFormat(taxTotal)}</div>
</div>
</div>
@@ -254,7 +269,7 @@ const Quotation = () => {
<div className='flex gap-x-2 justify-between mb-4'>
<div>Grand Total</div>
<div className='font-semibold text-gray_r-12'>
- {currencyFormat(totalAmount - totalDiscountAmount)}
+ {currencyFormat(totalAmount - totalDiscountAmount + taxTotal)}
</div>
</div>
<p className='text-caption-2 text-gray_r-11 mb-2'>
diff --git a/src/lib/transaction/components/Transaction.jsx b/src/lib/transaction/components/Transaction.jsx
index b921eb0d..669966da 100644
--- a/src/lib/transaction/components/Transaction.jsx
+++ b/src/lib/transaction/components/Transaction.jsx
@@ -103,14 +103,14 @@ const Transaction = ({ id }) => {
<p className='text-gray_r-12/70'>Total Diskon</p>
<p>{currencyFormat(-totalDiscountAmount)}</p>
</div>
- <div className='flex justify-between mt-1'>
- <p className='text-gray_r-12/70'>PPN 11% (Incl.)</p>
- <p>{currencyFormat(totalAmount * 0.11)}</p>
- </div>
<div className='flex justify-between mt-1 font-medium'>
<p>Total Belanja</p>
<p>{currencyFormat(transaction.data?.amountTotal)}</p>
</div>
+ <div className='flex justify-between mt-1'>
+ <p className='text-gray_r-12/70'>PPN 11% (Incl.)</p>
+ <p>{currencyFormat(totalAmount * 0.11)}</p>
+ </div>
</div>
),
[transaction.data, totalAmount, totalDiscountAmount]
@@ -414,13 +414,13 @@ const Transaction = ({ id }) => {
{currencyFormat(-totalDiscountAmount)}
</div>
- <div className='text-right'>PPN 11% (Incl.)</div>
- <div className='text-right font-medium'>{currencyFormat(totalAmount * 0.11)}</div>
-
<div className='text-right'>Grand Total</div>
<div className='text-right font-medium text-gray_r-12'>
{currencyFormat(transaction.data?.amountTotal)}
</div>
+
+ <div className='text-right'>PPN 11% (Incl.)</div>
+ <div className='text-right font-medium'>{currencyFormat(totalAmount * 0.11)}</div>
</div>
</div>
diff --git a/src/pages/api/shop/midtrans-payment.js b/src/pages/api/shop/midtrans-payment.js
index be676d38..1772e9e0 100644
--- a/src/pages/api/shop/midtrans-payment.js
+++ b/src/pages/api/shop/midtrans-payment.js
@@ -31,6 +31,20 @@ export default async function handler(req, res) {
serverKey: process.env.MIDTRANS_SERVER_KEY
})
+ let itemDetails = transaction.products.map((product) => ({
+ id: product.code,
+ price: Math.round(product.price.priceDiscount),
+ quantity: product.quantity,
+ name: product.name?.substring(0, 50)
+ }))
+
+ itemDetails.push({
+ id: 'TAX',
+ price: transaction.amountTax,
+ quantity: 1,
+ name: 'PPN 11%'
+ })
+
const parameter = {
transaction_details: {
order_id: transaction.name?.replaceAll('/', '-'),
@@ -39,12 +53,6 @@ export default async function handler(req, res) {
credit_card: {
secure: true
},
- item_details: transaction.products.map((product) => ({
- id: product.code,
- price: Math.round(product.price.priceDiscount),
- quantity: product.quantity,
- name: product.name?.substring(0, 50)
- })),
customer_details: {
first_name: transaction.address.customer.name,
email: transaction.address.customer.email || '',
diff --git a/src/pages/shop/quotation/finish.jsx b/src/pages/shop/quotation/finish.jsx
index 15881ea0..32638b62 100644
--- a/src/pages/shop/quotation/finish.jsx
+++ b/src/pages/shop/quotation/finish.jsx
@@ -12,31 +12,30 @@ export default function FinishQuotation() {
return (
<IsAuth>
<BasicLayout>
- <div className='m-4 px-4 py-6 shadow-md border border-gray_r-3'>
- <div className='flex'>
- <span className='p-3 mx-auto bg-yellow_r-3 border border-yellow_r-6 rounded'>
- <EnvelopeIcon className='w-8 text-yellow_r-11' />
- </span>
- </div>
- <p className='h2 text-center mt-6'>Terima Kasih {auth?.name}</p>
- <p className='text-center mt-3 leading-6 text-gray_r-11'>
- Penawaran harga kamu di Indoteknik.com berhasil dikirimkan, tim kami akan segera
- menghubungi anda.
- </p>
- {id && (
- <Link
- href={`/my/transaction/${id}`}
- className='btn-yellow !text-gray_r-12 mt-6 w-full'
- >
- Lihat Penawaran
+ <div className='mx-auto container'>
+ <div className='m-4 md:m-0 md:mt-10 px-4 py-6 shadow-md border border-gray_r-3'>
+ <div className='flex'>
+ <span className='p-3 mx-auto bg-yellow_r-3 border border-yellow_r-6 rounded'>
+ <EnvelopeIcon className='w-8 text-yellow_r-11' />
+ </span>
+ </div>
+ <p className='h2 text-center mt-6'>Terima Kasih {auth?.name}</p>
+ <p className='text-center mt-3 leading-6 text-gray_r-11'>
+ Penawaran harga kamu di Indoteknik.com berhasil dikirimkan, tim kami akan segera
+ menghubungi anda.
+ </p>
+ {id && (
+ <Link
+ href={`/my/transaction/${id}`}
+ className='btn-yellow !text-gray_r-12 mt-6 w-full md:w-1/3 md:mx-auto'
+ >
+ Lihat Penawaran
+ </Link>
+ )}
+ <Link href='/' className='btn-light !text-gray_r-12 mt-2 w-full md:w-1/3 md:mx-auto'>
+ Ke Halaman Utama
</Link>
- )}
- <Link
- href='/'
- className='btn-light !text-gray_r-12 mt-2 w-full'
- >
- Ke Halaman Utama
- </Link>
+ </div>
</div>
</BasicLayout>
</IsAuth>