summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafi Zadanly <zadanlyr@gmail.com>2023-02-21 16:25:35 +0700
committerRafi Zadanly <zadanlyr@gmail.com>2023-02-21 16:25:35 +0700
commitde7361718def0f6bb32294bb074841ba2c0a3ce6 (patch)
tree9265f358f5dfa496dbb564c357e89d7c7d4e0cd7
parent3f2ff1475676ba47a841796e39e7d17d627e5356 (diff)
fix
-rw-r--r--src/core/components/elements/Appbar/Appbar.jsx2
-rw-r--r--src/lib/invoice/api/invoiceApi.js10
-rw-r--r--src/lib/invoice/api/invoicesApi.js10
-rw-r--r--src/lib/invoice/components/Invoice.jsx126
-rw-r--r--src/lib/invoice/components/Invoices.jsx157
-rw-r--r--src/lib/invoice/hooks/useInvoice.js13
-rw-r--r--src/lib/invoice/hooks/useInvoices.js15
-rw-r--r--src/lib/invoice/utils/invoices.js14
-rw-r--r--src/lib/transaction/components/Transaction.jsx377
-rw-r--r--src/lib/transaction/components/Transactions.jsx133
-rw-r--r--src/pages/my/invoice/[id].jsx13
-rw-r--r--src/pages/my/invoices.jsx10
-rw-r--r--src/pages/my/menu.jsx4
13 files changed, 624 insertions, 260 deletions
diff --git a/src/core/components/elements/Appbar/Appbar.jsx b/src/core/components/elements/Appbar/Appbar.jsx
index 8fa5a2a7..36df9edb 100644
--- a/src/core/components/elements/Appbar/Appbar.jsx
+++ b/src/core/components/elements/Appbar/Appbar.jsx
@@ -11,7 +11,7 @@ const AppBar = ({ title }) => {
<button type="button" className="p-4" onClick={() => router.back()}>
<ChevronLeftIcon className="w-6 stroke-2" />
</button>
- <div className="font-semibold text-h-md">
+ <div className="font-medium text-h-sm line-clamp-1">
{ title }
</div>
</div>
diff --git a/src/lib/invoice/api/invoiceApi.js b/src/lib/invoice/api/invoiceApi.js
new file mode 100644
index 00000000..f9bacf8e
--- /dev/null
+++ b/src/lib/invoice/api/invoiceApi.js
@@ -0,0 +1,10 @@
+import odooApi from "@/core/api/odooApi"
+import { getAuth } from "@/core/utils/auth"
+
+const invoiceApi = async ({ id }) => {
+ const auth = getAuth()
+ const dataInvoice = await odooApi('GET', `/api/v1/partner/${auth.partnerId}/invoice/${id}`)
+ return dataInvoice
+}
+
+export default invoiceApi \ No newline at end of file
diff --git a/src/lib/invoice/api/invoicesApi.js b/src/lib/invoice/api/invoicesApi.js
new file mode 100644
index 00000000..4e842f55
--- /dev/null
+++ b/src/lib/invoice/api/invoicesApi.js
@@ -0,0 +1,10 @@
+import odooApi from "@/core/api/odooApi"
+import { getAuth } from "@/core/utils/auth"
+
+const invoicesApi = async ({ query }) => {
+ const auth = getAuth()
+ const dataInvoices = await odooApi('GET', `/api/v1/partner/${auth.partnerId}/invoice?${query}`)
+ return dataInvoices
+}
+
+export default invoicesApi \ No newline at end of file
diff --git a/src/lib/invoice/components/Invoice.jsx b/src/lib/invoice/components/Invoice.jsx
new file mode 100644
index 00000000..de6eacca
--- /dev/null
+++ b/src/lib/invoice/components/Invoice.jsx
@@ -0,0 +1,126 @@
+import Spinner from "@/core/components/elements/Spinner/Spinner"
+import useInvoice from "../hooks/useInvoice"
+import { downloadInvoice, downloadTaxInvoice } from "../utils/invoices"
+import Divider from "@/core/components/elements/Divider/Divider"
+import VariantGroupCard from "@/lib/variant/components/VariantGroupCard"
+import currencyFormat from "@/core/utils/currencyFormat"
+
+const Invoice = ({ id }) => {
+ const { invoice } = useInvoice({ id })
+
+ if (invoice.isLoading) {
+ return (
+ <div className="flex justify-center my-4">
+ <Spinner className="w-6 text-gray_r-12/50 fill-gray_r-12" />
+ </div>
+ )
+ }
+
+ const address = invoice.data?.customer
+ let fullAddress = []
+ if (address?.street) fullAddress.push(address.street)
+ if (address?.subDistrict?.name) fullAddress.push(address.subDistrict.name)
+ if (address?.district?.name) fullAddress.push(address.district.name)
+ if (address?.city?.name) fullAddress.push(address.city.name)
+ fullAddress = fullAddress.join(', ')
+
+ return invoice.data?.name && (
+ <>
+ <div className="flex flex-col gap-y-4 p-4">
+ <DescriptionRow label="No Invoice">
+ { invoice.data?.name }
+ </DescriptionRow>
+ <DescriptionRow label="Status Transaksi">
+ { invoice.data?.amountResidual > 0 ? (
+ <span className="badge-solid-red">Belum Lunas</span>
+ ) : (
+ <span className="badge-solid-green">Lunas</span>
+ ) }
+ </DescriptionRow>
+ <DescriptionRow label="Purchase Order">
+ { invoice.data?.purchaseOrderName || '-' }
+ </DescriptionRow>
+ <DescriptionRow label="Ketentuan Pembayaran">
+ { invoice.data?.paymentTerm }
+ </DescriptionRow>
+ { invoice.data?.amountResidual > 0 && invoice.invoiceDate != invoice.invoiceDateDue && (
+ <DescriptionRow label="Tanggal Jatuh Tempo">
+ { invoice.data?.invoiceDateDue }
+ </DescriptionRow>
+ ) }
+ <DescriptionRow label="Nama Sales">
+ { invoice.data?.sales }
+ </DescriptionRow>
+ <DescriptionRow label="Tanggal Invoice">
+ { invoice.data?.invoiceDate }
+ </DescriptionRow>
+ <div className="flex items-center">
+ <p className="text-gray_r-11 leading-none">Faktur Pembelian</p>
+ <button
+ type="button"
+ className="btn-light py-1.5 px-3 ml-auto"
+ onClick={() => downloadInvoice(invoice.data)}
+ >
+ Download
+ </button>
+ </div>
+ <div className="flex items-center">
+ <p className="text-gray_r-11 leading-none">Faktur Pajak</p>
+ <button
+ type="button"
+ className="btn-light py-1.5 px-3 ml-auto"
+ onClick={() => downloadTaxInvoice(invoice.data)}
+ disabled={!invoice.data?.efaktur}
+ >
+ Download
+ </button>
+ </div>
+ </div>
+
+ <Divider />
+
+ <div className="p-4 font-medium">
+ Detail Penagihan
+ </div>
+
+ <div className="flex flex-col gap-y-4 p-4 border-t border-gray_r-6">
+ <DescriptionRow label="Nama">
+ { address?.name }
+ </DescriptionRow>
+ <DescriptionRow label="Email">
+ { address?.email || '-' }
+ </DescriptionRow>
+ <DescriptionRow label="No Telepon">
+ { address?.mobile || '-' }
+ </DescriptionRow>
+ <DescriptionRow label="Alamat">
+ { fullAddress }
+ </DescriptionRow>
+ </div>
+
+ <Divider />
+
+ <div className="font-medium p-4">Detail Produk</div>
+
+ <div className="p-4 pt-0 flex flex-col gap-y-3">
+ <VariantGroupCard
+ variants={invoice.data?.products}
+ buyMore
+ />
+ <div className="flex justify-between mt-3 font-medium">
+ <p>Total Belanja</p>
+ <p>{ currencyFormat(invoice.data?.amountTotal) }</p>
+ </div>
+ </div>
+ </>
+ )
+}
+
+const DescriptionRow = ({ children, label }) => (
+ <div className="grid grid-cols-2">
+ <span className="text-gray_r-11">{ label }</span>
+ <span className="text-right">{ children }</span>
+ </div>
+)
+
+export default Invoice \ No newline at end of file
diff --git a/src/lib/invoice/components/Invoices.jsx b/src/lib/invoice/components/Invoices.jsx
new file mode 100644
index 00000000..3b1e71e3
--- /dev/null
+++ b/src/lib/invoice/components/Invoices.jsx
@@ -0,0 +1,157 @@
+import { CheckIcon, ClockIcon, EllipsisVerticalIcon, MagnifyingGlassIcon } from "@heroicons/react/24/outline"
+import { toQuery } from "lodash-contrib"
+import _ from "lodash"
+import { useRouter } from "next/router"
+import { useState } from "react"
+import useInvoices from "../hooks/useInvoices"
+import Spinner from "@/core/components/elements/Spinner/Spinner"
+import Alert from "@/core/components/elements/Alert/Alert"
+import Pagination from "@/core/components/elements/Pagination/Pagination"
+import Link from "@/core/components/elements/Link/Link"
+import currencyFormat from "@/core/utils/currencyFormat"
+import BottomPopup from "@/core/components/elements/Popup/BottomPopup"
+import { downloadInvoice, downloadTaxInvoice } from "../utils/invoices"
+
+const Invoices = () => {
+ const router = useRouter()
+ const {
+ q = '',
+ page = 1
+ } = router.query
+
+ const limit = 10
+
+ const query = {
+ name: q,
+ offset: (page - 1) * limit,
+ limit
+ }
+ const { invoices } = useInvoices({ query })
+
+ const [ inputQuery, setInputQuery ] = useState(q)
+ const [ toOthers, setToOthers ] = useState(null)
+
+ const pageCount = Math.ceil(invoices?.data?.saleOrderTotal / limit)
+ let pageQuery = _.omit(query, ['limit', 'offset'])
+ pageQuery = _.pickBy(pageQuery, _.identity)
+ pageQuery = toQuery(pageQuery)
+
+ const handleSubmit = (e) => {
+ e.preventDefault()
+ router.push(`/my/invoices?q=${inputQuery}`)
+ }
+
+ return (
+ <div className="p-4 flex flex-col gap-y-4">
+ <form className="flex gap-x-3" onSubmit={handleSubmit}>
+ <input
+ type="text"
+ className="form-input"
+ placeholder="Cari Transaksi..."
+ value={inputQuery}
+ onChange={(e) => setInputQuery(e.target.value)}
+ />
+ <button
+ className="btn-light bg-transparent px-3"
+ type="submit"
+ >
+ <MagnifyingGlassIcon className="w-6" />
+ </button>
+ </form>
+
+ { invoices.isLoading && (
+ <div className="flex justify-center my-4">
+ <Spinner className="w-6 text-gray_r-12/50 fill-gray_r-12" />
+ </div>
+ ) }
+
+ { !invoices.isLoading && invoices.data?.invoices?.length === 0 && (
+ <Alert type="info" className="text-center">
+ Tidak ada data transaksi
+ </Alert>
+ ) }
+
+ { invoices.data?.invoices?.map((invoice, index) => (
+ <div className="p-4 shadow border border-gray_r-3 rounded-md" key={index}>
+ <div className="grid grid-cols-2">
+ <Link href={`/my/invoice/${invoice.id}`}>
+ <span className="text-caption-2 text-gray_r-11">No. Invoice</span>
+ <h2 className="text-red_r-11 mt-1">{ invoice.name }</h2>
+ </Link>
+ <div className="flex gap-x-1 justify-end">
+ { invoice.amountResidual > 0 ? (
+ <div className="badge-solid-red h-fit ml-auto">Belum Lunas</div>
+ ) : (
+ <div className="badge-solid-green h-fit ml-auto">Lunas</div>
+ ) }
+ <EllipsisVerticalIcon className="w-5 h-5" onClick={() => setToOthers(invoice)} />
+ </div>
+ </div>
+ <Link href={`/my/invoice/${invoice.id}`}>
+ <div className="grid grid-cols-2 text-caption-2 text-gray_r-11 mt-2 font-normal">
+ <p>
+ { invoice.invoiceDate }
+ </p>
+ <p className="text-right">
+ { invoice.paymentTerm }
+ </p>
+ </div>
+ <hr className="my-3"/>
+ <div className="grid grid-cols-2">
+ <div>
+ <span className="text-caption-2 text-gray_r-11">No. Purchase Order</span>
+ <p className="mt-1 font-medium text-gray_r-12">{ invoice.purchaseOrderName || '-' }</p>
+ </div>
+ <div className="text-right">
+ <span className="text-caption-2 text-gray_r-11">Total Invoice</span>
+ <p className="mt-1 font-medium text-gray_r-12">{ currencyFormat(invoice.amountTotal) }</p>
+ </div>
+ </div>
+ </Link>
+ { invoice.efaktur ? (
+ <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>
+ )) }
+
+ <Pagination
+ pageCount={pageCount}
+ currentPage={parseInt(page)}
+ url={`/my/invoices${pageQuery}`}
+ className="mt-2 mb-2"
+ />
+
+ <BottomPopup
+ title="Lainnya"
+ active={toOthers}
+ close={() => setToOthers(null)}
+ >
+ <div className="flex flex-col gap-y-4 mt-2">
+ <button
+ className="text-left disabled:opacity-60"
+ onClick={() => { downloadInvoice(toOthers); setToOthers(null) }}
+ >
+ Download Invoice
+ </button>
+ <button
+ className="text-left disabled:opacity-60"
+ disabled={!toOthers?.efaktur}
+ onClick={() => { downloadTaxInvoice(toOthers); setToOthers(null) }}
+ >
+ Download Faktur Pajak
+ </button>
+ </div>
+ </BottomPopup>
+ </div>
+ )
+}
+
+export default Invoices \ No newline at end of file
diff --git a/src/lib/invoice/hooks/useInvoice.js b/src/lib/invoice/hooks/useInvoice.js
new file mode 100644
index 00000000..0e612f2f
--- /dev/null
+++ b/src/lib/invoice/hooks/useInvoice.js
@@ -0,0 +1,13 @@
+import { useQuery } from "react-query"
+import invoiceApi from "../api/invoiceApi"
+
+const useInvoice = ({ id }) => {
+ const fetchInvoice = async () => await invoiceApi({ id })
+ const { data, isLoading, refetch } = useQuery(`invoice-${id}`, fetchInvoice)
+
+ return {
+ invoice: { data, isLoading, refetch }
+ }
+}
+
+export default useInvoice \ No newline at end of file
diff --git a/src/lib/invoice/hooks/useInvoices.js b/src/lib/invoice/hooks/useInvoices.js
new file mode 100644
index 00000000..7bcdc952
--- /dev/null
+++ b/src/lib/invoice/hooks/useInvoices.js
@@ -0,0 +1,15 @@
+import { useQuery } from "react-query"
+import invoicesApi from "../api/invoicesApi"
+import _ from "lodash-contrib"
+
+const useInvoices = ({ query }) => {
+ const queryString = _.toQuery(query)
+ const fetchInvoices = async () => await invoicesApi({ query: queryString })
+ const { data, isLoading, refetch } = useQuery(`invoices-${queryString}`, fetchInvoices)
+
+ return {
+ invoices: { data, isLoading, refetch }
+ }
+}
+
+export default useInvoices \ No newline at end of file
diff --git a/src/lib/invoice/utils/invoices.js b/src/lib/invoice/utils/invoices.js
new file mode 100644
index 00000000..c152191d
--- /dev/null
+++ b/src/lib/invoice/utils/invoices.js
@@ -0,0 +1,14 @@
+const downloadInvoice = (invoice) => {
+ const url = `${process.env.ODOO_HOST}/api/v1/download/invoice/${invoice.id}/${invoice.token}`
+ window.open(url, 'download')
+}
+
+const downloadTaxInvoice = (invoice) => {
+ const url = `${process.env.ODOO_HOST}/api/v1/download/tax-invoice/${invoice.id}/${invoice.token}`
+ window.open(url, 'download')
+}
+
+export {
+ downloadInvoice,
+ downloadTaxInvoice
+} \ No newline at end of file
diff --git a/src/lib/transaction/components/Transaction.jsx b/src/lib/transaction/components/Transaction.jsx
index 143b24bb..e049a9ac 100644
--- a/src/lib/transaction/components/Transaction.jsx
+++ b/src/lib/transaction/components/Transaction.jsx
@@ -77,216 +77,213 @@ const Transaction = ({ id }) => {
transaction.refetch()
}
- return (
- <>
- { transaction.isLoading && (
- <div className="flex justify-center my-4">
- <Spinner className="w-6 text-gray_r-12/50 fill-gray_r-12" />
- </div>
- ) }
+ if (transaction.isLoading) {
+ return (
+ <div className="flex justify-center my-4">
+ <Spinner className="w-6 text-gray_r-12/50 fill-gray_r-12" />
+ </div>
+ )
+ }
- { transaction.data?.name && (
- <>
- <div className="flex flex-col gap-y-4 p-4">
- <DescriptionRow label="Status Transaksi">
- <div className="flex justify-end">
- <TransactionStatusBadge status={transaction.data?.status} />
- </div>
- </DescriptionRow>
- <DescriptionRow label="No Transaksi">
- { transaction.data?.name }
- </DescriptionRow>
- <DescriptionRow label="Ketentuan Pembayaran">
- { transaction.data?.paymentTerm }
- </DescriptionRow>
- <DescriptionRow label="Nama Sales">
- { transaction.data?.sales }
- </DescriptionRow>
- <DescriptionRow label="Waktu Transaksi">
- { transaction.data?.dateOrder }
- </DescriptionRow>
+ return transaction.data?.name && (
+ <>
+ <div className="flex flex-col gap-y-4 p-4">
+ <DescriptionRow label="Status Transaksi">
+ <div className="flex justify-end">
+ <TransactionStatusBadge status={transaction.data?.status} />
</div>
-
- <Divider />
+ </DescriptionRow>
+ <DescriptionRow label="No Transaksi">
+ { transaction.data?.name }
+ </DescriptionRow>
+ <DescriptionRow label="Ketentuan Pembayaran">
+ { transaction.data?.paymentTerm }
+ </DescriptionRow>
+ <DescriptionRow label="Nama Sales">
+ { transaction.data?.sales }
+ </DescriptionRow>
+ <DescriptionRow label="Waktu Transaksi">
+ { transaction.data?.dateOrder }
+ </DescriptionRow>
+ </div>
+
+ <Divider />
- <div className="p-4 flex flex-col gap-y-4">
- <DescriptionRow label="Purchase Order">
- { transaction.data?.purchaseOrderName || '-' }
- </DescriptionRow>
- <div className="flex items-center">
- <p className="text-gray_r-11 leading-none">Dokumen PO</p>
- <button
- type="button"
- className="btn-light py-1.5 px-3 ml-auto"
- onClick={transaction.data?.purchaseOrderFile ? () => downloadPurchaseOrder(transaction.data) : openUploadPo}
- >
- { transaction.data?.purchaseOrderFile ? 'Download' : 'Upload' }
- </button>
- </div>
- </div>
+ <div className="p-4 flex flex-col gap-y-4">
+ <DescriptionRow label="Purchase Order">
+ { transaction.data?.purchaseOrderName || '-' }
+ </DescriptionRow>
+ <div className="flex items-center">
+ <p className="text-gray_r-11 leading-none">Dokumen PO</p>
+ <button
+ type="button"
+ className="btn-light py-1.5 px-3 ml-auto"
+ onClick={transaction.data?.purchaseOrderFile ? () => downloadPurchaseOrder(transaction.data) : openUploadPo}
+ >
+ { transaction.data?.purchaseOrderFile ? 'Download' : 'Upload' }
+ </button>
+ </div>
+ </div>
- <Divider />
+ <Divider />
- <div className="font-medium p-4">Detail Produk</div>
+ <div className="font-medium p-4">Detail Produk</div>
- <div className="p-4 pt-0 flex flex-col gap-y-3">
- <VariantGroupCard
- variants={transaction.data?.products}
- buyMore
- />
- <div className="flex justify-between mt-3 font-medium">
- <p>Total Belanja</p>
- <p>{ currencyFormat(transaction.data?.amountTotal) }</p>
- </div>
- </div>
+ <div className="p-4 pt-0 flex flex-col gap-y-3">
+ <VariantGroupCard
+ variants={transaction.data?.products}
+ buyMore
+ />
+ <div className="flex justify-between mt-3 font-medium">
+ <p>Total Belanja</p>
+ <p>{ currencyFormat(transaction.data?.amountTotal) }</p>
+ </div>
+ </div>
- <Divider />
-
- <SectionButton
- label="Detail Pelanggan"
- active={section.customer}
- toggle={() => toggleSection('customer')}
- />
+ <Divider />
+
+ <SectionButton
+ label="Detail Pelanggan"
+ active={section.customer}
+ toggle={() => toggleSection('customer')}
+ />
- { section.customer && <SectionContent address={transaction.data?.address?.customer} /> }
+ { section.customer && <SectionContent address={transaction.data?.address?.customer} /> }
- <Divider />
-
- <SectionButton
- label="Detail Pengiriman"
- active={section.shipping}
- toggle={() => toggleSection('shipping')}
- />
+ <Divider />
+
+ <SectionButton
+ label="Detail Pengiriman"
+ active={section.shipping}
+ toggle={() => toggleSection('shipping')}
+ />
- { section.shipping && <SectionContent address={transaction.data?.address?.shipping} /> }
+ { section.shipping && <SectionContent address={transaction.data?.address?.shipping} /> }
- <Divider />
-
- <SectionButton
- label="Detail Penagihan"
- active={section.invoice}
- toggle={() => toggleSection('invoice')}
- />
+ <Divider />
+
+ <SectionButton
+ label="Detail Penagihan"
+ active={section.invoice}
+ toggle={() => toggleSection('invoice')}
+ />
- { section.invoice && <SectionContent address={transaction.data?.address?.invoice} /> }
+ { section.invoice && <SectionContent address={transaction.data?.address?.invoice} /> }
- <Divider />
+ <Divider />
- <div className="p-4">
- <p className="font-medium">Invoice</p>
- <div className="flex flex-col gap-y-3 mt-4">
- { transaction.data?.invoices?.map((invoice, index) => (
- <Link href={`/my/invoice/${invoice.id}`} key={index}>
- <div className="shadow rounded-md p-4 text-gray_r-12 font-normal flex justify-between">
- <div>
- <p className="mb-2">{ invoice?.name }</p>
- <div className="flex items-center gap-x-1">
- { invoice.amountResidual > 0 ? (
- <div className="badge-red">Belum Lunas</div>
- ) : (
- <div className="badge-green">Lunas</div>
- ) }
- <p className="text-caption-2 text-gray_r-11">
- { currencyFormat(invoice.amountTotal) }
- </p>
- </div>
- </div>
- <ChevronRightIcon className="w-5 stroke-2" />
+ <div className="p-4">
+ <p className="font-medium">Invoice</p>
+ <div className="flex flex-col gap-y-3 mt-4">
+ { transaction.data?.invoices?.map((invoice, index) => (
+ <Link href={`/my/invoice/${invoice.id}`} key={index}>
+ <div className="shadow rounded-md p-4 text-gray_r-12 font-normal flex justify-between">
+ <div>
+ <p className="mb-2">{ invoice?.name }</p>
+ <div className="flex items-center gap-x-1">
+ { invoice.amountResidual > 0 ? (
+ <div className="badge-red">Belum Lunas</div>
+ ) : (
+ <div className="badge-green">Lunas</div>
+ ) }
+ <p className="text-caption-2 text-gray_r-11">
+ { currencyFormat(invoice.amountTotal) }
+ </p>
</div>
- </Link>
- )) }
- { transaction.data?.invoices?.length === 0 && (
- <Alert type='info' className='text-center'>
- Belum ada Invoice
- </Alert>
- ) }
- </div>
- </div>
-
- <Divider />
+ </div>
+ <ChevronRightIcon className="w-5 stroke-2" />
+ </div>
+ </Link>
+ )) }
+ { transaction.data?.invoices?.length === 0 && (
+ <Alert type='info' className='text-center'>
+ Belum ada Invoice
+ </Alert>
+ ) }
+ </div>
+ </div>
- <div className="p-4 pt-0">
- { transaction.data?.status == 'draft' && (
- <button
- className="btn-yellow w-full mt-4"
- onClick={checkout}
- >
- Lanjutkan Transaksi
- </button>
- ) }
- <button
- className="btn-light w-full mt-4"
- disabled={transaction.data?.status != 'draft'}
- onClick={downloadQuotation}
- >
- Download Quotation
- </button>
- { transaction.data?.status != 'draft' && (
- <button
- className="btn-light w-full mt-4"
- disabled={transaction.data?.status != 'waiting'}
- onClick={openCancelTransaction}
- >
- Batalkan Transaksi
- </button>
- ) }
- </div>
+ <Divider />
- <BottomPopup
- active={cancelTransaction}
- close={closeCancelTransaction}
- title="Batalkan Transaksi"
+ <div className="p-4 pt-0">
+ { transaction.data?.status == 'draft' && (
+ <button
+ className="btn-yellow w-full mt-4"
+ onClick={checkout}
+ >
+ Lanjutkan Transaksi
+ </button>
+ ) }
+ <button
+ className="btn-light w-full mt-4"
+ disabled={transaction.data?.status != 'draft'}
+ onClick={downloadQuotation}
+ >
+ Download Quotation
+ </button>
+ { transaction.data?.status != 'draft' && (
+ <button
+ className="btn-light w-full mt-4"
+ disabled={transaction.data?.status != 'waiting'}
+ onClick={openCancelTransaction}
>
- <div className="leading-7 text-gray_r-12/80">
- Apakah anda yakin membatalkan transaksi <span className="underline">{transaction.data?.name}</span>?
- </div>
- <div className="flex mt-6 gap-x-4">
- <button
- className="btn-solid-red flex-1"
- type="button"
- onClick={submitCancelTransaction}
- >
- Ya, Batalkan
- </button>
- <button
- className="btn-light flex-1"
- type="button"
- onClick={closeCancelTransaction}
- >
- Batal
- </button>
- </div>
- </BottomPopup>
+ Batalkan Transaksi
+ </button>
+ ) }
+ </div>
- <BottomPopup
- title="Upload PO"
- close={closeUploadPo}
- active={uploadPo}
+ <BottomPopup
+ active={cancelTransaction}
+ close={closeCancelTransaction}
+ title="Batalkan Transaksi"
+ >
+ <div className="leading-7 text-gray_r-12/80">
+ Apakah anda yakin membatalkan transaksi <span className="underline">{transaction.data?.name}</span>?
+ </div>
+ <div className="flex mt-6 gap-x-4">
+ <button
+ className="btn-solid-red flex-1"
+ type="button"
+ onClick={submitCancelTransaction}
>
- <div>
- <label>Nomor PO</label>
- <input type="text" className="form-input mt-3" ref={poNumber} />
- </div>
- <div className="mt-4">
- <label>Dokumen PO</label>
- <input type="file" className="form-input mt-3 py-2" ref={poFile} />
- </div>
- <div className="grid grid-cols-2 gap-x-3 mt-6">
- <button
- type="button"
- className="btn-light w-full"
- onClick={closeUploadPo}
- >Batal</button>
- <button
- type="button"
- className="btn-solid-red w-full"
- onClick={submitUploadPo}
- >Upload</button>
- </div>
- </BottomPopup>
- </>
- )}
+ Ya, Batalkan
+ </button>
+ <button
+ className="btn-light flex-1"
+ type="button"
+ onClick={closeCancelTransaction}
+ >
+ Batal
+ </button>
+ </div>
+ </BottomPopup>
+ <BottomPopup
+ title="Upload PO"
+ close={closeUploadPo}
+ active={uploadPo}
+ >
+ <div>
+ <label>Nomor PO</label>
+ <input type="text" className="form-input mt-3" ref={poNumber} />
+ </div>
+ <div className="mt-4">
+ <label>Dokumen PO</label>
+ <input type="file" className="form-input mt-3 py-2" ref={poFile} />
+ </div>
+ <div className="grid grid-cols-2 gap-x-3 mt-6">
+ <button
+ type="button"
+ className="btn-light w-full"
+ onClick={closeUploadPo}
+ >Batal</button>
+ <button
+ type="button"
+ className="btn-solid-red w-full"
+ onClick={submitUploadPo}
+ >Upload</button>
+ </div>
+ </BottomPopup>
</>
)
}
@@ -305,7 +302,7 @@ const SectionButton = ({ label, active, toggle }) => (
const SectionContent = ({ address }) => {
let fullAddress = []
if (address?.street) fullAddress.push(address.street)
- if (address?.sub_district?.name) fullAddress.push(address.sub_district.name)
+ if (address?.subDistrict?.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)
fullAddress = fullAddress.join(', ')
diff --git a/src/lib/transaction/components/Transactions.jsx b/src/lib/transaction/components/Transactions.jsx
index 25a6076a..280e8fc5 100644
--- a/src/lib/transaction/components/Transactions.jsx
+++ b/src/lib/transaction/components/Transactions.jsx
@@ -58,79 +58,78 @@ const Transactions = () => {
}
return (
- <div className="p-4">
- <div className="flex flex-col gap-y-4">
- <form className="flex gap-x-3" onSubmit={handleSubmit}>
- <input
- type="text"
- className="form-input"
- placeholder="Cari Transaksi..."
- value={inputQuery}
- onChange={(e) => setInputQuery(e.target.value)}
- />
- <button
- className="btn-light bg-transparent px-3"
- type="submit"
- >
- <MagnifyingGlassIcon className="w-6" />
- </button>
- </form>
- { transactions.isLoading && (
- <div className="flex justify-center my-4">
- <Spinner className="w-6 text-gray_r-12/50 fill-gray_r-12" />
- </div>
- ) }
+ <div className="p-4 flex flex-col gap-y-4">
+ <form className="flex gap-x-3" onSubmit={handleSubmit}>
+ <input
+ type="text"
+ className="form-input"
+ placeholder="Cari Transaksi..."
+ value={inputQuery}
+ onChange={(e) => setInputQuery(e.target.value)}
+ />
+ <button
+ className="btn-light bg-transparent px-3"
+ type="submit"
+ >
+ <MagnifyingGlassIcon className="w-6" />
+ </button>
+ </form>
+
+ { transactions.isLoading && (
+ <div className="flex justify-center my-4">
+ <Spinner className="w-6 text-gray_r-12/50 fill-gray_r-12" />
+ </div>
+ ) }
- { !transactions.isLoading && transactions.data?.saleOrders?.length === 0 && (
- <Alert type="info" className="text-center">
- Tidak ada data transaksi
- </Alert>
- ) }
+ { !transactions.isLoading && transactions.data?.saleOrders?.length === 0 && (
+ <Alert type="info" className="text-center">
+ Tidak ada data transaksi
+ </Alert>
+ ) }
- { transactions.data?.saleOrders?.map((saleOrder, index) => (
- <div className="p-4 shadow border border-gray_r-3 rounded-md" key={index}>
- <div className="grid grid-cols-2">
- <Link href={`/my/transaction/${saleOrder.id}`}>
- <span className="text-caption-2 text-gray_r-11">No. Transaksi</span>
- <h2 className="text-red_r-11 mt-1">{ saleOrder.name }</h2>
- </Link>
- <div className="flex gap-x-1 justify-end">
- <TransactionStatusBadge status={saleOrder.status} />
- <EllipsisVerticalIcon className="w-5 h-5" onClick={() => setToOthers(saleOrder)} />
+ { transactions.data?.saleOrders?.map((saleOrder, index) => (
+ <div className="p-4 shadow border border-gray_r-3 rounded-md" key={index}>
+ <div className="grid grid-cols-2">
+ <Link href={`/my/transaction/${saleOrder.id}`}>
+ <span className="text-caption-2 text-gray_r-11">No. Transaksi</span>
+ <h2 className="text-red_r-11 mt-1">{ saleOrder.name }</h2>
+ </Link>
+ <div className="flex gap-x-1 justify-end">
+ <TransactionStatusBadge status={saleOrder.status} />
+ <EllipsisVerticalIcon className="w-5 h-5" onClick={() => setToOthers(saleOrder)} />
+ </div>
+ </div>
+ <Link href={`/my/transaction/${saleOrder.id}`}>
+ <div className="grid grid-cols-2 mt-3">
+ <div>
+ <span className="text-caption-2 text-gray_r-11">No. Purchase Order</span>
+ <p className="mt-1 font-medium text-gray_r-12">{ saleOrder.purchaseOrderName || '-' }</p>
+ </div>
+ <div className="text-right">
+ <span className="text-caption-2 text-gray_r-11">Total Invoice</span>
+ <p className="mt-1 font-medium text-gray_r-12">{ saleOrder.invoiceCount } Invoice</p>
</div>
</div>
- <Link href={`/my/transaction/${saleOrder.id}`}>
- <div className="grid grid-cols-2 mt-3">
- <div>
- <span className="text-caption-2 text-gray_r-11">No. Purchase Order</span>
- <p className="mt-1 font-medium text-gray_r-12">{ saleOrder.purchaseOrderName || '-' }</p>
- </div>
- <div className="text-right">
- <span className="text-caption-2 text-gray_r-11">Total Invoice</span>
- <p className="mt-1 font-medium text-gray_r-12">{ saleOrder.invoiceCount } Invoice</p>
- </div>
+ <div className="grid grid-cols-2 mt-3">
+ <div>
+ <span className="text-caption-2 text-gray_r-11">Sales</span>
+ <p className="mt-1 font-medium text-gray_r-12">{ saleOrder.sales }</p>
</div>
- <div className="grid grid-cols-2 mt-3">
- <div>
- <span className="text-caption-2 text-gray_r-11">Sales</span>
- <p className="mt-1 font-medium text-gray_r-12">{ saleOrder.sales }</p>
- </div>
- <div className="text-right">
- <span className="text-caption-2 text-gray_r-11">Total Harga</span>
- <p className="mt-1 font-medium text-gray_r-12">{ currencyFormat(saleOrder.amountTotal) }</p>
- </div>
+ <div className="text-right">
+ <span className="text-caption-2 text-gray_r-11">Total Harga</span>
+ <p className="mt-1 font-medium text-gray_r-12">{ currencyFormat(saleOrder.amountTotal) }</p>
</div>
- </Link>
- </div>
- )) }
-
- <Pagination
- pageCount={pageCount}
- currentPage={parseInt(page)}
- url={`/my/transactions${pageQuery}`}
- className="mt-2 mb-2"
- />
- </div>
+ </div>
+ </Link>
+ </div>
+ )) }
+
+ <Pagination
+ pageCount={pageCount}
+ currentPage={parseInt(page)}
+ url={`/my/transactions${pageQuery}`}
+ className="mt-2 mb-2"
+ />
<BottomPopup title="Lainnya" active={toOthers} close={() => setToOthers(null)}>
<div className="flex flex-col gap-y-4 mt-2">
diff --git a/src/pages/my/invoice/[id].jsx b/src/pages/my/invoice/[id].jsx
new file mode 100644
index 00000000..a3cbeb5c
--- /dev/null
+++ b/src/pages/my/invoice/[id].jsx
@@ -0,0 +1,13 @@
+import AppLayout from "@/core/components/layouts/AppLayout"
+import InvoiceComponent from "@/lib/invoice/components/Invoice"
+import { useRouter } from "next/router"
+
+export default function Invoice() {
+ const router = useRouter()
+
+ return (
+ <AppLayout title="Invoice & Faktur Pajak">
+ <InvoiceComponent id={router.query.id} />
+ </AppLayout>
+ )
+} \ No newline at end of file
diff --git a/src/pages/my/invoices.jsx b/src/pages/my/invoices.jsx
new file mode 100644
index 00000000..04842110
--- /dev/null
+++ b/src/pages/my/invoices.jsx
@@ -0,0 +1,10 @@
+import AppLayout from "@/core/components/layouts/AppLayout"
+import InvoicesComponent from "@/lib/invoice/components/Invoices"
+
+export default function Invoices() {
+ return (
+ <AppLayout title="Invoice & Faktur Pajak">
+ <InvoicesComponent />
+ </AppLayout>
+ )
+} \ No newline at end of file
diff --git a/src/pages/my/menu.jsx b/src/pages/my/menu.jsx
index 69e4b8bb..e2a11390 100644
--- a/src/pages/my/menu.jsx
+++ b/src/pages/my/menu.jsx
@@ -47,10 +47,10 @@ export default function Menu() {
<LinkItem href="/my/transactions">
Daftar Transaksi
</LinkItem>
- <LinkItem href="/">
+ <LinkItem href="/my/invoices">
Invoice & Faktur Pajak
</LinkItem>
- <LinkItem href="/">
+ <LinkItem href="/my/wishlist">
Wishlist
</LinkItem>
</div>