asset_browser/public/modules/labelGen.js
2026-03-27 09:18:39 -04:00

81 lines
3.4 KiB
JavaScript
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
}