From c8d679d6a9edb3f301a7a50d9b12fe4b872c4429 Mon Sep 17 00:00:00 2001 From: Skylar Grant Date: Mon, 5 Jan 2026 15:11:25 -0500 Subject: [PATCH] Improved error handling, added FontInfo class. --- src/assets/ITThermal.js | 121 +++++++++++++++++++++++++++++++--------- 1 file changed, 96 insertions(+), 25 deletions(-) diff --git a/src/assets/ITThermal.js b/src/assets/ITThermal.js index bda7daa..be0f0bd 100644 --- a/src/assets/ITThermal.js +++ b/src/assets/ITThermal.js @@ -1,15 +1,13 @@ /* ITS Thermal Receipt Printer * Developed by Skylar Grant for MCCS ITS */ -const version = "1.2.3"; +const version = "1.2.4"; // ############################################################# // Variables // ############################################################# const docWidthPts = 204.09; // Documment width in points const docHeightPts = 1000; // Document height in points const verticalSpacing = 5; // Number of units to move down after each element -const standard = 'Helvetica'; // Font name to use for standard text -const monospace = 'Courier'; // Font name to use for monospace text const logoHeightMm = 32; // Logo height in millimeters const logoWidthMm = 70; // Logo width in millimeters @@ -48,9 +46,9 @@ const strings = { // Classes // ############################################################# class LineItem { - constructor(text, font, moveDownAfter) { + constructor(text, fontInfo, moveDownAfter) { this.text = text; - this.font = font || standard; + this.fontInfo = fontInfo; this.moveDownAfter = moveDownAfter || false; return this; @@ -64,11 +62,11 @@ class LineItem { return this; } - setFont(font) { - if (typeof font !== 'string') { - throw new Error('Font must be a string'); + setFontInfo(fontInfo) { + if (!(fontInfo instanceof FontInfo)) { + throw new Error('fontInfo must be an instance of FontInfo'); } - this.font = font; + this.fontInfo = fontInfo; return this; } @@ -81,6 +79,45 @@ class LineItem { } } +class FontInfo { + constructor(name, size, style) { + this.name = name || 'Helvetica'; + this.style = style || ''; + this.size = size || 12; + return this; + } + + setName(name) { + if (typeof name !== 'string') { + throw new Error('Font name must be a string'); + } + this.name = name; + return this; + } + + setSize(size) { + if (typeof size !== 'number' || size <= 0) { + throw new Error('Font size must be a positive number'); + } + this.size = size; + return this; + } + + setStyle(style) { + if (typeof style !== 'string') { + throw new Error('Font style must be a string'); + } + this.style = style; + return this; + } +} + +// ############################################################# +// Fonts +// ############################################################# +const standard = new FontInfo('Helvetica', 12); +const standardBold = new FontInfo('Helvetica', 12, 'Bold'); +const monospace = new FontInfo('Courier', 16, 'Bold'); // ############################################################# // Functions @@ -94,6 +131,11 @@ function tempPasswordHandler() { const username = document.getElementById('tempPwUsername').value; const password = document.getElementById('tempPwPassword').value; + if (password.trim() === '') { + alert('Please enter a temporary password.'); + return; + } + // Generate the line array and PDF const lineArray = prepTempPassword(password, username); const bUrl = generateFile(lineArray, true, true); @@ -104,6 +146,10 @@ function tempPasswordHandler() { function customNoteHandler() { // Grab the form values const customNoteDetails = document.getElementById('customNoteTextArea').value; + if (customNoteDetails.trim() === '') { + alert('Please enter some details for the note.'); + return; + } // Generate the line array and PDF const lineArray = prepCustomDetails(customNoteDetails); @@ -116,9 +162,19 @@ function deviceTrackerHandler() { // Grab the form values const dtticket = document.getElementById('dtticket').value; const dtuser = document.getElementById('dtuser').value; - const dtservice = document.querySelector('input[name="dtservice"]:checked').value; + const dtserviceinput = document.querySelector('input[name="dtservice"]:checked'); + if (!dtserviceinput) { + alert('Please select a service type.'); + return; + } + const dtservice = dtserviceinput.value; const dtnotes = document.getElementById('dtnotes').value; + if (dtticket.trim() === '' || dtuser.trim() === '' || dtservice.trim() === '') { + alert('Please fill out all required fields (Ticket Number, User, Service Type).'); + return; + } + // Generate the line array and PDF const lineArray = prepDeviceTracker(dtticket, dtuser, dtservice, dtnotes); const bUrl = generateFile(lineArray, true, false); @@ -152,7 +208,7 @@ function prepTempPassword(password, username) { lineArray.push(new LineItem(strings.tempPassword.pwLabel, standard, false)); lineArray.push(new LineItem(password, monospace, true)); - lineArray.push(new LineItem(strings.tempPassword.pwRequirements, standard, true)); + lineArray.push(new LineItem(strings.tempPassword.pwRequirements, standardBold, true)); return lineArray; }; @@ -218,15 +274,8 @@ function generateFile(lineArray, header, footer) { currentPos += logoHeightMm + ( verticalSpacing * 2); for (row of lineArray) { - // Set the fonts, TODO: this should be cleaned up with new data options in lineArray - if (row.font === monospace) { - doc.setFont(monospace, 'bold'); - doc.setFontSize(16); - } - if (row.font === standard) { - doc.setFontSize(12); - doc.setFont(standard, ''); - } + doc.setFont(row.fontInfo.name, row.fontInfo.style); + doc.setFontSize(row.fontInfo.size); // Split the text only after changing the font info: const stringArray = doc.splitTextToSize(row.text, 68); @@ -244,7 +293,7 @@ function generateFile(lineArray, header, footer) { // Print the footer if needed if (footer) { doc.setFontSize(12); - doc.setFont(standard, ''); + doc.setFont(standard.name, ''); doc.text(strings.global.receiptFooter, 0, currentPos); } @@ -276,11 +325,33 @@ function printPdf() { // Event Listeners // ############################################################# -document.getElementById('tempPasswordBtn').addEventListener('click', tempPasswordHandler); -document.getElementById('customNoteBtn').addEventListener('click', customNoteHandler); -document.getElementById('deviceTrackerBtn').addEventListener('click', deviceTrackerHandler); +document.getElementById('tempPasswordBtn').addEventListener('click', () => { + try { + tempPasswordHandler(); + } catch (error) { + alert(`An error occurred while generating the PDF: ${error.message}`); + } +}); +document.getElementById('customNoteBtn').addEventListener('click', () => { + try { + customNoteHandler(); + } catch (error) { + alert(`An error occurred while generating the PDF: ${error.message}`); + } +}); +document.getElementById('deviceTrackerBtn').addEventListener('click', () => { + try { + deviceTrackerHandler(); + } catch (error) { + alert(`An error occurred while generating the PDF: ${error.message}`); + } +}); // ############################################################# // Function Calls // ############################################################# -setVersionNumber(); \ No newline at end of file +try { + setVersionNumber(); +} catch (error) { + console.error(`An error occurred during initialization: ${error.message}`); +} \ No newline at end of file