document.addEventListener('DOMContentLoaded', () => {
// --- DOM ELEMENTS ---
const stationsGrid = document.getElementById('stations-grid');
const stationCountEl = document.getElementById('station-count'); // Make sure you have an element with this ID in your HTML
// --- CONFIG & STATE ---
const API_BASE = 'http://172.20.10.4:5000/api';
let allStations = []; // Master list of stations from the API
let pollingInterval = null;
// --- AUTHENTICATION ---
const user = JSON.parse(localStorage.getItem('user'));
if (!user) {
window.location.href = 'index.html'; // Redirect if not logged in
return;
}
// (Your other button listeners for logout, add user, etc., can go here)
// document.getElementById('logoutBtn').onclick = () => { ... };
// --- 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}`;
};
// --- UI RENDERING ---
// This function's only job is to build the HTML. It does not add event listeners.
const renderStations = (stations) => {
stationsGrid.innerHTML = ''; // Clear the grid
stationCountEl.textContent = `${stations.length} stations found.`;
stations.forEach(station => {
const status = getStatusAttributes(station.status);
const card = document.createElement('div');
// Add station ID to the card's dataset for easy access
card.dataset.stationId = station.id;
card.dataset.stationName = station.name;
card.className = "station-card group bg-gray-900/60 backdrop-blur-xl rounded-2xl shadow-lg border border-gray-700 transition-transform duration-300 ease-out 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.innerHTML = `
${station.name}
# ${station.product_id || 'N/A'}
${station.status}
${station.id}
`;
stationsGrid.appendChild(card);
});
if (window.lucide) {
lucide.createIcons();
}
};
const updateStationStatuses = (stations) => {
stations.forEach(station => {
const card = stationsGrid.querySelector(`[data-station-id="${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);
}
}
});
if (window.lucide) {
lucide.createIcons();
}
};
//-- NEW: Fetch and apply daily stats to each card ---
const fetchAndApplyStats = async () => {
try {
const response = await fetch(`${API_BASE}/stations/daily-stats`);
if (!response.ok) return; // Fail silently if stats aren't available
const stats = await response.json();
// Loop through the stats object and update each card
for (const stationId in stats) {
const stationCard = stationsGrid.querySelector(`.station-card[data-station-id="${stationId}"]`);
if (stationCard) {
const statData = stats[stationId];
stationCard.querySelector('.stat-total').textContent = statData.total_starts;
stationCard.querySelector('.stat-completed').textContent = statData.completed;
stationCard.querySelector('.stat-aborted').textContent = statData.aborted;
}
}
} catch (error) {
console.error("Could not fetch daily stats:", error);
}
};
// --- MAIN EVENT LISTENER ---
// This single listener handles all clicks on the grid for efficiency.
stationsGrid.addEventListener('click', async (event) => {
const mainContent = event.target.closest('.main-content');
const removeButton = event.target.closest('.remove-btn');
if (mainContent) {
const card = mainContent.closest('[data-station-id]');
if (card) {
handleStationSelect(card.dataset.stationId);
}
} else if (removeButton) {
event.stopPropagation(); // Prevent main content click
const card = removeButton.closest('[data-station-id]');
const stationId = card.dataset.stationId;
const stationName = card.dataset.stationName;
if (!confirm(`Are you sure you want to permanently remove "${stationName}"?`)) {
return;
}
try {
const response = await fetch(`${API_BASE}/stations/${stationId}`, { method: 'DELETE' });
if (response.ok) {
alert(`Station "${stationName}" removed successfully.`);
allStations = []; // Force a full refresh on next poll
loadAndPollStations();
} else {
const error = await response.json();
alert(`Failed to remove station: ${error.message}`);
}
} catch (error) {
console.error('Error removing station:', error);
alert('An error occurred while trying to remove the station.');
}
}
});
// --- DATA FETCHING & POLLING ---
const loadAndPollStations = async () => {
try {
const response = await fetch(`${API_BASE}/stations`);
if (!response.ok) throw new Error('Failed to fetch stations');
const newStationList = await response.json();
// If the number of stations has changed, we must do a full re-render.
if (newStationList.length !== allStations.length) {
allStations = newStationList;
renderStations(allStations);
} else {
// Otherwise, we can do a more efficient status-only update.
allStations = newStationList;
updateStationStatuses(allStations);
fetchAndApplyStats(); // Fetch and update daily stats
}
} catch (error) {
console.error(error);
stationCountEl.textContent = 'Could not load stations. Is the backend running?';
if (pollingInterval) clearInterval(pollingInterval);
}
};
// --- INITIALIZATION ---
loadAndPollStations(); // Load immediately on page start
pollingInterval = setInterval(loadAndPollStations, 10000);
});