diff options
| author | Rafi Zadanly <zadanlyr@gmail.com> | 2023-03-26 15:10:59 +0700 |
|---|---|---|
| committer | Rafi Zadanly <zadanlyr@gmail.com> | 2023-03-26 15:10:59 +0700 |
| commit | de5ef26bb1017540969f8847016193f7e1933ee1 (patch) | |
| tree | f78223e275de072c57122727300fc72e9adf7240 | |
| parent | 1f20fafef46b4eecaf0dd1b91592f3214e8144d3 (diff) | |
transaction detail
| -rw-r--r-- | src/core/components/elements/Popup/BottomPopup.jsx | 4 | ||||
| -rw-r--r-- | src/lib/auth/components/Menu.jsx | 47 | ||||
| -rw-r--r-- | src/lib/transaction/components/Transaction.jsx | 471 | ||||
| -rw-r--r-- | src/lib/transaction/components/Transactions.jsx | 12 | ||||
| -rw-r--r-- | src/pages/my/menu.jsx | 2 | ||||
| -rw-r--r-- | src/pages/my/transaction/[id].jsx | 17 | ||||
| -rw-r--r-- | src/styles/globals.css | 4 |
7 files changed, 395 insertions, 162 deletions
diff --git a/src/core/components/elements/Popup/BottomPopup.jsx b/src/core/components/elements/Popup/BottomPopup.jsx index 95c75473..c244330c 100644 --- a/src/core/components/elements/Popup/BottomPopup.jsx +++ b/src/core/components/elements/Popup/BottomPopup.jsx @@ -49,8 +49,8 @@ const BottomPopup = ({ children, active = false, title, close }) => { <DesktopView> <motion.div initial={{ bottom: '35%', opacity: 0 }} - animate={{ bottom: '50%', opacity: 1 }} - exit={{ bottom: '35%', opacity: 0 }} + animate={{ bottom: '30%', opacity: 1 }} + exit={{ bottom: '25%', opacity: 0 }} transition={transition} className='fixed left-1/2 -translate-x-1/2 w-2/5 border border-gray_r-6 rounded-xl z-[60] p-4 pt-0 bg-white' > diff --git a/src/lib/auth/components/Menu.jsx b/src/lib/auth/components/Menu.jsx new file mode 100644 index 00000000..3f2b2fb2 --- /dev/null +++ b/src/lib/auth/components/Menu.jsx @@ -0,0 +1,47 @@ +import Link from '@/core/components/elements/Link/Link' +import { useRouter } from 'next/router' + +const Menu = () => { + const router = useRouter() + + const routeStartWith = (route) => router.pathname.startsWith(route) + + return ( + <div className='grid grid-cols-1 border border-gray_r-6 rounded py-2 px-4'> + <div className='mt-4 mb-1 font-medium'>Menu</div> + <LinkItem href='/my/transactions' active={routeStartWith('/my/transaction')}> + Daftar Transaksi + </LinkItem> + <LinkItem href='/my/invoices' active={routeStartWith('/my/invoice')}> + Invoice & Faktur Pajak + </LinkItem> + <LinkItem href='/my/wishlist' active={routeStartWith('/my/wishlist')}> + Wishlist + </LinkItem> + + <div className='mt-4 mb-1 font-medium'>Pusat Bantuan</div> + <LinkItem href='/'>Layanan Pelanggan</LinkItem> + + <div className='mt-4 mb-1 font-medium'>Pengaturan Akun</div> + <LinkItem href='/my/address' active={routeStartWith('/my/address')}> + Daftar Alamat + </LinkItem> + <button type='button' className='text-gray_r-12/80 p-2 text-left'> + Keluar Akun + </button> + </div> + ) +} + +const LinkItem = ({ children, ...props }) => ( + <Link + {...props} + className={`!text-gray_r-12/80 !font-normal p-2 rounded ${ + props.active == true ? 'bg-gray_r-3' : '' + }`} + > + {children} + </Link> +) + +export default Menu diff --git a/src/lib/transaction/components/Transaction.jsx b/src/lib/transaction/components/Transaction.jsx index dc9338fa..dbfdbae9 100644 --- a/src/lib/transaction/components/Transaction.jsx +++ b/src/lib/transaction/components/Transaction.jsx @@ -15,6 +15,11 @@ import Link from '@/core/components/elements/Link/Link' import Alert from '@/core/components/elements/Alert/Alert' import checkoutPoApi from '../api/checkoutPoApi' import cancelTransactionApi from '../api/cancelTransactionApi' +import MobileView from '@/core/components/views/MobileView' +import DesktopView from '@/core/components/views/DesktopView' +import Menu from '@/lib/auth/components/Menu' +import Image from '@/core/components/elements/Image/Image' +import { createSlug } from '@/core/utils/slug' const Transaction = ({ id }) => { const { transaction } = useTransaction({ id }) @@ -88,10 +93,7 @@ const Transaction = ({ id }) => { const memoizeVariantGroupCard = useMemo( () => ( <div className='p-4 pt-0 flex flex-col gap-y-3'> - <VariantGroupCard - variants={transaction.data?.products} - buyMore - /> + <VariantGroupCard variants={transaction.data?.products} buyMore /> <div className='flex justify-between mt-1'> <p className='text-gray_r-12/70'>Subtotal</p> <p>{currencyFormat(totalAmount)}</p> @@ -124,120 +126,6 @@ const Transaction = ({ id }) => { 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> - </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> - - <Divider /> - - <div className='font-medium p-4'>Detail Produk</div> - - {memoizeVariantGroupCard} - - <Divider /> - - <SectionAddress address={transaction.data?.address} /> - - <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> - </Link> - ))} - {transaction.data?.invoices?.length === 0 && ( - <Alert - type='info' - className='text-center' - > - Belum ada Invoice - </Alert> - )} - </div> - </div> - - <Divider /> - - <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> - <BottomPopup active={cancelTransaction} close={closeCancelTransaction} @@ -255,54 +143,334 @@ const Transaction = ({ id }) => { > Ya, Batalkan </button> - <button - className='btn-light flex-1' - type='button' - onClick={closeCancelTransaction} - > + <button className='btn-light flex-1' type='button' onClick={closeCancelTransaction}> Batal </button> </div> </BottomPopup> - <BottomPopup - title='Upload PO' - close={closeUploadPo} - active={uploadPo} - > + <BottomPopup title='Upload PO' close={closeUploadPo} active={uploadPo}> <div> <label>Nomor PO</label> - <input - type='text' - className='form-input mt-3' - ref={poNumber} - /> + <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} - /> + <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} - > + <button type='button' className='btn-light w-full' onClick={closeUploadPo}> Batal </button> - <button - type='button' - className='btn-solid-red w-full' - onClick={submitUploadPo} - > + <button type='button' className='btn-solid-red w-full' onClick={submitUploadPo}> Upload </button> </div> </BottomPopup> + + <MobileView> + <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> + </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> + + <Divider /> + + <div className='font-medium p-4'>Detail Produk</div> + + {memoizeVariantGroupCard} + + <Divider /> + + <SectionAddress address={transaction.data?.address} /> + + <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> + </Link> + ))} + {transaction.data?.invoices?.length === 0 && ( + <Alert type='info' className='text-center'> + Belum ada Invoice + </Alert> + )} + </div> + </div> + + <Divider /> + + <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> + </MobileView> + + <DesktopView> + <div className='container mx-auto flex py-10'> + <div className='w-3/12 pr-4'> + <Menu /> + </div> + <div className='w-9/12 p-4 bg-white border border-gray_r-6 rounded'> + <h1 className='text-title-sm font-semibold mb-6'>Detail Transaksi</h1> + + <div className='flex items-center gap-x-2 mb-3'> + <span className='text-h-sm font-medium'>{transaction?.data?.name}</span> + <TransactionStatusBadge status={transaction?.data?.status} /> + </div> + <button + type='button' + className='btn-solid-red px-3 py-2' + disabled={transaction.data?.status != 'draft'} + onClick={downloadQuotation} + > + Download + </button> + + <div className='grid grid-cols-2 gap-x-6 mt-6'> + <div className='grid grid-cols-2 gap-y-3'> + <div>Nama Sales</div> + <div>: {transaction?.data?.sales}</div> + + <div>Tanggal Transaksi</div> + <div>: {transaction?.data?.dateOrder}</div> + </div> + <div className='grid grid-cols-2 gap-y-3'> + <div>Ketentuan Pembayaran</div> + <div>: {transaction?.data?.paymentTerm}</div> + + <div>Purchase Order</div> + <div> + : {transaction?.data?.purchaseOrderName}{' '} + <button + type='button' + className='inline-block text-red_r-11' + onClick={ + transaction.data?.purchaseOrderFile + ? () => downloadPurchaseOrder(transaction.data) + : openUploadPo + } + > + {transaction?.data?.purchaseOrderFile ? 'Download' : 'Upload'} + </button> + </div> + </div> + </div> + + <div className='text-h-sm font-semibold mt-6 mb-4'>Info Pengiriman</div> + <div className='grid grid-cols-3 gap-x-4'> + <div className='border border-gray_r-6 rounded p-3'> + <div className='font-medium mb-4'>Detail Pelanggan</div> + <SectionContent address={transaction?.data?.address?.customer} /> + </div> + <div className='border border-gray_r-6 rounded p-3'> + <div className='font-medium mb-4'>Detail Pengiriman</div> + <SectionContent address={transaction?.data?.address?.shipping} /> + </div> + <div className='border border-gray_r-6 rounded p-3'> + <div className='font-medium mb-4'>Detail Penagihan</div> + <SectionContent address={transaction?.data?.address?.invoice} /> + </div> + </div> + + <div className='text-h-sm font-semibold mt-6 mb-4'>Rincian Pembelian</div> + <table className='table-data'> + <thead> + <tr> + <th>Nama Produk</th> + <th>Jumlah</th> + <th>Harga</th> + <th>Diskon</th> + <th>Subtotal</th> + </tr> + </thead> + <tbody> + {transaction?.data?.products?.map((product) => ( + <tr key={product.id}> + <td className='flex'> + <Link + href={createSlug( + '/shop/product/', + product?.parent.name, + product?.parent.id + )} + className='w-[30%] flex-shrink-0' + > + <Image + src={product?.parent?.image} + alt={product?.name} + className='object-contain object-center border border-gray_r-6 h-40 w-full rounded-md' + /> + </Link> + <div className='px-2 text-left'> + <Link + href={createSlug( + '/shop/product/', + product?.parent.name, + product?.parent.id + )} + className='line-clamp-2 leading-6 !text-gray_r-12 font-normal' + > + {product?.parent?.name} + </Link> + <div className='text-gray_r-11 mt-2'> + {product?.code}{' '} + {product?.attributes.length > 0 + ? `| ${product?.attributes.join(', ')}` + : ''} + </div> + </div> + </td> + <td>{product.quantity}</td> + <td>{currencyFormat(product.price.price)}</td> + <td> + {product.price.discountPercentage > 0 + ? `${product.price.discountPercentage}%` + : ''} + </td> + <td>{currencyFormat(product.price.priceDiscount)}</td> + </tr> + ))} + </tbody> + </table> + + <div className='flex justify-end mt-4'> + <div className='w-1/4 grid grid-cols-2 gap-y-2 text-gray_r-12/80'> + <div className='text-right'>Subtotal</div> + <div className='text-right font-medium'>{currencyFormat(totalAmount)}</div> + + <div className='text-right'>Total Diskon</div> + <div className='text-right font-medium'> + {currencyFormat(-totalDiscountAmount)} + </div> + + <div className='text-right'>PPN 11% (Incl.)</div> + <div className='text-right font-medium'>{currencyFormat(totalAmount * 0.11)}</div> + + <div className='text-right'>Grand Total</div> + <div className='text-right font-medium text-gray_r-12'> + {currencyFormat(transaction.data?.amountTotal)} + </div> + </div> + </div> + + <div className='text-h-sm font-semibold mt-6 mb-4'>Invoice</div> + <div className='grid grid-cols-4 gap-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> + </Link> + ))} + </div> + {transaction.data?.invoices?.length === 0 && ( + <Alert type='info' className='text-center'> + Belum ada Invoice + </Alert> + )} + + <div className='mt-6'> + {transaction.data?.status == 'draft' && ( + <button className='btn-yellow' onClick={checkout}> + Lanjutkan Transaksi + </button> + )} + {transaction.data?.status != 'draft' && ( + <button + className='btn-light' + disabled={transaction.data?.status != 'waiting'} + onClick={openCancelTransaction} + > + Batalkan Transaksi + </button> + )} + </div> + </div> + </div> + </DesktopView> </> ) ) @@ -351,10 +519,7 @@ const SectionAddress = ({ address }) => { } const SectionButton = ({ label, active, toggle }) => ( - <button - className='p-4 font-medium flex justify-between w-full' - onClick={toggle} - > + <button className='p-4 font-medium flex justify-between w-full' onClick={toggle}> <span>{label}</span> {active ? <ChevronUpIcon className='w-5' /> : <ChevronDownIcon className='w-5' />} </button> @@ -369,7 +534,7 @@ const SectionContent = ({ address }) => { fullAddress = fullAddress.join(', ') return ( - <div className='flex flex-col gap-y-4 p-4 border-t border-gray_r-6'> + <div className='flex flex-col gap-y-4 p-4 md:p-0 border-t border-gray_r-6 md:border-0'> <DescriptionRow label='Nama'>{address.name}</DescriptionRow> <DescriptionRow label='Email'>{address.email || '-'}</DescriptionRow> <DescriptionRow label='No Telepon'>{address.mobile || '-'}</DescriptionRow> diff --git a/src/lib/transaction/components/Transactions.jsx b/src/lib/transaction/components/Transactions.jsx index 3d3dd533..0a772967 100644 --- a/src/lib/transaction/components/Transactions.jsx +++ b/src/lib/transaction/components/Transactions.jsx @@ -17,6 +17,7 @@ import _ from 'lodash' import Alert from '@/core/components/elements/Alert/Alert' import MobileView from '@/core/components/views/MobileView' import DesktopView from '@/core/components/views/DesktopView' +import Menu from '@/lib/auth/components/Menu' const Transactions = () => { const router = useRouter() @@ -196,10 +197,15 @@ const Transactions = () => { <DesktopView> <div className='container mx-auto flex py-10'> - <div className='w-3/12'></div> + <div className='w-3/12 pr-4'> + <Menu /> + </div> <div className='w-9/12 p-4 bg-white border border-gray_r-6 rounded'> <div className='flex mb-6 items-center justify-between'> - <h1 className='text-title-sm font-semibold'>Daftar Transaksi</h1> + <h1 className='text-title-sm font-semibold'> + Daftar Transaksi{' '} + {transactions?.data?.saleOrders ? `(${transactions?.data?.saleOrders.length})` : ''} + </h1> <form className='flex gap-x-2' onSubmit={handleSubmit}> <input type='text' @@ -213,7 +219,7 @@ const Transactions = () => { </button> </form> </div> - <table className='table-data w-full'> + <table className='table-data'> <thead> <tr> <th>No. Transaksi</th> diff --git a/src/pages/my/menu.jsx b/src/pages/my/menu.jsx index 67158242..851bcf56 100644 --- a/src/pages/my/menu.jsx +++ b/src/pages/my/menu.jsx @@ -53,7 +53,7 @@ export default function Menu() { <MenuHeader>Pusat Bantuan</MenuHeader> <div className='divide-y divide-gray_r-6 border-y border-gray_r-6 mt-4'> - <LinkItem href='/'>Customer Support</LinkItem> + <LinkItem href='/'>Layanan Pelanggan</LinkItem> </div> </div> diff --git a/src/pages/my/transaction/[id].jsx b/src/pages/my/transaction/[id].jsx index 5167748c..c3283783 100644 --- a/src/pages/my/transaction/[id].jsx +++ b/src/pages/my/transaction/[id].jsx @@ -1,4 +1,7 @@ import AppLayout from '@/core/components/layouts/AppLayout' +import BasicLayout from '@/core/components/layouts/BasicLayout' +import DesktopView from '@/core/components/views/DesktopView' +import MobileView from '@/core/components/views/MobileView' import IsAuth from '@/lib/auth/components/IsAuth' import TransactionComponent from '@/lib/transaction/components/Transaction' import { useRouter } from 'next/router' @@ -8,9 +11,17 @@ export default function Transaction() { return ( <IsAuth> - <AppLayout title='Transaksi'> - <TransactionComponent id={router.query.id} /> - </AppLayout> + <MobileView> + <AppLayout title='Transaksi'> + <TransactionComponent id={router.query.id} /> + </AppLayout> + </MobileView> + + <DesktopView> + <BasicLayout> + <TransactionComponent id={router.query.id} /> + </BasicLayout> + </DesktopView> </IsAuth> ) } diff --git a/src/styles/globals.css b/src/styles/globals.css index 7f33abe8..d43dad1f 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -459,6 +459,10 @@ button { @apply font-medium; } +.table-data { + @apply w-full; +} + .table-data thead tr { @apply bg-gray_r-3; } |
