import { Controller } from '@hotwired/stimulus'; // Connects to data-controller="qr-code-scanner" export default class extends Controller { static targets = ['result', 'status']; isNativeApp = false; connect() { console.log('QR code scanner controller connected'); // Check if running in native app this.checkNativeApp(); // Register callback for QR code scan result this.registerCallback(); // Make handleScanResult available globally for iOS window.handleQrCodeScanResult = this.handleScanResult.bind(this); // Listen for hotwireNativeAvailable event document.addEventListener('hotwireNativeAvailable', this.onHotwireNativeAvailable.bind(this)); } disconnect() { console.log('QR code scanner controller disconnected'); document.removeEventListener('hotwireNativeAvailable', this.onHotwireNativeAvailable.bind(this)); if (window.handleQrCodeScanResult) { delete window.handleQrCodeScanResult; } } // Called when HotwireNative becomes available onHotwireNativeAvailable(event) { console.log('HotwireNative is now available event received'); // A small delay might be needed for the interface to be fully ready setTimeout(() => { this.checkNativeApp(); this.registerCallback(); }, 100); } // Check if running in native app checkNativeApp() { // Check for Android and iOS native interfaces if ( (window.HotwireNative && typeof window.HotwireNative.perform === 'function') || (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.qrCodeScanned) ) { console.log('Running in native app'); this.isNativeApp = true; } else { console.log('Not running in native app'); this.isNativeApp = false; } } registerCallback() { console.log('Attempting to register QR code scan callback'); // Android if (window.HotwireNative && typeof window.HotwireNative.registerCallback === 'function') { window.HotwireNative.registerCallback('qrCodeScanned', this.handleScanResult.bind(this)); console.log('QR code scan callback registered successfully for Android.'); // iOS } else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.qrCodeScanned) { console.log('iOS native interface detected. Callback will be handled by global function.'); } else { console.warn('Native callback registration is not available.'); } } scan() { console.log('Scan button clicked'); this.checkNativeApp(); if (this.isNativeApp) { // Android if (window.HotwireNative && typeof window.HotwireNative.perform === 'function') { console.log('Calling HotwireNative.perform("scanQrCode")'); window.HotwireNative.perform('scanQrCode'); // iOS } else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.qrCodeScanned) { console.log('Calling iOS QR code scanner'); window.webkit.messageHandlers.qrCodeScanned.postMessage({}); } } else { console.log('Not in native app, cannot scan.'); if (window.navigator.userAgent.includes('Android') || window.navigator.userAgent.includes('iPhone')) { this.showStatus('Scanner de QR code não disponível. Por favor, reinicie o aplicativo.', 'error'); } else { this.showStatus('O scanner de QR code só está disponível no aplicativo móvel.', 'info'); } } } // Handle scan result from native app handleScanResult(result) { console.log('Handling scan result:', result); if (!result || !result.qr_code) { console.error('Invalid QR code scan result', result); this.showStatus('Código QR inválido ou não reconhecido.', 'error'); return; } // Show the QR code in the UI this.showStatus(`Código QR escaneado: ${result.qr_code}`, 'info'); // Submit the QR code to the server this.submitQrCode(result.qr_code); } // Submit QR code to server submitQrCode(qrCode) { console.log('Submitting QR code to server:', qrCode); fetch('/tags/check', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]')?.content, }, body: JSON.stringify({ qr_code: qrCode }), }) .then((response) => { console.log('Server response:', response); if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then((data) => { console.log('Server data:', data); if (data.valid) { // Show success message this.showStatus(`Tag '${qrCode}' válido!`, 'success'); } else { // Show error message this.showStatus(`Tag '${qrCode}' não encontrado.`, 'error'); } }) .catch((error) => { console.error('Error checking QR code:', error); this.showStatus('Erro ao verificar o código QR.', 'error'); }); } // Show status message showStatus(message, type) { console.log('Showing status:', message, type); // Create status element if it doesn't exist if (!document.getElementById('status-message')) { const statusDiv = document.createElement('div'); statusDiv.id = 'status-message'; statusDiv.className = 'py-2 px-3 mb-5 font-medium rounded-md inline-block'; document.querySelector('.w-full')?.prepend(statusDiv); } const statusElement = document.getElementById('status-message'); if (statusElement) { statusElement.textContent = message; // Set appropriate class based on message type if (type === 'success') { statusElement.className = 'py-2 px-3 bg-green-50 mb-5 text-green-500 font-medium rounded-md inline-block'; } else if (type === 'error') { statusElement.className = 'py-2 px-3 bg-red-50 mb-5 text-red-500 font-medium rounded-md inline-block'; } else { statusElement.className = 'py-2 px-3 bg-blue-50 mb-5 text-blue-500 font-medium rounded-md inline-block'; } // Make sure the element is visible statusElement.style.display = 'block'; } else { console.error('Status element not found'); } } }