Mise à jour
This commit is contained in:
117
js/map.js
117
js/map.js
@@ -1,15 +1,6 @@
|
||||
/**
|
||||
* ============================================
|
||||
* MAP.JS - Carte des places de parking
|
||||
* Smart Parking v2.0
|
||||
* MODIFIÉ : polling API toutes les 3s pour recevoir
|
||||
* les mises à jour en temps réel depuis Arduino
|
||||
* ============================================
|
||||
*/
|
||||
|
||||
const MAP_CONFIG = {
|
||||
totalSpots: 10,
|
||||
updateInterval: 3000 // Refresh depuis l'API toutes les 3 secondes
|
||||
updateInterval: 3000
|
||||
};
|
||||
|
||||
let spotsState = {
|
||||
@@ -19,9 +10,7 @@ let spotsState = {
|
||||
|
||||
const SPOT_STATUS = { FREE: 'free', OCCUPIED: 'occupied', RESERVED: 'reserved' };
|
||||
|
||||
// ============================================
|
||||
// INITIALISATION
|
||||
// ============================================
|
||||
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
console.log('🗺️ Initialisation de la carte...');
|
||||
@@ -29,30 +18,17 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
});
|
||||
|
||||
async function initParkingMap() {
|
||||
// Essayer d'abord de charger depuis l'API (données MariaDB + Arduino)
|
||||
const loaded = await loadSpotsFromAPI();
|
||||
|
||||
// Si pas d'API disponible, utiliser le localStorage (mode offline)
|
||||
if (!loaded) {
|
||||
loadSpotsFromStorage();
|
||||
}
|
||||
if (!loaded) loadSpotsFromStorage();
|
||||
|
||||
renderMap();
|
||||
updateStats();
|
||||
updateReservationForm();
|
||||
|
||||
// ⭐ Polling toutes les 3 secondes pour recevoir les updates Arduino
|
||||
startAPIPolling();
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// CHARGEMENT DES PLACES
|
||||
// ============================================
|
||||
|
||||
/**
|
||||
* Charge les places depuis l'API (MariaDB)
|
||||
* Retourne true si succès, false si hors-ligne
|
||||
*/
|
||||
|
||||
async function loadSpotsFromAPI() {
|
||||
try {
|
||||
const token = localStorage.getItem('smart_parking_token');
|
||||
@@ -67,7 +43,6 @@ async function loadSpotsFromAPI() {
|
||||
const data = await response.json();
|
||||
if (!data.success || !data.data.length) return false;
|
||||
|
||||
// Convertir le format API → format interne
|
||||
spotsState.spots = data.data.map(s => ({
|
||||
id: s.id,
|
||||
number: s.number,
|
||||
@@ -76,19 +51,14 @@ async function loadSpotsFromAPI() {
|
||||
sensorId: s.sensor_id
|
||||
}));
|
||||
|
||||
// Synchroniser avec localStorage pour le mode offline
|
||||
saveSpots();
|
||||
return true;
|
||||
|
||||
} catch (_err) {
|
||||
// Serveur non joignable → mode offline
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Charge les places depuis le localStorage (mode offline)
|
||||
*/
|
||||
function loadSpotsFromStorage() {
|
||||
const stored = localStorage.getItem('smart_parking_spots');
|
||||
if (stored) {
|
||||
@@ -116,23 +86,22 @@ function saveSpots() {
|
||||
localStorage.setItem('smart_parking_spots', JSON.stringify(spotsState.spots));
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// ⭐ POLLING TEMPS RÉEL (mises à jour Arduino)
|
||||
// ============================================
|
||||
|
||||
/**
|
||||
* Interroge l'API toutes les 3 secondes.
|
||||
* Si l'Arduino a changé l'état d'une place via MQTT,
|
||||
* la carte se met à jour automatiquement.
|
||||
*/
|
||||
function startAPIPolling() {
|
||||
setInterval(async () => {
|
||||
const loaded = await loadSpotsFromAPI();
|
||||
if (loaded) {
|
||||
renderMap();
|
||||
updateStats();
|
||||
updateReservationForm();
|
||||
// Rafraîchir les détails si une place est sélectionnée
|
||||
|
||||
|
||||
const resSpot = document.getElementById('resSpot');
|
||||
const hasSelection = resSpot && resSpot.value !== '';
|
||||
if (!hasSelection) {
|
||||
updateReservationForm();
|
||||
}
|
||||
|
||||
|
||||
if (spotsState.selectedSpot) {
|
||||
const updated = spotsState.spots.find(s => s.id === spotsState.selectedSpot.id);
|
||||
if (updated) {
|
||||
@@ -144,9 +113,6 @@ function startAPIPolling() {
|
||||
}, MAP_CONFIG.updateInterval);
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// RENDU DE LA CARTE
|
||||
// ============================================
|
||||
|
||||
function renderMap() {
|
||||
const mapContainer = document.getElementById('parkingMap');
|
||||
@@ -202,21 +168,21 @@ function showSpotDetails(spot) {
|
||||
</div>
|
||||
${reservation ? `
|
||||
<div class="spot-info-row">
|
||||
<span class="spot-info-label">Réservé par</span>
|
||||
<span class="spot-info-value">${reservation.userName}</span>
|
||||
</div>
|
||||
<div class="spot-info-row">
|
||||
<span class="spot-info-label">Jusqu'à</span>
|
||||
<span class="spot-info-label">Réservé jusqu'à</span>
|
||||
<span class="spot-info-value">${reservation.endTime}</span>
|
||||
</div>
|
||||
` : ''}
|
||||
${spot.status === SPOT_STATUS.FREE ? `
|
||||
${spot.status !== SPOT_STATUS.OCCUPIED ? `
|
||||
<button class="btn btn-primary btn-block"
|
||||
onclick="Dashboard.navigateToPage('reservation'); selectSpotForReservation(${spot.id});">
|
||||
<span class="btn-icon">📅</span>
|
||||
Réserver cette place
|
||||
</button>
|
||||
` : ''}
|
||||
` : `
|
||||
<p style="color: var(--danger); text-align: center; margin-top: 12px;">
|
||||
🚗 Une voiture est physiquement sur cette place
|
||||
</p>
|
||||
`}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
@@ -226,9 +192,6 @@ function findReservationForSpot(spotId) {
|
||||
return reservations.find(r => r.spotId === spotId && r.status === 'active');
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// STATISTIQUES & FORMULAIRE
|
||||
// ============================================
|
||||
|
||||
function updateStats() {
|
||||
const free = spotsState.spots.filter(s => s.status === SPOT_STATUS.FREE).length;
|
||||
@@ -241,22 +204,35 @@ function updateStats() {
|
||||
document.getElementById('totalCount').textContent = spotsState.spots.length;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function updateReservationForm() {
|
||||
const select = document.getElementById('resSpot');
|
||||
if (!select) return;
|
||||
|
||||
|
||||
const currentValue = select.value;
|
||||
|
||||
const firstOption = select.options[0];
|
||||
select.innerHTML = '';
|
||||
select.appendChild(firstOption);
|
||||
|
||||
spotsState.spots
|
||||
.filter(s => s.status === SPOT_STATUS.FREE)
|
||||
.forEach(spot => {
|
||||
const option = document.createElement('option');
|
||||
option.value = spot.id;
|
||||
option.textContent = `Place ${spot.number}`;
|
||||
select.appendChild(option);
|
||||
});
|
||||
|
||||
const availableSpots = spotsState.spots.filter(s => s.status !== SPOT_STATUS.OCCUPIED);
|
||||
|
||||
availableSpots.forEach(spot => {
|
||||
const option = document.createElement('option');
|
||||
option.value = spot.id;
|
||||
|
||||
option.textContent = spot.status === SPOT_STATUS.RESERVED
|
||||
? `Place ${spot.number} (réservée en ce moment)`
|
||||
: `Place ${spot.number}`;
|
||||
select.appendChild(option);
|
||||
});
|
||||
|
||||
if (currentValue) {
|
||||
select.value = currentValue;
|
||||
}
|
||||
}
|
||||
|
||||
function selectSpotForReservation(spotId) {
|
||||
@@ -264,9 +240,7 @@ function selectSpotForReservation(spotId) {
|
||||
if (select) select.value = spotId;
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// ACTIONS ADMIN & SIMULATION
|
||||
// ============================================
|
||||
|
||||
|
||||
async function setSpotStatus(spotId, status) {
|
||||
const spot = spotsState.spots.find(s => s.id === spotId || s.number === spotId);
|
||||
@@ -279,7 +253,6 @@ async function setSpotStatus(spotId, status) {
|
||||
updateStats();
|
||||
updateReservationForm();
|
||||
|
||||
// Synchroniser avec l'API si connecté
|
||||
try {
|
||||
const token = localStorage.getItem('smart_parking_token');
|
||||
if (token) {
|
||||
@@ -315,9 +288,6 @@ function setTotalSpots(count) {
|
||||
updateReservationForm();
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// UTILITAIRES
|
||||
// ============================================
|
||||
|
||||
function isAdmin() {
|
||||
const user = JSON.parse(localStorage.getItem('smart_parking_user') || 'null');
|
||||
@@ -340,9 +310,6 @@ function formatDate(dateString) {
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// EXPORT
|
||||
// ============================================
|
||||
|
||||
window.ParkingMap = {
|
||||
refresh: async () => {
|
||||
|
||||
Reference in New Issue
Block a user