diff --git a/Js/fonctions.js b/Js/fonctions.js index db589be..63c7ac2 100755 --- a/Js/fonctions.js +++ b/Js/fonctions.js @@ -61,8 +61,9 @@ $(function() { // On ne lance le timer que si l'utilisateur est connecté (pas sur la vue Connexion) if (vueActuelle !== "Connexion") { setInterval(function() { - + console.log("Actualisation gabarit"); raffraichier_gabarit(); + /* On vérifie si l'onglet est actif pour éviter des requêtes inutiles if (!document.hidden) { @@ -523,15 +524,8 @@ function afficher_quittances_police_periode() { } // 3. Préparation de l'interface (Loader) - $conteneur.html(` -
-
- Chargement... -
-

Chargement des quittances...

-
- `); - + showLoader("#div_quittancepolice", { size: 3 }); + // 4. Appel AJAX $.ajax({ url: racine + "Ajaxfichepolice/", @@ -617,15 +611,9 @@ function imprimer_quittance_client(idQuittance) { /* =================================================== * 3. Préparation visuelle (Spinner) * =================================================== */ - divExport.innerHTML = ` -
-
- Chargement... -
-

Génération du document client en cours...

-
- `; + showLoader("#div_export_quittance", { size: 3 }); + /* =================================================== * 4. Initialisation de l'instance Bootstrap * =================================================== */ @@ -794,8 +782,8 @@ function adherents_police() function afficher_adherents_police() { - $("#div_liste_adherent").html('
  ' + 'Veuillez patienter... / Please wait...' + '
'); - + showLoader("#div_liste_adherent", { size: 3 }); + $.ajax({ url: $("#racineWeb").val()+"Ajaxlisteadherent/", type : 'post', @@ -809,150 +797,274 @@ function afficher_adherents_police() } +// --- I18n dictionary --- +const I18N = { + fr_FR: { + loading: "Affichage en cours...", + exportPdf: "Exporter les graphiques en PDF", + dashboardTitle: "Graphiques des sinistres", + charts: { + claimsTitle: "Répartition des sinistres", + claimsCount: "Nombre de sinistres", + monthlyTitle: "Évolution mensuelle", + monthlyCumulative: "Sinistres cumulés", + monthlySingle: "Sinistres uniques", + lossRatioTitle: "Ratio de sinistralité", + lossRatioLabel: "Ratio de sinistralité" + }, + months: ["Jan", "Fév", "Mar", "Avr", "Mai", "Juin", "Juil", "Août", "Sep", "Oct", "Nov", "Déc"], + errors: { + ajax: "Impossible de charger les graphiques.", + pdfLib: "Erreur : jsPDF n'est pas chargé." + } + }, + en_US: { + loading: "Loading in progress...", + exportPdf: "Export charts to PDF", + dashboardTitle: "Claims Charts", + charts: { + claimsTitle: "Claims distribution", + claimsCount: "Number of claims", + monthlyTitle: "Monthly trend", + monthlyCumulative: "Claims cumulative", + monthlySingle: "Claims single", + lossRatioTitle: "Loss ratio", + lossRatioLabel: "Loss ratio" + }, + months: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], + errors: { + ajax: "Unable to load charts.", + pdfLib: "Error: jsPDF is not loaded." + } + } +}; + +// --- Helpers --- +function getLang() { + const codeLangue = $("#codeLangue").val() || "fr_FR"; + return I18N[codeLangue] ? codeLangue : "fr_FR"; +} + +function t(path) { + const lang = getLang(); + return path.split(".").reduce((acc, key) => (acc && acc[key] != null ? acc[key] : null), I18N[lang]); +} + +// Optional: normalize backend month keys to localized labels +function localizeMonths(months) { + const map = { + Jan: "Jan", Feb: "Feb", Mar: "Mar", Apr: "Apr", May: "May", Jun: "Jun", + Jul: "Jul", Aug: "Aug", Sep: "Sep", Oct: "Oct", Nov: "Nov", Dec: "Dec" + }; + const langMonths = t("months"); + // If backend already provides localized months, keep them; else map to language months by index + if (!Array.isArray(months) || months.length !== 12) return months; + const canonical = months.map(m => map[m] || m); + // Use the language month names but preserve array length and order + return langMonths && langMonths.length === 12 ? langMonths : canonical; +} + +function showLoader(selector, options = {}) { + const { message = null, size = 3 } = options; + const text = message || t("loading"); + + const loaderHtml = ` +
+
+ ${text} +
+

${text}

+
+ `; + $(selector).html(loaderHtml); +} + +function hideLoader(selector, contentHtml = "") { + $(selector).html(contentHtml); +} + function graphique_sinistre() { - // Spinner pendant le chargement - $("#div_graphique").html(` -
-
- Chargement... -
-

Affichage des graphiques en cours...

+ showLoader("#div_graphique", { size: 3 }); + + $.ajax({ + url: $("#racineWeb").val() + "Ajaxgraphiquesinistres/api/", + type: "get", + dataType: "json", + success: function (data) { + const exportLabel = t("exportPdf"); + + const html = ` +
+
- `); +
+
+
+
+
${t("charts.claimsTitle")}
+ +
+
+
+
+
+
+
${t("charts.monthlyTitle")}
+ +
+
+
+
+
+
+
${t("charts.lossRatioTitle")}
+ +
+
+
+
+ `; + hideLoader("#div_graphique", html); - $.ajax({ - url: $("#racineWeb").val() + "Ajaxgraphiquesinistres/api/", - type: 'get', - dataType: 'json', - success: function(data) { - console.log("Réponse JSON reçue:", data); + // Render charts with localized labels + renderClaimsChart(data.claims); + renderClaimsMonthChart(data.claimsMonth); + renderLossRatioChart(data.lossRatio); - // Layout HTML - $("#div_graphique").html(` -
- -
-
-
-
-
-
Répartition des sinistres
- -
-
-
-
-
-
-
Évolution mensuelle
- -
-
-
-
-
-
-
Ratio de sinistralité
- -
-
-
-
- `); + setupExportPdf(); + }, + error: function (err) { + console.error("Erreur AJAX:", err); + hideLoader("#div_graphique", ` +
${t("errors.ajax")}
+ `); + } + }); +} - // --- Graphiques Chart.js --- +// --- Charts --- - // 1. Répartition - new Chart(document.getElementById('claimsChart'), { - type: 'bar', - data: { - labels: data.claims.claimsLabels, - datasets: [{ - label: 'Nombre de sinistres', - data: data.claims.claimsValues, - backgroundColor: 'rgba(54, 162, 235, 0.6)' - }] - } - }); +function renderClaimsChart(claims) { + new Chart(document.getElementById("claimsChart"), { + type: "bar", + data: { + labels: claims.claimsLabels, + datasets: [{ + label: t("charts.claimsCount"), + data: claims.claimsValues, + backgroundColor: "rgba(54, 162, 235, 0.6)" + }] + }, + options: { + plugins: { + legend: { display: true } + }, + scales: { + x: { title: { display: false } }, + y: { title: { display: false }, beginAtZero: true } + } + } + }); +} - // 2. Évolution mensuelle - new Chart(document.getElementById('claimsMonthChart'), { - type: 'line', - data: { - labels: data.claimsMonth.months, - datasets: [ - { - label: 'Sinistres mensuels', - data: data.claimsMonth.monthlyClaims, - borderColor: 'rgba(255, 99, 132, 0.8)', - fill: false - }, - { - label: 'Sinistres uniques', - data: data.claimsMonth.singleClaims, - borderColor: 'rgba(75, 192, 192, 0.8)', - fill: false - } - ] - } - }); +function renderClaimsMonthChart(claimsMonth) { + const labels = localizeMonths(claimsMonth.months); - // 3. Ratio de sinistralité - new Chart(document.getElementById('lossRatioChart'), { - type: 'line', - data: { - labels: data.lossRatio.lossRatioLabels, - datasets: [{ - label: 'Ratio de sinistralité', - data: data.lossRatio.lossRatioValues, - borderColor: 'rgba(255, 206, 86, 0.8)', - fill: false - }] - } - }); - - // --- Export PDF --- - $("#exportPdfBtn").on("click", function() { - if (!window.jspdf) { - alert("Erreur : jsPDF n'est pas chargé."); - return; - } - - const { jsPDF } = window.jspdf; - const pdf = new jsPDF('p', 'mm', 'a4'); - - pdf.setFontSize(18); - pdf.text("Tableau de bord - Synthèse", 10, 20); - - // Ajout des graphiques - addChartToPdf(pdf, 'claimsChart', 'Répartition des sinistres', 40); - addChartToPdf(pdf, 'claimsMonthChart', 'Évolution mensuelle', 120); - - pdf.addPage(); - addChartToPdf(pdf, 'lossRatioChart', 'Ratio de sinistralité', 40); - - pdf.save('Tableau_de_bord.pdf'); - }); - - function addChartToPdf(pdf, canvasId, title, startY) { - const canvas = document.getElementById(canvasId); - if (canvas) { - const imgData = canvas.toDataURL('image/png', 1.0); - pdf.setFontSize(14); - pdf.text(title, 10, startY); - pdf.addImage(imgData, 'PNG', 10, startY + 5, 180, 60); - } - } + new Chart(document.getElementById("claimsMonthChart"), { + type: "line", + data: { + labels, + datasets: [ + { + label: t("charts.monthlyCumulative"), + data: claimsMonth.monthlyClaims, + borderColor: "rgba(255, 99, 132, 0.8)", + backgroundColor: "rgba(255, 99, 132, 0.2)", + tension: 0.25, + fill: false }, - error: function(err) { - console.error("Erreur AJAX:", err); - $("#div_graphique").html(` -
- Impossible de charger les graphiques. -
- `); + { + label: t("charts.monthlySingle"), + data: claimsMonth.singleClaims, + borderColor: "rgba(75, 192, 192, 0.8)", + backgroundColor: "rgba(75, 192, 192, 0.2)", + tension: 0.25, + fill: false } - }); -} \ No newline at end of file + ] + }, + options: { + plugins: { + legend: { display: true } + }, + scales: { + x: { title: { display: false } }, + y: { title: { display: false }, beginAtZero: true } + } + } + }); +} + +function renderLossRatioChart(lossRatio) { + const labels = localizeMonths(lossRatio.lossRatioLabels); + + new Chart(document.getElementById("lossRatioChart"), { + type: "line", + data: { + labels, + datasets: [{ + label: t("charts.lossRatioLabel"), + data: lossRatio.lossRatioValues, + borderColor: "rgba(255, 206, 86, 0.8)", + backgroundColor: "rgba(255, 206, 86, 0.2)", + tension: 0.25, + fill: false + }] + }, + options: { + plugins: { + legend: { display: true } + }, + scales: { + x: { title: { display: false } }, + y: { title: { display: false }, beginAtZero: true } + } + } + }); +} + +// --- Export PDF --- + +function setupExportPdf() { + $("#exportPdfBtn").on("click", function () { + if (!window.jspdf) { + alert(t("errors.pdfLib")); + return; + } + const { jsPDF } = window.jspdf; + const pdf = new jsPDF("p", "mm", "a4"); + + pdf.setFontSize(18); + pdf.text(t("dashboardTitle"), 10, 20); + + addChartToPdf(pdf, "claimsChart", t("charts.claimsTitle"), 40); + addChartToPdf(pdf, "claimsMonthChart", t("charts.monthlyTitle"), 120); + + pdf.addPage(); + addChartToPdf(pdf, "lossRatioChart", t("charts.lossRatioTitle"), 40); + + pdf.save("Tableau_de_bord.pdf"); // you can also localize the filename if needed + }); +} + +function addChartToPdf(pdf, canvasId, title, startY) { + const canvas = document.getElementById(canvasId); + if (canvas) { + const imgData = canvas.toDataURL("image/png", 1.0); + pdf.setFontSize(14); + pdf.text(title, 10, startY); + pdf.addImage(imgData, "PNG", 10, startY + 5, 180, 60); + } +} diff --git a/Vue/gabarit.php b/Vue/gabarit.php index c2ae9e4..b03acfc 100755 --- a/Vue/gabarit.php +++ b/Vue/gabarit.php @@ -599,7 +599,7 @@ $activeChildId = $menuData['child']; - +