From d4d4227dfb2fefa56ded8ff5897469459f56b069 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Thu, 2 Feb 2023 17:13:12 +0700 Subject: no message --- src/components/layouts/Footer.js | 32 ++++++++-- src/components/products/ProductCard.js | 11 ++-- src/components/products/ProductSlider.js | 3 +- src/pages/index.js | 5 +- src/pages/my/address/index.js | 12 ++-- src/pages/my/invoice/[id].js | 19 +++++- src/pages/my/invoices.js | 17 ++++- src/pages/my/transactions.js | 1 - src/pages/shop/checkout.js | 105 ++++++++++++++++--------------- src/pages/shop/product/[slug].js | 78 +++++++++++++++-------- src/styles/globals.css | 11 ++++ 11 files changed, 196 insertions(+), 98 deletions(-) (limited to 'src') diff --git a/src/components/layouts/Footer.js b/src/components/layouts/Footer.js index e48daf7f..d173a525 100644 --- a/src/components/layouts/Footer.js +++ b/src/components/layouts/Footer.js @@ -6,10 +6,11 @@ import { import Image from "next/image"; import InstagramIcon from "@/icons/instagram.svg"; import LinkedinIcon from "@/icons/linkedin.svg"; +import Link from "../elements/Link"; export default function Footer() { return ( -
+

Kantor Pusat

@@ -20,18 +21,39 @@ export default function Footer() {

Layanan Informasi

-

(021) 2933-8828 / 29

+ + (021) 2933-8828 + + {'/'} + + 29 +
-

0812-8080-622

+ + 0812-8080-622 +
-

sales@indoteknik.com

+ + sales@indoteknik.com +
- {/*

Panduan Pelanggan

*/} +

Panduan Pelanggan

+
+ FAQ + Kebijakan Privasi + Pengajuan Tempo + Garansi Produk + Online Quotation + Pengiriman + Pembayaran + Syarat & Ketentuan + +

Jam Operasional

diff --git a/src/components/products/ProductCard.js b/src/components/products/ProductCard.js index e32463a7..c79a4900 100644 --- a/src/components/products/ProductCard.js +++ b/src/components/products/ProductCard.js @@ -5,7 +5,10 @@ import { ChevronRightIcon } from "@heroicons/react/20/solid"; import Image from "../elements/Image"; -export default function ProductCard({ data }) { +export default function ProductCard({ + data, + simpleProductTitleLine = false +}) { let product = data; return (
@@ -26,7 +29,7 @@ export default function ProductCard({ data }) { ) : ( - )} - + {product.name}
@@ -34,7 +37,7 @@ export default function ProductCard({ data }) { {product.lowest_price.discount_percentage > 0 ? (

{currencyFormat(product.lowest_price.price)}

- {product.lowest_price.discount_percentage}% + {product.lowest_price.discount_percentage}%
) : ''} @@ -55,7 +58,7 @@ export default function ProductCard({ data }) { {product.stock_total > 0 ? (
-
Ready Stock
+
Ready Stock
{product.stock_total > 5 ? '> 5' : '< 5'}
) : ''} diff --git a/src/components/products/ProductSlider.js b/src/components/products/ProductSlider.js index b7c17ecd..6ee31f9b 100644 --- a/src/components/products/ProductSlider.js +++ b/src/components/products/ProductSlider.js @@ -8,6 +8,7 @@ import { useState } from "react"; export default function ProductSlider({ products, + simpleProductTitleLine = false, bannerMode = false }) { const [ activeIndex, setActiveIndex ] = useState(0); @@ -28,7 +29,7 @@ export default function ProductSlider({ ) } {products?.products?.map((product, index) => ( - + ))} diff --git a/src/pages/index.js b/src/pages/index.js index e7eb4af0..49300883 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -101,7 +101,7 @@ export default function Home({ heroBanners }) {

Produk Populer

- +
{ categoryProducts?.map((categoryProduct, index) => ( @@ -115,7 +115,8 @@ export default function Home({ heroBanners }) { url: `/shop/search?category=${categoryProduct.name}` } } : null} - bannerMode={true} + simpleProductTitleLine + bannerMode />
)) } diff --git a/src/pages/my/address/index.js b/src/pages/my/address/index.js index 54e721b6..7026d5ea 100644 --- a/src/pages/my/address/index.js +++ b/src/pages/my/address/index.js @@ -56,7 +56,7 @@ export default function Address() { return (
changeSelectedAddress(address.id)}>
@@ -65,9 +65,13 @@ export default function Address() {
Utama
) }
-

{ address.name }

-

{ address.mobile }

-

{ address.street } { address.street2 }

+

{ address.name }

+ { address.mobile && ( +

{ address.mobile }

+ ) } +

+ { address.street } +

Ubah Alamat
diff --git a/src/pages/my/invoice/[id].js b/src/pages/my/invoice/[id].js index c1cacfc6..d13cf7a6 100644 --- a/src/pages/my/invoice/[id].js +++ b/src/pages/my/invoice/[id].js @@ -46,6 +46,10 @@ export default function DetailInvoice() { ); }; + const downloadTaxInvoice = () => { + window.open(`${process.env.ODOO_HOST}/api/v1/download/tax-invoice/${invoice.id}/${invoice.efaktur_token}`, '_blank') + } + return ( @@ -59,9 +63,9 @@ export default function DetailInvoice() { { invoice?.amount_residual > 0 ? ( - Belum Lunas + Belum Lunas ) : ( - Lunas + Lunas ) } @@ -81,6 +85,17 @@ export default function DetailInvoice() { { invoice?.invoice_date } +
+

Faktur Pajak

+ +
diff --git a/src/pages/my/invoices.js b/src/pages/my/invoices.js index a3107bfd..d54f9487 100644 --- a/src/pages/my/invoices.js +++ b/src/pages/my/invoices.js @@ -6,7 +6,7 @@ import Layout from "@/components/layouts/Layout"; import apiOdoo from "@/core/utils/apiOdoo"; import { useAuth } from "@/core/utils/auth"; import currencyFormat from "@/core/utils/currencyFormat"; -import { EllipsisVerticalIcon, MagnifyingGlassIcon } from "@heroicons/react/24/outline"; +import { CheckIcon, ClockIcon, EllipsisVerticalIcon, MagnifyingGlassIcon } from "@heroicons/react/24/outline"; import { useRouter } from "next/router"; import { useEffect, useRef, useState } from "react"; @@ -87,9 +87,9 @@ export default function Invoices() {
{ invoice.amount_residual > 0 ? ( -
Belum Lunas
+
Belum Lunas
) : ( -
Lunas
+
Lunas
) } {}} />
@@ -115,6 +115,17 @@ export default function Invoices() {
+ { invoice.efaktur_token ? ( +
+ + Faktur Pajak +
+ ) : ( +
+ + Faktur Pajak +
+ ) } )) } diff --git a/src/pages/my/transactions.js b/src/pages/my/transactions.js index 221859f9..a03ff007 100644 --- a/src/pages/my/transactions.js +++ b/src/pages/my/transactions.js @@ -41,7 +41,6 @@ export default function Transactions() { const dataTransactions = await apiOdoo('GET', `/api/v1/partner/${auth.partner_id}/sale_order${queryParams}`); setTransactions(dataTransactions); - console.log(dataTransactions); setPageCount(Math.ceil(dataTransactions?.sale_order_total / limit)); setIsLoading(false); }; diff --git a/src/pages/shop/checkout.js b/src/pages/shop/checkout.js index f55b200f..875cf0f1 100644 --- a/src/pages/shop/checkout.js +++ b/src/pages/shop/checkout.js @@ -20,6 +20,7 @@ import VariantCard from "@/components/variants/VariantCard"; export default function Checkout() { const router = useRouter(); + const { product_id, qty } = router.query; const [ auth ] = useAuth(); const [ addresses, setAddresses ] = useState(null); const [ poNumber, setPoNumber ] = useState(''); @@ -30,8 +31,7 @@ export default function Checkout() { }); const [ selectedPayment, setSelectedPayment ] = useState(null); const [ products, setProducts ] = useState(null); - const [ totalPriceBeforeTax, setTotalPriceBeforeTax ] = useState(0); - const [ totalTaxAmount, setTotalTaxAmount ] = useState(0); + const [ totalAmount, setTotalAmount ] = useState(0); const [ totalDiscountAmount, setTotalDiscountAmount ] = useState(0); const [ finishCheckout, setFinishCheckout ] = useState(null); @@ -53,25 +53,34 @@ export default function Checkout() { useEffect(() => { const getProducts = async () => { let cart = getCart(); - let productIds = Object - .values(cart) - .filter((itemCart) => itemCart.selected == true) - .map((itemCart) => itemCart.product_id); + let productIds = []; + if (product_id) { + productIds = [parseInt(product_id)]; + } else { + productIds = Object + .values(cart) + .filter((itemCart) => itemCart.selected == true) + .map((itemCart) => itemCart.product_id); + } if (productIds.length > 0) { productIds = productIds.join(','); let dataProducts = await apiOdoo('GET', `/api/v1/product_variant/${productIds}`); - dataProducts = dataProducts.map((product) => ({ - ...product, - quantity: cart[product.id].quantity, - selected: cart[product.id].selected, - })); + dataProducts = dataProducts.map((product) => { + if (product_id) { + product.quantity = 1; + if (qty) product.quantity = parseInt(qty); + } else { + product.quantity = cart[product.id].quantity; + } + return product; + }); setProducts(dataProducts); } else { if (auth) router.push('/shop/cart'); } }; getProducts(); - }, [router, auth]); + }, [router, auth, product_id, qty]); useEffect(() => { if (addresses) { @@ -92,18 +101,13 @@ export default function Checkout() { useEffect(() => { if (products) { - const productsSelected = products.filter((product) => product.selected == true); - let calculateTotalPriceBeforeTax = 0; - let calculateTotalTaxAmount = 0; + let calculateTotalAmount = 0; let calculateTotalDiscountAmount = 0; - productsSelected.forEach(product => { - let priceBeforeTax = product.price.price / 1.11; - calculateTotalPriceBeforeTax += priceBeforeTax * product.quantity; - calculateTotalTaxAmount += (product.price.price - priceBeforeTax) * product.quantity; + products.forEach(product => { + calculateTotalAmount += product.price.price * product.quantity; calculateTotalDiscountAmount += (product.price.price - product.price.price_discount) * product.quantity; }); - setTotalPriceBeforeTax(calculateTotalPriceBeforeTax); - setTotalTaxAmount(calculateTotalTaxAmount); + setTotalAmount(calculateTotalAmount); setTotalDiscountAmount(calculateTotalDiscountAmount); } }, [products]); @@ -115,17 +119,18 @@ export default function Checkout() { }); return; } + if (poFile && poFile.size > 5000000) { + toast.error('Maksimal ukuran file adalah 5MB', { + position: 'bottom-center' + }); + return; + } let productOrder = products.map((product) => ({ 'product_id': product.id, 'quantity': product.quantity })); let data = { 'partner_shipping_id': selectedAddress.shipping.id, 'partner_invoice_id': selectedAddress.invoicing.id, - 'order_line': JSON.stringify(productOrder) - }; - if (auth?.company && !poFile) { - toast.error('Mohon isi file PO', { - position: 'bottom-center' - }); - return; + 'order_line': JSON.stringify(productOrder), + 'type': 'sale_order' }; if (poNumber) data.po_number = poNumber; if (poFile) data.po_file = await getFileBase64(poFile); @@ -192,7 +197,7 @@ export default function Checkout() {

{ selectedAddress.shipping.name }

{ selectedAddress.shipping.mobile }

-

{ selectedAddress.shipping.street }, { selectedAddress.shipping.city.name }

+

{ selectedAddress.shipping.street }, { selectedAddress.shipping?.city?.name }

) } @@ -219,22 +224,26 @@ export default function Checkout() {
-

Subtotal

-

{currencyFormat(totalPriceBeforeTax)}

-
-
-

PPN 11%

-

{currencyFormat(totalTaxAmount)}

+

Total Belanja

+

{currencyFormat(totalAmount)}

Total Diskon

- {currencyFormat(totalDiscountAmount)}

+
+

Subtotal

+

{currencyFormat(totalAmount - totalDiscountAmount)}

+
+
+

PPN 11% (Incl.)

+

{currencyFormat((totalAmount - totalDiscountAmount) * 0.11)}

+

Grand Total

-

{currencyFormat(totalPriceBeforeTax + totalTaxAmount - totalDiscountAmount)}

+

{currencyFormat(totalAmount - totalDiscountAmount)}

*) Belum termasuk biaya pengiriman

@@ -284,21 +293,9 @@ export default function Checkout() {

Purchase Order

-
- - setPoNumber(e.target.value)} - /> -
setPoFile(e.target.files[0])} />
+
+ + setPoNumber(e.target.value)} + /> +
+

Ukuran dokumen PO Maksimal 5MB

diff --git a/src/pages/shop/product/[slug].js b/src/pages/shop/product/[slug].js index bcfb12ba..281f2bc2 100644 --- a/src/pages/shop/product/[slug].js +++ b/src/pages/shop/product/[slug].js @@ -138,6 +138,23 @@ export default function ProductDetail({ product }) { return true; } + const checkoutProduct = () => { + if (!auth) { + toast.error('Login terlebih dahulu untuk melanjutkan', { duration: 2000 }); + router.push('/login'); + return; + } + if (product.variant_total > 1 && !selectedVariant) { + toast.error('Pilih varian terlebih dahulu untuk melanjutkan pembelian', { duration: 2000 }); + return; + } + if (quantity < 0) { + toast.error('Jumlah barang yang ditambahkan minimal 1 pcs', { duration: 2000 }); + return; + } + router.push(`/shop/checkout?product_id=${activeVariant.id}&qty=${quantity}`); + } + return ( <>
@@ -187,36 +204,38 @@ export default function ProductDetail({ product }) {
-
-
- - -
-
- - -
+
+ +
+
- + + +
@@ -230,7 +249,7 @@ export default function ProductDetail({ product }) {

{product.variant_total} Varian

-

Nomor SKU

+

No. SKU

SKU-{activeVariant.id}

@@ -239,9 +258,14 @@ export default function ProductDetail({ product }) {

Stok

-

- {activeVariant.stock > 0 ? (activeVariant.stock > 5 ? 'Lebih dari 5' : 'Kurang dari 5') : '0'} -

+
+ {activeVariant.stock > 0 ? (activeVariant.stock > 5 && ( + <> +
Ready Stock
+
{activeVariant.stock > 5 ? '> 5' : '< 5'}
+ + )) : '0'} +

Berat Barang

@@ -259,7 +283,7 @@ export default function ProductDetail({ product }) {
-

Produk Lainnya

+

Kamu Mungkin Juga Suka

diff --git a/src/styles/globals.css b/src/styles/globals.css index 2b2b6271..ec603157 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -153,6 +153,7 @@ html, body { .btn-yellow, .btn-light, .btn-red, + .btn-solid-red, .btn-green { @apply block @@ -188,6 +189,16 @@ html, body { ; } + .btn-solid-red { + @apply + bg-red_r-11 + border-red_r-11 + text-gray_r-1 + disabled:text-gray_r-1 + disabled:bg-red_r-8 + ; + } + .btn-green { @apply bg-green_r-3 -- cgit v1.2.3