summaryrefslogtreecommitdiff
path: root/src/pages
diff options
context:
space:
mode:
authorRafi Zadanly <zadanlyr@gmail.com>2023-02-02 17:13:12 +0700
committerRafi Zadanly <zadanlyr@gmail.com>2023-02-02 17:13:12 +0700
commitd4d4227dfb2fefa56ded8ff5897469459f56b069 (patch)
tree46b1572614684e7472b60b696d148749cdc71f77 /src/pages
parentbe2bc90edc387966cb1b23c60a80e4b5fcf4bec9 (diff)
no message
Diffstat (limited to 'src/pages')
-rw-r--r--src/pages/index.js5
-rw-r--r--src/pages/my/address/index.js12
-rw-r--r--src/pages/my/invoice/[id].js19
-rw-r--r--src/pages/my/invoices.js17
-rw-r--r--src/pages/my/transactions.js1
-rw-r--r--src/pages/shop/checkout.js105
-rw-r--r--src/pages/shop/product/[slug].js78
7 files changed, 149 insertions, 88 deletions
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 }) {
</div>
<div className="my-6 p-4 pt-0">
<h2 className="mb-4">Produk Populer</h2>
- <ProductSlider products={popularProducts} />
+ <ProductSlider products={popularProducts} simpleProductTitleLine />
</div>
{ categoryProducts?.map((categoryProduct, index) => (
@@ -115,7 +115,8 @@ export default function Home({ heroBanners }) {
url: `/shop/search?category=${categoryProduct.name}`
}
} : null}
- bannerMode={true}
+ simpleProductTitleLine
+ bannerMode
/>
</div>
)) }
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 (
<div
key={index}
- className={"p-4 rounded-md border " + (selectedAdress && selectedAdress == address.id ? "border-yellow_r-7 bg-yellow_r-2" : "border-gray_r-7") }
+ className={"p-4 rounded-md border " + (selectedAdress && selectedAdress == address.id ? "border-yellow_r-7 bg-yellow_r-8" : "border-gray_r-7") }
>
<div onClick={() => changeSelectedAddress(address.id)}>
<div className="flex gap-x-2" >
@@ -65,9 +65,13 @@ export default function Address() {
<div className="badge-green">Utama</div>
) }
</div>
- <p className="font-medium mt-1">{ address.name }</p>
- <p className="mt-2 text-gray_r-11">{ address.mobile }</p>
- <p className="mt-1 text-gray_r-11 leading-6">{ address.street } { address.street2 }</p>
+ <p className="font-medium mt-2">{ address.name }</p>
+ { address.mobile && (
+ <p className="mt-2 text-gray_r-11">{ address.mobile }</p>
+ ) }
+ <p className={`mt-1 leading-6 ${selectedAdress && selectedAdress == address.id ? "text-gray_r-12" : "text-gray_r-11"}`}>
+ { address.street }
+ </p>
</div>
<Link href={`/my/address/${address.id}/edit`} className="btn-light mt-3 w-full text-gray_r-11">Ubah Alamat</Link>
</div>
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 (
<WithAuth>
<Layout className="pb-4">
@@ -59,9 +63,9 @@ export default function DetailInvoice() {
</DescriptionRow>
<DescriptionRow label="Status Transaksi">
{ invoice?.amount_residual > 0 ? (
- <span className="badge-red">Belum Lunas</span>
+ <span className="badge-solid-red">Belum Lunas</span>
) : (
- <span className="badge-green">Lunas</span>
+ <span className="badge-solid-green">Lunas</span>
) }
</DescriptionRow>
<DescriptionRow label="Purchase Order">
@@ -81,6 +85,17 @@ export default function DetailInvoice() {
<DescriptionRow label="Tanggal Invoice">
{ invoice?.invoice_date }
</DescriptionRow>
+ <div className="flex items-center">
+ <p className="text-gray_r-11 leading-none">Faktur Pajak</p>
+ <button
+ type="button"
+ className="btn-solid-red py-1 px-2 ml-auto"
+ onClick={downloadTaxInvoice}
+ disabled={invoice.efaktur_token ? false : true}
+ >
+ Download
+ </button>
+ </div>
</div>
<LineDivider />
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() {
</Link>
<div className="flex gap-x-1 justify-end">
{ invoice.amount_residual > 0 ? (
- <div className="badge-red h-fit ml-auto">Belum Lunas</div>
+ <div className="badge-solid-red h-fit ml-auto">Belum Lunas</div>
) : (
- <div className="badge-green h-fit ml-auto">Lunas</div>
+ <div className="badge-solid-green h-fit ml-auto">Lunas</div>
) }
<EllipsisVerticalIcon className="w-5 h-5" onClick={() => {}} />
</div>
@@ -115,6 +115,17 @@ export default function Invoices() {
</div>
</div>
</Link>
+ { invoice.efaktur_token ? (
+ <div className="badge-green h-fit mt-3 ml-auto flex items-center gap-x-0.5">
+ <CheckIcon className="w-4 stroke-2" />
+ Faktur Pajak
+ </div>
+ ) : (
+ <div className="badge-red h-fit mt-3 ml-auto flex items-center gap-x-0.5">
+ <ClockIcon className="w-4 stroke-2" />
+ Faktur Pajak
+ </div>
+ ) }
</div>
)) }
</div>
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() {
<div className="mt-4 text-caption-1">
<p className="font-medium">{ selectedAddress.shipping.name }</p>
<p className="mt-2 text-gray_r-11">{ selectedAddress.shipping.mobile }</p>
- <p className="mt-1 text-gray_r-11">{ selectedAddress.shipping.street }, { selectedAddress.shipping.city.name }</p>
+ <p className="mt-1 text-gray_r-11">{ selectedAddress.shipping.street }, { selectedAddress.shipping?.city?.name }</p>
</div>
) }
</div>
@@ -219,22 +224,26 @@ export default function Checkout() {
<hr className="my-4 border-gray_r-6"/>
<div className="flex flex-col gap-y-4">
<div className="flex gap-x-2 justify-between">
- <p>Subtotal</p>
- <p className="font-medium">{currencyFormat(totalPriceBeforeTax)}</p>
- </div>
- <div className="flex gap-x-2 justify-between">
- <p>PPN 11%</p>
- <p className="font-medium">{currencyFormat(totalTaxAmount)}</p>
+ <p>Total Belanja</p>
+ <p className="font-medium">{currencyFormat(totalAmount)}</p>
</div>
<div className="flex gap-x-2 justify-between">
<p>Total Diskon</p>
<p className="font-medium text-red_r-11">- {currencyFormat(totalDiscountAmount)}</p>
</div>
+ <div className="flex gap-x-2 justify-between">
+ <p>Subtotal</p>
+ <p className="font-medium">{currencyFormat(totalAmount - totalDiscountAmount)}</p>
+ </div>
+ <div className="flex gap-x-2 justify-between">
+ <p>PPN 11% (Incl.)</p>
+ <p className="font-medium">{currencyFormat((totalAmount - totalDiscountAmount) * 0.11)}</p>
+ </div>
</div>
<hr className="my-4 border-gray_r-6"/>
<div className="flex gap-x-2 justify-between mb-4">
<p>Grand Total</p>
- <p className="font-medium text-yellow_r-11">{currencyFormat(totalPriceBeforeTax + totalTaxAmount - totalDiscountAmount)}</p>
+ <p className="font-medium text-yellow_r-11">{currencyFormat(totalAmount - totalDiscountAmount)}</p>
</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">
@@ -285,20 +294,8 @@ export default function Checkout() {
<div className="mt-4 flex gap-x-3">
<div className="w-6/12">
- <label className="form-label font-normal">Nomor PO</label>
- <input
- type="text"
- className="form-input mt-2 h-12"
- value={poNumber}
- onChange={(e) => setPoNumber(e.target.value)}
- />
- </div>
- <div className="w-6/12">
<label className="form-label font-normal">
- File PO
- {auth?.company && (
- <span className="font-normal text-gray_r-11 ml-1">(Wajib diisi)</span>
- )}
+ Dokumen PO
</label>
<input
type="file"
@@ -307,7 +304,17 @@ export default function Checkout() {
onChange={(e) => setPoFile(e.target.files[0])}
/>
</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"
+ value={poNumber}
+ onChange={(e) => setPoNumber(e.target.value)}
+ />
+ </div>
</div>
+ <p className="text-caption-2 text-gray_r-11 mt-2">Ukuran dokumen PO Maksimal 5MB</p>
</div>
<LineDivider/>
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 (
<>
<Header title={`${product.name} - Indoteknik`}/>
@@ -187,36 +204,38 @@ export default function ProductDetail({ product }) {
<LineDivider />
<div className="p-4">
- <div className="flex gap-x-2">
- <div className="w-9/12">
- <label className="form-label mb-1">Pilih: <span className="text-gray_r-11 font-normal">{product.variant_total} Varian</span></label>
- <select name="variant" className="form-input" value={selectedVariant} onChange={onchangeVariant} >
- <option value="" disabled={selectedVariant != "" ? true : false}>Pilih Varian...</option>
- {product.variants.length > 1 ? (
- product.variants.map((variant) => {
- return (
- <option key={variant.id} value={variant.id}>{variant.attributes.join(', ')}</option>
- );
- })
- ) : (
- <option key={product.variants[0].id} value={product.variants[0].id}>{product.variants[0].name}</option>
- )}
- </select>
- </div>
- <div className="w-3/12">
- <label htmlFor="quantity" className="form-label mb-1">Jumlah</label>
- <input type="number" name="quantity" id="quantity" className="form-input text-center is-invalid" value={quantity} onChange={onChangeQuantity} />
- </div>
+ <div className="">
+ <label className="form-label mb-2">Pilih: <span className="text-gray_r-11 font-normal">{product.variant_total} Varian</span></label>
+ <select name="variant" className="form-input" value={selectedVariant} onChange={onchangeVariant} >
+ <option value="" disabled={selectedVariant != "" ? true : false}>Pilih Varian...</option>
+ {product.variants.length > 1 ? (
+ product.variants.map((variant) => {
+ return (
+ <option key={variant.id} value={variant.id}>{variant.attributes.join(', ')}</option>
+ );
+ })
+ ) : (
+ <option key={product.variants[0].id} value={product.variants[0].id}>{product.variants[0].name}</option>
+ )}
+ </select>
</div>
+ <label htmlFor="quantity" className="form-label mb-1 mt-3">Jumlah</label>
<div className="flex gap-x-2 mt-2">
- <button className="btn-light w-full">+ Quotation</button>
+ <input type="number" name="quantity" id="quantity" className="form-input h-full w-5/12 text-center" value={quantity} onChange={onChangeQuantity} />
+
<button
className="btn-yellow w-full"
onClick={addItemToCart}
disabled={(product.lowest_price.price == 0 ? true : false)}
>
- + Keranjang
+ Keranjang
+ </button>
+ <button
+ onClick={checkoutProduct}
+ className="btn-solid-red w-full"
+ >
+ Beli
</button>
</div>
</div>
@@ -230,7 +249,7 @@ export default function ProductDetail({ product }) {
<p className="text-gray-800">{product.variant_total} Varian</p>
</div>
<div className="flex py-2 justify-between items-center gap-x-1">
- <h3 className="text-gray-900">Nomor SKU</h3>
+ <h3 className="text-gray-900">No. SKU</h3>
<p className="text-gray-800" id="sku_number">SKU-{activeVariant.id}</p>
</div>
<div className="flex py-2 justify-between items-center gap-x-1">
@@ -239,9 +258,14 @@ export default function ProductDetail({ product }) {
</div>
<div className="flex py-2 justify-between items-center gap-x-1">
<h3 className="text-gray-900">Stok</h3>
- <p className="text-gray-800" id="stock">
- {activeVariant.stock > 0 ? (activeVariant.stock > 5 ? 'Lebih dari 5' : 'Kurang dari 5') : '0'}
- </p>
+ <div className="flex gap-x-2" id="stock">
+ {activeVariant.stock > 0 ? (activeVariant.stock > 5 && (
+ <>
+ <div className="badge-solid-red">Ready Stock</div>
+ <div className="badge-gray">{activeVariant.stock > 5 ? '> 5' : '< 5'}</div>
+ </>
+ )) : '0'}
+ </div>
</div>
<div className="flex py-2 justify-between items-center gap-x-1">
<h3 className="text-gray-900">Berat Barang</h3>
@@ -259,7 +283,7 @@ export default function ProductDetail({ product }) {
<LineDivider />
<div className="p-4">
- <h2 className="font-bold mb-4">Produk Lainnya</h2>
+ <h2 className="font-bold mb-4">Kamu Mungkin Juga Suka</h2>
<ProductSlider products={similarProducts}/>
</div>