diff --git a/css/base/style.css b/css/base/style.css index 5d1b7d8..53551ba 100644 --- a/css/base/style.css +++ b/css/base/style.css @@ -5,7 +5,7 @@ body::before { left: 0; width: 100%; height: 100%; - background-image: url("../image/camera-image"); + background-image: url("../image/camera-image.png"); background-position: center; background-size: cover; filter: blur(1px) brightness(0.3); @@ -443,4 +443,30 @@ footer { .global_title_h1 { color: white; font-size: 10vh; +} + +/* Styles pour les statuts des projets dans le carrousel */ +.status-draft { + color: #6B8E23; /* Vert haricot/marron pour les brouillons */ + font-weight: bold; +} + +.status-capturing { + color: #87CEEB; /* Bleu ciel pour les projets en capture/en cours */ + font-weight: bold; +} + +.status-idle { + color: #32CD32; /* Vert vif pour les projets terminés */ + font-weight: bold; +} + +.status-stopping { + color: #FF4500; /* Orange rougeâtre pour les projets arrêtés */ + font-weight: bold; +} + +.status-unknown { + color: #cccccc; /* Gris pour les statuts inconnus */ + font-style: italic; } \ No newline at end of file diff --git a/css/image/camera-image b/css/image/camera-image.png similarity index 100% rename from css/image/camera-image rename to css/image/camera-image.png diff --git a/js/core/routes.js b/js/core/routes.js index 0a50fe6..c116ad6 100644 --- a/js/core/routes.js +++ b/js/core/routes.js @@ -197,8 +197,10 @@ async function start_timelapse(id,frequency,nbimages){ data: mydata }); - alert("data retrieval started:", response); + alert("Configuration de la caméra réussie"); + return response; } catch (error) { + alert("Erreur lors de la configuration de la caméra: " + error); throw error; } } @@ -216,9 +218,36 @@ async function stopCamera(id){ data: mydata }); - alert("Camera stopped succesfully :", response); + alert("La caméra a été arrêtée avec succès"); + return response; } catch (error) { - alert("Error stopping the camera :", error); + alert("Erreur lors de l'arrêt de la caméra : " + error); throw error; } -} \ No newline at end of file +} + +async function manualUpload(imageFile, projectId, timestamp, temperature, humidity) { + try { + // Create FormData to send the file and metadata + const formData = new FormData(); + formData.append('image', imageFile); + formData.append('projectId', projectId); + formData.append('timestamp', timestamp); + formData.append('temperature', temperature); + formData.append('humidity', humidity); + + const response = await $.ajax({ + url: api_url.concat("/camera/upload"), + method: "POST", + data: formData, + processData: false, // Prevents jQuery from converting FormData to string + contentType: false, // Lets browser set the content type with boundary + }); + + alert("Image uploaded successfully"); + return response; + } catch (error) { + alert("Error uploading image: " + error); + throw error; + } +} diff --git a/js/pages/index.js b/js/pages/index.js index 62de315..8cfc2f7 100644 --- a/js/pages/index.js +++ b/js/pages/index.js @@ -9,18 +9,57 @@ document.addEventListener("DOMContentLoaded", () => { }); }); +function formatDateToFrench(dateString) { + const options = { + year: 'numeric', + month: 'long', + day: 'numeric' + }; + const date = new Date(dateString); + return date.toLocaleDateString('fr-FR', options); +} + +function formatStatusWithColor(status) { + let statusText = ""; + let colorClass = ""; + + switch (status) { + case 0: + statusText = "Brouillon"; + colorClass = "status-draft"; + break; + case 1: + statusText = "En capture"; + colorClass = "status-capturing"; + break; + case 2: + statusText = "Terminé"; + colorClass = "status-idle"; + break; + case 3: + statusText = "En cours d\'arrêt"; + colorClass = "status-stopping"; + break; // Ajout du break manquant ici + default: + statusText = "Inconnu"; + colorClass = "status-unknown"; + } + + return `${statusText}`; +} + function formatStatus(status) { switch (status) { case 0: - return "brouillon"; + return "Brouillon"; // Projet à peine créé, vide sans config case 1: - return "en cours"; + return "En capture"; // Projet en cours de capture case 2: - return "terminé"; + return "En pause"; // Projet en pause ou inactif case 3: - return "En cours de génération"; + return "En cours d\'arrêt"; // Projet en cours d'arrêt default: - return "inconnu"; + return "Inconnu"; } } @@ -91,10 +130,10 @@ function setupCarousel(global_project_list) { projectDiv.classList.add(letter[index]); projectDiv.innerHTML = `
${formatDate(project.start_date)}
-Status : ${formatStatus(parseInt(project.status))}
+Date de début : ${formatDateToFrench(project.start_date)}
+Statut : ${formatStatusWithColor(parseInt(project.status))}
`; @@ -111,6 +150,14 @@ function setupCarousel(global_project_list) { deleteButton.addEventListener('click', (event) => { event.stopPropagation(); const projectName = project.name; + const projectStatus = parseInt(project.status); + + // Vérifier si le projet est en cours de capture (statut 1) ou en cours d'arrêt (statut 3) + if (projectStatus === 1 || projectStatus === 3) { + alert(`Impossible de supprimer "${projectName}" car sa capture est ${projectStatus === 1 ? 'en cours' : 'en cours d\'arrêt'}.\nVeuillez d'abord arrêter la procédure de capture.`); + return; + } + document.getElementById('alertMessage').textContent = `Veux-tu vraiment supprimer le projet : ${projectName} ?`; document.getElementById('customAlert').style.display = 'block'; diff --git a/js/pages/projet_detail.js b/js/pages/projet_detail.js index 88e0c9e..e28e6d7 100644 --- a/js/pages/projet_detail.js +++ b/js/pages/projet_detail.js @@ -30,6 +30,40 @@ document.addEventListener("DOMContentLoaded", async () => { const firstInput = document.getElementById("first"); const lastInput = document.getElementById("last"); + const formContainerUpload = document.getElementById("form-container-upload"); + const showFormButtonUpload = document.getElementById("show-form-button-upload"); + const closeFormButtonUpload = document.getElementById("close-form-button-upload"); + const manualUploadForm = document.getElementById("manual-upload-form"); + + if (formContainerUpload && showFormButtonUpload && closeFormButtonUpload && manualUploadForm) { + showFormButtonUpload.addEventListener("click", () => { + formContainerUpload.style.display = "flex"; + }); + + closeFormButtonUpload.addEventListener("click", () => { + formContainerUpload.style.display = "none"; + }); + + manualUploadForm.addEventListener("submit", async (event) => { + event.preventDefault(); + + const imageFile = document.getElementById("imageFile").files[0]; + const temperature = document.getElementById("temperature").value; + const humidity = document.getElementById("humidity").value; + const timestamp = new Date().toISOString(); + + try { + await manualUpload(imageFile, projectId, timestamp, temperature, humidity); + alert("Image uploadée avec succès !"); + formContainerUpload.style.display = "none"; + } catch (error) { + alert("Erreur lors de l'upload de l'image : " + error); + } + }); + } else { + console.error("Un ou plusieurs éléments du formulaire d'upload manuel sont introuvables."); + } + let selectedNumbers = []; populateTimelapseLogic(start_timelapse_button, projectId).then(() => { @@ -51,10 +85,14 @@ document.addEventListener("DOMContentLoaded", async () => { const minutes = document.getElementById("minutes").value; const frequency = days * 1440 + hours * 60 + minutes; if(frequency >= 3) { - const nbrimages = document.getElementById("totalImages").value; - start_timelapse(projectId, frequency, nbrimages).then(() => { + const nbrimages = document.getElementById("totalImages").value; + try { + // Attendre que la requête API soit terminée avant de recharger la page + await start_timelapse(projectId, frequency, nbrimages); location.reload(); - }); + } catch (error) { + console.error("Erreur lors du démarrage du timelapse:", error); + } } else { alert("La fréquence doit être supérieure à 3 minutes !"); } @@ -64,8 +102,13 @@ document.addEventListener("DOMContentLoaded", async () => { document .getElementById("stop-camera") .addEventListener("click", async () => { - stopCamera(projectId); - location.reload(); + try { + // Attendre que la requête API soit terminée avant de recharger la page + await stopCamera(projectId); + location.reload(); + } catch (error) { + console.error("Erreur lors de l'arrêt de la caméra:", error); + } }); } }); @@ -345,24 +388,44 @@ async function generateViewMetric(projectId) { if (measurements != 404) { let samples; if (videoId != -1) { - currentVideoDatas = await getDataVideoFromApi(videoId); - samples = JSON.parse(currentVideoDatas[0]["measurement_ids"]); - if (currentVideoDatas[0].status != 0) { - videoPlaceHolder.innerHTML = ` - `; - } else { - videoPlaceHolder.innerHTML = `