81 lines
3.4 KiB
JavaScript
Executable file
81 lines
3.4 KiB
JavaScript
Executable file
// labelGen.js — generates a label preview (barcode rendered via JsBarcode to canvas)
|
||
// and builds ZPL for Zebra printing.
|
||
|
||
export function formatPhone(raw) {
|
||
const digits = String(raw ?? '').replace(/\D/g, '');
|
||
if (digits.length === 10) {
|
||
return `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6)}`;
|
||
}
|
||
if (digits.length === 11 && digits[0] === '1') {
|
||
return `(${digits.slice(1, 4)}) ${digits.slice(4, 7)}-${digits.slice(7)}`;
|
||
}
|
||
return raw ?? '';
|
||
}
|
||
|
||
// Returns { html, svgIdForId, svgIdForSn } — caller renders serial barcode via renderBarcode()
|
||
export function buildLabelHTML(asset, prefix = 'lbl') {
|
||
const assetName = asset.name ?? 'Unknown Asset';
|
||
const serial = asset.asset_serial ?? asset.serial ?? asset.serial_number ?? '';
|
||
const customerName = asset.customer?.business_name ?? asset.customer?.business_then_name ?? asset.customer?.name ?? '';
|
||
const customerPhone = formatPhone(asset.customer?.phone ?? asset.customer?.mobile ?? '');
|
||
const customLine = asset.custom_line ?? '';
|
||
const logoSrc = '/assets/logo-swirl.png';
|
||
const svgIdForSn = `${prefix}-sn`;
|
||
|
||
const html = `
|
||
<div class="label-preview-wrap">
|
||
<div class="label-preview" id="label-preview-box">
|
||
<div class="label-header-row">
|
||
<div class="label-header-left">
|
||
<img src="${logoSrc}" alt="deRenzy BT" class="label-logo">
|
||
<span class="label-company">deRenzy Business Technologies</span>
|
||
</div>
|
||
<span class="label-derenzy-phone">(413) 739-4706</span>
|
||
</div>
|
||
<div class="label-content-row">
|
||
<div class="label-text-block">
|
||
<div class="label-asset-name">${esc(assetName)}</div>
|
||
${customerName ? `<div class="label-info-line">${esc(customerName)}</div>` : ''}
|
||
${customerPhone ? `<div class="label-info-line">${esc(customerPhone)}</div>` : ''}
|
||
${customLine ? `<div class="label-info-line label-custom-line">${esc(customLine)}</div>` : ''}
|
||
</div>
|
||
</div>
|
||
${serial ? `<div class="label-barcode-area"><img id="${svgIdForSn}" class="label-barcode-img" alt="barcode"></div>` : ''}
|
||
${serial ? `<div class="label-barcode-caption"><span>SN: ${esc(serial)}</span></div>` : ''}
|
||
</div>
|
||
</div>`;
|
||
|
||
return { html, svgIdForId: null, svgIdForSn: serial ? svgIdForSn : null, serial };
|
||
}
|
||
|
||
export function renderBarcode(imgId, value) {
|
||
// JsBarcode is loaded globally from /vendor/JsBarcode.all.min.js
|
||
if (typeof JsBarcode === 'undefined') {
|
||
console.error('JsBarcode not loaded');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
// Render to an off-screen canvas, then blast it into an <img> as a data URL.
|
||
// <img object-fit:fill> stretches reliably to fill its container — no SVG
|
||
// viewBox / preserveAspectRatio fighting required.
|
||
const canvas = document.createElement('canvas');
|
||
// JsBarcode sets canvas.width/height from (bar modules × width) and height option.
|
||
// width:4 gives 4px per bar module → crisp source pixels before CSS scaling.
|
||
JsBarcode(canvas, String(value), {
|
||
format: 'CODE128',
|
||
width: 4,
|
||
height: 400,
|
||
displayValue: false,
|
||
margin: 0,
|
||
});
|
||
const img = document.getElementById(imgId);
|
||
if (img) img.src = canvas.toDataURL('image/png');
|
||
} catch (err) {
|
||
console.warn('Barcode render error:', err);
|
||
}
|
||
}
|
||
|
||
function esc(s) {
|
||
return String(s ?? '').replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
|
||
}
|