Mise à jour
This commit is contained in:
134
js/admin.js
134
js/admin.js
@@ -1,14 +1,3 @@
|
||||
/**
|
||||
* ============================================
|
||||
* ADMIN.JS - Panel d'administration
|
||||
* Smart Parking v3.0
|
||||
* CORRIGÉ :
|
||||
* - Suppression du graphique d'occupation
|
||||
* - Historique affiche la date complète
|
||||
* (jour + mois + année + heure + minute)
|
||||
* ============================================
|
||||
*/
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
console.log('⚙️ Initialisation du panel admin...');
|
||||
if (!isAdmin()) return;
|
||||
@@ -27,7 +16,6 @@ function initAdminPanel() {
|
||||
loadReservationsTable();
|
||||
loadHistoryLog();
|
||||
|
||||
// Rafraîchissement périodique toutes les 10 secondes
|
||||
setInterval(() => {
|
||||
loadAdminStats();
|
||||
loadReservationsTable();
|
||||
@@ -35,9 +23,6 @@ function initAdminPanel() {
|
||||
}, 10000);
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// STATISTIQUES ADMIN
|
||||
// ============================================
|
||||
|
||||
function loadAdminStats() {
|
||||
const users = JSON.parse(localStorage.getItem('smart_parking_users') || '[]');
|
||||
@@ -62,21 +47,44 @@ function loadAdminStats() {
|
||||
document.getElementById('adminOccupancyRate').textContent = occupancyRate + '%';
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// GESTION DES PLACES
|
||||
// ============================================
|
||||
|
||||
function initPlacesControl() {
|
||||
const spots = JSON.parse(localStorage.getItem('smart_parking_spots') || '[]');
|
||||
const spotsInput = document.getElementById('adminTotalSpots');
|
||||
if (spotsInput) spotsInput.value = spots.length || 10;
|
||||
|
||||
document.getElementById('updateSpotsBtn')?.addEventListener('click', () => {
|
||||
document.getElementById('updateSpotsBtn')?.addEventListener('click', async () => {
|
||||
const newCount = parseInt(document.getElementById('adminTotalSpots').value);
|
||||
if (newCount < 5 || newCount > 50) {
|
||||
Dashboard.showToast('Le nombre de places doit être entre 5 et 50', 'error');
|
||||
|
||||
if (newCount < 1 || newCount > 20) {
|
||||
Dashboard.showToast('Le nombre de places doit être entre 1 et 20', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const token = localStorage.getItem('smart_parking_token');
|
||||
if (token) {
|
||||
try {
|
||||
const response = await fetch('/api/spots/init', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer ' + token
|
||||
},
|
||||
body: JSON.stringify({ count: newCount })
|
||||
});
|
||||
const data = await response.json();
|
||||
if (data.success) {
|
||||
|
||||
if (window.ParkingMap) await window.ParkingMap.refresh();
|
||||
renderAdminPlacesList();
|
||||
Dashboard.showToast('Nombre de places mis à jour', 'success');
|
||||
return;
|
||||
}
|
||||
} catch (_err) { /* fallback local */ }
|
||||
}
|
||||
|
||||
|
||||
if (window.ParkingMap) {
|
||||
window.ParkingMap.setTotalSpots(newCount);
|
||||
renderAdminPlacesList();
|
||||
@@ -104,27 +112,48 @@ function renderAdminPlacesList() {
|
||||
`).join('');
|
||||
}
|
||||
|
||||
function toggleSpotStatus(spotId) {
|
||||
|
||||
async function toggleSpotStatus(spotId) {
|
||||
const spots = JSON.parse(localStorage.getItem('smart_parking_spots') || '[]');
|
||||
const spot = spots.find(s => s.id === spotId);
|
||||
if (!spot) return;
|
||||
|
||||
const cycle = ['free', 'occupied', 'reserved'];
|
||||
const nextStatus = cycle[(cycle.indexOf(spot.status) + 1) % cycle.length];
|
||||
spot.status = nextStatus;
|
||||
spot.lastUpdate = new Date().toISOString();
|
||||
const cycle = ['free', 'occupied', 'reserved'];
|
||||
const nextStatus = cycle[(cycle.indexOf(spot.status) + 1) % cycle.length];
|
||||
|
||||
const token = localStorage.getItem('smart_parking_token');
|
||||
if (token) {
|
||||
try {
|
||||
const response = await fetch(`/api/spots/${spot.id}/status`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer ' + token
|
||||
},
|
||||
body: JSON.stringify({ status: nextStatus })
|
||||
});
|
||||
const data = await response.json();
|
||||
if (!data.success) {
|
||||
Dashboard.showToast('Erreur : ' + data.message, 'error');
|
||||
return;
|
||||
}
|
||||
} catch (_err) {
|
||||
console.warn('⚠️ API indisponible, modification locale uniquement');
|
||||
}
|
||||
}
|
||||
|
||||
spot.status = nextStatus;
|
||||
spot.lastUpdate = new Date().toISOString();
|
||||
localStorage.setItem('smart_parking_spots', JSON.stringify(spots));
|
||||
|
||||
renderAdminPlacesList();
|
||||
if (window.ParkingMap) window.ParkingMap.refresh();
|
||||
loadAdminStats();
|
||||
|
||||
Dashboard.showToast(`Place ${spot.number} — ${getStatusLabel(nextStatus)}`, 'success');
|
||||
Dashboard.showToast(`Place ${spot.number} → ${getStatusLabel(nextStatus)}`, 'success');
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// TABLEAU UTILISATEURS
|
||||
// ============================================
|
||||
|
||||
|
||||
function loadUsersTable() {
|
||||
const tbody = document.getElementById('adminUsersTable');
|
||||
@@ -176,9 +205,7 @@ function deleteUser(userId) {
|
||||
Dashboard.showToast('Utilisateur supprimé', 'success');
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// TABLEAU RÉSERVATIONS
|
||||
// ============================================
|
||||
|
||||
|
||||
function loadReservationsTable() {
|
||||
const tbody = document.getElementById('adminReservationsTable');
|
||||
@@ -218,11 +245,22 @@ function loadReservationsTable() {
|
||||
`).join('');
|
||||
}
|
||||
|
||||
function completeReservation(reservationId) {
|
||||
async function completeReservation(reservationId) {
|
||||
let reservations = JSON.parse(localStorage.getItem('smart_parking_reservations') || '[]');
|
||||
const reservation = reservations.find(r => r.id === reservationId);
|
||||
if (!reservation) return;
|
||||
|
||||
|
||||
const token = localStorage.getItem('smart_parking_token');
|
||||
if (token) {
|
||||
try {
|
||||
await fetch(`/api/reservations/${reservationId}/complete`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Authorization': 'Bearer ' + token }
|
||||
});
|
||||
} catch (_err) { /* fallback local */ }
|
||||
}
|
||||
|
||||
reservation.status = 'completed';
|
||||
localStorage.setItem('smart_parking_reservations', JSON.stringify(reservations));
|
||||
|
||||
@@ -233,13 +271,24 @@ function completeReservation(reservationId) {
|
||||
Dashboard.showToast('Réservation terminée', 'success');
|
||||
}
|
||||
|
||||
function adminCancelReservation(reservationId) {
|
||||
async function adminCancelReservation(reservationId) {
|
||||
if (!confirm('Êtes-vous sûr de vouloir annuler cette réservation ?')) return;
|
||||
|
||||
let reservations = JSON.parse(localStorage.getItem('smart_parking_reservations') || '[]');
|
||||
const reservation = reservations.find(r => r.id === reservationId);
|
||||
if (!reservation) return;
|
||||
|
||||
// Appeler l'API
|
||||
const token = localStorage.getItem('smart_parking_token');
|
||||
if (token) {
|
||||
try {
|
||||
await fetch(`/api/reservations/${reservationId}/cancel`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Authorization': 'Bearer ' + token }
|
||||
});
|
||||
} catch (_err) { /* fallback local */ }
|
||||
}
|
||||
|
||||
reservation.status = 'cancelled';
|
||||
localStorage.setItem('smart_parking_reservations', JSON.stringify(reservations));
|
||||
|
||||
@@ -250,9 +299,6 @@ function adminCancelReservation(reservationId) {
|
||||
Dashboard.showToast('Réservation annulée', 'success');
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// HISTORIQUE — CORRIGÉ : date complète
|
||||
// ============================================
|
||||
|
||||
function loadHistoryLog() {
|
||||
const container = document.getElementById('adminLogContainer');
|
||||
@@ -273,15 +319,8 @@ function loadHistoryLog() {
|
||||
`).join('');
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// FONCTIONS DE FORMAT DATE
|
||||
// ============================================
|
||||
|
||||
/**
|
||||
* CORRIGÉ — Affiche la date complète dans l'historique
|
||||
* Avant : seulement "14:32"
|
||||
* Après : "12/06/2025 à 14:32"
|
||||
*/
|
||||
|
||||
function formatDateComplete(dateString) {
|
||||
if (!dateString) return 'N/A';
|
||||
const date = new Date(dateString);
|
||||
@@ -312,9 +351,6 @@ function getStatusLabel(status) {
|
||||
}[status] || status;
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// EXPORT
|
||||
// ============================================
|
||||
|
||||
window.AdminModule = {
|
||||
refresh: () => {
|
||||
|
||||
Reference in New Issue
Block a user