summaryrefslogtreecommitdiff
path: root/src/pages
diff options
context:
space:
mode:
authorRafi Zadanly <zadanlyr@gmail.com>2023-01-09 12:08:27 +0700
committerRafi Zadanly <zadanlyr@gmail.com>2023-01-09 12:08:27 +0700
commitbd1e930f875e942ee8a60718a3c1268a62598266 (patch)
tree6c6ca1d56fd257b33425c25fe2aa75623bddcbe9 /src/pages
parentdb76cfe50ea485333f9aab8e3580ac7b352350ed (diff)
checkout to odoo, select address
Diffstat (limited to 'src/pages')
-rw-r--r--src/pages/my/address/index.js28
-rw-r--r--src/pages/shop/cart.js14
-rw-r--r--src/pages/shop/checkout.js362
3 files changed, 254 insertions, 150 deletions
diff --git a/src/pages/my/address/index.js b/src/pages/my/address/index.js
index cac6e8f6..b97e21e7 100644
--- a/src/pages/my/address/index.js
+++ b/src/pages/my/address/index.js
@@ -5,10 +5,15 @@ import Link from "../../../components/Link";
import WithAuth from "../../../components/WithAuth";
import apiOdoo from "../../../helpers/apiOdoo";
import { useAuth } from "../../../helpers/auth";
+import { useRouter } from "next/router";
+import { createOrUpdateItemAddress, getItemAddress } from "../../../helpers/address";
export default function Address() {
- const [auth] = useAuth();
- const [addresses, setAddresses] = useState(null);
+ const router = useRouter();
+ const { select } = router.query;
+ const [ auth ] = useAuth();
+ const [ addresses, setAddresses ] = useState(null);
+ const [ selectedAdress, setSelectedAdress ] = useState(null);
useEffect(() => {
const getAddress = async () => {
@@ -20,6 +25,19 @@ export default function Address() {
getAddress();
}, [auth]);
+ useEffect(() => {
+ if (select) {
+ setSelectedAdress(getItemAddress(select));
+ }
+ }, [select]);
+
+ const changeSelectedAddress = (id) => {
+ if (select) {
+ createOrUpdateItemAddress(select, id);
+ router.back();
+ }
+ };
+
return (
<WithAuth>
<Layout>
@@ -31,7 +49,11 @@ export default function Address() {
<div className="grid gap-y-4 p-4">
{ addresses && addresses.map((address, index) => (
- <div className="p-4 rounded-md border border-gray_r-7" key={index}>
+ <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") }
+ onClick={() => changeSelectedAddress(address.id)}
+ >
<p className="font-medium">{ address.name }</p>
<p className="mt-3 text-gray_r-11">{ address.mobile }</p>
<p className="mt-1 text-gray_r-11 leading-6">{ address.street } { address.street2 }</p>
diff --git a/src/pages/shop/cart.js b/src/pages/shop/cart.js
index eb295c1f..e480d117 100644
--- a/src/pages/shop/cart.js
+++ b/src/pages/shop/cart.js
@@ -187,12 +187,14 @@ export default function Cart() {
<LineDivider/>
{/* --- Start Alert */}
- <Alert type="warning" className="text-caption-2 flex gap-x-3 items-center my-2">
- <div>
- <ExclamationCircleIcon className="w-8 text-yellow_r-11"/>
- </div>
- <span>Mohon dicek kembali & pastikan pesanan kamu sudah sesuai dengan yang kamu butuhkan. Atau bisa hubungi kami.</span>
- </Alert>
+ <div className="p-4">
+ <Alert type="warning" className="text-caption-2 flex gap-x-3 items-center">
+ <div>
+ <ExclamationCircleIcon className="w-8 text-yellow_r-11"/>
+ </div>
+ <span>Mohon dicek kembali & pastikan pesanan kamu sudah sesuai dengan yang kamu butuhkan. Atau bisa hubungi kami.</span>
+ </Alert>
+ </div>
{/* ---- End Alert */}
<LineDivider/>
diff --git a/src/pages/shop/checkout.js b/src/pages/shop/checkout.js
index 54b9d598..a72b8976 100644
--- a/src/pages/shop/checkout.js
+++ b/src/pages/shop/checkout.js
@@ -1,6 +1,5 @@
import { ExclamationCircleIcon } from "@heroicons/react/24/solid";
import { useEffect, useState } from "react";
-import { toast } from "react-hot-toast";
import Alert from "../../components/Alert";
import AppBar from "../../components/AppBar";
import Image from "../../components/Image";
@@ -11,21 +10,28 @@ import ProgressBar from "../../components/ProgressBar";
import Spinner from "../../components/Spinner";
import apiOdoo from "../../helpers/apiOdoo";
import { useAuth } from "../../helpers/auth";
-import { getCart } from "../../helpers/cart";
+import { deleteItemCart, getCart } from "../../helpers/cart";
import currencyFormat from "../../helpers/currencyFormat";
-import { createSlug } from "../../helpers/slug";
-
+import { getItemAddress } from "../../helpers/address";
+import { useRouter } from "next/router";
+import WithAuth from "../../components/WithAuth";
+import { toast } from "react-hot-toast";
export default function Checkout() {
+ const router = useRouter();
const [auth] = useAuth();
- const [address, setAddress] = useState(null);
- const [selectedAddress, setSelectedAddress] = useState(null);
+ const [addresses, setAddresses] = useState(null);
+ const [selectedAddress, setSelectedAddress] = useState({
+ shipping: null,
+ invoicing: null
+ });
const [selectedPayment, setSelectedPayment] = useState(null);
const [products, setProducts] = useState(null);
const [totalPriceBeforeTax, setTotalPriceBeforeTax] = useState(0);
const [totalTaxAmount, setTotalTaxAmount] = useState(0);
const [totalDiscountAmount, setTotalDiscountAmount] = useState(0);
const [isLoading, setIsLoading] = useState(true);
+ const [finishCheckout, setFinishCheckout] = useState(null);
const payments = [
{ name: 'BCA', number: '8870-4000-81' },
@@ -33,13 +39,13 @@ export default function Checkout() {
];
useEffect(() => {
- const getAddress = async () => {
+ const getAddresses = async () => {
if (auth) {
- const dataAddress = await apiOdoo('GET', `/api/v1/user/${auth.id}/address`);
- setAddress(dataAddress);
+ const dataAddresses = await apiOdoo('GET', `/api/v1/user/${auth.id}/address`);
+ setAddresses(dataAddresses);
}
};
- getAddress();
+ getAddresses();
}, [auth]);
useEffect(() => {
@@ -58,14 +64,29 @@ export default function Checkout() {
selected: cart[product.id].selected,
}));
setProducts(dataProducts);
+ } else {
+ if (auth) router.push('/shop/cart');
}
};
getProducts();
- }, []);
+ }, [router, auth]);
useEffect(() => {
- if (address) setSelectedAddress(address[0]);
- }, [address]);
+ if (addresses) {
+ const matchAddress = (key) => {
+ const addressToMatch = getItemAddress(key);
+ let 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]);
useEffect(() => {
if (products) {
@@ -86,147 +107,206 @@ export default function Checkout() {
}, [products]);
useEffect(() => {
- if (address && products) setIsLoading(false);
- }, [address, products]);
+ if (addresses && products) setIsLoading(false);
+ }, [addresses, products]);
+
+ const submit = async () => {
+ if (!selectedPayment) {
+ toast.error('Mohon pilih metode pembayaran terlebih dahulu', {
+ position: 'bottom-center'
+ });
+ return;
+ }
+ let productOrder = products.map((product) => ({ 'product_id': product.id, 'quantity': product.quantity }));
+ let data = {
+ 'user_id': auth.id,
+ 'partner_id': auth.partner_id,
+ 'partner_shipping_id': selectedAddress.shipping.id,
+ 'partner_invoice_id': selectedAddress.invoicing.id,
+ 'order_line': JSON.stringify(productOrder)
+ }
+ const checkoutToOdoo = await apiOdoo('POST', '/api/v1/sale_order/checkout', data);
+ for (const product of products) {
+ deleteItemCart(product.id);
+ }
+ setFinishCheckout(checkoutToOdoo);
+ }
return (
- <Layout>
- <AppBar title="Checkout" />
-
- {isLoading && (
- <div className="flex justify-center items-center gap-x-3 mt-14">
- <Spinner className="w-10 text-gray_r-8 fill-gray_r-12" />
- </div>
- )}
-
- { products && address && (
- <>
- <ProgressBar
- current={2}
- labels={['Keranjang', 'Pembayaran', 'Selesai']}
- />
-
- <LineDivider/>
-
- <Alert type="info" className="text-caption-2 flex gap-x-3 items-center my-2">
- <div>
- <ExclamationCircleIcon className="w-6 text-blue-700"/>
+ <WithAuth>
+ <Layout>
+ <AppBar title={finishCheckout ? "Pembelian Berhasil" : "Checkout"} />
+
+ { finishCheckout ? (
+ <div className="m-4 rounded-xl bg-yellow_r-4 text-center border border-yellow_r-7">
+ <div className="px-4 py-6">
+ <p className="h2 mb-2">Terima Kasih atas Pembelian Anda</p>
+ <p className="text-gray_r-11 mb-4">Details pembelian sudah kami kirimkan melalui email anda. Mohon dicek kembali. jika tidak menerima email anda dapat menghubungi kami disini.</p>
+ <p className="mb-2 font-medium">{ finishCheckout.name }</p>
+ <p className="text-caption-2 text-gray_r-11">No. Transaksi</p>
</div>
- <span>Jika mengalami kesulitan dalam melakukan pembelian di website Indoteknik. Hubungi kami disini</span>
- </Alert>
+ <div className="bg-yellow_r-6 rounded-b-xl py-4">
+ Mohon konfirmasi pembelian Anda disini
+ </div>
+ </div>
+ ) : (
+ <>
+ {isLoading && (
+ <div className="flex justify-center items-center gap-x-3 mt-14">
+ <Spinner className="w-10 text-gray_r-8 fill-gray_r-12" />
+ </div>
+ )}
- <LineDivider/>
+ { products && addresses && (
+ <>
+ <ProgressBar
+ current={2}
+ labels={['Keranjang', 'Pembayaran', 'Selesai']}
+ />
- <div className="p-4">
- <div className="flex justify-between items-center">
- <h2>Alamat Pengiriman</h2>
- <Link className="text-caption-1" href="/">Ubah Alamat</Link>
- </div>
+ <LineDivider/>
- { selectedAddress && (
- <div className="mt-4 text-caption-1">
- <p className="font-medium">{ selectedAddress.name }</p>
- <p className="mt-2 text-gray_r-11">{ selectedAddress.mobile }</p>
- <p className="mt-1 text-gray_r-11">{ selectedAddress.street } { selectedAddress.street2 }</p>
- </div>
- ) }
- </div>
+ <div className="p-4">
+ <Alert type="info" className="text-caption-2 flex gap-x-3 items-center">
+ <div>
+ <ExclamationCircleIcon className="w-6 text-blue-700"/>
+ </div>
+ <span>Jika mengalami kesulitan dalam melakukan pembelian di website Indoteknik. Hubungi kami disini</span>
+ </Alert>
+ </div>
+
+ <LineDivider/>
- <LineDivider/>
-
- <div className="p-4 flex flex-col gap-y-4">
- {products.map((product, index) => (
- <div className="flex gap-x-3" key={index}>
- <div className="w-4/12 flex items-center gap-x-2">
- <Image
- src={product.parent.image}
- alt={product.parent.name}
- className="object-contain object-center border border-gray_r-6 h-32 w-full rounded-md"
- />
+ <div className="p-4">
+ <div className="flex justify-between items-center">
+ <h2>Alamat Pengiriman</h2>
+ <Link className="text-caption-1" href="/my/address?select=shipping">Pilih Alamat Lain</Link>
+ </div>
+
+ { selectedAddress.shipping && (
+ <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.street2 }</p>
+ </div>
+ ) }
</div>
- <div className="w-8/12 flex flex-col">
- <p className="product-card__title wrap-line-ellipsis-2">
- {product.parent.name}
- </p>
- <p className="text-caption-2 text-gray_r-11 mt-1">
- {product.code || '-'}
- {product.attributes.length > 0 ? ` | ${product.attributes.join(', ')}` : ''}
- </p>
- <p className="text-caption-2 text-gray_r-11 mt-1">
- {currencyFormat(product.price.price_discount)} × {product.quantity} Barang
- </p>
- <p className="text-caption-2 text-gray_r-12 font-bold mt-2">
- {currencyFormat(product.quantity * product.price.price_discount)}
+
+ <LineDivider/>
+
+ <div className="p-4 flex flex-col gap-y-4">
+ {products.map((product, index) => (
+ <div className="flex gap-x-3" key={index}>
+ <div className="w-4/12 flex items-center gap-x-2">
+ <Image
+ src={product.parent.image}
+ alt={product.parent.name}
+ className="object-contain object-center border border-gray_r-6 h-32 w-full rounded-md"
+ />
+ </div>
+ <div className="w-8/12 flex flex-col">
+ <p className="product-card__title wrap-line-ellipsis-2">
+ {product.parent.name}
+ </p>
+ <p className="text-caption-2 text-gray_r-11 mt-1">
+ {product.code || '-'}
+ {product.attributes.length > 0 ? ` | ${product.attributes.join(', ')}` : ''}
+ </p>
+ <p className="text-caption-2 text-gray_r-11 mt-1">
+ {currencyFormat(product.price.price_discount)} × {product.quantity} Barang
+ </p>
+ <p className="text-caption-2 text-gray_r-12 font-bold mt-2">
+ {currencyFormat(product.quantity * product.price.price_discount)}
+ </p>
+ </div>
+ </div>
+ ))}
+ </div>
+
+ <LineDivider/>
+
+ <div className="p-4">
+ <div className="flex justify-between items-center">
+ <h2>Ringkasan Pesanan</h2>
+ <p className="text-gray_r-11 text-caption-1">{products.length} Barang</p>
+ </div>
+ <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>
+ </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>
+ <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>
+ </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">
+ Dengan melakukan pembelian melalui website Indoteknik, saya menyetujui <Link href="/">Syarat & Ketentuan</Link> yang berlaku
</p>
</div>
- </div>
- ))}
- </div>
- <LineDivider/>
-
- <div className="p-4">
- <div className="flex justify-between items-center">
- <h2>Ringkasan Pesanan</h2>
- <p className="text-gray_r-11 text-caption-1">{products.length} Barang</p>
- </div>
- <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>
- </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>
- <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>
- </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">
- Dengan melakukan pembelian melalui website Indoteknik, saya menyetujui <Link href="/">Syarat & Ketentuan</Link> yang berlaku
- </p>
- </div>
+ <LineDivider/>
- <LineDivider/>
-
- <div className="p-4">
- <h2>Pilih Metode Pembayaran</h2>
- <div className="grid gap-y-3 mt-4">
- { payments.map((payment, index) => (
- <button
- type="button"
- className={"text-left border border-gray_r-6 rounded-md p-3 " + (selectedPayment == payment.name && 'border-yellow_r-10 bg-yellow_r-3')}
- onClick={() => setSelectedPayment(payment.name)}
- key={index}
- >
- <p>{payment.name} - {payment.number}</p>
- <p className="mt-1 text-gray_r-11">PT. Indoteknik Dotcom Gemilang</p>
- </button>
- )) }
- </div>
- </div>
+ <div className="p-4">
+ <div className="flex justify-between items-center">
+ <h2>Alamat Penagihan</h2>
+ <Link className="text-caption-1" href="/my/address?select=invoicing">Pilih Alamat Lain</Link>
+ </div>
- <LineDivider/>
+ { selectedAddress.invoicing && (
+ <div className="mt-4 text-caption-1">
+ <p className="font-medium">{ selectedAddress.invoicing.name }</p>
+ <p className="mt-2 text-gray_r-11">{ selectedAddress.invoicing.mobile }</p>
+ <p className="mt-1 text-gray_r-11">{ selectedAddress.invoicing.street } { selectedAddress.invoicing.street2 }</p>
+ </div>
+ ) }
+ </div>
- <div className="flex gap-x-3 p-4">
- <button
- className="flex-1 btn-yellow"
- onClick={() => router.push('/shop/checkout')}
- >
- Bayar
- </button>
- </div>
- </>
- ) }
- </Layout>
+ <LineDivider/>
+
+ <div className="p-4">
+ <h2>Pilih Metode Pembayaran</h2>
+ <div className="grid gap-y-3 mt-4">
+ { payments.map((payment, index) => (
+ <button
+ type="button"
+ className={"text-left border border-gray_r-6 rounded-md p-3 " + (selectedPayment == payment.name && 'border-yellow_r-10 bg-yellow_r-3')}
+ onClick={() => setSelectedPayment(payment.name)}
+ key={index}
+ >
+ <p>{payment.name} - {payment.number}</p>
+ <p className="mt-1 text-gray_r-11">PT. Indoteknik Dotcom Gemilang</p>
+ </button>
+ )) }
+ </div>
+ </div>
+
+ <LineDivider/>
+
+ <div className="flex gap-x-3 p-4">
+ <button
+ className="flex-1 btn-yellow"
+ onClick={submit}
+ >
+ Bayar
+ </button>
+ </div>
+ </>
+ ) }
+ </>
+ ) }
+ </Layout>
+ </WithAuth>
)
} \ No newline at end of file