200 lines
7.2 KiB
Plaintext
200 lines
7.2 KiB
Plaintext
<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<title>Page d'accueil - Smart Building</title>
|
|
<link rel="stylesheet" href="/styleObjets.css" />
|
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet" />
|
|
<script src="https://kit.fontawesome.com/a076d05399.js" crossorigin="anonymous"></script>
|
|
<style>
|
|
.setting-btn.disabled {
|
|
opacity: 0.4;
|
|
pointer-events: none;
|
|
cursor: not-allowed;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<%- include('partials/header') %>
|
|
|
|
<main>
|
|
<section class="left-panel">
|
|
<img src="/images/batiment.png" alt="Bâtiment" />
|
|
</section>
|
|
|
|
<section class="right-panel">
|
|
<div class="header-objets">
|
|
<h1>Objets Connectés</h1>
|
|
<form class="form">
|
|
<label for="search">
|
|
<input class="input" type="text" required placeholder="Rechercher" id="search" />
|
|
<div class="fancy-bg"></div>
|
|
<div class="search">
|
|
<svg viewBox="0 0 24 24" aria-hidden="true" class="r-yyyyoo">
|
|
<g>
|
|
<path d="M21.53 20.47l-3.66-3.66C19.195 15.24 20 13.214 20 11c0-4.97-4.03-9-9-9s-9 4.03-9 9 4.03 9 9 9c2.215 0 4.24-.804 5.808-2.13l3.66 3.66c.147.146.34.22.53.22s.385-.073.53-.22c.295-.293.295-.767.002-1.06zM3.5 11c0-4.135 3.365-7.5 7.5-7.5s7.5 3.365 7.5 7.5-3.365 7.5-7.5 7.5-7.5-3.365-7.5-7.5z"></path>
|
|
</g>
|
|
</svg>
|
|
</div>
|
|
<span class="close-btn" aria-label="Reset" onClick="clearInput()">×</span>
|
|
</label>
|
|
</form>
|
|
</div>
|
|
<div id="objets-container" data-statut="<%= session.utilisateur ? session.utilisateur.statut : '' %>"></div>
|
|
</section>
|
|
|
|
<div id="myModal" class="modal">
|
|
<div class="modal-content">
|
|
<span class="close">×</span>
|
|
<div id="modal-info"></div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<%- include('partials/footer') %>
|
|
</body>
|
|
</html>
|
|
|
|
<script>
|
|
const span = document.getElementsByClassName("close")[0];
|
|
span.onclick = () => document.getElementById('myModal').style.display = "none";
|
|
|
|
function openModal(objet) {
|
|
const modal = document.getElementById('myModal');
|
|
const modalInfo = document.getElementById('modal-info');
|
|
|
|
modalInfo.innerHTML = `
|
|
<div class='info_objet'>
|
|
<h2 id='denomination-edit'>${objet.denomination}</h2>
|
|
<button type="submit" onClick="toggleEdit('${objet.adresse_ip}','edit-icon_denomination', 'denomination')">
|
|
<i id="edit-icon_denomination" class="fas fa-pen"></i>
|
|
</button>
|
|
</div>
|
|
<div class='info_objet'>
|
|
<p id='adresse_ip-edit'>${objet.adresse_ip}</p>
|
|
<button type="submit" onClick="toggleEdit('${objet.adresse_ip}','edit-icon_adresse_ip', 'adresse_ip')">
|
|
<i id="edit-icon_adresse_ip" class="fas fa-pen"></i>
|
|
</button>
|
|
</div>
|
|
<div class='info_objet'>
|
|
<p id='niveau-edit'>${objet.niveau}</p>
|
|
<button type="submit" onClick="toggleEdit('${objet.adresse_ip}','edit-icon_niveau', 'niveau')">
|
|
<i id="edit-icon_niveau" class="fas fa-pen"></i>
|
|
</button>
|
|
</div>
|
|
<div class='info_objet'>
|
|
<p id='type-edit'>${objet.type}</p>
|
|
<button type="submit" onClick="toggleEdit('${objet.adresse_ip}','edit-icon_type', 'type')">
|
|
<i id="edit-icon_type" class="fas fa-pen"></i>
|
|
</button>
|
|
</div>
|
|
<div class='info_objet'>
|
|
<p><strong>Dernière interaction:</strong> ${objet.derniere_interaction}</p>
|
|
</div>
|
|
<div class='info_objet'>
|
|
<p><strong>État:</strong> ${objet.etat}</p>
|
|
</div>
|
|
`;
|
|
|
|
modal.style.display = 'block';
|
|
}
|
|
|
|
function toggleEdit(adresse_ip, edit_icon, field) {
|
|
const editIcon = document.getElementById(edit_icon);
|
|
const paragraph = document.getElementById(field + "-edit");
|
|
if (editIcon.className === "fas fa-pen") {
|
|
editIcon.className = "fas fa-check";
|
|
paragraph.contentEditable = true;
|
|
paragraph.style.backgroundColor = "transparent";
|
|
} else {
|
|
editIcon.className = "fas fa-pen";
|
|
paragraph.contentEditable = false;
|
|
paragraph.style.backgroundColor = "rgba(60, 60, 60, 0.98)";
|
|
saveChanges(adresse_ip, field, paragraph.innerText);
|
|
}
|
|
}
|
|
|
|
async function saveChanges(adresse_ip, field, newValue) {
|
|
document.getElementById('h3_' + adresse_ip).innerText = newValue;
|
|
try {
|
|
const response = await fetch('/api/objets/' + encodeURIComponent(adresse_ip), {
|
|
method: 'PUT',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ [field]: newValue })
|
|
});
|
|
|
|
if (response.ok) {
|
|
console.log('Objet mis à jour avec succès !');
|
|
} else {
|
|
console.error('Erreur serveur :', response.statusText);
|
|
}
|
|
} catch (error) {
|
|
console.error('Erreur réseau :', error);
|
|
}
|
|
}
|
|
|
|
function clearInput() {
|
|
const input = document.getElementById("search");
|
|
input.value = "";
|
|
input.dispatchEvent(new Event("input"));
|
|
fetchObjets();
|
|
}
|
|
|
|
async function fetchObjets() {
|
|
try {
|
|
const response = await fetch('/api/objets');
|
|
const objets = await response.json();
|
|
const container = document.getElementById('objets-container');
|
|
const userStatut = container.getAttribute("data-statut");
|
|
|
|
container.innerHTML = "";
|
|
|
|
const niveauColor = {
|
|
débutant: "#2ecc71",
|
|
intermédiaire: "#3498db",
|
|
avancé: "#f39c12",
|
|
expert: "#e74c3c",
|
|
};
|
|
|
|
const peutModifier = ['administrateur', 'complexe', 'simple'].includes(userStatut);
|
|
|
|
|
|
objets.forEach(objet => {
|
|
console.log(objet);
|
|
const div = document.createElement('div');
|
|
div.className = 'objet';
|
|
div.innerHTML = `
|
|
<button class="setting-btn ${peutModifier ? '' : 'disabled'}"
|
|
${peutModifier ? `onclick='openModal(${JSON.stringify(objet)})'` : ''}>
|
|
<i class="fas fa-cog"></i>
|
|
</button>
|
|
<h3 id='h3_${objet.adresse_ip}'>${objet.denomination}</h3>
|
|
<p>${objet.adresse_ip}</p>
|
|
<p><strong>Type</strong> : ${objet.type}</p>
|
|
${objet.temperature_actuelle !== null ? `<p><strong>Temperature Actuelle</strong> : ${objet.temperature_actuelle}°</p>` : ''}
|
|
${objet.temperature_cible !== null ? `<p><strong>Temperature Cible</strong> : ${objet.temperature_cible}°</p>` : ''}
|
|
${objet.mode !== null ? `<p><strong>Mode</strong> : ${objet.mode}</p>` : ''}
|
|
<p><strong>Niveau:</strong> <span style="color: ${niveauColor[objet.niveau]}">${objet.niveau}</span></p>
|
|
<div class="etat-point ${objet.etat === 'Actif' ? 'actif' : 'inactif'}"></div>
|
|
`;
|
|
container.appendChild(div);
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('Erreur fetchObjets :', error);
|
|
}
|
|
}
|
|
|
|
document.getElementById('search').addEventListener('input', function (e) {
|
|
const searchTerm = e.target.value.toLowerCase();
|
|
document.querySelectorAll('.objet').forEach(objet => {
|
|
const text = objet.innerText.toLowerCase();
|
|
objet.style.display = text.includes(searchTerm) ? 'block' : 'none';
|
|
});
|
|
});
|
|
|
|
window.onload = fetchObjets;
|
|
</script> |