/** * VenueFlow — Queue Management UI */ // Filter queue stations by category document.addEventListener('DOMContentLoaded', () => { const filterBtns = document.querySelectorAll('.queue-filter'); filterBtns.forEach(btn => { btn.addEventListener('click', () => { const category = btn.dataset.category; // Update active state filterBtns.forEach(b => { b.classList.remove('active'); b.classList.replace('btn-primary', 'btn-secondary'); b.setAttribute('aria-selected', 'false'); }); btn.classList.add('active'); btn.classList.replace('btn-secondary', 'btn-primary'); btn.setAttribute('aria-selected', 'true'); // Filter cards const cards = document.querySelectorAll('#queue-stations-list .queue-card'); cards.forEach(card => { if (category === 'all' || card.dataset.category === category) { card.style.display = 'flex'; } else { card.style.display = 'none'; } }); }); }); // Auto-refresh queue data setInterval(refreshQueues, 5000); }); async function refreshQueues() { try { const data = await apiCall('/api/queue/summary'); if (!data || !data.stations) return; data.stations.forEach(station => { const card = document.querySelector(`[data-station-id="${station.id}"]`); if (!card) return; const waitEl = card.querySelector('.queue-wait'); if (waitEl) { waitEl.textContent = Math.round(station.estimated_wait_minutes) + ' min'; waitEl.style.color = station.wait_color; } const metaEl = card.querySelector('.queue-meta'); if (metaEl) { metaEl.textContent = `${station.category_label} • ${station.current_length} in line`; } const progressBar = card.querySelector('.progress-bar'); if (progressBar) { const w = Math.min(station.estimated_wait_minutes * 3.3, 100); progressBar.style.width = w + '%'; progressBar.className = `progress-bar ${station.wait_level}`; } }); } catch (e) { // Silent fail for background refresh } } async function joinQueue(stationId) { try { const ticket = await apiCall('/api/queue/join', { method: 'POST', body: JSON.stringify({ station_id: stationId }), }); if (ticket && ticket.id) { showToast( 'Queue Joined! 🎫', `Ticket #${ticket.id} — Position ${ticket.position} at ${ticket.station_name}`, 'success', 8000 ); // Refresh the page to show updated tickets setTimeout(() => location.reload(), 1500); } } catch (err) { showToast('Could not join queue', err.message || 'Please try again', 'error'); } } async function cancelTicket(ticketId) { if (!confirm('Cancel this virtual queue ticket?')) return; try { await apiCall('/api/queue/cancel', { method: 'POST', body: JSON.stringify({ ticket_id: ticketId }), }); showToast('Ticket Cancelled', 'Your virtual queue spot has been released.', 'info'); setTimeout(() => location.reload(), 1000); } catch (err) { showToast('Could not cancel', err.message || 'Please try again', 'error'); } } console.log('⏱️ Queue UI loaded');