diff options
| author | it-fixcomart <it@fixcomart.co.id> | 2025-07-29 09:46:05 +0700 |
|---|---|---|
| committer | it-fixcomart <it@fixcomart.co.id> | 2025-07-29 09:46:05 +0700 |
| commit | 077467cf53b46d8049df8b812577cd1a03011eba (patch) | |
| tree | 0dc641a9acb1237a3caca3f7f8a157a3e938c0b8 /src/lib/treckingAwb | |
| parent | 0d28dc8ff5fb8c5399e356ed6ecae4fce2019ca6 (diff) | |
| parent | dc31efb2fec4c7b79917324d922ae820c4b5bb50 (diff) | |
<hafid> merging new release
Diffstat (limited to 'src/lib/treckingAwb')
| -rw-r--r-- | src/lib/treckingAwb/api/getManifest.js | 17 | ||||
| -rw-r--r-- | src/lib/treckingAwb/component/InformationSection.jsx | 77 | ||||
| -rw-r--r-- | src/lib/treckingAwb/component/Manifest.jsx | 146 |
3 files changed, 210 insertions, 30 deletions
diff --git a/src/lib/treckingAwb/api/getManifest.js b/src/lib/treckingAwb/api/getManifest.js index 7d78a5f2..5523a164 100644 --- a/src/lib/treckingAwb/api/getManifest.js +++ b/src/lib/treckingAwb/api/getManifest.js @@ -1,9 +1,12 @@ -const { default: odooApi } = require("@/core/api/odooApi") -const { getAuth } = require("@/core/utils/auth") +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`) +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 + return manifest; +}; diff --git a/src/lib/treckingAwb/component/InformationSection.jsx b/src/lib/treckingAwb/component/InformationSection.jsx new file mode 100644 index 00000000..a2297af3 --- /dev/null +++ b/src/lib/treckingAwb/component/InformationSection.jsx @@ -0,0 +1,77 @@ +import { useState } from 'react'; +import toast from 'react-hot-toast'; + +const InformationSection = ({ manifests }) => { + 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 ( + <div className=''> + <div className='grid gap-y-4 p-4'> + <div className='grid grid-cols-[150px_auto] mb-4'> + <span className='font-semibold '>Nomor Resi</span> + <div className='flex gap-x-3'> + <span className='font-semibold'>: {manifests?.waybillNumber} </span> + <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 className='grid grid-cols-[150px_auto]'>*/} + {/* <span>Barang</span>*/} + {/* <span className='font-semibold'>: {manifests?.products}</span>*/} + {/*</div>*/} + <div className='grid grid-cols-[150px_auto]'> + <span>Kurir</span> + <span className='font-semibold'> + {' '} + : {manifests?.deliveryOrder?.carrier} + </span> + </div> + <div className='grid grid-cols-[150px_auto]'> + <span>Jenis Service</span> + <span className='font-semibold'> + {' '} + : {manifests?.deliveryOrder?.service} + </span> + </div> + <div className='grid grid-cols-[150px_auto]'> + <span>Tanggal Dikirim</span> + <span className='font-semibold'> : {manifests?.deliveredDate}</span> + </div> + <div className='grid grid-cols-[150px_auto]'> + <span>Estimasi Tiba</span> + <span className='font-semibold'> + :{' '} + <span className='text-red-600 font-semibold'>{manifests?.eta}</span> + </span> + </div> + </div> + </div> + ); +}; + +export default InformationSection; diff --git a/src/lib/treckingAwb/component/Manifest.jsx b/src/lib/treckingAwb/component/Manifest.jsx index 109bc832..5b456ccf 100644 --- a/src/lib/treckingAwb/component/Manifest.jsx +++ b/src/lib/treckingAwb/component/Manifest.jsx @@ -6,6 +6,32 @@ import { useEffect, useState } from 'react'; import { toast } from 'react-hot-toast'; import ImageNext from 'next/image'; import { list } from 'postcss'; +import InformationSection from './InformationSection'; +import Link from 'next/link'; + +function capitalizeFirstLetter(str) { + return str.charAt(0).toUpperCase() + str.slice(1); +} + +function capitalizeWords(str) { + return str + .split(' ') + .map((word) => capitalizeFirstLetter(word)) + .join(' '); +} + +function mappingLiveTracking(kurir, resi){ + let url = null + switch (kurir){ + case('grab'): + url = 'https://express.grab.com/track/orders?ids='+resi + break; + default: + url = false + } + + return url +} const Manifest = ({ idAWB, closePopup }) => { const [manifests, setManifests] = useState(null); @@ -60,15 +86,7 @@ const Manifest = ({ idAWB, closePopup }) => { } }, [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 - }; + const isLiveTracking = mappingLiveTracking(manifests?.deliveryOrder?.carrier.toLowerCase(), manifests?.waybillNumber) return ( <> @@ -85,7 +103,7 @@ const Manifest = ({ idAWB, closePopup }) => { {!isLoading && ( <BottomPopup key={manifests?.waybillNumber} - title='Detail Pengiriman' + title='Lacak Pengiriman' active={idAWB} close={closePopup} > @@ -101,12 +119,23 @@ const Manifest = ({ idAWB, closePopup }) => { <p className='text-yellow-600 text-sm'>Sedang Dikirim</p> </div> )} + {manifests?.status === 'cancelled' && ( + <div className='bg-red-800 p-2 rounded '> + <p className='text-white text-sm'>Di Batalkan</p> + </div> + )} + {manifests?.status === 'on_hold' && ( + <div className='bg-red-800 p-2 rounded '> + <p className='text-white text-sm'>Ditunda Sementara </p> + </div> + )} {manifests?.status === 'pending' && ( <div className='bg-red-100 p-2 rounded '> <p className='text-red-600 text-sm'>Pending</p> </div> )} </div> +<<<<<<< HEAD <div className=''> <h1 className='text-body-1'> Estimasi tiba pada{' '} @@ -180,25 +209,96 @@ const Manifest = ({ idAWB, closePopup }) => { } `} /> )} +======= +>>>>>>> new-release + + <InformationSection manifests={manifests} /> + + <hr className='mt-4' /> + {manifests?.isDelay && ( + <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>Pesanan anda mungkin mengalami keterlambatan tiba</div> + </div> + )} + <div className='pt-4'> + <ol className='relative'> + {manifests?.manifests?.map((manifest, index) => { + const isFirst = index === 0; + const isDelivered = manifests.delivered === true; + const isBiteship = manifests.isBiteship === true; + const statusTitle = + isDelivered && isFirst && !isBiteship + ? 'Pesanan sampai' + : isBiteship + ? capitalizeWords(manifest.status) + : ''; - <time class='text-sm leading-none text-gray-400'> + return ( + <li + className='grid grid-cols-[80px_20px_1fr] gap-2 mb-6 items-start' + key={index} + > + {/* Kolom 1: Tanggal + Jam */} + <div className='text-sm text-gray-400 whitespace-nowrap'> {formatCustomDate(manifest.datetime)} - </time> - {manifests.delivered == true && index == 0 && ( - <p - class={`leading-6 font-semibold text-sm text-green-600 `} - > - Sudah Sampai + </div> + + {/* Kolom 2: Bullet/Poin */} + <div className='relative flex items-start justify-center pt-1'> + <div + className={`w-3 h-3 rounded-full border ${ + index === 0 && manifests.delivered + ? 'bg-green-600 border-green-600' + : 'bg-gray-400 border-white' + }`} + /> + </div> + + {/* Kolom 3: Status dan Deskripsi */} + <div> + <p className='text-sm font-semibold text-green-600'> + {manifests?.deliveryOrder.carrier != 'Self Pick Up' + ? capitalizeWords(manifest.status) + : ''} </p> - )} - <p class={`leading-6 text-[12px] text-gray_r-11`}> - {manifest.description} - </p> + <p + className='text-xs text-gray-600' + dangerouslySetInnerHTML={{ + __html: manifest.description, + }} + /> + </div> </li> - </> - ))} + ); + })} </ol> </div> + <div className='pt-2'> + { + isLiveTracking && + manifests?.status === 'shipment' && ( + <Link + href={isLiveTracking} + target="_blank" + rel="noopener noreferrer" + className="inline-block px-4 py-2 bg-red-600 text-white font-semibold rounded-lg shadow-md hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-400 focus:ring-opacity-75" + > + Live Tracking + </Link> + ) + } + </div> </BottomPopup> )} </> |
