diff options
Diffstat (limited to 'src2/pages/my/transactions.js')
| -rw-r--r-- | src2/pages/my/transactions.js | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/src2/pages/my/transactions.js b/src2/pages/my/transactions.js new file mode 100644 index 00000000..8be43af7 --- /dev/null +++ b/src2/pages/my/transactions.js @@ -0,0 +1,198 @@ +import { useRouter } from "next/router"; +import AppBar from "@/components/layouts/AppBar"; +import Layout from "@/components/layouts/Layout"; +import WithAuth from "@/components/auth/WithAuth"; +import { useCallback, useEffect, useRef, useState } from "react"; +import { useAuth } from "@/core/utils/auth"; +import apiOdoo from "@/core/utils/apiOdoo"; +import currencyFormat from "@/core/utils/currencyFormat"; +import { EllipsisVerticalIcon, MagnifyingGlassIcon } from "@heroicons/react/24/outline"; +import Link from "@/components/elements/Link"; +import Pagination from "@/components/elements/Pagination"; +import Alert from "@/components/elements/Alert"; +import TransactionStatusBadge from "@/components/transactions/TransactionStatusBadge"; +import { toast } from "react-hot-toast"; +import useConfirmAlert from "@/lib/elements/hooks/useConfirmAlert"; +import useBottomPopup from "@/lib/elements/hooks/useBottomPopup"; + +export default function Transactions() { + const [ auth ] = useAuth(); + const router = useRouter(); + const { + q, + page = 1 + } = router.query; + + const [ transactions, setTransactions ] = useState([]); + + const [ pageCount, setPageCount ] = useState(0); + const [ isLoading, setIsLoading ] = useState(true); + + const searchQueryRef = useRef(); + const loadTransactions = useCallback(async () => { + if (auth) { + const limit = 10; + let offset = (page - 1) * 10; + let queryParams = [`limit=${limit}`, `offset=${offset}`]; + if (q) queryParams.push(`name=${q}`); + queryParams = queryParams.join('&'); + queryParams = queryParams ? '?' + queryParams : ''; + + const dataTransactions = await apiOdoo('GET', `/api/v1/partner/${auth.partner_id}/sale_order${queryParams}`); + setTransactions(dataTransactions); + setPageCount(Math.ceil(dataTransactions?.sale_order_total / limit)); + setIsLoading(false); + }; + }, [ auth, q, page ]); + + useEffect(() => { + loadTransactions(); + }, [ loadTransactions ]); + + const actionSearch = (e) => { + e.preventDefault(); + let queryParams = []; + if (searchQueryRef.current.value) queryParams.push(`q=${searchQueryRef.current.value}`); + queryParams = queryParams.join('&'); + queryParams = queryParams ? `?${queryParams}` : ''; + router.push(`/my/transactions${queryParams}`); + }; + + const downloadPurchaseOrder = (data) => { + const url = `${process.env.ODOO_HOST}/api/v1/partner/${auth.partner_id}/sale_order/${data.id}/download_po/${data.token}`; + window.open(url, 'download'); + closePopup(); + }; + + const downloadQuotation = (data) => { + const url = `${process.env.ODOO_HOST}/api/v1/partner/${auth.partner_id}/sale_order/${data.id}/download/${data.token}`; + window.open(url, 'download'); + closePopup(); + }; + + const childrenPopup = (data) => ( + <div className="flex flex-col gap-y-6"> + <button + className="text-left disabled:opacity-60" + disabled={!data?.purchase_order_file} + onClick={() => downloadPurchaseOrder(data)} + > + Download PO + </button> + <button + className="text-left disabled:opacity-60" + disabled={data?.status != 'draft'} + onClick={() => downloadQuotation(data)} + > + Download Quotation + </button> + <button + className="text-left disabled:opacity-60" + disabled={ data?.status != 'waiting' } + onClick={() => {openConfirmAlert(data); closePopup()}} + > + Batalkan Transaksi + </button> + </div> + ); + + const { + closePopup, + openPopup, + BottomPopup + } = useBottomPopup({ + title: 'Lainnya', + children: childrenPopup + }); + + const submitCancelTransaction = async (data) => { + const isCancelled = await apiOdoo('POST', `/api/v1/partner/${auth.partner_id}/sale_order/${data.id}/cancel`); + if (isCancelled) { + toast.success('Berhasil batalkan transaksi'); + loadTransactions(); + } + } + + const { + openConfirmAlert, + ConfirmAlert + } = useConfirmAlert({ + title: 'Batalkan Transaksi', + caption: 'Apakah anda yakin untuk membatalkan transaksi?', + closeText: 'Tidak', + submitText: 'Ya, Batalkan', + onSubmit: submitCancelTransaction + }); + + return ( + <WithAuth> + <Layout> + <AppBar title="Transaksi" /> + + <form onSubmit={actionSearch} className="p-4 pb-0 flex gap-x-4"> + <input + type="text" + className="form-input" + placeholder="Cari Transaksi" + ref={searchQueryRef} + defaultValue={q} + /> + <button type="submit" className="border border-gray_r-7 rounded px-3"> + <MagnifyingGlassIcon className="w-5"/> + </button> + </form> + + <div className="p-4 flex flex-col gap-y-5"> + { transactions?.sale_order_total === 0 && !isLoading && ( + <Alert type="info" className="text-center"> + Transaksi tidak ditemukan + </Alert> + ) } + { transactions?.sale_orders?.map((transaction, 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/${transaction.id}`}> + <span className="text-caption-2 text-gray_r-11">No. Transaksi</span> + <h2 className="text-red_r-11 mt-1">{ transaction.name }</h2> + </Link> + <div className="flex gap-x-1 justify-end"> + <TransactionStatusBadge status={transaction.status} /> + <EllipsisVerticalIcon className="w-5 h-5" onClick={() => openPopup(transaction)} /> + </div> + </div> + <Link href={`/my/transaction/${transaction.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">{ transaction.purchase_order_name || '-' }</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">{ transaction.invoice_count } Invoice</p> + </div> + </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">{ transaction.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(transaction.amount_total) }</p> + </div> + </div> + </Link> + </div> + )) } + </div> + + <div className="pb-6 pt-2"> + <Pagination currentPage={page} pageCount={pageCount} url={`/my/transactions${q ? `?q=${q}` : ''}`} /> + </div> + + { ConfirmAlert } + { BottomPopup } + </Layout> + </WithAuth> + ); +};
\ No newline at end of file |
