import Alpine from 'alpinejs'; Alpine.data('waitingRoom', () => ({ message: 'Waiting for the host to let you in…', denied: false, pollTimer: null, init() { this.pollTimer = setInterval(() => this.poll(), 5000); this.poll(); }, destroy() { if (this.pollTimer) { clearInterval(this.pollTimer); } }, async poll() { const url = this.$el.dataset.statusUrl; if (!url) return; try { const res = await fetch(url, { headers: { Accept: 'application/json' } }); const data = await res.json(); if (data.ended && data.redirect) { window.location.href = data.redirect; return; } if (data.redirect) { window.location.href = data.redirect; return; } if (data.denied) { this.denied = true; this.message = 'The host declined your request to join.'; clearInterval(this.pollTimer); } } catch { // ignore transient errors } }, })); Alpine.data('leaveFeedback', () => ({ rating: 0, audioRating: 0, videoRating: 0, hoverRating: 0, hoverAudio: 0, hoverVideo: 0, comment: '', setRating(value) { this.rating = value; }, setAudioRating(value) { this.audioRating = value; }, setVideoRating(value) { this.videoRating = value; }, canSubmit() { return this.rating > 0; }, })); Alpine.data('meetBadgeScanner', () => ({ scanning: false, scanError: '', scanner: null, toggle() { if (this.scanning) { this.stop(); return; } this.scanning = true; this.scanError = ''; this.$nextTick(() => this.start()); }, start() { if (typeof Html5Qrcode === 'undefined') { this.scanError = 'QR scanner could not load. Enter your badge code manually.'; this.scanning = false; return; } const el = document.getElementById('meet-badge-qr-reader'); if (!el) { return; } this.scanner = new Html5Qrcode('meet-badge-qr-reader'); this.scanner.start( { facingMode: 'environment' }, { fps: 10, qrbox: { width: 220, height: 220 } }, (decoded) => { const code = (decoded || '').trim().toUpperCase(); if (!code) { return; } this.stop(); const input = document.querySelector('input[name="badge_code"]'); if (input) { input.value = code; } input?.closest('form')?.requestSubmit(); }, () => {}, ).catch(() => { this.scanError = 'Camera access was denied or unavailable.'; this.scanning = false; }); }, stop() { if (!this.scanner) { this.scanning = false; return; } this.scanner.stop().catch(() => {}).finally(() => { this.scanner.clear().catch(() => {}); this.scanner = null; this.scanning = false; }); }, })); window.Alpine = Alpine; Alpine.start();