feat: remove thermal view and switcher for Delhivery, display official carrier PDF directly
This commit is contained in:
parent
6100e8cdf7
commit
8ebbd3f6fc
1 changed files with 17 additions and 186 deletions
|
|
@ -33,7 +33,6 @@ export const OrdersPage: React.FC = () => {
|
|||
|
||||
// Modals state
|
||||
const [selectedOrderForLabel, setSelectedOrderForLabel] = useState<any | null>(null);
|
||||
const [labelViewMode, setLabelViewMode] = useState<'pdf' | 'thermal'>('pdf');
|
||||
|
||||
// Memoized PDF Blob URL from Delhivery base64 pdf_encoding, direct S3 pdf_url, or backend API endpoint
|
||||
const pdfBlobUrl = useMemo(() => {
|
||||
|
|
@ -211,7 +210,6 @@ export const OrdersPage: React.FC = () => {
|
|||
const labelData = res.label || res;
|
||||
labelData._order_id = ord.id;
|
||||
setSelectedOrderForLabel(labelData);
|
||||
setLabelViewMode('pdf');
|
||||
} catch (e: any) {
|
||||
alert(`Failed to fetch label: ${e.message}`);
|
||||
} finally {
|
||||
|
|
@ -757,13 +755,13 @@ export const OrdersPage: React.FC = () => {
|
|||
return (
|
||||
<div className="modal is-active">
|
||||
<div className="modal-background" onClick={() => setSelectedOrderForLabel(null)}></div>
|
||||
<div className="modal-card" style={{ maxWidth: (isDelhivery && labelViewMode === 'pdf' && pdfBlobUrl) ? '540px' : '480px', width: '95%' }}>
|
||||
<div className="modal-card" style={{ maxWidth: isDelhivery ? '560px' : '480px', width: '95%' }}>
|
||||
<header className="modal-card-head" style={{ background: '#ffffff', borderBottom: '1px solid var(--trad-border)', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<div>
|
||||
<p className="modal-card-title is-size-6 has-text-weight-bold" style={{ marginBottom: '2px' }}>
|
||||
{isDelhivery ? 'Delhivery Official Shipping Label' : 'Shadowfax 360 Official Shipping Label (4x6)'}
|
||||
</p>
|
||||
{isDelhivery && pdfBlobUrl && (
|
||||
{isDelhivery && (
|
||||
<span className="tag is-success is-light is-rounded" style={{ fontSize: '10px', height: '1.4em' }}>
|
||||
✓ Official Delhivery Vector PDF
|
||||
</span>
|
||||
|
|
@ -773,189 +771,22 @@ export const OrdersPage: React.FC = () => {
|
|||
</header>
|
||||
<section className="modal-card-body p-4 has-text-centered" style={{ background: '#EAEAEA' }}>
|
||||
|
||||
{/* Switcher Tab for Delhivery */}
|
||||
{isDelhivery && pdfBlobUrl && (
|
||||
<div className="is-flex is-justify-content-center mb-3">
|
||||
<div className="buttons has-addons">
|
||||
<button
|
||||
className={`button is-small is-rounded ${labelViewMode === 'pdf' ? 'is-trad-primary has-text-weight-bold' : 'is-white'}`}
|
||||
style={{ border: '1px solid var(--trad-border)' }}
|
||||
onClick={() => setLabelViewMode('pdf')}
|
||||
>
|
||||
📄 Official Carrier PDF
|
||||
</button>
|
||||
<button
|
||||
className={`button is-small is-rounded ${labelViewMode === 'thermal' ? 'is-trad-primary has-text-weight-bold' : 'is-white'}`}
|
||||
style={{ border: '1px solid var(--trad-border)' }}
|
||||
onClick={() => setLabelViewMode('thermal')}
|
||||
>
|
||||
🏷️ 4x6 Thermal View
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isDelhivery && labelViewMode === 'pdf' && pdfBlobUrl ? (
|
||||
{isDelhivery ? (
|
||||
/* Live Embedded Official Carrier PDF from Delhivery */
|
||||
<div style={{ width: '100%', height: '600px', background: '#ffffff', borderRadius: '6px', overflow: 'hidden', boxShadow: '0 4px 14px rgba(0,0,0,0.12)' }}>
|
||||
<iframe
|
||||
id="delhivery-pdf-frame"
|
||||
src={`${pdfBlobUrl}#view=FitH&toolbar=0`}
|
||||
title="Official Delhivery Shipping Label"
|
||||
style={{ width: '100%', height: '100%', border: 'none', display: 'block' }}
|
||||
/>
|
||||
</div>
|
||||
) : isDelhivery ? (
|
||||
/* Official Delhivery Packing Slip Thermal Label Format */
|
||||
<div
|
||||
id="printable-thermal-label"
|
||||
className="thermal-label-container has-text-left"
|
||||
style={{
|
||||
background: '#ffffff',
|
||||
border: '1.5px solid #000000',
|
||||
padding: '16px 14px 12px 14px',
|
||||
borderRadius: '2px',
|
||||
fontFamily: 'Arial, "Helvetica Neue", sans-serif',
|
||||
color: '#000000',
|
||||
width: '380px',
|
||||
minHeight: '570px',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
boxSizing: 'border-box',
|
||||
margin: '0 auto'
|
||||
}}
|
||||
>
|
||||
{/* Header Bar */}
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', paddingBottom: '4px', borderBottom: '1px solid #c8c8c8' }}>
|
||||
<span style={{ color: '#880000', fontWeight: 'bold', fontSize: '11px', letterSpacing: '0.2px' }}>
|
||||
Tradhox
|
||||
</span>
|
||||
<img
|
||||
src="https://track.delhivery.com/static/images/new_logo.png"
|
||||
alt="DELHIVERY"
|
||||
style={{ height: '30px', objectFit: 'contain' }}
|
||||
<div style={{ width: '100%', height: '620px', background: '#ffffff', borderRadius: '6px', overflow: 'hidden', boxShadow: '0 4px 14px rgba(0,0,0,0.12)' }}>
|
||||
{pdfBlobUrl ? (
|
||||
<iframe
|
||||
id="delhivery-pdf-frame"
|
||||
src={`${pdfBlobUrl}#view=FitH&toolbar=0`}
|
||||
title="Official Delhivery Shipping Label"
|
||||
style={{ width: '100%', height: '100%', border: 'none', display: 'block' }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* AWB Section */}
|
||||
<div style={{ marginTop: '8px', marginBottom: '6px' }}>
|
||||
<div style={{ fontSize: '13px', fontWeight: 'bold', color: '#000', marginBottom: '2px' }}>
|
||||
AWB# {awbStr}
|
||||
) : (
|
||||
<div className="p-6 has-text-centered is-flex is-flex-direction-column is-align-items-center is-justify-content-center" style={{ height: '100%' }}>
|
||||
<span className="loader mb-3" style={{ width: '28px', height: '28px' }}></span>
|
||||
<p className="has-text-grey has-text-weight-semibold">Loading official Delhivery carrier label...</p>
|
||||
</div>
|
||||
<div style={{ textAlign: 'center', margin: '3px 0' }}>
|
||||
<img
|
||||
src={selectedOrderForLabel.barcode_url || `https://bwipjs-api.metafloor.com/?bcid=code128&text=${encodeURIComponent(awbStr)}&scale=2&height=14`}
|
||||
alt="AWB Barcode"
|
||||
style={{ width: '100%', height: '54px', objectFit: 'fill', display: 'block' }}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', fontSize: '9.5px', color: '#000', marginTop: '2px' }}>
|
||||
<span>{destPincode}</span>
|
||||
<span style={{ fontWeight: 'bold', fontSize: '10.5px' }}>AWB# {awbStr}</span>
|
||||
<span>{sortCode}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ borderBottom: '1px solid #d0d0d0', marginBottom: '8px' }} />
|
||||
|
||||
{/* Ship to & Mode/Date */}
|
||||
<div style={{ display: 'flex', borderBottom: '2px solid #e0e0e0', paddingBottom: '8px', marginBottom: '8px' }}>
|
||||
{/* Ship to (Left) */}
|
||||
<div style={{ flex: '1 1 65%', paddingRight: '8px' }}>
|
||||
<div style={{ fontSize: '12px', color: '#000', marginBottom: '2px' }}>
|
||||
Ship to - <strong>{recipientName}</strong>{recipientPhone ? ` (Ph: ${recipientPhone})` : ''}
|
||||
</div>
|
||||
<div style={{ fontSize: '9.5px', color: '#222', lineHeight: '1.35', marginBottom: '4px' }}>
|
||||
{recipientAddress}
|
||||
</div>
|
||||
<div style={{ fontSize: '12px', fontWeight: 'bold', color: '#000', marginTop: '4px' }}>
|
||||
{destHub}
|
||||
</div>
|
||||
<div style={{ fontSize: '12px', fontWeight: 'bold', color: '#000' }}>
|
||||
PIN - {destPincode}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Payment & Date (Right) */}
|
||||
<div style={{ flex: '0 0 35%', borderLeft: '1px solid #d0d0d0', paddingLeft: '8px', display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
|
||||
<div>
|
||||
<div style={{ fontSize: '10px', fontWeight: 'bold', color: '#000' }}>
|
||||
{payModeDisplay}
|
||||
</div>
|
||||
<div style={{ fontSize: '14px', fontWeight: 'bold', color: '#000', marginTop: '2px' }}>
|
||||
INR {orderTotal}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div style={{ borderTop: '1px solid #e0e0e0', paddingTop: '4px', marginTop: '4px' }}>
|
||||
<div style={{ fontSize: '9.5px', color: '#666', fontWeight: '500' }}>Date</div>
|
||||
<div style={{ fontSize: '8.5px', color: '#222', whiteSpace: 'nowrap' }}>
|
||||
{labelDateDisplay}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Seller & Order ID Barcode */}
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', borderBottom: '1px solid #d0d0d0', paddingBottom: '8px', marginBottom: '8px' }}>
|
||||
{/* Seller info (Left) */}
|
||||
<div style={{ flex: '1 1 58%', paddingRight: '8px' }}>
|
||||
<div style={{ fontSize: '10px', color: '#000' }}>
|
||||
Seller:<strong>{sellerName}</strong>{sellerPhone ? ` (Ph: ${sellerPhone})` : ''}
|
||||
</div>
|
||||
<div style={{ fontSize: '9px', color: '#333', lineHeight: '1.3', marginTop: '2px' }}>
|
||||
{sellerAddress}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Order ID & Barcode (Right) */}
|
||||
<div style={{ flex: '0 0 42%', textAlign: 'left', paddingLeft: '4px' }}>
|
||||
<div style={{ fontSize: '12px', fontWeight: 'bold', color: '#000', marginBottom: '2px' }}>
|
||||
{cleanOrderId}
|
||||
</div>
|
||||
<div>
|
||||
<img
|
||||
src={selectedOrderForLabel.oid_barcode || `https://bwipjs-api.metafloor.com/?bcid=code128&text=${encodeURIComponent(cleanOrderId)}&scale=2&height=10`}
|
||||
alt="Order ID Barcode"
|
||||
style={{ width: '100%', height: '34px', objectFit: 'fill', display: 'block' }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Product Table */}
|
||||
<div style={{ flex: '1 1 auto', marginBottom: '14px' }}>
|
||||
<table style={{ width: '100%', borderCollapse: 'collapse', fontSize: '9.5px' }}>
|
||||
<thead>
|
||||
<tr style={{ color: '#000', fontWeight: 'bold', borderBottom: '1px solid #f0f0f0' }}>
|
||||
<th style={{ textAlign: 'left', padding: '2px 0', fontWeight: 'bold' }}>Product Name</th>
|
||||
<th style={{ textAlign: 'right', padding: '2px 4px', fontWeight: 'bold' }}>Qty.</th>
|
||||
<th style={{ textAlign: 'right', padding: '2px 4px', fontWeight: 'bold' }}>Price</th>
|
||||
<th style={{ textAlign: 'right', padding: '2px 0', fontWeight: 'bold' }}>Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style={{ textAlign: 'left', padding: '4px 0', color: '#222' }}>{itemName}</td>
|
||||
<td style={{ textAlign: 'right', padding: '4px 4px', color: '#222' }}>{itemQty}</td>
|
||||
<td style={{ textAlign: 'right', padding: '4px 4px', color: '#222' }}>{itemPrice}</td>
|
||||
<td style={{ textAlign: 'right', padding: '4px 0', color: '#222' }}>{orderTotal}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{/* Footer */}
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', borderTop: '1px solid #f0f0f0', paddingTop: '6px', fontSize: '8.5px', color: '#333' }}>
|
||||
<div style={{ maxWidth: '78%', lineHeight: '1.25' }}>
|
||||
Return Address: {returnAddress}
|
||||
</div>
|
||||
<div style={{ textAlign: 'right', color: '#444' }}>
|
||||
Page 1 of 1
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
/* Standard Shadowfax Label Format */
|
||||
|
|
@ -1036,7 +867,7 @@ export const OrdersPage: React.FC = () => {
|
|||
<button
|
||||
className="button is-trad-primary is-small is-rounded"
|
||||
onClick={() => {
|
||||
if (isDelhivery && labelViewMode === 'pdf' && pdfBlobUrl) {
|
||||
if (isDelhivery && pdfBlobUrl) {
|
||||
const iframe = document.getElementById('delhivery-pdf-frame') as HTMLIFrameElement;
|
||||
if (iframe && iframe.contentWindow) {
|
||||
try {
|
||||
|
|
@ -1056,7 +887,7 @@ export const OrdersPage: React.FC = () => {
|
|||
}}
|
||||
>
|
||||
<Printer size={14} className="mr-1" />
|
||||
<span>Print 4x6 Label</span>
|
||||
<span>{isDelhivery ? 'Print Official Label' : 'Print 4x6 Label'}</span>
|
||||
</button>
|
||||
</div>
|
||||
</footer>
|
||||
|
|
|
|||
Loading…
Reference in a new issue