|
|
|
|
@ -0,0 +1,487 @@
@@ -0,0 +1,487 @@
|
|
|
|
|
<!DOCTYPE html> |
|
|
|
|
<html> |
|
|
|
|
<head> |
|
|
|
|
<meta charset="UTF-8"> |
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
|
|
<title>Contrôleur Solaire - Configuration</title> |
|
|
|
|
<style> |
|
|
|
|
body { |
|
|
|
|
font-family: Arial, sans-serif; |
|
|
|
|
max-width: 800px; |
|
|
|
|
margin: 50px auto; |
|
|
|
|
padding: 20px; |
|
|
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
|
|
|
|
min-height: 100vh; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.container { |
|
|
|
|
background: white; |
|
|
|
|
padding: 40px; |
|
|
|
|
border-radius: 10px; |
|
|
|
|
box-shadow: 0 10px 30px rgba(0,0,0,0.3); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
h1 { |
|
|
|
|
color: #333; |
|
|
|
|
text-align: center; |
|
|
|
|
margin-bottom: 30px; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
h2 { |
|
|
|
|
color: #667eea; |
|
|
|
|
border-bottom: 2px solid #667eea; |
|
|
|
|
padding-bottom: 10px; |
|
|
|
|
margin-top: 30px; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.nav-links { |
|
|
|
|
text-align: center; |
|
|
|
|
margin-top: 30px; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.nav-links a { |
|
|
|
|
display: inline-block; |
|
|
|
|
padding: 10px 20px; |
|
|
|
|
background: #95a5a6; |
|
|
|
|
color: white; |
|
|
|
|
text-decoration: none; |
|
|
|
|
border-radius: 5px; |
|
|
|
|
margin: 5px; |
|
|
|
|
transition: background 0.3s; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.nav-links a:hover { |
|
|
|
|
background: #7f8c8d; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.form-section { |
|
|
|
|
background: #f9f9f9; |
|
|
|
|
padding: 20px; |
|
|
|
|
border-radius: 5px; |
|
|
|
|
margin-bottom: 20px; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.form-group { |
|
|
|
|
margin-bottom: 20px; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
label { |
|
|
|
|
display: block; |
|
|
|
|
margin-bottom: 5px; |
|
|
|
|
color: #555; |
|
|
|
|
font-weight: bold; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
input[type="text"], |
|
|
|
|
input[type="password"], |
|
|
|
|
input[type="number"] { |
|
|
|
|
width: 100%; |
|
|
|
|
padding: 10px; |
|
|
|
|
border: 2px solid #ddd; |
|
|
|
|
border-radius: 5px; |
|
|
|
|
font-size: 16px; |
|
|
|
|
box-sizing: border-box; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
input[type="text"]:focus, |
|
|
|
|
input[type="password"]:focus, |
|
|
|
|
input[type="number"]:focus { |
|
|
|
|
outline: none; |
|
|
|
|
border-color: #667eea; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.password-hint { |
|
|
|
|
font-size: 12px; |
|
|
|
|
color: #777; |
|
|
|
|
margin-top: 5px; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
button { |
|
|
|
|
padding: 12px 30px; |
|
|
|
|
background: #667eea; |
|
|
|
|
color: white; |
|
|
|
|
border: none; |
|
|
|
|
border-radius: 5px; |
|
|
|
|
font-size: 16px; |
|
|
|
|
font-weight: bold; |
|
|
|
|
cursor: pointer; |
|
|
|
|
transition: background 0.3s; |
|
|
|
|
margin-right: 10px; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
button:hover { |
|
|
|
|
background: #764ba2; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
button:disabled { |
|
|
|
|
background: #ccc; |
|
|
|
|
cursor: not-allowed; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
button.secondary { |
|
|
|
|
background: #95a5a6; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
button.secondary:hover { |
|
|
|
|
background: #7f8c8d; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.message { |
|
|
|
|
padding: 15px; |
|
|
|
|
border-radius: 5px; |
|
|
|
|
margin-bottom: 20px; |
|
|
|
|
display: none; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.message.success { |
|
|
|
|
background: #d4edda; |
|
|
|
|
color: #155724; |
|
|
|
|
border: 1px solid #c3e6cb; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.message.error { |
|
|
|
|
background: #f8d7da; |
|
|
|
|
color: #721c24; |
|
|
|
|
border: 1px solid #f5c6cb; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.loading { |
|
|
|
|
text-align: center; |
|
|
|
|
color: #667eea; |
|
|
|
|
font-style: italic; |
|
|
|
|
} |
|
|
|
|
</style> |
|
|
|
|
</head> |
|
|
|
|
<body> |
|
|
|
|
<div class="container"> |
|
|
|
|
<h1>⚙️ Configuration</h1> |
|
|
|
|
|
|
|
|
|
<div id="message" class="message"></div> |
|
|
|
|
<div id="loading" class="loading" style="display:none;">Chargement...</div> |
|
|
|
|
|
|
|
|
|
<form id="settingsForm"> |
|
|
|
|
<!-- Section Authentification --> |
|
|
|
|
<h2>🔐 Authentification</h2> |
|
|
|
|
<div class="form-section"> |
|
|
|
|
<div class="form-group"> |
|
|
|
|
<label for="username">Nom d'utilisateur:</label> |
|
|
|
|
<input type="text" id="username" name="username" required> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div class="form-group"> |
|
|
|
|
<label for="current_password">Mot de passe actuel:</label> |
|
|
|
|
<input type="password" id="current_password" name="current_password" placeholder="Laisser vide pour ne pas changer"> |
|
|
|
|
<div class="password-hint">Requis uniquement si vous changez le mot de passe</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div class="form-group"> |
|
|
|
|
<label for="new_password">Nouveau mot de passe:</label> |
|
|
|
|
<input type="password" id="new_password" name="new_password" placeholder="Laisser vide pour garder l'actuel"> |
|
|
|
|
<div class="password-hint">Minimum 8 caractères recommandé</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div class="form-group"> |
|
|
|
|
<label for="confirm_password">Confirmer le nouveau mot de passe:</label> |
|
|
|
|
<input type="password" id="confirm_password" name="confirm_password" placeholder="Confirmer le nouveau mot de passe"> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<!-- Section Système --> |
|
|
|
|
<h2>🌐 Configuration Système</h2> |
|
|
|
|
<div class="form-section"> |
|
|
|
|
<div class="form-group"> |
|
|
|
|
<label for="hostname">Nom d'hôte :</label> |
|
|
|
|
<input type="text" id="hostname" name="hostname" placeholder="ESP12-OTA"> |
|
|
|
|
<div class="password-hint">Nom de l'appareil sur le réseau</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div class="form-group"> |
|
|
|
|
<label for="session_timeout">Durée de session (minutes):</label> |
|
|
|
|
<input type="number" id="session_timeout" name="session_timeout" min="5" max="1440" value="60"> |
|
|
|
|
<div class="password-hint">Durée avant déconnexion automatique (5-1440 min)</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div class="form-group"> |
|
|
|
|
<label for="wifi_ssid">Nom du réseau (SSID):</label> |
|
|
|
|
<input type="text" id="wifi_ssid" name="wifi_ssid" placeholder="Nom du réseau WiFi"> |
|
|
|
|
<div class="password-hint">SSID du réseau WiFi auquel se connecter</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div class="form-group"> |
|
|
|
|
<label for="wifi_password">Mot de passe WiFi:</label> |
|
|
|
|
<input type="password" id="wifi_password" name="wifi_password" placeholder="Laisser vide pour ne pas changer"> |
|
|
|
|
<div class="password-hint">⚠️ Attention: Un redémarrage sera nécessaire pour appliquer les changements WiFi</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div class="form-group"> |
|
|
|
|
<label for="ap_password">Mot de passe mode AP (secours):</label> |
|
|
|
|
<input type="text" id="ap_password" name="ap_password" placeholder="123456"> |
|
|
|
|
<div class="password-hint">Mot de passe pour se connecter à l'ESP si impossible de rejoindre le WiFi (minimum 8 caractères)</div> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<!-- Section Paramètres routeur --> |
|
|
|
|
<h2>☀️ Configuration routeur</h2> |
|
|
|
|
<div class="form-section"> |
|
|
|
|
|
|
|
|
|
<div class="form-group"> |
|
|
|
|
<label for="heater_max_power">Puissance chauffe-eau (Watts):</label> |
|
|
|
|
<input type="number" id="heater_max_power" name="heater_max_power" min="500" max="5000" value="2400"> |
|
|
|
|
<div class="password-hint">Puissance maximale du chauffe-eau</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div class="form-group"> |
|
|
|
|
<label for="min_water_temp">Température eau minimale (°C):</label> |
|
|
|
|
<input type="number" id="min_water_temp" name="min_water_temp" min="20" max="80" step="0.1" value="40.0"> |
|
|
|
|
<div class="password-hint">Température minimale de l'eau du chauffe-eau (mode NUIT)</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div class="form-group"> |
|
|
|
|
<label for="max_water_temp">Température eau maximale (°C):</label> |
|
|
|
|
<input type="number" id="max_water_temp" name="max_water_temp" min="20" max="80" step="0.1" value="60.0"> |
|
|
|
|
<div class="password-hint">Température cible maximale de l'eau (mode JOUR)</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div class="form-group"> |
|
|
|
|
<label for="coeff_jour">Coefficient mode JOUR:</label> |
|
|
|
|
<input type="number" id="coeff_jour" name="coeff_jour" min="1" max="1000" step="1" value="350"> |
|
|
|
|
<div class="password-hint">Coefficient pour le calcul de puissance en mode JOUR</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div class="form-group"> |
|
|
|
|
<label for="target_max_water_temp_hour">Heure cible température max (0-23):</label> |
|
|
|
|
<input type="number" id="target_max_water_temp_hour" name="target_max_water_temp_hour" min="0" max="23" value="17"> |
|
|
|
|
<div class="password-hint">Heure à laquelle l'eau doit atteindre la température maximale (mode JOUR)</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div class="form-group"> |
|
|
|
|
<label for="latitude">Latitude:</label> |
|
|
|
|
<input type="number" id="latitude" name="latitude" min="-90" max="90" step="0.00001" value="49.01023"> |
|
|
|
|
<div class="password-hint">Latitude pour calcul lever/coucher du soleil</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div class="form-group"> |
|
|
|
|
<label for="longitude">Longitude:</label> |
|
|
|
|
<input type="number" id="longitude" name="longitude" min="-180" max="180" step="0.00001" value="2.03552"> |
|
|
|
|
<div class="password-hint">Longitude pour calcul lever/coucher du soleil</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div class="form-group"> |
|
|
|
|
<label for="night_start_hour">Heure début nuit (0-23):</label> |
|
|
|
|
<input type="number" id="night_start_hour" name="night_start_hour" min="0" max="23" value="0"> |
|
|
|
|
<div class="password-hint">Heure de début de la période nuit pour le mode NUIT</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div class="form-group"> |
|
|
|
|
<label for="night_end_hour">Heure fin nuit (0-23):</label> |
|
|
|
|
<input type="number" id="night_end_hour" name="night_end_hour" min="0" max="23" value="4"> |
|
|
|
|
<div class="password-hint">Heure de fin de la période nuit pour le mode NUIT</div> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<!-- Section Passerelle Enphase --> |
|
|
|
|
<h2>☀️ Passerelle Enphase</h2> |
|
|
|
|
<div class="form-section"> |
|
|
|
|
<div class="form-group"> |
|
|
|
|
<label for="enphase_ip">Adresse IP de la passerelle:</label> |
|
|
|
|
<input type="text" id="enphase_ip" name="enphase_ip" placeholder="192.168.0.201"> |
|
|
|
|
<div class="password-hint">Adresse IP locale de votre passerelle Enphase Envoy</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div class="form-group"> |
|
|
|
|
<label for="enphase_token">Token d'authentification:</label> |
|
|
|
|
<input type="text" id="enphase_token" name="enphase_token" placeholder="eyJraWQiOi..."> |
|
|
|
|
<div class="password-hint">Token JWT Bearer pour l'API Enphase (obtenu depuis entrez.enphaseenergy.com)</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div class="form-group"> |
|
|
|
|
<label for="update_interval">Intervalle de mise à jour (secondes):</label> |
|
|
|
|
<input type="number" id="update_interval" name="update_interval" min="2" max="60" value="5"> |
|
|
|
|
<div class="password-hint">Fréquence de récupération des données (2-60 sec)</div> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<!-- Boutons d'action --> |
|
|
|
|
<div style="margin-top: 30px;"> |
|
|
|
|
<button type="submit">💾 Enregistrer les modifications</button> |
|
|
|
|
<button type="button" class="secondary" onclick="loadSettings()">🔄 Recharger</button> |
|
|
|
|
</div> |
|
|
|
|
</form> |
|
|
|
|
|
|
|
|
|
<div class="nav-links"> |
|
|
|
|
<a href="/">🏠 Accueil</a> |
|
|
|
|
<a href="/update.html">📦 Mise à jour OTA</a> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<script> |
|
|
|
|
// Charger les paramètres au démarrage |
|
|
|
|
window.addEventListener('DOMContentLoaded', loadSettings); |
|
|
|
|
|
|
|
|
|
function showMessage(text, type) { |
|
|
|
|
const messageDiv = document.getElementById('message'); |
|
|
|
|
messageDiv.textContent = text; |
|
|
|
|
messageDiv.className = 'message ' + type; |
|
|
|
|
messageDiv.style.display = 'block'; |
|
|
|
|
setTimeout(() => { |
|
|
|
|
messageDiv.style.display = 'none'; |
|
|
|
|
}, 5000); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function loadSettings() { |
|
|
|
|
const loading = document.getElementById('loading'); |
|
|
|
|
loading.style.display = 'block'; |
|
|
|
|
|
|
|
|
|
fetch('/api/settings') |
|
|
|
|
.then(response => response.json()) |
|
|
|
|
.then(data => { |
|
|
|
|
loading.style.display = 'none'; |
|
|
|
|
|
|
|
|
|
document.getElementById('username').value = data.auth.username || 'admin'; |
|
|
|
|
|
|
|
|
|
// Paramètres WiFi |
|
|
|
|
if (data.wifi) { |
|
|
|
|
document.getElementById('wifi_ssid').value = data.wifi.ssid || ''; |
|
|
|
|
document.getElementById('ap_password').value = data.wifi.ap_password || '123456'; |
|
|
|
|
// Ne pas charger le mot de passe WiFi pour des raisons de sécurité |
|
|
|
|
document.getElementById('wifi_password').value = ''; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
document.getElementById('hostname').value = data.system.hostname || 'ESP12-OTA'; |
|
|
|
|
document.getElementById('session_timeout').value = data.system.session_timeout || 60; |
|
|
|
|
document.getElementById('heater_max_power').value = data.system.heater_max_power || 2400; |
|
|
|
|
document.getElementById('min_water_temp').value = data.system.min_water_temp || 40.0; |
|
|
|
|
document.getElementById('max_water_temp').value = data.system.max_water_temp || 60.0; |
|
|
|
|
document.getElementById('coeff_jour').value = data.system.coeff_jour || 350; |
|
|
|
|
document.getElementById('target_max_water_temp_hour').value = data.system.target_max_water_temp_hour || 17; |
|
|
|
|
document.getElementById('latitude').value = data.system.latitude || 49.01023; |
|
|
|
|
document.getElementById('longitude').value = data.system.longitude || 2.03552; |
|
|
|
|
document.getElementById('night_start_hour').value = data.system.night_start_hour || 0; |
|
|
|
|
document.getElementById('night_end_hour').value = data.system.night_end_hour || 4; |
|
|
|
|
|
|
|
|
|
// Paramètres Enphase |
|
|
|
|
if (data.enphase) { |
|
|
|
|
document.getElementById('enphase_ip').value = data.enphase.gateway_ip || ''; |
|
|
|
|
document.getElementById('enphase_token').value = data.enphase.token || ''; |
|
|
|
|
document.getElementById('update_interval').value = data.enphase.update_interval || 5; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Réinitialiser les champs de mot de passe |
|
|
|
|
document.getElementById('current_password').value = ''; |
|
|
|
|
document.getElementById('new_password').value = ''; |
|
|
|
|
document.getElementById('confirm_password').value = ''; |
|
|
|
|
}) |
|
|
|
|
.catch(error => { |
|
|
|
|
loading.style.display = 'none'; |
|
|
|
|
showMessage('Erreur lors du chargement des paramètres', 'error'); |
|
|
|
|
console.error('Erreur:', error); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
document.getElementById('settingsForm').addEventListener('submit', function(e) { |
|
|
|
|
e.preventDefault(); |
|
|
|
|
|
|
|
|
|
const newPassword = document.getElementById('new_password').value; |
|
|
|
|
const confirmPassword = document.getElementById('confirm_password').value; |
|
|
|
|
const currentPassword = document.getElementById('current_password').value; |
|
|
|
|
|
|
|
|
|
// Validation du mot de passe |
|
|
|
|
if (newPassword && newPassword !== confirmPassword) { |
|
|
|
|
showMessage('Les mots de passe ne correspondent pas', 'error'); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (newPassword && !currentPassword) { |
|
|
|
|
showMessage('Le mot de passe actuel est requis pour changer le mot de passe', 'error'); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (newPassword && newPassword.length < 4) { |
|
|
|
|
showMessage('Le nouveau mot de passe doit contenir au moins 4 caractères', 'error'); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Préparer les données |
|
|
|
|
const settings = { |
|
|
|
|
auth: { |
|
|
|
|
username: document.getElementById('username').value, |
|
|
|
|
current_password: currentPassword, |
|
|
|
|
new_password: newPassword |
|
|
|
|
}, |
|
|
|
|
wifi: { |
|
|
|
|
ssid: document.getElementById('wifi_ssid').value, |
|
|
|
|
password: document.getElementById('wifi_password').value, |
|
|
|
|
ap_password: document.getElementById('ap_password').value |
|
|
|
|
}, |
|
|
|
|
system: { |
|
|
|
|
hostname: document.getElementById('hostname').value, |
|
|
|
|
session_timeout: parseInt(document.getElementById('session_timeout').value), |
|
|
|
|
heater_max_power: parseInt(document.getElementById('heater_max_power').value), |
|
|
|
|
min_water_temp: parseFloat(document.getElementById('min_water_temp').value), |
|
|
|
|
max_water_temp: parseFloat(document.getElementById('max_water_temp').value), |
|
|
|
|
coeff_jour: parseFloat(document.getElementById('coeff_jour').value), |
|
|
|
|
target_max_water_temp_hour: parseInt(document.getElementById('target_max_water_temp_hour').value), |
|
|
|
|
latitude: parseFloat(document.getElementById('latitude').value), |
|
|
|
|
longitude: parseFloat(document.getElementById('longitude').value), |
|
|
|
|
night_start_hour: parseInt(document.getElementById('night_start_hour').value), |
|
|
|
|
night_end_hour: parseInt(document.getElementById('night_end_hour').value) |
|
|
|
|
}, |
|
|
|
|
enphase: { |
|
|
|
|
gateway_ip: document.getElementById('enphase_ip').value, |
|
|
|
|
token: document.getElementById('enphase_token').value, |
|
|
|
|
update_interval: parseInt(document.getElementById('update_interval').value) |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// Envoyer les données |
|
|
|
|
const loading = document.getElementById('loading'); |
|
|
|
|
loading.style.display = 'block'; |
|
|
|
|
|
|
|
|
|
fetch('/api/settings', { |
|
|
|
|
method: 'POST', |
|
|
|
|
headers: { |
|
|
|
|
'Content-Type': 'application/json', |
|
|
|
|
}, |
|
|
|
|
body: JSON.stringify(settings) |
|
|
|
|
}) |
|
|
|
|
.then(response => { |
|
|
|
|
loading.style.display = 'none'; |
|
|
|
|
if (response.ok) { |
|
|
|
|
return response.json(); |
|
|
|
|
} else { |
|
|
|
|
throw new Error('Erreur lors de la sauvegarde'); |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
.then(data => { |
|
|
|
|
const wifiChanged = document.getElementById('wifi_ssid').value || document.getElementById('wifi_password').value; |
|
|
|
|
|
|
|
|
|
if (wifiChanged) { |
|
|
|
|
showMessage(data.message + ' - L\'ESP va redémarrer pour appliquer les changements WiFi.', 'success'); |
|
|
|
|
setTimeout(() => { |
|
|
|
|
showMessage('Redémarrage en cours... Reconnexion au nouveau réseau nécessaire.', 'error'); |
|
|
|
|
}, 3000); |
|
|
|
|
} else { |
|
|
|
|
showMessage(data.message || 'Paramètres sauvegardés avec succès!', 'success'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Si le mot de passe a changé, rediriger vers login après 2 secondes |
|
|
|
|
if (newPassword) { |
|
|
|
|
setTimeout(() => { |
|
|
|
|
window.location.href = '/logout'; |
|
|
|
|
}, 2000); |
|
|
|
|
} else { |
|
|
|
|
// Recharger les paramètres |
|
|
|
|
setTimeout(() => { |
|
|
|
|
loadSettings(); |
|
|
|
|
}, 1000); |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
.catch(error => { |
|
|
|
|
loading.style.display = 'none'; |
|
|
|
|
showMessage('Erreur lors de la sauvegarde des paramètres', 'error'); |
|
|
|
|
console.error('Erreur:', error); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
</script> |
|
|
|
|
</body> |
|
|
|
|
</html> |