zkt26/z1/webapp/views/objets.ejs
2026-03-31 19:33:15 +02:00

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()">&times;</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">&times;</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>