// frontend/js/common-header.js document.addEventListener('DOMContentLoaded', () => { // --- CONFIGURATION --- const SOCKET_URL = "http://10.10.1.183:5000"; const API_BASE = "http://10.10.1.183:5000/api"; // --- STATE & SELECTED STATION --- let selectedStation = null; let socket; let statusPollingInterval; try { selectedStation = JSON.parse(localStorage.getItem('selected_station')); if (!selectedStation || !selectedStation.id) { window.location.href = './station_selection.html'; return; } } catch (e) { window.location.href = './station_selection.html'; return; } // --- HEADER DOM ELEMENTS --- const stationNameEl = document.getElementById('station-name'); const stationLocationEl = document.getElementById('station-location'); const stationIdEl = document.getElementById('station-id-display'); const productIdEl = document.getElementById('product-id-display'); const connChip = document.getElementById('connection-status-chip'); const lastUpdateEl = document.getElementById('last-update-status'); const logoutBtn = document.getElementById('logout-btn'); const navLinks = document.getElementById('main-nav'); const downloadBtn = document.getElementById('downloadBtn'); // --- INITIALIZATION --- function initializeHeader() { // Populate header with initial data if (stationNameEl) stationNameEl.textContent = selectedStation.name || 'Unknown'; if (stationLocationEl) stationLocationEl.textContent = selectedStation.location || 'No location'; if (stationIdEl) stationIdEl.textContent = selectedStation.id; if (productIdEl) productIdEl.textContent = selectedStation.product_id; // Highlight the active tab if (navLinks) { const currentPage = window.location.pathname.split('/').pop(); const activeLink = navLinks.querySelector(`a[href="./${currentPage}"]`); if (activeLink) { activeLink.classList.remove('text-gray-400', 'hover:text-gray-200'); activeLink.classList.add('border-b-2', 'border-emerald-400/70', 'text-white'); } } // Start polling and connect WebSocket checkStationStatus(); statusPollingInterval = setInterval(checkStationStatus, 10000); connectSocket(); // Add event listener for the logout button if (logoutBtn) { logoutBtn.addEventListener('click', () => { localStorage.clear(); window.location.href = './index.html'; }); } if (downloadBtn) { downloadBtn.addEventListener('click', showDownloadModal); } } // --- POLLING FOR ONLINE/OFFLINE STATUS --- const checkStationStatus = async () => { try { const response = await fetch(`${API_BASE}/stations`); if (!response.ok) return; const stations = await response.json(); const thisStation = stations.find(s => s.id === selectedStation.id); if (thisStation && connChip) { if (thisStation.status === 'Online') { connChip.innerHTML = ` Online`; connChip.className = 'cham_chip cham_chip-emerald'; } else { connChip.innerHTML = ` Offline`; connChip.className = 'cham_chip cham_chip-rose'; if (lastUpdateEl) lastUpdateEl.textContent = "Waiting for data..."; } } } catch (error) { console.error("Failed to fetch station status:", error); } }; const showDownloadModal = () => { const modalOverlay = document.createElement('div'); modalOverlay.className = "fixed inset-0 bg-black/70 backdrop-blur-sm flex items-center justify-center z-50"; modalOverlay.innerHTML = `

Export Logs

`; document.body.appendChild(modalOverlay); const startInput = document.getElementById('start-datetime'); const endInput = document.getElementById('end-datetime'); const fpConfig = { enableTime: true, dateFormat: "Y-m-d\\TH:i", time_24hr: true }; const fpStart = flatpickr(startInput, fpConfig); const fpEnd = flatpickr(endInput, fpConfig); const now = new Date(); fpStart.setDate(new Date(now.getTime() - 3600 * 1000), true); fpEnd.setDate(now, true); modalOverlay.querySelectorAll('.time-range-btn').forEach(button => { button.addEventListener('click', () => { const range = button.dataset.range; const now = new Date(); let start = new Date(); if (range === 'today') { start.setHours(0, 0, 0, 0); } else if (range === 'yesterday') { start.setDate(start.getDate() - 1); start.setHours(0, 0, 0, 0); now.setDate(now.getDate() - 1); now.setHours(23, 59, 59, 999); } else { start.setHours(now.getHours() - parseInt(range, 10)); } fpStart.setDate(start, true); fpEnd.setDate(now, true); }); }); document.getElementById('cancel-download').onclick = () => document.body.removeChild(modalOverlay); document.getElementById('confirm-download').onclick = async () => { const logType = document.getElementById('log-type').value; const startDateStr = document.getElementById('start-datetime').value; const endDateStr = document.getElementById('end-datetime').value; const confirmBtn = document.getElementById('confirm-download'); if (!startDateStr || !endDateStr) { return alert('Please select both a start and end date/time.'); } confirmBtn.textContent = 'Fetching...'; confirmBtn.disabled = true; const downloadUrl = `${API_BASE}/logs/export?station_id=${selectedStation.id}&start_datetime=${startDateStr}&end_datetime=${endDateStr}&log_type=${logType}`; try { const response = await fetch(downloadUrl); if (response.ok) { const blob = await response.blob(); const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.style.display = 'none'; a.href = url; let filename = `${selectedStation.name || selectedStation.id}_${logType}_${startDateStr.split('T')[0]}.csv`; const disposition = response.headers.get('Content-Disposition'); if (disposition && disposition.includes('attachment')) { const filenameMatch = disposition.match(/filename="(.+?)"/); if (filenameMatch && filenameMatch.length === 2) filename = filenameMatch[1]; } a.download = filename; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); document.body.removeChild(a); document.body.removeChild(modalOverlay); } else { const errorData = await response.json(); alert(`Could not download: ${errorData.message}`); } } catch (error) { alert('An unexpected error occurred. Please check the console.'); console.error('Download error:', error); } finally { confirmBtn.textContent = 'Download CSV'; confirmBtn.disabled = false; } }; }; // --- WEBSOCKET CONNECTION --- const connectSocket = () => { socket = io(SOCKET_URL); socket.on('connect', () => { console.log("Header: Connected to WebSocket."); socket.emit('join_station_room', { station_id: selectedStation.id }); }); socket.on('disconnect', () => console.log("Header: Disconnected from WebSocket.")); socket.on('dashboard_update', (message) => { if (message.stationId === selectedStation.id && lastUpdateEl) { lastUpdateEl.textContent = `Last Recv ${new Date().toLocaleTimeString()}`; } }); }; // --- START THE SCRIPT --- initializeHeader(); });