Files
pantry-management-frontend/barcode-scanner.js
2026-03-08 16:25:59 +00:00

148 lines
4.4 KiB
JavaScript

// barcode-scanner.js - Barcode scanning module with console logging for testing
/**
* Initialize barcode scanner with dual input support:
* - Keyboard input (simulation)
* - Hardware barcode scanner devices
*
* Logs scanned barcodes to console for testing purposes
*/
let barcodeBuffer = '';
let lastBarcodeTime = 0;
const SCANNER_TIMEOUT = 100; // ms - detect hardware scanner vs human typing
/**
* Log barcode to console with metadata
* @param {string} barcode - The scanned barcode value
* @param {string} inputType - Either 'keyboard' or 'hardware-scanner'
*/
export function logBarcodeToConsole(barcode, inputType = 'keyboard') {
const timestamp = new Date().toLocaleTimeString('en-US', {
hour12: false,
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
fractionalSecondDigits: 3
});
console.log(
`%c[Barcode Scanned] %c${timestamp} | %cBarcode: %c${barcode} %c| Input: %c${inputType}`,
'color: #4CAF50; font-weight: bold;',
'color: #666; font-family: monospace;',
'color: #333; font-weight: bold;',
'color: #2196F3; font-weight: bold; font-family: monospace;',
'color: #666;',
'color: #FF9800; font-weight: bold;'
);
// Additional metadata for debugging
console.log({
barcode,
timestamp: new Date().toISOString(),
inputType,
length: barcode.length
});
}
/**
* Detect if input is from a hardware scanner or keyboard
* Hardware scanners typically input a full barcode very quickly (within SCANNER_TIMEOUT ms)
* @returns {string} - 'hardware-scanner' or 'keyboard'
*/
function detectInputType(currentTime) {
const timeSinceLastInput = currentTime - lastBarcodeTime;
lastBarcodeTime = currentTime;
// If more than SCANNER_TIMEOUT ms since last character, it's likely keyboard input
return timeSinceLastInput > SCANNER_TIMEOUT ? 'keyboard' : 'hardware-scanner';
}
/**
* Handle barcode input from both keyboard and hardware scanner
* @param {HTMLElement} inputElement - The input field element
* @param {Function} onBarcodeScanned - Callback function when barcode is complete
*/
export function initializeBarcodeScanner(inputElement, onBarcodeScanned) {
if (!inputElement) {
console.error('Barcode input element not found');
return;
}
// Auto-focus for seamless scanning
inputElement.focus();
inputElement.addEventListener('keypress', (event) => {
// Most barcode scanners send Enter key at the end
if (event.key === 'Enter') {
event.preventDefault();
const barcode = inputElement.value.trim();
if (barcode) {
// Detect input type
const inputType = barcodeBuffer.length === 0 ? 'keyboard' : 'hardware-scanner';
barcodeBuffer = '';
// Log to console
logBarcodeToConsole(barcode, inputType);
// Call the callback function
if (onBarcodeScanned) {
onBarcodeScanned(barcode, inputType);
}
}
// Clear input for next scan
inputElement.value = '';
inputElement.focus();
} else {
// Accumulate characters in buffer for input type detection
const now = Date.now();
if (barcodeBuffer === '') {
lastBarcodeTime = now;
}
barcodeBuffer += event.key;
}
});
// Handle pasted input (in case user pastes barcode)
inputElement.addEventListener('paste', (event) => {
event.preventDefault();
const pastedText = (event.clipboardData || window.clipboardData).getData('text').trim();
if (pastedText) {
logBarcodeToConsole(pastedText, 'keyboard-paste');
if (onBarcodeScanned) {
onBarcodeScanned(pastedText, 'keyboard-paste');
}
}
inputElement.value = '';
inputElement.focus();
});
// Maintain focus
inputElement.addEventListener('blur', () => {
setTimeout(() => inputElement.focus(), 0);
});
console.log('%cBarcode Scanner Initialized', 'color: #4CAF50; font-weight: bold;');
console.log('Ready to scan. Focus the input field and scan a barcode or press Enter to complete.');
}
/**
* Get scanning statistics from console (for testing)
* This is just a helper for development/testing
* @returns {Object} - Statistics object
*/
export function getScanningStats() {
return {
initialized: true,
timestamp: new Date().toISOString(),
message: 'Barcode scanner is active. Check console for scanned barcodes.'
};
}