// ========================================================= // Tableaux globaux // ========================================================= let configIndices = []; // Données issues de la table "indice" let coursActionsData = []; // Données issues de la table "cours_actions" // ========================================================= // CHARGEMENT DES DONNÉES // ========================================================= function chargerDonnees() { // Chargement en parallèle des deux API Promise.all([ fetch("./php/api_lecture_tableindice.php").then((res) => res.json()), fetch("./php/api_indices.php").then((res) => res.json()), ]) .then(([configResult, coursResult]) => { // ----------------------------------------------------- // Configuration des indices // ----------------------------------------------------- if (configResult.status === "success") { configIndices = configResult.data; console.log( "Configuration indices chargée :", configIndices.length, "éléments", ); } else { console.error("Erreur API config indices :", configResult.message); } // ----------------------------------------------------- // Cours des actions // ----------------------------------------------------- if (coursResult.status === "success") { coursActionsData = coursResult.data; console.log( "Cours actions chargés :", coursActionsData.length, "éléments", ); } else { console.error("Erreur API cours_actions :", coursResult.message); } // ----------------------------------------------------- // Mise à jour des vues // ----------------------------------------------------- afficherSyntheseCartes(); alimenterBandeauxTicker(); // ----------------------------------------------------- // Statut de rafraîchissement // ----------------------------------------------------- const statut = document.getElementById("statut"); if (statut) { statut.innerText = `Dernière mise à jour : ${new Date().toLocaleTimeString()}`; } }) .catch((error) => { console.error("Erreur réseau lors du chargement des API :", error); }); } // ========================================================= // AFFICHAGE DES CARTES // ========================================================= function afficherSyntheseCartes() { const container = document.getElementById("cards-container"); if (!container) return; container.innerHTML = ""; // ------------------------------------------------------- // On se base STRICTEMENT sur afficher == 1 // ------------------------------------------------------- const actionsAffichees = configIndices.filter( (item) => String(item.afficher) === "1" || item.afficher == 1, ); if (actionsAffichees.length > 0) { actionsAffichees.forEach((conf) => { // --------------------------------------------------- // Croisement avec les cours en direct // --------------------------------------------------- const d = coursActionsData.find( (item) => item.symbole === conf.symbole || item.isin === conf.isin, ) || {}; const ecartValeur = parseFloat(d.variation || 0); const isPositive = ecartValeur >= 0; const badgeColor = isPositive ? "text-emerald-400" : "text-rose-400"; const sign = isPositive ? "+" : ""; // --------------------------------------------------- // Volume // --------------------------------------------------- const volumeFormate = d.volume ? parseInt(d.volume).toLocaleString("fr-FR") : "--"; // --------------------------------------------------- // Carte // --------------------------------------------------- container.innerHTML += `

${conf.nom || conf.indice} (${conf.symbole || "N/A"})

${conf.isin || "Aucun ISIN"} ${conf.indice || ""}
${ d.cours ? parseFloat(d.cours).toLocaleString("fr-FR", { minimumFractionDigits: 2, }) : "--" }
${sign} ${ecartValeur.toLocaleString("fr-FR", { minimumFractionDigits: 2, maximumFractionDigits: 4, })} ( ${sign}${parseFloat(d.variation_pct || 0).toFixed(2)}% )
${d.date_cours || "--/--"}
Haut ${ d.plus_haut ? parseFloat(d.plus_haut).toLocaleString("fr-FR", { minimumFractionDigits: 2, }) : "--" }
Bas ${ d.plus_bas ? parseFloat(d.plus_bas).toLocaleString("fr-FR", { minimumFractionDigits: 2, }) : "--" }
Volume ${volumeFormate}
`; }); } else { container.innerHTML = `
Aucune action configurée à 'afficher = 1'.
`; } } // ========================================================= // PRÉPARATION DES BANDEAUX // ========================================================= function alimenterBandeauxTicker() { const preparerDonneesTicker = (nomIndiceRecherche) => { const cleanSearch = nomIndiceRecherche .replace(/[^a-z0-9]/gi, "") .toLowerCase(); // --------------------------------------------------- // Recherche dans coursActionsData // --------------------------------------------------- let liste = coursActionsData.filter((item) => { if (!item.indice) { return false; } const cleanItemIndice = item.indice .replace(/[^a-z0-9]/gi, "") .toLowerCase(); return cleanItemIndice === cleanSearch; }); // --------------------------------------------------- // Si aucune donnée, utiliser configIndices // --------------------------------------------------- if (liste.length === 0) { liste = configIndices.filter((item) => { if (!item.indice) { return false; } const cleanItemIndice = item.indice .replace(/[^a-z0-9]/gi, "") .toLowerCase(); return cleanItemIndice === cleanSearch; }); } // --------------------------------------------------- // Fusion et formatage // --------------------------------------------------- let listeFinale = liste.map((conf) => { const coursMatch = coursActionsData.find( (item) => item.symbole === conf.symbole || item.isin === conf.isin, ) || conf; return { nom: conf.nom || coursMatch.nom || conf.symbole, cours: coursMatch.cours || 0, variation_pct: coursMatch.variation_pct || 0, }; }); // --------------------------------------------------- // Tri alphabétique // --------------------------------------------------- listeFinale.sort((a, b) => a.nom.localeCompare(b.nom)); return listeFinale; }; // ------------------------------------------------------- // Remplissage des trois bandeaux // ------------------------------------------------------- remplirUnBandeau("ticker-cac40", preparerDonneesTicker("CAC40")); remplirUnBandeau("ticker-ibex35", preparerDonneesTicker("IBEX35")); remplirUnBandeau("ticker-dowjones", preparerDonneesTicker("DOWJONES")); } // ========================================================= // REMPLIR UN BANDEAU // ========================================================= function remplirUnBandeau(elementId, donneesTriees) { const container = document.getElementById(elementId); if (!container) return; if (donneesTriees.length === 0) { container.innerHTML = ` Aucune donnée disponible `; return; } let blocs = ""; donneesTriees.forEach((item) => { const isPositive = parseFloat(item.variation_pct || 0) >= 0; const colorClass = isPositive ? "text-emerald-400" : "text-rose-400"; const sign = isPositive ? "+" : ""; const coursFormate = parseFloat(item.cours || 0).toLocaleString("fr-FR", { minimumFractionDigits: 2, }); const variationFormatee = parseFloat(item.variation_pct || 0).toFixed(2); blocs += `
${item.nom} ${coursFormate} ${sign}${variationFormatee}%
`; }); // Triple répétition pour assurer // le défilement continu container.innerHTML = blocs + blocs + blocs; const dureeTotale = Math.max(20, donneesTriees.length * 4); container.style.animationDuration = `${dureeTotale}s`; } // ========================================================= // DÉMARRAGE // ========================================================= // Chargement initial chargerDonnees(); // Rafraîchissement toutes les 60 secondes setInterval(chargerDonnees, 60000); // ========================================================= // RACCOURCIS CLAVIER // ========================================================= document.addEventListener("keydown", (event) => { // F1 → Administration if (event.key === "F1") { event.preventDefault(); window.location.href = "https://www.giraud-finance.com/html/admin.html"; } // F2 → Site principal if (event.key === "F2") { event.preventDefault(); window.location.href = "https://giraud-finance.com"; } });