summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRafi Zadanly <zadanlyr@gmail.com>2023-01-25 11:17:37 +0700
committerRafi Zadanly <zadanlyr@gmail.com>2023-01-25 11:17:37 +0700
commitebc09c5062cc7996b0f2aaf879062fc950c2e1c2 (patch)
tree3b031b68afa9aaaca156986382670490c32f0e18 /src
parentee4297280c1305c7e03bedd4df63ccf136c28c6c (diff)
Transaction detail and variant card component
Diffstat (limited to 'src')
-rw-r--r--src/components/elements/DescriptionRow.js10
-rw-r--r--src/components/elements/Disclosure.js14
-rw-r--r--src/components/transactions/TransactionDetail.js21
-rw-r--r--src/components/variants/VariantCard.js48
-rw-r--r--src/pages/my/transactions/[id].js124
-rw-r--r--src/pages/my/transactions/[slug].js126
-rw-r--r--src/pages/shop/checkout.js30
-rw-r--r--src/styles/globals.css4
8 files changed, 227 insertions, 150 deletions
diff --git a/src/components/elements/DescriptionRow.js b/src/components/elements/DescriptionRow.js
new file mode 100644
index 00000000..7fe9e3a1
--- /dev/null
+++ b/src/components/elements/DescriptionRow.js
@@ -0,0 +1,10 @@
+const DescriptionRow = ({ label, children }) => (
+ <div className="grid grid-cols-2">
+ <p className="leading-normal text-gray_r-11">{ label }</p>
+ <div className="text-right leading-normal">
+ { children }
+ </div>
+ </div>
+);
+
+export default DescriptionRow; \ No newline at end of file
diff --git a/src/components/elements/Disclosure.js b/src/components/elements/Disclosure.js
new file mode 100644
index 00000000..0aaedf87
--- /dev/null
+++ b/src/components/elements/Disclosure.js
@@ -0,0 +1,14 @@
+const { ChevronUpIcon, ChevronDownIcon } = require("@heroicons/react/24/outline");
+
+const Disclosure = ({ label, active, onClick }) => (
+ <div className="flex justify-between p-4" onClick={onClick}>
+ <p className="font-medium leading-normal">{ label }</p>
+ { onClick && ( active ? (
+ <ChevronUpIcon className="w-5 h-5" />
+ ) : (
+ <ChevronDownIcon className="w-5 h-5" />
+ ) ) }
+ </div>
+);
+
+export default Disclosure; \ No newline at end of file
diff --git a/src/components/transactions/TransactionDetail.js b/src/components/transactions/TransactionDetail.js
new file mode 100644
index 00000000..6d304d31
--- /dev/null
+++ b/src/components/transactions/TransactionDetail.js
@@ -0,0 +1,21 @@
+import DescriptionRow from "../elements/DescriptionRow";
+
+const CustomerSection = ({ address }) => {
+ const fullAddress = [];
+ if (address?.street) fullAddress.push(address.street);
+ if (address?.sub_district?.name) fullAddress.push(address.sub_district.name);
+ if (address?.district?.name) fullAddress.push(address.district.name);
+ if (address?.city?.name) fullAddress.push(address.city.name);
+ return (
+ <div className="px-4 pb-4 flex flex-col gap-y-4">
+ <DescriptionRow label="Nama">{ address?.name }</DescriptionRow>
+ <DescriptionRow label="Email">{ address?.email || '-' }</DescriptionRow>
+ <DescriptionRow label="No Telepon">{ address?.mobile || '-' }</DescriptionRow>
+ <DescriptionRow label="Alamat">{ fullAddress.join(', ') }</DescriptionRow>
+ </div>
+ );
+};
+
+export {
+ CustomerSection
+}; \ No newline at end of file
diff --git a/src/components/variants/VariantCard.js b/src/components/variants/VariantCard.js
new file mode 100644
index 00000000..cb4d8272
--- /dev/null
+++ b/src/components/variants/VariantCard.js
@@ -0,0 +1,48 @@
+import { createSlug } from "@/core/utils/slug";
+import Image from "../elements/Image";
+import Link from "../elements/Link";
+import currencyFormat from "@/core/utils/currencyFormat";
+
+export default function VariantCard({
+ data,
+ openOnClick = true
+}) {
+ let product = data;
+
+ const Card = () => (
+ <div className="flex gap-x-3">
+ <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>
+ );
+
+ if (openOnClick) {
+ return (
+ <Link href={'/shop/product/' + createSlug(product.parent.name, product.parent.id)}>
+ <Card />
+ </Link>
+ );
+ }
+
+ return <Card/>;
+} \ No newline at end of file
diff --git a/src/pages/my/transactions/[id].js b/src/pages/my/transactions/[id].js
new file mode 100644
index 00000000..79337a29
--- /dev/null
+++ b/src/pages/my/transactions/[id].js
@@ -0,0 +1,124 @@
+import AppBar from "@/components/layouts/AppBar";
+import Layout from "@/components/layouts/Layout";
+import LineDivider from "@/components/elements/LineDivider";
+import WithAuth from "@/components/auth/WithAuth";
+import { useEffect, useState } from "react";
+import apiOdoo from "@/core/utils/apiOdoo";
+import { useRouter } from "next/router";
+import { useAuth } from "@/core/utils/auth";
+import VariantCard from "@/components/variants/VariantCard";
+import currencyFormat from "@/core/utils/currencyFormat";
+import Disclosure from "@/components/elements/Disclosure";
+import DescriptionRow from "@/components/elements/DescriptionRow";
+import { CustomerSection } from "@/components/transactions/TransactionDetail";
+
+export default function DetailTransactions() {
+ const router = useRouter();
+ const { id } = router.query;
+ const [ auth ] = useAuth();
+ const [ transaction, setTransaction ] = useState(null);
+ const [ activeSection, setActiveSection ] = useState({
+ purchase: false,
+ shipping: false,
+ invoice: false,
+ });
+
+ const toggleSection = ( name ) => {
+ setActiveSection({
+ ...activeSection,
+ [name]: !activeSection[name]
+ });
+ };
+
+ useEffect(() => {
+ if (auth) {
+ const loadTransaction = async () => {
+ const dataTransaction = await apiOdoo('GET', `/api/v1/partner/${auth?.partner_id}/sale_order/${id}`);
+ setTransaction(dataTransaction);
+ }
+ loadTransaction();
+ }
+ }, [ auth, id ]);
+
+ return (
+ <WithAuth>
+ <Layout className="pb-4">
+ <AppBar title="Detail Transaksi" />
+
+ <div className="p-4 flex flex-col gap-y-4">
+ <DescriptionRow label="Status Transaksi">
+ <span className="badge-green">Pending Quotation</span>
+ </DescriptionRow>
+ <DescriptionRow label="No Transaksi">
+ { transaction?.name }
+ </DescriptionRow>
+ <DescriptionRow label="Purchase Order">
+ { transaction?.po_name || '-' }
+ </DescriptionRow>
+ <DescriptionRow label="Ketentuan Pembayaran">
+ { transaction?.payment_term }
+ </DescriptionRow>
+ <DescriptionRow label="Nama Sales">
+ { transaction?.sales }
+ </DescriptionRow>
+ <DescriptionRow label="Waktu Transaksi">
+ { transaction?.date_order }
+ </DescriptionRow>
+ </div>
+
+ <LineDivider />
+
+ <Disclosure
+ label="Detail Produk"
+ />
+
+ <div className="mt-2 p-4 pt-0 flex flex-col gap-y-3">
+ { transaction?.products?.map((product, index) => (
+ <VariantCard
+ key={index}
+ data={product}
+ />
+ )) }
+ <div className="flex justify-between mt-3 font-medium">
+ <p>Total Belanja</p>
+ <p>{ currencyFormat(transaction?.amount_total || 0) }</p>
+ </div>
+ </div>
+
+
+ <LineDivider />
+
+ <Disclosure
+ label="Detail Pembeli"
+ active={activeSection.purchase}
+ onClick={() => toggleSection('purchase')}
+ />
+ { activeSection.purchase && (
+ <CustomerSection address={transaction?.address?.customer} />
+ ) }
+
+ <LineDivider />
+
+ <Disclosure
+ label="Detail Pengiriman"
+ active={activeSection.shipping}
+ onClick={() => toggleSection('shipping')}
+ />
+ { activeSection.shipping && (
+ <CustomerSection address={transaction?.address?.shipping} />
+ ) }
+
+ <LineDivider />
+
+ <Disclosure
+ label="Detail Penagihan"
+ active={activeSection.invoice}
+ onClick={() => toggleSection('invoice')}
+ />
+ { activeSection.invoice && (
+ <CustomerSection address={transaction?.address?.invoice} />
+ ) }
+ </Layout>
+ </WithAuth>
+ );
+} \ No newline at end of file
diff --git a/src/pages/my/transactions/[slug].js b/src/pages/my/transactions/[slug].js
deleted file mode 100644
index a76b0c4d..00000000
--- a/src/pages/my/transactions/[slug].js
+++ /dev/null
@@ -1,126 +0,0 @@
-import { ArrowDownOnSquareIcon, ArrowDownTrayIcon, ChevronDownIcon, ChevronRightIcon, ChevronUpIcon } from "@heroicons/react/24/outline";
-import AppBar from "@/components/layouts/AppBar";
-import Layout from "@/components/layouts/Layout";
-import LineDivider from "@/components/elements/LineDivider";
-import WithAuth from "@/components/auth/WithAuth";
-import { useState } from "react";
-
-const Row = ({ label, children }) => (
- <div className="grid grid-cols-2">
- <p className="leading-normal text-gray_r-11">{ label }</p>
- <div className="text-right leading-normal">
- { children }
- </div>
- </div>
-);
-
-const Section = ({ children }) => (
- <div className="px-4 pb-4 flex flex-col gap-y-4">
- { children }
- </div>
-);
-
-const TitleRow = ({ label, active, onClick }) => (
- <div className="flex justify-between p-4" onClick={onClick}>
- <p className="font-medium leading-normal">{ label }</p>
- { onClick && ( active ? (
- <ChevronUpIcon className="w-5 h-5" />
- ) : (
- <ChevronDownIcon className="w-5 h-5" />
- ) ) }
- </div>
-);
-
-export default function DetailTransactions() {
- const [ activeSection, setActiveSection ] = useState({
- purchase: false,
- shipping: false,
- invoice: false,
- });
-
- const toggleSection = ( name ) => {
- setActiveSection({
- ...activeSection,
- [name]: !activeSection[name]
- });
- };
-
- return (
- <WithAuth>
- <Layout>
- <AppBar title="Detail Transaksi" />
-
- <div className="text-caption-1">
- <div className="p-4 flex flex-col gap-y-4">
- <Row label="Status Transaksi">
- <span className="badge-green">Pending Quotation</span>
- </Row>
- <Row label="No Transaksi">SO/2023/03212</Row>
- <Row label="Purchase Order">PO/2023/02123</Row>
- <Row label="Dokumen PO"><a href="">Download</a></Row>
- <Row label="Metode Pembayaran">BCA Transfer</Row>
- <Row label="Ketentuan Pembayaran">Cash Before Delivery</Row>
- <Row label="Nama Sales">Rafi Zadanly</Row>
- <Row label="Waktu Transaksi">01 Januari 2023</Row>
- </div>
-
- <LineDivider />
-
- <TitleRow
- label="Detail Produk"
- active={false}
- />
-
- <LineDivider />
-
- <TitleRow
- label="Detail Pembeli"
- active={activeSection.purchase}
- onClick={() => toggleSection('purchase')}
- />
- { activeSection.purchase && (
- <Section>
- <Row label="Nama">John Doe</Row>
- <Row label="Email">johndoe@gmail.com</Row>
- <Row label="No Telepon">081223538754</Row>
- <Row label="Alamat">Jalan Bandengan Utara No 85A, Kel. Penjaringan, Kec. Penjaringan, Jakarta Utara</Row>
- </Section>
- ) }
-
- <LineDivider />
-
- <TitleRow
- label="Detail Pengiriman"
- active={activeSection.shipping}
- onClick={() => toggleSection('shipping')}
- />
- { activeSection.shipping && (
- <Section>
- <Row label="Nama">John Doe</Row>
- <Row label="Email">johndoe@gmail.com</Row>
- <Row label="No Telepon">081223538754</Row>
- <Row label="Alamat">Jalan Bandengan Utara No 85A, Kel. Penjaringan, Kec. Penjaringan, Jakarta Utara</Row>
- </Section>
- ) }
-
- <LineDivider />
-
- <TitleRow
- label="Detail Penagihan"
- active={activeSection.invoice}
- onClick={() => toggleSection('invoice')}
- />
- { activeSection.invoice && (
- <Section>
- <Row label="Nama">John Doe</Row>
- <Row label="Email">johndoe@gmail.com</Row>
- <Row label="No Telepon">081223538754</Row>
- <Row label="Alamat">Jalan Bandengan Utara No 85A, Kel. Penjaringan, Kec. Penjaringan, Jakarta Utara</Row>
- </Section>
- ) }
-
- </div>
- </Layout>
- </WithAuth>
- );
-} \ No newline at end of file
diff --git a/src/pages/shop/checkout.js b/src/pages/shop/checkout.js
index 1849e0fe..49d1a848 100644
--- a/src/pages/shop/checkout.js
+++ b/src/pages/shop/checkout.js
@@ -17,6 +17,7 @@ import { useRouter } from "next/router";
import WithAuth from "@/components/auth/WithAuth";
import { toast } from "react-hot-toast";
import getFileBase64 from "@/core/utils/getFileBase64";
+import VariantCard from "@/components/variants/VariantCard";
export default function Checkout() {
const router = useRouter();
@@ -201,30 +202,11 @@ export default function Checkout() {
<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>
+ <VariantCard
+ data={product}
+ openOnClick={false}
+ key={index}
+ />
))}
</div>
diff --git a/src/styles/globals.css b/src/styles/globals.css
index 6c0a7607..e43ad1a9 100644
--- a/src/styles/globals.css
+++ b/src/styles/globals.css
@@ -4,6 +4,10 @@
@tailwind components;
@tailwind utilities;
+* {
+ -webkit-tap-highlight-color: transparent;
+}
+
html, body {
@apply
w-screen