document.addEventListener('DOMContentLoaded', () => { // --- DOM ELEMENTS --- const stationsGrid = document.getElementById('stations-grid'); const stationTemplate = document.getElementById('stationCardTemplate'); const errorMessage = document.getElementById('error-message'); const stationCountEl = document.getElementById('station-count'); // Note: SocketIO is not needed on this page anymore let allStations = []; // To store the master list of stations // --- AUTHENTICATION & USER INFO (Your existing code is perfect) --- const user = JSON.parse(localStorage.getItem('user')); if (!user) { window.location.href = 'index.html'; // Redirect if not logged in return; } // User info and logout button logic... (omitted for brevity, no changes needed) // --- ADMIN FEATURES (Your existing code is perfect) --- // Admin button and add station card logic... (omitted for brevity, no changes needed) // --- HELPER FUNCTIONS --- const getStatusAttributes = (status) => { switch (status) { case 'Online': return { color: 'text-green-500', bgColor: 'bg-green-100/60 dark:bg-green-500/10', icon: 'power' }; case 'Offline': return { color: 'text-red-500', bgColor: 'bg-red-100/60 dark:bg-red-500/10', icon: 'power-off' }; default: return { color: 'text-gray-500', bgColor: 'bg-gray-100/60 dark:bg-gray-500/10', icon: 'help-circle' }; } }; const handleStationSelect = (stationId) => { window.location.href = `dashboard.html?station_id=${stationId}`; }; // This function now only renders the initial grid const renderStations = (stations) => { stationsGrid.innerHTML = ''; stationCountEl.textContent = `${stations.length} stations found. Select one to monitor.`; stations.forEach(station => { const status = getStatusAttributes(station.status); const card = document.createElement('div'); card.className = "group bg-gray-900/60 backdrop-blur-xl rounded-2xl shadow-lg border border-gray-700 transition-transform duration-300 ease-out cursor-pointer flex flex-col justify-between hover:-translate-y-1.5 hover:border-emerald-400/60 hover:shadow-[0_0_0_1px_rgba(16,185,129,0.25),0_20px_40px_rgba(0,0,0,0.45)]"; card.id = `station-${station.id}`; card.onclick = () => handleStationSelect(station.id); card.innerHTML = `

${station.name}

${station.status}

${station.id}

`; stationsGrid.appendChild(card); }); lucide.createIcons(); }; // --- NEW: Function to update statuses without redrawing everything --- const updateStationStatuses = (stations) => { stations.forEach(station => { const card = document.getElementById(`station-${station.id}`); if (card) { const status = getStatusAttributes(station.status); const statusBadge = card.querySelector('.status-badge'); const statusText = card.querySelector('.status-text'); const statusIcon = card.querySelector('i[data-lucide]'); if (statusBadge && statusText && statusIcon) { statusBadge.className = `status-badge flex items-center text-xs font-semibold px-3 py-1 rounded-full ${status.bgColor} ${status.color}`; statusText.textContent = station.status; statusIcon.setAttribute('data-lucide', status.icon); } } }); lucide.createIcons(); // Re-render icons if any changed }; // --- DATA FETCHING & STATUS POLLING --- const loadAndPollStations = async () => { try { const response = await fetch('http://localhost:5000/api/stations'); if (!response.ok) throw new Error('Failed to fetch stations'); const stations = await response.json(); // Check if this is the first time loading data if (allStations.length === 0) { allStations = stations; renderStations(allStations); // Initial full render } else { allStations = stations; updateStationStatuses(allStations); // Subsequent, efficient updates } } catch (error) { console.error(error); stationCountEl.textContent = 'Could not load stations. Is the backend running?'; // Stop polling on error if (pollingInterval) clearInterval(pollingInterval); } }; // --- INITIALIZATION --- loadAndPollStations(); // Load immediately on page start // Then, set an interval to refresh the statuses every 10 seconds const pollingInterval = setInterval(loadAndPollStations, 10000); });