diff options
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/auth/components/Menu.jsx | 50 | ||||
| -rw-r--r-- | src/lib/checkout/components/Checkout.jsx | 18 | ||||
| -rw-r--r-- | src/lib/shipment/api/listShipment.js | 9 | ||||
| -rw-r--r-- | src/lib/shipment/components/Shipments.jsx | 315 | ||||
| -rw-r--r-- | src/lib/transaction/components/Transaction.jsx | 53 | ||||
| -rw-r--r-- | src/lib/treckingAwb/api/getManifest.js | 9 | ||||
| -rw-r--r-- | src/lib/treckingAwb/component/Manifest.jsx | 177 |
7 files changed, 601 insertions, 30 deletions
diff --git a/src/lib/auth/components/Menu.jsx b/src/lib/auth/components/Menu.jsx index 386b817c..939a0d5f 100644 --- a/src/lib/auth/components/Menu.jsx +++ b/src/lib/auth/components/Menu.jsx @@ -1,5 +1,6 @@ import Link from '@/core/components/elements/Link/Link' import { useRouter } from 'next/router' +import ImageNext from 'next/image' const Menu = () => { const router = useRouter() @@ -10,30 +11,61 @@ const Menu = () => { <div className='grid grid-cols-1 bg-white border border-gray_r-6 rounded py-2 px-4 sticky top-48'> <div className='mt-4 mb-1 font-medium'>Menu</div> <LinkItem href='/my/quotations' active={routeStartWith('/my/quotations')}> - Daftar Quotation + <div className='flex gap-x-3 items-center'> + <ImageNext src='/images/icon/icon_daftar_quotation.svg' width={18} height={20} /> + <p>Daftar Quotation</p> + </div> </LinkItem> <LinkItem href='/my/transactions' active={routeStartWith('/my/transactions')}> - Daftar Transaksi + <div className='flex gap-x-3 items-center'> + <ImageNext src='/images/icon/icon_daftar_transaksi.svg' width={18} height={20} /> + <p>Daftar Transaksi</p> + </div> + </LinkItem> + <LinkItem href='/my/shipments' active={routeStartWith('/my/shipments')}> + <div className='flex gap-x-3 items-center'> + <ImageNext src='/images/icon/icon_pengiriman.svg' width={18} height={20} /> + <p>Daftar Pengiriman</p> + </div> </LinkItem> <LinkItem href='/my/invoices' active={routeStartWith('/my/invoices')}> - Invoice & Faktur Pajak + <div className='flex gap-x-3 items-center'> + <ImageNext src='/images/icon/icon_invoice.svg' width={18} height={20} /> + <p>Invoice & Faktur Pajak</p> + </div> </LinkItem> <LinkItem href='/my/wishlist' active={routeStartWith('/my/wishlist')}> - Wishlist + <div className='flex gap-x-3 items-center'> + <ImageNext src='/images/icon/icon_wishlist.svg' width={18} height={20} /> + <p>Wishlist</p> + </div> </LinkItem> - <div className='mt-4 mb-1 font-medium'>Pusat Bantuan</div> - <LinkItem href='/'>Layanan Pelanggan</LinkItem> + <LinkItem href='/'> + <div className='flex gap-x-3 items-center'> + <ImageNext src='/images/icon/icon_layanan_pelanggan.svg' width={18} height={20} /> + <p>Layanan Pelanggan</p> + </div> + </LinkItem> <div className='mt-4 mb-1 font-medium'>Pengaturan Akun</div> <LinkItem href='/my/address' active={routeStartWith('/my/address')}> - Daftar Alamat + <div className='flex gap-x-3 items-center'> + <ImageNext src='/images/icon/icon_daftar_alamat.svg' width={18} height={20} /> + <p>Daftar Alamat</p> + </div> </LinkItem> <LinkItem href='/my/profile' active={routeStartWith('/my/profile')}> - Profil Saya + <div className='flex gap-x-3 items-center'> + <ImageNext src='/images/icon/icon_profile.svg' width={18} height={20} /> + <p>Profil Saya</p> + </div> </LinkItem> <button type='button' className='text-gray_r-12/80 p-2 text-left'> - Keluar Akun + <div className='flex gap-x-3 items-center'> + <ImageNext src='/images/icon/icon_logout.svg' width={18} height={20} /> + <p>Keluar Akun</p> + </div> </button> </div> ) diff --git a/src/lib/checkout/components/Checkout.jsx b/src/lib/checkout/components/Checkout.jsx index afb94c10..0eb05345 100644 --- a/src/lib/checkout/components/Checkout.jsx +++ b/src/lib/checkout/components/Checkout.jsx @@ -297,10 +297,12 @@ const Checkout = () => { order_line: JSON.stringify(productOrder), delivery_amount: biayaKirim, carrier_id: selectedCarrierId, + estimated_arrival_days: splitDuration(etd), delivery_service_type: selectedExpedisiService, voucher: activeVoucher, type: 'sale_order' } + if (query) { data.source = 'buy' } @@ -1444,6 +1446,22 @@ function calculateEstimatedArrival(duration) { return '' } +function splitDuration(duration){ + if (duration) { + let estimationDate = null + if (duration.includes('-')){ + estimationDate = duration.split('-') + estimationDate = parseInt(estimationDate[1]) + }else{ + estimationDate = parseInt(duration) + } + + return estimationDate + } + + return '' +} + const extractDuration = (text) => { const matches = text.match(/\d+(?:-\d+)?/g) diff --git a/src/lib/shipment/api/listShipment.js b/src/lib/shipment/api/listShipment.js new file mode 100644 index 00000000..a9237b76 --- /dev/null +++ b/src/lib/shipment/api/listShipment.js @@ -0,0 +1,9 @@ +import odooApi from "@/core/api/odooApi"; +import { getAuth } from "@/core/utils/auth" + +export const listShipments = async ({query}) => { + const auth = getAuth() + const list = await odooApi('GET', `/api/v1/partner/${auth.partnerId}/stock-picking?${query}`) + + return list; +} diff --git a/src/lib/shipment/components/Shipments.jsx b/src/lib/shipment/components/Shipments.jsx new file mode 100644 index 00000000..c9d3e627 --- /dev/null +++ b/src/lib/shipment/components/Shipments.jsx @@ -0,0 +1,315 @@ +import DesktopView from '@/core/components/views/DesktopView' +import MobileView from '@/core/components/views/MobileView' +import Menu from '@/lib/auth/components/Menu' +import { EllipsisVerticalIcon, MagnifyingGlassIcon } from '@heroicons/react/24/outline' +import ImageNext from 'next/image' +import { useRouter } from 'next/router' +import { useQuery } from 'react-query' +import _ from 'lodash-contrib' +import Spinner from '@/core/components/elements/Spinner/Spinner' +import Manifest from '@/lib/treckingAwb/component/Manifest' +import { useState } from 'react' +import Pagination from '@/core/components/elements/Pagination/Pagination' +import Link from 'next/link' +import TransactionStatusBadge from '@/lib/transaction/components/TransactionStatusBadge' + +const { listShipments } = require('../api/listShipment') + +const Shipments = () => { + const router = useRouter() + const { q = '', page = 1 } = router.query + + const limit = 15 + + const query = { + q: q, + offset: (page - 1) * limit, + limit + } + console.log('ini query', query) + const [inputQuery, setInputQuery] = useState(q) + const queryString = _.toQuery(query) + + const { data: shipments } = useQuery('shipments', () => listShipments({ query: queryString })) + const [idAWB, setIdAWB] = useState(null) + + const pageCount = Math.ceil(shipments?.pickingTotal / limit) + let pageQuery = _.omit(query, ['limit', 'offset', 'context']) + pageQuery = _.pickBy(pageQuery, _.identity) + pageQuery = _.toQuery(pageQuery) + + const closePopup = () => { + setIdAWB(null) + } + + const handleSubmit = async (e) => { + e.preventDefault() + router.push(`${router.pathname}?q=${inputQuery}`) + } + return ( + <> + <MobileView> + <div className='p-4 flex flex-col gap-y-4'> + <div className='flex justify-between gap-x-1'> + <div className='flex justify-between items-center gap-x-2 p-2 bg-white border border-gray-200 rounded-lg shadow'> + <div> + <ImageNext src='/images/BOX(1).svg' width={15} height={20} /> + </div> + <h1 className='text-xs'>Pending</h1> + <h1 className='text-xs'> + {' '} + {shipments?.summary?.pendingCount} {'>'} + </h1> + </div> + <div className='flex justify-between items-center gap-x-2 p-2 bg-white border border-gray-200 rounded-lg shadow'> + <div> + <ImageNext src='/images/BOX_DELIVER_(1).svg' width={18} height={20} /> + </div> + <h1 className='text-xs'>Pengiriman</h1> + <h1 className='text-xs'> + {' '} + {shipments?.summary?.shipmentCount} {'>'} + </h1> + </div> + <div className='flex justify-between items-center gap-x-2 p-2 bg-white border border-gray-200 rounded-lg shadow'> + <div> + <ImageNext src='/images/open-box(1).svg' width={16} height={20} /> + </div> + <h1 className='text-xs'>Selesai</h1> + <h1 className='text-xs'> + {' '} + {shipments?.summary?.shipmentCount} {'>'} + </h1> + </div> + </div> + + <form className='flex gap-x-3' onSubmit={handleSubmit}> + <input + type='text' + className='form-input' + placeholder='Cari Pengiriman...' + value={inputQuery} + onChange={(e) => setInputQuery(e.target.value)} + /> + <button className='btn-light bg-transparent px-3' type='submit'> + <MagnifyingGlassIcon className='w-6' /> + </button> + </form> + + {shipments?.pickings.map((shipment) => ( + <div className='p-4 shadow border border-gray_r-3 rounded-md' key={shipment.id}> + <div className='flex justify-between items-center mb-3'> + <div className='text-caption-2 text-gray_r-11'> + <p> + Kurir :{' '} + <span className='text-gray_r-11 font-semibold'> + {shipment.carrierName || '-'} + </span> + </p> + <p className='mt-2'>No. Resi : {shipment.trackingNumber || '-'}</p> + </div> + <div className='flex justify-between'> + {shipment?.delivered && ( + <div className='bg-green-100 p-2 rounded '> + <p className='text-green-600 text-sm'>Pesanan Tiba</p> + </div> + )} + {!shipment?.delivered && ( + <div className='bg-red-100 p-2 rounded '> + <p className='text-red-600 text-sm'>Sedang Dikirim</p> + </div> + )} + </div> + </div> + <hr /> + <div className='flex justify-between mt-2 items-center mb-5'> + <div> + <span className='text-caption-2 text-gray_r-11'>No. Transaksi</span> + <Link href={`/my/transactions/${shipment.saleOrder.id}`}> + <h2 className='text-danger-500 mt-1 mb-2'>{shipment.saleOrder.name}</h2> + </Link> + <span className='text-caption-2 text-gray_r-11'>{shipment.date}</span> + </div> + <div> + <button + onClick={() => setIdAWB(shipment.id)} + className='bg-red-600 p-2 border border-red-600 rounded text-white w-24' + > + {!shipment.delivered ? 'Lacak' : 'Histori'} + </button> + </div> + </div> + <hr /> + <button + onClick={() => setIdAWB(shipment.id)} + className='flex items-center mt-1 gap-x-1 min-w-full' + > + <ImageNext src={`/images/BOX_DELIVERY_GREEN.svg`} width={20} height={20} /> + <p className='text-sm text-green-700 truncate'> + {shipment.lastManifest.description} + </p> + <p className='ml-auto'>{'>'}</p> + </button> + </div> + ))} + + <Pagination + pageCount={pageCount} + currentPage={parseInt(page)} + url={router.pathname + pageQuery} + className='mt-2 mb-2' + /> + </div> + + <Manifest idAWB={idAWB} closePopup={closePopup} /> + </MobileView> + <DesktopView> + <div className='container mx-auto flex py-10'> + <div className='w-3/12 pr-4'> + <Menu /> + </div> + <div className='w-9/12'> + <div className='p-4 bg-white border border-gray_r-6 rounded mb-2'> + <h1 className='text-title-sm font-semibold'>Pengiriman</h1> + <div + class='flex items-center p-4 mb-4 text-sm text-yellow-800 rounded-lg bg-yellow-50' + role='alert' + > + <svg + class='flex-shrink-0 inline w-4 h-4 mr-3' + aria-hidden='true' + fill='currentColor' + viewBox='0 0 20 20' + > + <path d='M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z' /> + </svg> + <div> + <span class='font-medium'>Warning alert!</span> Change a few things up and try + submitting again. + </div> + </div> + <div className='flex justify-between gap-x-5'> + <div class='max-w-sm p-6 bg-white border border-gray-200 rounded-lg shadow min-w-[268px]'> + <h2 class='mb-2 text-lg font-bold tracking-tight'>Pending</h2> + <div className='bg-red-100 border border-red-200 rounded-sm p-2 w-20 h-[39px] mb-2'> + <div> + <ImageNext + src='/images/BOX(1).svg' + width={25} + height={20} + style={{ stroke: 'red' }} + /> + </div> + </div> + <h1 className='text-xl font-bold'> + {shipments?.summary?.pendingCount} <span className='text-sm'>Pesanan</span> + </h1> + </div> + <div class='max-w-sm p-6 bg-white border border-gray-200 rounded-lg shadow min-w-[268px]'> + <h5 class='mb-2 text-lg font-bold tracking-tight'>Pengiriman</h5> + <div className='bg-yellow-100 border border-yellow-200 rounded-sm p-1 w-20 mb-2'> + <div> + <ImageNext src='/images/BOX_DELIVER_(1).svg' width={30} height={20} /> + </div> + </div> + <h1 className='text-xl font-bold'> + {shipments?.summary?.shipmentCount} <span className='text-sm'>Pesanan</span> + </h1> + </div> + <div class='max-w-sm p-6 bg-white border border-gray-200 rounded-lg shadow min-w-[268px]'> + <h5 class='mb-2 text-lg font-bold tracking-tight'>Pesanan Tiba</h5> + <div className='bg-green-100 border border-green-200 rounded-sm p-1 w-20 mb-2'> + <div> + <ImageNext + src='/images/open-box(1).svg' + width={30} + height={20} + className='stroke-orange-600' + /> + </div> + </div> + <h1 className='text-xl font-bold'> + {shipments?.summary?.completedCount} <span className='text-sm'>Pesanan</span> + </h1> + </div> + </div> + </div> + <div className='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'>Detail Pengiriman</h1> + <form className='flex gap-x-2' onSubmit={handleSubmit}> + <input + type='text' + className='form-input' + placeholder='Cari Pengiriman...' + value={inputQuery} + onChange={(e) => setInputQuery(e.target.value)} + /> + <button className='btn-light bg-transparent px-3' type='submit'> + <MagnifyingGlassIcon className='w-6' /> + </button> + </form> + </div> + <table className='table-data'> + <thead> + <tr> + <th>Tanggal</th> + <th>No. Resi</th> + <th>No. Pengiriman</th> + <th>Sales Order</th> + <th>Purchase Order</th> + <th>Expedisi</th> + <th>Status</th> + </tr> + </thead> + <tbody> + {!shipments && ( + <tr> + <td colSpan={7}> + <div className='flex justify-center my-2'> + <Spinner className='w-6 text-gray_r-12/50 fill-gray_r-12' /> + </div> + </td> + </tr> + )} + {shipments && shipments?.pickings?.length == 0 && ( + <tr> + <td colSpan={7}>Tidak ada transaksi</td> + </tr> + )} + {shipments?.pickings.map((shipment) => ( + <tr key={shipment.id}> + <td>{shipment.date || '-'}</td> + <td>{shipment.trackingNumber || '-'}</td> + <td>{shipment.name || '-'}</td> + <td>{shipment.saleOrder.name || '-'}</td> + <td>{shipment.saleOrder.clientOrderRef || '-'}</td> + <td>{shipment.carrierName || '-'}</td> + <td> + <button + onClick={() => setIdAWB(shipment.id)} + className='bg-red-600 border border-red-600 rounded-md text-sm text-white p-1 w-20' + > + Lacak + </button> + </td> + </tr> + ))} + </tbody> + </table> + <Pagination + pageCount={pageCount} + currentPage={parseInt(page)} + url={router.pathname + pageQuery} + className='mt-2 mb-2' + /> + </div> + </div> + </div> + <Manifest idAWB={idAWB} closePopup={closePopup} /> + </DesktopView> + </> + ) +} + +export default Shipments diff --git a/src/lib/transaction/components/Transaction.jsx b/src/lib/transaction/components/Transaction.jsx index 74f3dbd5..82eb1775 100644 --- a/src/lib/transaction/components/Transaction.jsx +++ b/src/lib/transaction/components/Transaction.jsx @@ -21,6 +21,7 @@ import Image from '@/core/components/elements/Image/Image' import { createSlug } from '@/core/utils/slug' import toTitleCase from '@/core/utils/toTitleCase' import useAirwayBill from '../hooks/useAirwayBill' +import Manifest from '@/lib/treckingAwb/component/Manifest' const Transaction = ({ id }) => { const { transaction } = useTransaction({ id }) @@ -31,6 +32,7 @@ const Transaction = ({ id }) => { const poNumber = useRef(null) const poFile = useRef(null) const [uploadPo, setUploadPo] = useState(false) + const [idAWB, setIdAWB] = useState(null) const openUploadPo = () => setUploadPo(true) const closeUploadPo = () => setUploadPo(false) const submitUploadPo = async () => { @@ -110,6 +112,10 @@ const Transaction = ({ id }) => { ) } + const closePopup = () => { + setIdAWB(null) + } + return ( transaction.data?.name && ( <> @@ -158,6 +164,7 @@ const Transaction = ({ id }) => { </button> </div> </BottomPopup> + <Manifest idAWB={idAWB} closePopup={closePopup}></Manifest> <MobileView> <div className='flex flex-col gap-y-4 p-4'> @@ -179,26 +186,28 @@ const Transaction = ({ id }) => { <div className='p-4'> <div className='font-medium'>Pengiriman</div> <div className='flex flex-col gap-y-3 mt-4'> - {queryAirwayBill.data?.airways?.map((airway) => ( + {transaction?.data?.pickings?.map((airway) => ( <button - className='shadow rounded-md p-4 text-gray_r-12 font-normal flex justify-between items-center text-left' - key={airway?.waybillNumber} - onClick={() => setAirwayBillPopup(airway?.waybillNumber)} + className='shadow rounded-md p-3 text-gray_r-12 font-normal flex justify-between items-center text-left' + key={airway?.id} + onClick={() => setIdAWB(airway?.id)} > <div> - <span className='text-sm text-gray_r-11'>No Resi</span> - <p className='mt-1 font-medium'>{airway?.waybillNumber}</p> + <span className='text-sm text-gray_r-11'> + No Resi : {airway?.trackingNumber || '-'}{' '} + </span> + <p className='mt-1 font-medium'>{airway?.name}</p> </div> <div className='flex gap-x-2'> - <div className='text-sm text-gray_r-11 badge-green'> - {airway?.deliveryStatus?.status} + <div className='text-sm text-gray-600 badge-green leading-[1.5] mt-1'> + {airway?.delivered ? 'Pesanan Tiba' : 'Sedang Dikirim'} </div> <ChevronRightIcon className='w-5 stroke-2' /> </div> </button> ))} </div> - {!queryAirwayBill?.data?.airways && ( + {transaction?.data?.pickings == 0 && ( <div className='badge-red text-sm px-2'>Belum ada pengiriman</div> )} </div> @@ -368,27 +377,29 @@ const Transaction = ({ id }) => { </div> <div className='text-h-sm font-semibold mt-10 mb-4'>Pengiriman</div> - <div className='grid grid-cols-3 gap-4'> - {queryAirwayBill.data?.airways?.map((airway) => ( + <div className='grid grid-cols-3 gap-1'> + {transaction?.data?.pickings?.map((airway) => ( <button - className='shadow rounded-md p-4 text-gray_r-12 font-normal flex justify-between items-center text-left' - key={airway?.waybillNumber} - onClick={() => setAirwayBillPopup(airway?.waybillNumber)} + className='shadow rounded-md p-3 text-gray_r-12 font-normal flex justify-between items-center text-left' + key={airway?.id} + onClick={() => setIdAWB(airway?.id)} > <div> - <span className='text-sm text-gray_r-11'>No Resi</span> - <p className='mt-1 font-medium'>{airway?.waybillNumber}</p> + <span className='text-sm text-gray_r-11'> + No Resi : {airway?.trackingNumber || '-'}{' '} + </span> + <p className='mt-1 font-medium'>{airway?.name}</p> </div> <div className='flex gap-x-2'> - <div className='text-sm text-gray_r-11 badge-green'> - {airway?.deliveryStatus?.status} + <div className='text-sm text-gray-600 badge-green leading-[1.5] mt-1'> + {airway?.delivered ? 'Pesanan Tiba' : 'Sedang Dikirim'} </div> <ChevronRightIcon className='w-5 stroke-2' /> </div> </button> ))} </div> - {!queryAirwayBill.data?.airways && ( + {transaction?.data?.pickings.length == 0 && ( <div className='badge-red text-sm'>Belum ada pengiriman</div> )} @@ -514,7 +525,7 @@ const Transaction = ({ id }) => { </div> </DesktopView> - {queryAirwayBill.data?.airways?.map((airway) => ( + {/* {queryAirwayBill.data?.airways?.map((airway) => ( <BottomPopup key={airway.waybillNumber} title='Detail Pengiriman' @@ -564,7 +575,7 @@ const Transaction = ({ id }) => { </ol> </div> </BottomPopup> - ))} + ))} */} </> ) ) diff --git a/src/lib/treckingAwb/api/getManifest.js b/src/lib/treckingAwb/api/getManifest.js new file mode 100644 index 00000000..7d78a5f2 --- /dev/null +++ b/src/lib/treckingAwb/api/getManifest.js @@ -0,0 +1,9 @@ +const { default: odooApi } = require("@/core/api/odooApi") +const { getAuth } = require("@/core/utils/auth") + +export const getManifest = async ({id}) => { + const auth = getAuth() + const manifest = await odooApi('GET', `/api/v1/partner/${auth.partnerId}/stock-picking/${id}/tracking`) + + return manifest +}
\ No newline at end of file diff --git a/src/lib/treckingAwb/component/Manifest.jsx b/src/lib/treckingAwb/component/Manifest.jsx new file mode 100644 index 00000000..185a9d55 --- /dev/null +++ b/src/lib/treckingAwb/component/Manifest.jsx @@ -0,0 +1,177 @@ +import odooApi from '@/core/api/odooApi' +import BottomPopup from '@/core/components/elements/Popup/BottomPopup' +import LogoSpinner from '@/core/components/elements/Spinner/LogoSpinner' +import { getAuth } from '@/core/utils/auth' +import { useEffect, useState } from 'react' +import { toast } from 'react-hot-toast' +import ImageNext from 'next/image' + +const Manifest = ({ idAWB, closePopup }) => { + const [manifests, setManifests] = useState(null) + const [isLoading, setIsLoading] = useState(false) + + const formatCustomDate = (date) => { + const months = [ + 'Jan', + 'Feb', + 'Mar', + 'Apr', + 'May', + 'Jun', + 'Jul', + 'Aug', + 'Sep', + 'Oct', + 'Nov', + 'Dec' + ] + + const parts = date.split(' ') // Pisahkan tanggal dan waktu + const [datePart, timePart] = parts + const [yyyy, mm, dd] = datePart.split('-') + const [hh, min] = timePart.split(':') + + const monthAbbreviation = months[parseInt(mm, 10) - 1] + + return `${dd} ${monthAbbreviation} ${hh}:${min}` + } + + const getManifest = async () => { + setIsLoading(true) + const auth = getAuth() + const list = await odooApi( + 'GET', + `/api/v1/partner/${auth.partnerId}/stock-picking/${idAWB}/tracking` + ) + setManifests(list) + setIsLoading(false) + } + + useEffect(() => { + if (idAWB) { + getManifest() + } else { + setManifests(null) + } + }, [idAWB]) + + const [copied, setCopied] = useState(false) + + const handleCopyClick = () => { + const textToCopy = manifests?.waybillNumber + navigator.clipboard.writeText(textToCopy) + setCopied(true) + toast.success('No Resi Berhasil di Copy') + setTimeout(() => setCopied(false), 2000) // Reset copied state after 2 seconds + } + + return ( + <> + {isLoading && ( + <BottomPopup active={true} close=''> + <div className='leading-7 text-gray_r-12/80 flex justify-center'>Mohon Tunggu</div> + <div className='container flex justify-center my-4'> + <LogoSpinner width={48} height={48} /> + </div> + </BottomPopup> + )} + {!isLoading && ( + <BottomPopup + key={manifests?.waybillNumber} + title='Detail Pengiriman' + active={idAWB} + close={closePopup} + > + <div className='flex justify-between items-center mb-5'> + <h1 className='text-body-1'>Status Pesanan</h1> + {manifests?.delivered && ( + <div className='bg-green-100 p-2 rounded '> + <p className='text-green-600 text-sm'>Pesanan Tiba</p> + </div> + )} + {!manifests?.delivered && ( + <div className='bg-red-100 p-2 rounded '> + <p className='text-red-600 text-sm'>Sedang Dikirim</p> + </div> + )} + </div> + <div className=''> + <h1 className='text-body-1'> + Estimasi tiba pada <span className='text-gray_r-11 text-sm'>({manifests?.eta})</span> + </h1> + <h1 className='text-sm mt-2 mb-3'> + Dikirim Menggunakan{' '} + <span className='text-red-500 font-semibold'>{manifests?.deliveryOrder.carrier}</span> + </h1> + {manifests?.waybillNumber && ( + <div className='flex justify-between items-center'> + <h1>No. Resi</h1> + <div className='flex justify-between gap-x-2 items-center'> + <h1 className='font-semibold'>{manifests?.waybillNumber}</h1> + <button + className={`${copied ? 'text-gray-400' : 'text-red-600 '}`} + onClick={() => handleCopyClick()} + > + <svg + aria-hidden='true' + fill='none' + stroke='currentColor' + stroke-width='1.5' + viewBox='0 0 24 24' + className='w-5 h-6' + > + <path + d='M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 01-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 011.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 00-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 01-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 00-3.375-3.375h-1.5a1.125 1.125 0 01-1.125-1.125v-1.5a3.375 3.375 0 00-3.375-3.375H9.75' + stroke-linecap='round' + stroke-linejoin='round' + ></path> + </svg> + </button> + </div> + </div> + )} + </div> + <hr className='mt-4' /> + <div className='pt-4'> + <ol class='relative border-l border-gray_r-7'> + {manifests?.manifests?.map((manifest, index) => ( + <> + <li class='mb-6 ml-4' key={index}> + {manifests.delivered == true && index == 0 ? ( + <div + class={`absolute w-6 h-6 rounded-full mt-1.5 -left-3 border ${ + index == 0 ? 'bg-green-100 border-green-100' : 'bg-gray_r-7 border-white' + }`} + > + <ImageNext src='/images/open-box(1).svg' width={30} height={20} /> + </div> + ) : ( + <div + class={`absolute w-3 h-3 rounded-full mt-1.5 -left-1.5 border bg-gray_r-7 border-white`} + /> + )} + {manifests.delivered != true && ( + <div + class={`absolute w-3 h-3 rounded-full mt-1.5 -left-1.5 border ${index == 0 ? 'bg-green-600 border-green-600' : 'bg-gray_r-7 border-white'} `} + /> + )} + + <time class='text-sm leading-none text-gray-400'> + {formatCustomDate(manifest.datetime)} + </time> + {manifests.delivered == true && index == 0 && ( + <p class={`leading-6 font-semibold text-sm text-green-600 `}>Sudah Sampai</p> + )} + <p class={`leading-6 text-[12px] text-gray_r-11`}>{manifest.description}</p> + </li> + </> + ))} + </ol> + </div> + </BottomPopup> + )} + </> + ) +} + +export default Manifest |
