import jsPDF from "jspdf"; import QRCode from "qrcode"; interface LabelData { partNumber: string; quantity: number; } /** Load an image from a URL and return its base64 data URL */ async function loadImageAsBase64(url: string): Promise { return new Promise((resolve, reject) => { const img = new Image(); img.crossOrigin = "anonymous"; img.onload = () => { const canvas = document.createElement("canvas"); canvas.width = img.naturalWidth; canvas.height = img.naturalHeight; const ctx = canvas.getContext("2d"); if (!ctx) return reject(new Error("Canvas not supported")); ctx.drawImage(img, 0, 0); resolve(canvas.toDataURL("image/png")); }; img.onerror = () => reject(new Error("Failed to load image")); img.src = url; }); } /** * Generate a 49mm x 12mm label PDF with: * - Company icon (left, square) * - Code, Quantity, Count date (center) * - QR code (right) containing "PartNumber,Quantity" */ export async function generateLabelPdf(data: LabelData): Promise { const labelW = 49; // mm const labelH = 12; // mm const contentLeft = 1; // small padding const contentRight = labelW - 1; const doc = new jsPDF({ orientation: "landscape", unit: "mm", format: [labelW, labelH], }); const now = new Date(); const countDate = `${String(now.getDate()).padStart(2, "0")}/${String(now.getMonth() + 1).padStart(2, "0")}/${now.getFullYear()}`; // --- Icon (left side, square, filling most of the label height) --- const iconSize = 9; const iconX = contentLeft; const iconY = (labelH - iconSize) / 2; try { const iconBase64 = await loadImageAsBase64("/images/linse-icon.png"); doc.addImage(iconBase64, "PNG", iconX, iconY, iconSize, iconSize); } catch { // If icon fails, skip } // --- Text (center, maximised for 12mm height) --- const textX = iconX + iconSize + 1.5; // Code doc.setFontSize(7); doc.setFont("helvetica", "bold"); doc.setTextColor(0, 0, 0); doc.text(`Code: ${data.partNumber}`, textX, 3.8); // Quantity doc.text(`Quantity: ${data.quantity}`, textX, 7.2); // Count date doc.setFontSize(5.5); doc.setFont("helvetica", "normal"); doc.text(`Count date: ${countDate}`, textX, 10.4); // --- QR Code (right side, filling most of the label height) --- const qrContent = `${data.partNumber},${data.quantity}`; try { const qrDataUrl = await QRCode.toDataURL(qrContent, { width: 200, margin: 0, errorCorrectionLevel: "M", color: { dark: "#000000", light: "#ffffff" }, }); const qrSize = 10; const qrX = contentRight - qrSize; const qrY = (labelH - qrSize) / 2; doc.addImage(qrDataUrl, "PNG", qrX, qrY, qrSize, qrSize); } catch { doc.setFontSize(4); doc.text("QR Error", contentRight - 10, labelH / 2); } return doc; }