/* ============================================================ 1. DONNÉES & TRADUCTIONS (FUSIONNÉES & COMPLÈTES) ============================================================ */ const translations = { fr: { // UI Base home: "Accueil", training: "Formation", others: "Autres", settings: "Réglages", welcomeTitle: "Bienvenue sur Biblia Pro", welcomeSub: "Testez vos connaissances et obtenez votre certificat certifié.", enterName: "Votre Nom Complet", selectLang: "Langue", selectLevel: "Choisissez un Niveau", lvlSimple: "Simple", lvlMedium: "Moyen", lvlHard: "Difficile", next: "Suivant", quizFinished: "Quiz Terminé !", certUnlocked: "Certificat Débloqué (Score > 7/10)", downloadCert: "Télécharger Certificat PDF", restart: "Retour à l'accueil", biblicalTraining: "Formation Biblique", resources: "Ressources", pass: "Réussi", fail: "Échoué", score: "Score", // Formation Module 1 & 3 courseTitle1: "La Structure de la Bible", courseDesc1: "Comprendre la bibliothèque de 66 livres : du Pentateuque à l'Apocalypse.", courseTitle2: "Le Salut par la Grâce", courseDesc2: "Pourquoi l'œuvre de la croix est suffisante pour la rédemption.", courseTitle5: "L'Art de la Méditation", courseDesc5: "Lire la parole à voix basse, la repasser dans son cœur.", courseTitle6: "Comprendre le Contexte", courseDesc6: "Identifier l'auteur et le public pour éviter les erreurs d'interprétation.", // Formation Module 2 (Leadership & Synergie) leadership: "Leadership: Inspirer par l'exemple", courseDescLeadership: "Le leader Nelo est celui qui sert sa communauté par la tech (Modèle Néhémie).", synergie: "Synergie: 1+1=3", courseDescSynergy: "Travailler en équipe pour multiplier les talents au lieu de les additionner.", // Formation Module 4 (Évangélisation Numérique) "réputation numérique": "Réputation Numérique : Ton Passeport", courseDesc7: "Ce que Google dit de toi. Soigne ton LinkedIn et ton GitHub, c'est ton nouveau passeport.", niche: "Niche : Résoudre pour impacter", courseDesc8: "Trouve un petit problème spécifique et deviens le meilleur au monde pour le résoudre.", "pitch deck": "Pitch Deck : Présenter sa Vision", courseDesc9: "Ta présentation visuelle pour convaincre en moins de 10 diapositives." }, en: { home: "Home", training: "Training", others: "Others", settings: "Settings", welcomeTitle: "Welcome to Biblia Pro", welcomeSub: "Test your knowledge and get your certified diploma.", enterName: "Full Name", selectLang: "Language", selectLevel: "Choose Level", lvlSimple: "Easy", lvlMedium: "Medium", lvlHard: "Hard", next: "Next", quizFinished: "Quiz Finished!", certUnlocked: "Certificate Unlocked (Score > 7/10)", downloadCert: "Download PDF Certificate", restart: "Back Home", biblicalTraining: "Biblical Training", resources: "Resources", pass: "Passed", fail: "Failed", score: "Score", courseTitle1: "The Bible Structure", courseDesc1: "Understanding the library of 66 books from Genesis to Revelation.", courseTitle2: "Salvation by Grace", courseDesc2: "Deep study on why the cross is sufficient for redemption.", courseTitle5: "The Art of Meditation", courseDesc5: "Muttering the word and keeping it in your heart.", courseTitle6: "Understanding Context", courseDesc6: "Identify author and audience to avoid misinterpretation.", leadership: "Leadership: Leading by Example", courseDescLeadership: "A Nelo leader serves the community through tech (Nehemiah model).", synergie: "Synergy: 1+1=3", courseDescSynergy: "Work as a team so talents multiply instead of just adding up.", "réputation numérique": "Digital Reputation: Your Passport", courseDesc7: "What Google says about you. Polish your LinkedIn and GitHub.", niche: "Niche: Solve to Impact", courseDesc8: "Find a specific small problem and become the best in the world at solving it.", "pitch deck": "Pitch Deck: Presenting the Vision", courseDesc9: "Your visual presentation to convince in less than 10 slides." }, ln: { home: "Ebandeli", training: "Kotangisa", others: "Mosusu", settings: "Bongisa", welcomeTitle: "Boyei malamu na Biblia Pro", welcomeSub: "Meka mayele na yo mpe zwa certificat.", enterName: "Kombo na yo mobimba", selectLang: "Lokota", selectLevel: "Pona Nivo", lvlSimple: "Petu", lvlMedium: "Kati", lvlHard: "Makasi", next: "Landi", quizFinished: "Masano esili!", certUnlocked: "Olongi Certificat (Matanga > 7/10)", downloadCert: "Zwa Certificat PDF", restart: "Zonga na ebandeli", biblicalTraining: "Mateya ya Biblia", resources: "Biloko", pass: "Olongi", fail: "Okweyi", score: "Matanga", courseTitle1: "Ndenge Biblia ebongisami", courseDesc1: "Toyeba mikanda 66 ya Biblia, kobanda na Genese tii na Emoniseli.", courseTitle2: "Lobiko na Ngolu", courseDesc2: "Mpo na nini mosala ya ekulusu ekoki mpo na kobikisama na biso.", courseTitle5: "Mayele ya kokanisa Liloba", courseDesc5: "Kotanga Liloba na nse ya mongongo, kobatela yango na motema.", courseTitle6: "Toyeba contexte", courseDesc6: "Toyeba nani akomi mpe mpo na nani, mpo tondima mateya ya lokuta te.", leadership: "Leadership: Kotambwisa na ndakisa", courseDescLeadership: "Mokonzi Nelo azali moto oyo asalelaka bato na tech (Ndakisa ya Nehemia).", synergie: "Synergie: 1+1=3", courseDescSynergy: "Kosala na lingomba mpo mayele na biso ekula na esika ya kobakisama.", "réputation numérique": "Lokumu na moninga ya nsinga (Digital)", courseDesc7: "Bongisa LinkedIn na GitHub na yo, ezali ndingisa (passeport) na yo ya sika.", niche: "Niche: Kosilisa mikakatano", courseDesc8: "Luka mokakatano moke mpe moko, mpe koma moto ya mayele mpo na kosilisa yango.", "pitch deck": "Pitch Deck: Kolakisa emonanseli", courseDesc9: "Ndenge ya kolakisa mpe kondimisa bato na mikanda moke mpenza." }, sw: { home: "Nyumbani", training: "Mafunzo", others: "Wengine", settings: "Mipangilio", welcomeTitle: "Karibu Biblia Pro", welcomeSub: "Pima ujuzi wako na upate cheti.", enterName: "Jina Kamili", selectLang: "Lugha", selectLevel: "Chagua Kiwango", lvlSimple: "Rahisi", lvlMedium: "Kati", lvlHard: "Ngumu", next: "Inayofuata", quizFinished: "Maswali yamekwisha!", certUnlocked: "Cheti kimefunguliwa (> 7/10)", downloadCert: "Pakua Cheti cha PDF", restart: "Rudi Nyumbani", biblicalTraining: "Mafunzo ya Biblia", resources: "Rasilimali", pass: "Umefaulu", fail: "Umeshindwa", score: "Alama", courseTitle1: "Muundo wa Biblia", courseDesc1: "Kuelewa maktaba ya vitabu 66 tangu Mwanzo hadi Ufunuo.", courseTitle2: "Wokovu kwa Neema", courseDesc2: "Kwa nini kazi ya msalaba inatosha kwa ukombozi wetu.", courseTitle5: "Sanaa ya Kutafakari", courseDesc5: "Kusoma neno kwa sauti ya chini na kuliweka moyoni.", courseTitle6: "Kuelewa Muktadha", courseDesc6: "Tambua mwandishi na hadhira ili kuepuka tafsiri potofu.", leadership: "Uongozi: Kuongoza kwa Mfano", courseDescLeadership: "Kiongozi Nelo ni yule anayetumikia jamii kupitia teknolojia.", synergie: "Ushirikiano (Synergy): 1+1=3", courseDescSynergy: "Fanya kazi kama timu ili vipaji viongezeke badala ya kujumlishwa tu.", "réputation numérique": "Sifa ya Kidijitali: Pasipoti Yako", courseDesc7: "Tengeneza LinkedIn na GitHub yako; ni pasipoti yako mpya.", niche: "Niche: Tatua ili Ulete Athari", courseDesc8: "Tafuta tatizo dogo mahususi na uwe bora zaidi duniani kulitatua.", "pitch deck": "Pitch Deck: Kuwasilisha Maono", courseDesc9: "Uwasilishaji wako wa picha ili kushawishi kwa chini ya slaidi 10." } }; const questionsDB = { Simple: [ { q: {fr:"Qui a construit l'arche ?", en:"Who built the ark?", ln:"Nani atongaki masuwa?", sw:"Nani alijenga safina?"}, o:["Moïse","Noé","Abraham","David"], a:1 }, { q: {fr:"Où Jésus est-il né ?", en:"Where was Jesus born?", ln:"Yesu abotamaki wapi?", sw:"Yesu alizaliwa wapi?"}, o:["Nazareth","Bethléem","Jérusalem","Galilée"], a:1 }, { q: {fr:"Combien de disciples avait Jésus ?", en:"How many disciples?", ln:"Bayekoli boni?", sw:"Wanafunzi wangapi?"}, o:["10","11","12","13"], a:2 }, { q: {fr:"Le premier livre de la Bible ?", en:"First book?", ln:"Mokanda ya liboso?", sw:"Kitabu cha kwanza?"}, o:["Exode","Genèse","Psaumes","Matthieu"], a:1 }, { q: {fr:"Qui a tué Goliath ?", en:"Who killed Goliath?", ln:"Nani abomaki Goliata?", sw:"Nani alimuua Goliathi?"}, o:["Saül","David","Samson","Jonathan"], a:1 }, { q: {fr:"La femme d'Abraham ?", en:"Abraham's wife?", ln:"Mwasi ya Abrahama?", sw:"Mke wa Ibrahimu?"}, o:["Sarah","Agar","Rebecca","Rachel"], a:0 }, { q: {fr:"Signe de l'alliance de Noé ?", en:"Sign of Noah's covenant?", ln:"Elembo ya kondimana?", sw:"Ishara ya agano?"}, o:["Feu","Arc-en-ciel","Colombe","Sang"], a:1 }, { q: {fr:"Qui a trahi Jésus ?", en:"Who betrayed Jesus?", ln:"Nani atekaki Yesu?", sw:"Nani alimsaliti Yesu?"}, o:["Pierre","Jean","Judas","Thomas"], a:2 }, { q: {fr:"Père de la foi ?", en:"Father of faith?", ln:"Tata ya kondima?", sw:"Baba wa imani?"}, o:["Moïse","Abraham","Paul","Elie"], a:1 }, { q: {fr:"Jésus a changé l'eau en... ?", en:"Water into...?", ln:"Yesu akomisaki mayi...?", sw:"Yesu aligeuza maji kuwa...?"}, o:["Lait","Vin","Huile","Jus"], a:1 } ], Moyen: [ { q: {fr:"Qui a écrit les Actes ?", en:"Who wrote Acts?", ln:"Nani akomaki Misala?", sw:"Nani aliandika Matendo?"}, o:["Paul","Luc","Pierre","Jean"], a:1 }, { q: {fr:"Combien de plaies en Égypte ?", en:"How many plagues?", ln:"Bampasi boni na Ezipito?", sw:"Mapigo mangapi Misri?"}, o:["7","10","12","40"], a:1 }, { q: {fr:"L'homme le plus fort ?", en:"Strongest man?", ln:"Moto ya makasi koleka?", sw:"Mtu mwenye nguvu zaidi?"}, o:["Goliath","Samson","David","Achab"], a:1 }, { q: {fr:"Frère de Moïse ?", en:"Moses' brother?", ln:"Ndeko ya Moize?", sw:"Kaka yake Musa?"}, o:["Josué","Aaron","Caleb","Hur"], a:1 }, { q: {fr:"Fils promis à Abraham ?", en:"Promised son?", ln:"Mwana ya elaka?", sw:"Mwana wa ahadi?"}, o:["Ismaël","Isaac","Jacob","Esaü"], a:1 }, { q: {fr:"Qui a marché sur l'eau ?", en:"Walked on water?", ln:"Atambolaki na mayi?", sw:"Alitembea juu ya maji?"}, o:["Jacques","Pierre","André","Philippe"], a:1 }, { q: {fr:"Ville détruite par trompettes ?", en:"Walls fell down?", ln:"Bingumba bikweyaki?", sw:"Kuta zilianguka?"}, o:["Jéricho","Aï","Ninive","Sodome"], a:0 }, { q: {fr:"Femme juge en Israël ?", en:"Female Judge?", ln:"Mwasi mosambisi?", sw:"Jaji mwanamke?"}, o:["Esther","Ruth","Déborah","Jézabel"], a:2 }, { q: {fr:"Successeur de Moïse ?", en:"Successor of Moses?", ln:"Nani azwaki esika ya Moize?", sw:"Mrithi wa Musa?"}, o:["Aaron","Josué","Caleb","Gédéon"], a:1 }, { q: {fr:"Arbre interdit en Éden ?", en:"Forbidden tree?", ln:"Nzete epekisama?", sw:"Mti uliokatazwa?"}, o:["Vie","Connaissance","Sagesse","Force"], a:1 } ], Difficile: [ { q: {fr:"Grand-père de David ?", en:"David's grandfather?", ln:"Nkoko ya David?", sw:"Babu wa Daudi?"}, o:["Jessé","Obed","Boaz","Salmon"], a:1 }, { q: {fr:"Roi de Salem ?", en:"King of Salem?", ln:"Mokonzi ya Saleme?", sw:"Mfalme wa Salemu?"}, o:["Melchisédek","Abimélec","Pharaon","Hérode"], a:0 }, { q: {fr:"Île de l'exil de Jean ?", en:"John's exile island?", ln:"Esanga ya Yoane?", sw:"Kisiwa cha Yohana?"}, o:["Malte","Chypre","Patmos","Crète"], a:2 }, { q: {fr:"Livre sans le nom de Dieu ?", en:"Book without God's name?", ln:"Mokanda ezanga kombo ya Nzambe?", sw:"Kitabu kisicho na jina la Mungu?"}, o:["Cantiques","Esther","Ruth","Ecclésiaste"], a:1 }, { q: {fr:"Combien d'années au désert ?", en:"Years in desert?", ln:"Bula boni na esobe?", sw:"Miaka mingapi jangwani?"}, o:["12","40","70","400"], a:1 }, { q: {fr:"Prophète des ossements ?", en:"Dry bones prophet?", ln:"Mosakoli ya mikuwa?", sw:"Nabii wa mifupa?"}, o:["Isaïe","Jérémie","Ézéchiel","Daniel"], a:2 }, { q: {fr:"Qui est tombé de la fenêtre ?", en:"Fell from window?", ln:"Akweyaki na fenetre?", sw:"Alianguka dirishani?"}, o:["Eutychus","Étienne","Timothée","Silas"], a:0 }, { q: {fr:"Tribus d'Israël ?", en:"Tribes of Israel?", ln:"Mabota ya Israele?", sw:"Makabila ya Israeli?"}, o:["10","12","14","7"], a:1 }, { q: {fr:"Auteur de l'Apocalypse ?", en:"Author of Revelation?", ln:"Moto akomi Emoniseli?", sw:"Mwandishi wa Ufunuo?"}, o:["Jean","Paul","Pierre","Jacques"], a:0 }, { q: {fr:"Dernier Juge d'Israël ?", en:"Last Judge?", ln:"Mosambisi ya suka?", sw:"Jaji wa mwisho?"}, o:["Gédéon","Samson","Samuel","Eli"], a:2 } ] }; /* ============================================================ 2. ÉTAT ET VARIABLES GLOBALES ============================================================ */ let state = { lang: 'fr', user: '', level: 'Simple', questions: [], currentIdx: 0, score: 0, time: 0, timerInterval: null }; window.addEventListener('load', () => { // 1. S'assurer que la section accueil est prête en arrière-plan const homeSection = document.getElementById('home'); if (homeSection) { homeSection.style.display = 'block'; } // 2. Délai de 2.5 secondes pour l'animation setTimeout(() => { const splash = document.getElementById('splash-screen'); if (splash) { splash.classList.add('fade-out'); // Lance l'effet Iris // 3. Après 1 seconde (fin de l'animation CSS), on retire le splash du chemin setTimeout(() => { splash.style.pointerEvents = 'none'; // Rend les clics possibles au travers splash.style.display = 'none'; // Supprime l'élément du visuel // On s'assure que le menu ou d'autres éléments ne sont pas cachés document.body.style.overflow = 'auto'; }, 1000); } }, 2500); }); /* ============================================================ 3. GESTION NAVIGATION & UI (CORRIGÉE & ROBUSTE) ============================================================ */ function toggleMenu() { const sidebar = document.getElementById('sidebar'); const overlay = document.getElementById('overlay'); if (sidebar && overlay) { sidebar.classList.toggle('active'); overlay.classList.toggle('active'); } } function showSection(id) { // 1. Masquer toutes les sections const sections = document.querySelectorAll('.section'); sections.forEach(s => { s.classList.remove('active'); s.style.display = 'none'; }); // 2. Afficher la section demandée const targetSection = document.getElementById(id); if (targetSection) { targetSection.classList.add('active'); targetSection.style.display = 'block'; } else { console.error("Section introuvable : " + id); return; } // 3. Mettre à jour les liens du menu (Effet visuel) const navLinks = document.querySelectorAll('.nav-link'); navLinks.forEach(link => { link.classList.remove('active'); // Si le onclick du lien contient l'ID de la section if (link.getAttribute('onclick') && link.getAttribute('onclick').includes(id)) { link.classList.add('active'); } }); // 4. Fermer le menu si on est sur mobile const sidebar = document.getElementById('sidebar'); if (sidebar && sidebar.classList.contains('active')) { toggleMenu(); } // 5. Remonter en haut de page window.scrollTo(0, 0); } function updateTranslations() { document.querySelectorAll('[data-i18n]').forEach(el => { const key = el.getAttribute('data-i18n'); if (translations[state.lang] && translations[state.lang][key]) { el.innerText = translations[state.lang][key]; } }); } function changeLanguage(lang) { state.lang = lang; updateTranslations(); // Si on est en train de jouer, mettre à jour la question courante if(document.getElementById('quiz').classList.contains('active') && state.questions.length > 0) { displayQuestion(); } } function saveUser() { state.user = document.getElementById('username').value; } /* ============================================================ 4. LOGIQUE DU QUIZ ============================================================ */ function startQuiz(lvl) { if (!state.user) { alert(state.lang === 'fr' ? "Veuillez entrer votre nom." : "Please enter your name."); document.getElementById('username').focus(); return; } state.level = lvl; state.currentIdx = 0; state.score = 0; state.time = 0; state.questions = [...questionsDB[lvl]].sort(() => Math.random() - 0.5); showSection('quiz'); const lvlKey = 'lvl'+lvl; const lvlText = translations[state.lang][lvlKey] || lvl; document.getElementById('level-badge').innerText = lvlText; startTimer(); displayQuestion(); } function startTimer() { if(state.timerInterval) clearInterval(state.timerInterval); state.timerInterval = setInterval(() => { state.time++; const m = Math.floor(state.time / 60).toString().padStart(2, '0'); const s = (state.time % 60).toString().padStart(2, '0'); const timerEl = document.getElementById('timer'); if(timerEl) timerEl.innerText = `${m}:${s}`; }, 1000); } function displayQuestion() { const qData = state.questions[state.currentIdx]; const qText = qData.q[state.lang] || qData.q['fr']; // Fallback FR document.getElementById('question').innerText = `${state.currentIdx + 1}. ${qText}`; // Progress bar const pct = ((state.currentIdx) / 10) * 100; document.getElementById('progress').style.width = `${pct}%`; const optsContainer = document.getElementById('options'); optsContainer.innerHTML = ''; qData.o.forEach((opt, idx) => { const li = document.createElement('li'); li.className = 'option-item'; li.innerHTML = `
${opt}`; li.onclick = () => selectAnswer(idx, li); optsContainer.appendChild(li); }); document.getElementById('next-btn').style.display = 'none'; canClick = true; // Réactiver le clic } let canClick = true; function selectAnswer(selectedIndex, element) { if(!canClick) return; canClick = false; const correctIndex = state.questions[state.currentIdx].a; const opts = document.querySelectorAll('.option-item'); element.classList.add('selected'); setTimeout(() => { if (selectedIndex === correctIndex) { element.classList.add('correct'); state.score++; } else { element.classList.add('wrong'); // Montrer la bonne réponse if(opts[correctIndex]) opts[correctIndex].classList.add('correct'); } document.getElementById('next-btn').style.display = 'inline-flex'; }, 400); } function nextQuestion() { canClick = true; state.currentIdx++; if (state.currentIdx < 10) { displayQuestion(); } else { endQuiz(); } } function endQuiz() { clearInterval(state.timerInterval); showSection('result'); const circle = document.getElementById('score-circle'); document.getElementById('final-score').innerText = `${state.score}/10`; // Animation Cercle const pct = (state.score / 10) * 100; const color = state.score >= 7 ? '#27ae60' : '#c0392b'; circle.style.background = `conic-gradient(${color} ${pct}%, #eee ${pct}%)`; const msg = state.score >= 7 ? (translations[state.lang].pass || "Réussi") : (translations[state.lang].fail || "Échoué"); document.getElementById('feedback-msg').innerText = msg; document.getElementById('feedback-msg').style.color = color; if (state.score >= 7) { document.getElementById('certificate-area').style.display = 'block'; } else { document.getElementById('certificate-area').style.display = 'none'; } // Sauvegarde Stats const stat = { date: new Date().toLocaleDateString(), score: state.score, level: state.level }; let stats = JSON.parse(localStorage.getItem('bibliaStats') || '[]'); stats.push(stat); localStorage.setItem('bibliaStats', JSON.stringify(stats)); renderStats(); } function renderStats() { const stats = JSON.parse(localStorage.getItem('bibliaStats') || '[]'); const container = document.getElementById('stats-display'); if(!container) return; if(stats.length === 0) { container.innerHTML = "Aucune donnée."; return; } container.innerHTML = stats.slice(-5).reverse().map(s => `
${s.date} (${s.level}) ${s.score}/10
` ).join(''); } /* ============================================================ 5. GÉNÉRATION DE CERTIFICAT PROFESSIONNEL (jsPDF) ============================================================ */ async function generateCertificate() { if(!window.jspdf) { alert("Erreur: Librairie PDF non chargée. Vérifiez votre connexion."); return; } const { jsPDF } = window.jspdf; const doc = new jsPDF({ orientation: 'landscape', unit: 'mm', format: 'a4' }); const gold = '#C5A059'; const dark = '#2C3E50'; // Bordures doc.setLineWidth(2); doc.setDrawColor(gold); doc.rect(10, 10, 277, 190); doc.setLineWidth(1); doc.rect(15, 15, 267, 180); // En-tête doc.setFont("times", "bold"); doc.setFontSize(40); doc.setTextColor(dark); doc.text("CERTIFICAT DE RÉUSSITE", 148.5, 60, { align: "center" }); doc.setFontSize(16); doc.setTextColor(100); doc.text("PLATEFORME BIBLIQUE INTERNATIONALE", 148.5, 75, { align: "center" }); // Corps doc.setFont("helvetica", "normal"); doc.setFontSize(14); doc.setTextColor(50); doc.text("Ce document certifie que", 148.5, 95, { align: "center" }); // Nom Utilisateur doc.setFont("times", "italic"); doc.setFontSize(36); doc.setTextColor(gold); doc.text(state.user || "Utilisateur", 148.5, 115, { align: "center" }); doc.setLineWidth(0.5); doc.line(80, 118, 217, 118); // Détails doc.setFont("helvetica", "normal"); doc.setFontSize(14); doc.setTextColor(50); doc.text(`A complété avec succès le quiz de niveau : ${state.level}`, 148.5, 135, { align: "center" }); doc.text(`Score obtenu : ${state.score} / 10`, 148.5, 145, { align: "center" }); // Footer const today = new Date().toLocaleDateString('fr-FR'); doc.setFontSize(12); doc.text(`Date : ${today}`, 50, 170); doc.text("Directeur Pédagogique", 220, 170); doc.setFont("times", "italic"); doc.setTextColor(gold); doc.text("BibliaPro Team", 220, 180); doc.save(`Certificat_${state.user}.pdf`); } // Lancement Initial document.addEventListener('DOMContentLoaded', () => { updateTranslations(); renderStats(); }); function clearStats() { if(confirm("Voulez-vous vraiment supprimer votre historique de scores ?")) { localStorage.removeItem('bibliaStats'); renderStats(); } } function shareApp() { if (navigator.share) { navigator.share({ title: 'Biblia Pro', text: 'Viens tester tes connaissances bibliques sur Biblia Pro !', url: window.location.href }); } else { alert("Le partage n'est pas supporté sur ce navigateur."); } } function toggleDarkMode() { const isDark = document.getElementById('darkModeToggle').checked; if (isDark) { document.body.classList.add('dark-theme'); localStorage.setItem('theme', 'dark'); } else { document.body.classList.remove('dark-theme'); localStorage.setItem('theme', 'light'); } } // Mise à jour de la fonction changeLanguage pour le visuel function changeLanguage(lang) { state.lang = lang; updateTranslations(); // Gérer l'icône "Check" visuelle document.querySelectorAll('.check-icon').forEach(el => el.style.display = 'none'); document.querySelector('.' + lang + '-check').style.display = 'block'; // Fermer le menu si besoin console.log("Langue changée en : " + lang); } // Vérifier au chargement si l'utilisateur préfère le mode sombre document.addEventListener('DOMContentLoaded', () => { const savedTheme = localStorage.getItem('theme'); const toggle = document.getElementById('darkModeToggle'); if (savedTheme === 'dark') { document.body.classList.add('dark-theme'); if (toggle) toggle.checked = true; } }); const bookSelect = document.getElementById("bible-book"); const chapterSelect = document.getElementById("bible-chapter"); const content = document.getElementById("bible-content"); const loader = document.getElementById("loader"); let favorites = JSON.parse(localStorage.getItem("bibleFavs")) || []; /* 📖 Liste simple des livres */ const books = [ // 📜 Old Testament "Genesis","Exodus","Leviticus","Numbers","Deuteronomy", "Joshua","Judges","Ruth", "1 Samuel","2 Samuel","1 Kings","2 Kings", "1 Chronicles","2 Chronicles", "Ezra","Nehemiah","Esther", "Job","Psalms","Proverbs","Ecclesiastes","Song of Solomon", "Isaiah","Jeremiah","Lamentations","Ezekiel","Daniel", "Hosea","Joel","Amos","Obadiah","Jonah","Micah", "Nahum","Habakkuk","Zephaniah","Haggai","Zechariah","Malachi", // 📜 New Testament "Matthew","Mark","Luke","John","Acts", "Romans","1 Corinthians","2 Corinthians", "Galatians","Ephesians","Philippians","Colossians", "1 Thessalonians","2 Thessalonians", "1 Timothy","2 Timothy","Titus","Philemon", "Hebrews","James", "1 Peter","2 Peter", "1 John","2 John","3 John", "Jude","Revelation" ]; /* 🔥 Charger livres */ books.forEach(b => { let opt = document.createElement("option"); opt.value = b; opt.textContent = b; bookSelect.appendChild(opt); }); /* 🔥 Chapitres dynamiques */ bookSelect.addEventListener("change", () => { chapterSelect.disabled = false; chapterSelect.innerHTML = ""; for (let i = 1; i <= 150; i++) { let opt = document.createElement("option"); opt.value = i; opt.textContent = i; chapterSelect.appendChild(opt); } }); /* 🔥 Charger Bible API */ chapterSelect.addEventListener("change", () => { const book = bookSelect.value; const chapter = chapterSelect.value; loader.style.display = "block"; content.innerHTML = ""; fetch(`https://bible-api.com/${book}+${chapter}`) .then(res => res.json()) .then(data => { loader.style.display = "none"; content.innerHTML = data.verses.map(v => `
${v.verse} ${v.text}
`).join(""); addFeatures(); }) .catch(() => { loader.style.display = "none"; content.innerHTML = "Erreur de chargement"; }); }); /* 🔥 Fonctionnalités */ function addFeatures() { /* ⭐ Favoris */ document.querySelectorAll(".fav").forEach(btn => { btn.onclick = function (e) { e.stopPropagation(); const text = this.parentElement.innerText; favorites.push(text); localStorage.setItem("bibleFavs", JSON.stringify(favorites)); this.innerText = "✅"; }; });document.querySelectorAll(".audio").forEach(btn => { btn.addEventListener("click", function (e) { e.stopPropagation(); const verseElement = this.closest(".verse"); if (!verseElement) return; const text = verseElement.dataset.text; if (!text) return; // 🔥 stop ancien son speechSynthesis.cancel(); const utterance = new SpeechSynthesisUtterance(text); // ⚠️ meilleur support que fr-FR sur Android utterance.lang = "en-US"; utterance.rate = 1; utterance.pitch = 1; utterance.volume = 1; // 🔥 important : attendre les voix let voices = speechSynthesis.getVoices(); if (voices.length > 0) { utterance.voice = voices[0]; } speechSynthesis.speak(utterance); }); }); /* ✍️ Surlignage */ document.querySelectorAll(".verse").forEach(v => { v.onclick = function () { this.classList.toggle("highlight"); }; }); } let deferredPrompt; window.addEventListener('beforeinstallprompt', (e) => { e.preventDefault(); deferredPrompt = e; // Afficher la bannière après un court délai setTimeout(() => { document.getElementById('pwa-install-banner').classList.add('show'); }, 3000); }); document.getElementById('btn-install').addEventListener('click', async () => { if (deferredPrompt) { deferredPrompt.prompt(); const { outcome } = await deferredPrompt.userChoice; if (outcome === 'accepted') { console.log('User accepted the install prompt'); } deferredPrompt = null; closeBanner(); } }); function closeBanner() { document.getElementById('pwa-install-banner').classList.remove('show'); } if ('serviceWorker' in navigator) { navigator.serviceWorker.register('sw.js'); }