SwapStation_WebApp/frontend/js/station_selection.js

114 lines
5.4 KiB
JavaScript

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 = `
<div class="p-5">
<div class="flex justify-between items-start">
<h3 class="text-lg font-bold text-white pr-2">${station.name}</h3>
<div class="status-badge flex items-center text-xs font-semibold px-3 py-1 rounded-full ${status.bgColor} ${status.color}">
<i data-lucide="${status.icon}" class="w-4 h-4 mr-1.5"></i>
<span class="status-text">${station.status}</span>
</div>
</div>
<p class="text-sm text-gray-400 mt-1">${station.id}</p>
</div>
`;
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);
});