From fb74a4314695ebe5c2ac470f828a45d71eaf4ac2 Mon Sep 17 00:00:00 2001 From: Alexis Burnaz <48258099+alxsbrz@users.noreply.github.com> Date: Mon, 17 Nov 2025 22:49:53 +0100 Subject: [PATCH] =?UTF-8?q?Am=C3=A9lioration=20du=20loader=20:=20timeout?= =?UTF-8?q?=205s,=20int=C3=A9gration=20automatique,=20correction=20usernam?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Ajout d'un timeout de 5 secondes avec message d'erreur pour mauvaise connexion - Intégration automatique du loader dans fetchWithJson() - Ajout du loader sur tous les appels fetch manuels (index, historiqueParcours, client-form, intermediaire-form, nav-parcours) - Correction du problème d'affichage username sur index.js (gestion erreurs et vérification éléments HTML) - Loader premier élément dans layout.ejs pour chargement immédiat - Délai de 500ms avant affichage pour éviter flash sur chargements rapides - Gestion d'erreurs améliorée dans nav-parcours.js --- etv2/public/js/auth.js | 1 + etv2/public/js/client-form.js | 276 ++++++++++++++++----------- etv2/public/js/global.js | 44 ++++- etv2/public/js/historiqueParcours.js | 57 +++++- etv2/public/js/index.js | 58 +++++- etv2/public/js/intermediaire-form.js | 144 +++++++++----- etv2/public/js/loader.js | 24 ++- etv2/public/js/nav-parcours.js | 8 +- etv2/views/layout.ejs | 4 +- test | 0 10 files changed, 436 insertions(+), 180 deletions(-) delete mode 100644 test diff --git a/etv2/public/js/auth.js b/etv2/public/js/auth.js index 5c54075e..3f1c1107 100644 --- a/etv2/public/js/auth.js +++ b/etv2/public/js/auth.js @@ -25,6 +25,7 @@ document.addEventListener('DOMContentLoaded', function () { // Récupération des informations du parcours (async () => { try { + // Le loader est déjà géré dans fetchWithJson const data = await fetchWithJson(`/auth/verifyMatricule/${matricule}`, 'GET'); if (data.valid) { diff --git a/etv2/public/js/client-form.js b/etv2/public/js/client-form.js index 4cc1e223..0dcaf12f 100644 --- a/etv2/public/js/client-form.js +++ b/etv2/public/js/client-form.js @@ -141,48 +141,67 @@ async function handleModalExtract() { document.getElementById('modalExtraireClient').disabled = true; - const response = await fetch(`/client/extract`, { - method: 'POST', - body: JSON.stringify({ - "matricule": matricule, - "numClient": document.getElementById("modalNumClient").value - }), - headers: { - 'Content-Type': 'application/json', - }, - }); - const res = await response.json(); + if (typeof window.showLoader === 'function') { + window.showLoader(); + } + + try { + const response = await fetch(`/client/extract`, { + method: 'POST', + body: JSON.stringify({ + "matricule": matricule, + "numClient": document.getElementById("modalNumClient").value + }), + headers: { + 'Content-Type': 'application/json', + }, + }); + const res = await response.json(); - if (res.valid) { - document.getElementById("error-extract").style.display = "none"; + if (res.valid) { + document.getElementById("error-extract").style.display = "none"; + document.getElementById('modalExtraireClient').disabled = false; + console.log(res); + + // Save sessionStorage for Intermediaire + sessionStorage.setItem('tmp', JSON.stringify(res.data)); + + // Populate data + document.getElementById("numClient").value = (res.data.numClient) ? res.data.numClient : null; + document.getElementById("nomClient").value = (res.data.nomClient) ? res.data.nomClient : null; + document.getElementById("adresseClient").value = (res.data.adresseClient) ? res.data.adresseClient : null; + document.getElementById("codePostalClient").value = (res.data.postalClient) ? res.data.postalClient : null; + document.getElementById("villeClient").value = (res.data.villeClient) ? res.data.villeClient : null; + + validateField('numClient', true); + validateField('nomClient', true); + validateField('adresseClient', true); + validateField('codePostalClient', true); + validateField('villeClient', true); + updateSubmitButtonState('clientForm'); + + // close le modal + const elem = document.getElementById('modalExtractAxAPAC'); + const instance = M.Modal.getInstance(elem); + instance.close(); + } else { + document.getElementById("error-extract").style.display = "block"; + document.getElementById('modalExtraireClient').disabled = false; + console.log("Problème rencontré lors de l'extraction cl063 AxA PAC :", res.error); + if (typeof window.showError === 'function') { + window.showError("Erreur lors de l'extraction des données client."); + } + } + } catch (error) { + console.error("Erreur lors de l'extraction client:", error); + if (typeof window.showError === 'function') { + window.showError("Erreur lors de l'extraction. Vérifiez votre connexion."); + } + } finally { document.getElementById('modalExtraireClient').disabled = false; - console.log(res); - - // Save sessionStorage for Intermediaire - sessionStorage.setItem('tmp', JSON.stringify(res.data)); - - // Populate data - document.getElementById("numClient").value = (res.data.numClient) ? res.data.numClient : null; - document.getElementById("nomClient").value = (res.data.nomClient) ? res.data.nomClient : null; - document.getElementById("adresseClient").value = (res.data.adresseClient) ? res.data.adresseClient : null; - document.getElementById("codePostalClient").value = (res.data.postalClient) ? res.data.postalClient : null; - document.getElementById("villeClient").value = (res.data.villeClient) ? res.data.villeClient : null; - - validateField('numClient', true); - validateField('nomClient', true); - validateField('adresseClient', true); - validateField('codePostalClient', true); - validateField('villeClient', true); - updateSubmitButtonState('clientForm'); - - // close le modal - const elem = document.getElementById('modalExtractAxAPAC'); - const instance = M.Modal.getInstance(elem); - instance.close(); - } else { - document.getElementById("error-extract").style.display = "block"; - document.getElementById('modalExtraireClient').disabled = false; - console.log("Problème rencontré lors de l'extraction cl063 AxA PAC :", res.error); + if (typeof window.hideLoader === 'function') { + window.hideLoader(); + } } } @@ -190,86 +209,123 @@ async function handleSubmitForm(event) { event.preventDefault(); - let idClient = client?.id; - const numClient = document.getElementById('numClient').value; - - let responseClient; - - if (numClient) { - responseClient = await fetch(`/client/read/${numClient}`, { - method: 'GET', - headers: { 'Content-Type': 'application/json' }, - }); + if (typeof window.showLoader === 'function') { + window.showLoader(); } - const dataClient = await responseClient.json(); - if (dataClient.valid) { - idClient = dataClient.idClient; - } else { - // Créez le client ici si non trouvé - const responseCreateClient = await fetch(`/client/create`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - }); - const dataCreateClient = await responseCreateClient.json(); + try { + let idClient = client?.id; + const numClient = document.getElementById('numClient').value; - if (dataCreateClient.valid) { - idClient = dataCreateClient.client.id; + let responseClient; + + if (numClient) { + responseClient = await fetch(`/client/read/${numClient}`, { + method: 'GET', + headers: { 'Content-Type': 'application/json' }, + }); } - } + const dataClient = await responseClient.json(); - // Mettre à jour le contrat avec l'ID du client - if (idClient) { - const response = await fetch(`/client/update/${idClient}`, { - method: 'POST', - body: JSON.stringify({ - "nom": document.getElementById('nomClient').value.toUpperCase(), - "numClient": document.getElementById('numClient').value, - "adresse": document.getElementById('adresseClient').value.toUpperCase(), - "mail": document.getElementById('emailClient').value, - "codePostal": document.getElementById('codePostalClient').value, - "ville": document.getElementById('villeClient').value.toUpperCase(), - "noteFinanciere": document.getElementById('noteFinanciereClient').value - }), - headers: { - 'Content-Type': 'application/json', - }, - }); - const data = await response.json(); - - if (data.valid) { - const idContrat = contrat?.id; - - fetch(`/contrat/update/client/${idContrat}/${idClient}`, { + if (dataClient.valid) { + idClient = dataClient.idClient; + } else { + // Créez le client ici si non trouvé + const responseCreateClient = await fetch(`/client/create`, { method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + }); + const dataCreateClient = await responseCreateClient.json(); + + if (dataCreateClient.valid) { + idClient = dataCreateClient.client.id; + } + } + + // Mettre à jour le contrat avec l'ID du client + if (idClient) { + const response = await fetch(`/client/update/${idClient}`, { + method: 'POST', + body: JSON.stringify({ + "nom": document.getElementById('nomClient').value.toUpperCase(), + "numClient": document.getElementById('numClient').value, + "adresse": document.getElementById('adresseClient').value.toUpperCase(), + "mail": document.getElementById('emailClient').value, + "codePostal": document.getElementById('codePostalClient').value, + "ville": document.getElementById('villeClient').value.toUpperCase(), + "noteFinanciere": document.getElementById('noteFinanciereClient').value + }), headers: { 'Content-Type': 'application/json', }, - }) - .then(response => response.json()) - .then(data => { - if (data.valid) { - // Update Session storage - const clientStorage = JSON.parse(sessionStorage.getItem('tmp')); - - if (clientStorage) { - clientStorage.nomClient = document.getElementById('nomClient').value.toUpperCase(); - clientStorage.numClient = document.getElementById('numClient').value; - clientStorage.adresseClient = document.getElementById('adresseClient').value.toUpperCase(); - clientStorage.postalClient = document.getElementById('codePostalClient').value; - clientStorage.villeClient = document.getElementById('villeClient').value.toUpperCase(); - - sessionStorage.setItem('tmp', JSON.stringify(clientStorage)) - } - - // Redirect vers intermédiaire - window.location.href = `/navParcours?numParcours=${getNumParcoursFromURL()}&submenu=intermediaire`; - } else { - console.log('Echec lors de la mise à jour de la relation id contrat - id client :', data); - } }); + const data = await response.json(); + + if (data.valid) { + const idContrat = contrat?.id; + + fetch(`/contrat/update/client/${idContrat}/${idClient}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + }) + .then(response => response.json()) + .then(data => { + if (data.valid) { + // Update Session storage + const clientStorage = JSON.parse(sessionStorage.getItem('tmp')); + + if (clientStorage) { + clientStorage.nomClient = document.getElementById('nomClient').value.toUpperCase(); + clientStorage.numClient = document.getElementById('numClient').value; + clientStorage.adresseClient = document.getElementById('adresseClient').value.toUpperCase(); + clientStorage.postalClient = document.getElementById('codePostalClient').value; + clientStorage.villeClient = document.getElementById('villeClient').value.toUpperCase(); + + sessionStorage.setItem('tmp', JSON.stringify(clientStorage)) + } + + // Le loader sera masqué lors de la redirection + // Redirect vers intermédiaire + window.location.href = `/navParcours?numParcours=${getNumParcoursFromURL()}&submenu=intermediaire`; + } else { + console.log('Echec lors de la mise à jour de la relation id contrat - id client :', data); + if (typeof window.hideLoader === 'function') { + window.hideLoader(); + } + if (typeof window.showError === 'function') { + window.showError("Erreur lors de la mise à jour du contrat."); + } + } + }) + .catch(error => { + console.error("Erreur lors de la mise à jour du contrat:", error); + if (typeof window.hideLoader === 'function') { + window.hideLoader(); + } + if (typeof window.showError === 'function') { + window.showError("Erreur lors de la mise à jour. Vérifiez votre connexion."); + } + }); + } else { + if (typeof window.hideLoader === 'function') { + window.hideLoader(); + } + if (typeof window.showError === 'function') { + window.showError("Erreur lors de la mise à jour du client."); + } + } + } + } catch (error) { + console.error("Erreur lors de la soumission du formulaire client:", error); + if (typeof window.hideLoader === 'function') { + window.hideLoader(); + } + if (typeof window.showError === 'function') { + window.showError("Erreur lors de la soumission. Vérifiez votre connexion."); } } } diff --git a/etv2/public/js/global.js b/etv2/public/js/global.js index 0d3b119a..1be35528 100644 --- a/etv2/public/js/global.js +++ b/etv2/public/js/global.js @@ -108,16 +108,40 @@ function isNullOrUndefined(value) { // Fonction pour éviter la duplication du code fetch async function fetchWithJson(url, method, body = null) { - const options = { - method: method, - headers: { 'Content-Type': 'application/json' }, - }; - if (body) options.body = JSON.stringify(body); + // Activer le loader si disponible + if (typeof window.showLoader === 'function') { + window.showLoader(); + } - const response = await fetch(url, options); - if (!response.ok) throw new Error('Réseau ou erreur serveur'); + try { + const options = { + method: method, + headers: { 'Content-Type': 'application/json' }, + }; + if (body) options.body = JSON.stringify(body); - return await response.json(); + const response = await fetch(url, options); + if (!response.ok) throw new Error('Réseau ou erreur serveur'); + + const result = await response.json(); + + // Désactiver le loader si disponible + if (typeof window.hideLoader === 'function') { + window.hideLoader(); + } + + return result; + } catch (error) { + // Désactiver le loader en cas d'erreur + if (typeof window.hideLoader === 'function') { + window.hideLoader(); + } + // Afficher l'erreur si disponible + if (typeof window.showError === 'function') { + window.showError('Erreur lors de la communication avec le serveur. Vérifiez votre connexion.'); + } + throw error; + } } // Fonction de load du parcours en session storage @@ -134,6 +158,7 @@ async function loadParcours(numParcours) { } } catch (error) { console.error("Erreur lors de la récupération des informations parcours :", error); + // Le loader est déjà géré dans fetchWithJson } } @@ -146,7 +171,7 @@ function toggler(btn, div) { } } -// Fonction de load du parcours en session storage +// Fonction de load du contrat en session storage async function loadContrat(idContrat) { try { const data = await fetchWithJson(`/contrat/read/id/${idContrat}`, 'GET'); @@ -159,5 +184,6 @@ async function loadContrat(idContrat) { } } catch (error) { console.error("Erreur lors de la récupération des informations contrat :", error); + // Le loader est déjà géré dans fetchWithJson } } \ No newline at end of file diff --git a/etv2/public/js/historiqueParcours.js b/etv2/public/js/historiqueParcours.js index 964fde60..dd1a4c7f 100644 --- a/etv2/public/js/historiqueParcours.js +++ b/etv2/public/js/historiqueParcours.js @@ -29,11 +29,22 @@ document.addEventListener("DOMContentLoaded", async function () { } try { + if (typeof window.showLoader === 'function') { + window.showLoader(); + } const userResponse = await fetchUserDetails(matriculeUser); regionUser = userResponse?.user["@expand"].region?.nom || null; + if (typeof window.hideLoader === 'function') { + window.hideLoader(); + } } catch (error) { displayError("Erreur lors de la récupération des données utilisateur."); - + if (typeof window.hideLoader === 'function') { + window.hideLoader(); + } + if (typeof window.showError === 'function') { + window.showError("Erreur lors de la récupération des données utilisateur."); + } return; } @@ -50,6 +61,9 @@ document.addEventListener("DOMContentLoaded", async function () { // Fetch initial data try { + if (typeof window.showLoader === 'function') { + window.showLoader(); + } const response = await fetch(`/historiqueParcours/${regionUser}`); const dataResponse = await response.json(); @@ -58,9 +72,21 @@ document.addEventListener("DOMContentLoaded", async function () { populateParcoursTable(tableData); } else { displayError("Erreur lors de la récupération des parcours"); + if (typeof window.showError === 'function') { + window.showError("Erreur lors de la récupération des parcours"); + } + } + if (typeof window.hideLoader === 'function') { + window.hideLoader(); } } catch (error) { displayError("Failed to fetch data. Please try again later."); + if (typeof window.hideLoader === 'function') { + window.hideLoader(); + } + if (typeof window.showError === 'function') { + window.showError("Erreur lors du chargement des données. Vérifiez votre connexion."); + } } // Add event listeners to checkboxes @@ -70,6 +96,9 @@ document.addEventListener("DOMContentLoaded", async function () { if (checkbox.checked) { try { + if (typeof window.showLoader === 'function') { + window.showLoader(); + } const response = await fetch(`/historiqueParcours/${region}`); const dataResponse = await response.json(); @@ -78,9 +107,21 @@ document.addEventListener("DOMContentLoaded", async function () { populateParcoursTable(tableData); } else { displayError("Erreur lors de la récupération des parcours"); + if (typeof window.showError === 'function') { + window.showError("Erreur lors de la récupération des parcours"); + } + } + if (typeof window.hideLoader === 'function') { + window.hideLoader(); } } catch (error) { displayError("Failed to fetch data. Please try again later."); + if (typeof window.hideLoader === 'function') { + window.hideLoader(); + } + if (typeof window.showError === 'function') { + window.showError("Erreur lors du chargement des données. Vérifiez votre connexion."); + } } } else { removeRegionFromTableData(region); @@ -104,6 +145,7 @@ const removeRegionFromTableData = (region) => { async function fetchUserDetails(matriculeUser) { try { + // Le loader doit être géré par l'appelant si nécessaire const response = await fetch(`/user/read/matricule/${matriculeUser}`); const data = await response.json(); @@ -308,6 +350,9 @@ function downloadCSV(applyFilters) { async function generateProject(numParcours, produit) { try { + if (typeof window.showLoader === 'function') { + window.showLoader(); + } const response = await fetch(`/generate/${produit}/projet/${numParcours}`, { method: "POST", headers: { "Content-Type": "application/json"}, @@ -328,8 +373,18 @@ async function generateProject(numParcours, produit) { a.click(); window.URL.revokeObjectURL(url); a.remove(); + + if (typeof window.hideLoader === 'function') { + window.hideLoader(); + } } catch (error) { console.error("Erreur lors de la génération du projet:", error); + if (typeof window.hideLoader === 'function') { + window.hideLoader(); + } + if (typeof window.showError === 'function') { + window.showError('Erreur lors de la génération du projet. Vérifiez votre connexion.'); + } } } diff --git a/etv2/public/js/index.js b/etv2/public/js/index.js index db26fc5d..bf5e5c9a 100644 --- a/etv2/public/js/index.js +++ b/etv2/public/js/index.js @@ -4,14 +4,30 @@ document.addEventListener('DOMContentLoaded', function () { const token = localStorage.getItem('jwtToken'); if (token) { - const decoded = jwt_decode(token); - const userFirstName = decoded.userFirstName; - const userLastName = decoded.userLastName; - const userMatricule = decoded.userMatricule; + try { + const decoded = jwt_decode(token); + const userFirstName = decoded?.userFirstName || ''; + const userLastName = decoded?.userLastName || ''; + const userMatricule = decoded?.userMatricule || ''; - document.getElementById("firstNameItem").innerHTML = userFirstName; - document.getElementById("lastNameItem").innerHTML = userLastName; - document.getElementById("userMatricule").innerHTML = userMatricule; + // Vérifier que les éléments HTML existent avant de les modifier + const firstNameItem = document.getElementById("firstNameItem"); + const lastNameItem = document.getElementById("lastNameItem"); + const userMatriculeItem = document.getElementById("userMatricule"); + + if (firstNameItem) { + firstNameItem.innerHTML = userFirstName; + } + if (lastNameItem) { + lastNameItem.innerHTML = userLastName; + } + if (userMatriculeItem) { + userMatriculeItem.innerHTML = userMatricule; + } + } catch (error) { + console.error("Erreur lors du décodage du token:", error); + // En cas d'erreur, ne pas afficher les informations utilisateur + } } /* ---------- EVENNEMENT ------------ */ @@ -30,10 +46,14 @@ document.addEventListener('DOMContentLoaded', function () { if (data.valid) { window.location.href = `/parcours?numParcours=${data.numParcours}`; } else { - console.log("Erreur dans la création d'un nouveau parcours") + console.log("Erreur dans la création d'un nouveau parcours"); + if (typeof window.showError === 'function') { + window.showError("Erreur lors de la création du parcours. Veuillez réessayer."); + } } } catch (error) { console.error("Erreur serveur lors de la création d'un nouveau parcours :", error); + // L'erreur est déjà gérée par fetchWithJson avec le loader } })(); }); @@ -50,6 +70,11 @@ document.addEventListener('DOMContentLoaded', function () { const produit = document.getElementById('produit').innerHTML.replace(/\s/g, ''); let filename; + // Activer le loader + if (typeof window.showLoader === 'function') { + window.showLoader(); + } + // Envoi de la requête POST au serveur pour générer le projet fetch(`/generate/${produit}/projet/${numParcours}`, { method: 'POST', @@ -78,8 +103,22 @@ document.addEventListener('DOMContentLoaded', function () { a.click(); // Simule un clic sur l'élément pour déclencher le téléchargement window.URL.revokeObjectURL(url); // Nettoie l'URL objet a.remove(); // Supprime l'élément a du document + + // Désactiver le loader + if (typeof window.hideLoader === 'function') { + window.hideLoader(); + } }) - .catch(error => console.error('Erreur lors de la génération du projet:', error)); + .catch(error => { + console.error('Erreur lors de la génération du projet:', error); + // Désactiver le loader et afficher l'erreur + if (typeof window.hideLoader === 'function') { + window.hideLoader(); + } + if (typeof window.showError === 'function') { + window.showError('Erreur lors de la génération du projet. Vérifiez votre connexion.'); + } + }); }); // Écoute de l'événement de soumission du formulaire @@ -95,6 +134,7 @@ document.addEventListener('DOMContentLoaded', function () { // Envoi de la requête pour avoir le parcours (async () => { try { + // Le loader est déjà géré dans loadParcours via fetchWithJson await loadParcours(numParcours); // Accéder aux informations stockées du parcours diff --git a/etv2/public/js/intermediaire-form.js b/etv2/public/js/intermediaire-form.js index 74a8ec7b..ae1d3301 100644 --- a/etv2/public/js/intermediaire-form.js +++ b/etv2/public/js/intermediaire-form.js @@ -176,18 +176,24 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio async function handleModalExtract() { document.getElementById('modalExtraireIntermediaire').disabled = true; - const response = await fetch(`/client/extract`, { - method: 'POST', - body: JSON.stringify({ - "matricule": matricule, - "numClient": document.getElementById("modalNumClient").value - }), - headers: { - 'Content-Type': 'application/json', - }, - }); - const res = await response.json(); - if (res.valid) { + + if (typeof window.showLoader === 'function') { + window.showLoader(); + } + + try { + const response = await fetch(`/client/extract`, { + method: 'POST', + body: JSON.stringify({ + "matricule": matricule, + "numClient": document.getElementById("modalNumClient").value + }), + headers: { + 'Content-Type': 'application/json', + }, + }); + const res = await response.json(); + if (res.valid) { document.getElementById("error-extract").style.display = "none"; document.getElementById('modalExtraireIntermediaire').disabled = false; console.log(res); @@ -207,14 +213,28 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio validateField('codePostalIntermediaire', true); validateField('villeIntermediaire', true); updateSubmitButtonState('intermediaireForm'); - // close le modal - const elem = document.getElementById('modalExtractAxAPAC'); - const instance = M.Modal.getInstance(elem); - instance.close(); - } else { - document.getElementById("error-extract").style.display = "block"; + // close le modal + const elem = document.getElementById('modalExtractAxAPAC'); + const instance = M.Modal.getInstance(elem); + instance.close(); + } else { + document.getElementById("error-extract").style.display = "block"; + document.getElementById('modalExtraireIntermediaire').disabled = false; + console.log("Problème rencontré lors de l'extraction cl063 AxA PAC :", res.error); + if (typeof window.showError === 'function') { + window.showError("Erreur lors de l'extraction des données intermédiaire."); + } + } + } catch (error) { + console.error("Erreur lors de l'extraction intermédiaire:", error); + if (typeof window.showError === 'function') { + window.showError("Erreur lors de l'extraction. Vérifiez votre connexion."); + } + } finally { document.getElementById('modalExtraireIntermediaire').disabled = false; - console.log("Problème rencontré lors de l'extraction cl063 AxA PAC :", res.error); + if (typeof window.hideLoader === 'function') { + window.hideLoader(); + } } } @@ -222,39 +242,44 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio async function handleSubmitForm(event, redirection) { event.preventDefault(); - let idIntermediaire = intermediaire?.id; - const numPortefeuille = document.getElementById('numPortefeuille').value; - let responseIntermediaire; - - if (numPortefeuille) { - responseIntermediaire = await fetch(`/intermediaire/read/${numPortefeuille}`, { - method: 'GET', - headers: {'Content-Type': 'application/json'}, - }); + if (typeof window.showLoader === 'function') { + window.showLoader(); } - const dataIntermediaire = await responseIntermediaire.json(); - if (dataIntermediaire.valid) { - idIntermediaire = dataIntermediaire.idIntermediaire; - } else { - // Créez l'intermediaire ici si non trouvé - const responseCreateIntermediaire = await fetch(`/intermediaire/create`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - }); - const dataCreateIntermediaire = await responseCreateIntermediaire.json(); + try { + let idIntermediaire = intermediaire?.id; + const numPortefeuille = document.getElementById('numPortefeuille').value; + let responseIntermediaire; - if (dataCreateIntermediaire.valid) { - idIntermediaire = dataCreateIntermediaire.intermediaire.id; + if (numPortefeuille) { + responseIntermediaire = await fetch(`/intermediaire/read/${numPortefeuille}`, { + method: 'GET', + headers: {'Content-Type': 'application/json'}, + }); } - } + const dataIntermediaire = await responseIntermediaire.json(); - console.log(idIntermediaire); + if (dataIntermediaire.valid) { + idIntermediaire = dataIntermediaire.idIntermediaire; + } else { + // Créez l'intermediaire ici si non trouvé + const responseCreateIntermediaire = await fetch(`/intermediaire/create`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + }); + const dataCreateIntermediaire = await responseCreateIntermediaire.json(); - // // Mettre à jour le contrat avec l'ID du intermediaire - if (idIntermediaire) { + if (dataCreateIntermediaire.valid) { + idIntermediaire = dataCreateIntermediaire.intermediaire.id; + } + } + + console.log(idIntermediaire); + + // // Mettre à jour le contrat avec l'ID du intermediaire + if (idIntermediaire) { let type if (document.getElementById('courtier').checked == true) { @@ -320,8 +345,35 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } else { console.log('Echec lors de la mise à jour de la relation id contrat - id client :', data); + if (typeof window.hideLoader === 'function') { + window.hideLoader(); + } + if (typeof window.showError === 'function') { + window.showError("Erreur lors de la mise à jour du contrat."); + } + } + }) + .catch(error => { + console.error("Erreur lors de la mise à jour du contrat:", error); + if (typeof window.hideLoader === 'function') { + window.hideLoader(); + } + if (typeof window.showError === 'function') { + window.showError("Erreur lors de la mise à jour. Vérifiez votre connexion."); } }); + } else { + if (typeof window.hideLoader === 'function') { + window.hideLoader(); + } + } + } catch (error) { + console.error("Erreur lors de la soumission du formulaire intermédiaire:", error); + if (typeof window.hideLoader === 'function') { + window.hideLoader(); + } + if (typeof window.showError === 'function') { + window.showError("Erreur lors de la soumission. Vérifiez votre connexion."); } } } diff --git a/etv2/public/js/loader.js b/etv2/public/js/loader.js index b7d123ae..742ead39 100644 --- a/etv2/public/js/loader.js +++ b/etv2/public/js/loader.js @@ -3,21 +3,40 @@ document.addEventListener("DOMContentLoaded", () => { const errorMessage = document.getElementById("error-message"); let activateTimeout = null; + let timeoutError = null; + + // Le loader est le premier élément dans le HTML, donc il est chargé en premier + // Il est prêt à s'afficher immédiatement dès que showLoader() est appelé + // Pas de classe "hidden" par défaut = il est dans le DOM et prêt instantanément //activer le loader et le montrer a l'écran window.showLoader = function() { clearTimeout(activateTimeout); + clearTimeout(timeoutError); errorMessage.style.display = "none"; loader.classList.remove("hidden"); - + + // Délai avant l'affichage : permet d'éviter le flash du loader sur les chargements rapides + // Si hideLoader() est appelé avant ce délai, l'utilisateur ne verra jamais le loader activateTimeout = setTimeout(() => { - loader.classList.add("active"); + // Vérifier qu'on est toujours pas caché (au cas où hideLoader() ait été appelé entre temps) + if (!loader.classList.contains("hidden")) { + loader.classList.add("active"); + } }, 500); + + // Afficher un message d'erreur après 5 secondes si le loader est toujours actif + timeoutError = setTimeout(() => { + if (loader.classList.contains("active") && !loader.classList.contains("hidden")) { + showError("Connexion lente ou problème de réseau. Veuillez vérifier votre connexion."); + } + }, 5000); }; //enlever le loader et le faire disparaitre window.hideLoader = function() { clearTimeout(activateTimeout); + clearTimeout(timeoutError); loader.classList.remove("active"); setTimeout(() => loader.classList.add("hidden"), 500); }; @@ -25,6 +44,7 @@ document.addEventListener("DOMContentLoaded", () => { //cas d'erreur window.showError = function(msg) { clearTimeout(activateTimeout); + clearTimeout(timeoutError); errorMessage.textContent = msg; errorMessage.style.display = "block"; }; diff --git a/etv2/public/js/nav-parcours.js b/etv2/public/js/nav-parcours.js index bb6ed373..32b5159c 100644 --- a/etv2/public/js/nav-parcours.js +++ b/etv2/public/js/nav-parcours.js @@ -122,7 +122,13 @@ document.addEventListener('DOMContentLoaded', function() { }) hideLoader(); }) - .catch(error => console.error('Error:', error)); + .catch(error => { + console.error('Error:', error); + hideLoader(); + if (typeof window.showError === 'function') { + window.showError("Erreur lors du chargement du formulaire. Vérifiez votre connexion."); + } + }); //A MODIFIER UNE FOIS QUE RC SERA ADAPTé AU PARCOURS if (produit == "RC") { diff --git a/etv2/views/layout.ejs b/etv2/views/layout.ejs index 5a423aad..b81dfe06 100644 --- a/etv2/views/layout.ejs +++ b/etv2/views/layout.ejs @@ -32,8 +32,8 @@