Spaces:
Running
Running
| <html lang="fr"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>BibleSearch - Concordance et Prédications</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/docx/7.8.2/docx.js"></script> | |
| <style> | |
| @import url('https://fonts.googleapis.com/css2?family=Cardo:wght@400;700&family=Open+Sans:wght@300;400;600&display=swap'); | |
| body { | |
| font-family: 'Open Sans', sans-serif; | |
| background-color: #f8f4e8; | |
| color: #333; | |
| } | |
| .title-font { | |
| font-family: 'Cardo', serif; | |
| } | |
| .parchment-bg { | |
| background-color: #f9f3e6; | |
| background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><rect width="100" height="100" fill="none" stroke="%23d4c9a8" stroke-width="1"/></svg>'); | |
| background-size: 20px 20px; | |
| } | |
| .gold-border { | |
| border: 1px solid #d4af37; | |
| } | |
| .purple-text { | |
| color: #6a0dad; | |
| } | |
| .verse-card:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); | |
| } | |
| .tab-active { | |
| border-bottom: 3px solid #d4af37; | |
| color: #6a0dad; | |
| font-weight: 600; | |
| } | |
| /* Animation for search results */ | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(10px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| .fade-in { | |
| animation: fadeIn 0.3s ease-out forwards; | |
| } | |
| </style> | |
| </head> | |
| <body class="min-h-screen"> | |
| <!-- Header --> | |
| <header class="bg-purple-900 text-white shadow-md"> | |
| <div class="container mx-auto px-4 py-6 flex justify-between items-center"> | |
| <div class="flex items-center space-x-2"> | |
| <i class="fas fa-bible text-2xl text-yellow-400"></i> | |
| <h1 class="title-font text-2xl md:text-3xl font-bold">BibleSearch</h1> | |
| </div> | |
| <div class="flex items-center space-x-4"> | |
| <button id="themeToggle" class="p-2 rounded-full bg-purple-700 hover:bg-purple-600 transition"> | |
| <i class="fas fa-moon"></i> | |
| </button> | |
| <button class="hidden md:flex items-center space-x-1 bg-yellow-500 hover:bg-yellow-600 text-purple-900 font-semibold px-4 py-2 rounded transition"> | |
| <i class="fas fa-user"></i> | |
| <span>Connexion</span> | |
| </button> | |
| </div> | |
| </div> | |
| </header> | |
| <!-- Main Content --> | |
| <main class="container mx-auto px-4 py-8"> | |
| <!-- Tabs Navigation --> | |
| <div class="flex border-b border-gray-300 mb-8"> | |
| <button id="concordanceTab" class="tab-active px-6 py-3 font-medium text-sm md:text-base">Concordance Biblique</button> | |
| <button id="sermonsTab" class="px-6 py-3 font-medium text-sm md:text-base text-gray-600 hover:text-purple-900">Mes Prédications</button> | |
| </div> | |
| <!-- Concordance Section --> | |
| <section id="concordanceSection" class=""> | |
| <!-- Search Area --> | |
| <div class="bg-white rounded-lg shadow-md p-6 mb-8 gold-border"> | |
| <h2 class="title-font text-xl md:text-2xl font-bold mb-4 purple-text">Recherche Biblique</h2> | |
| <div class="flex flex-col md:flex-row gap-4"> | |
| <div class="flex-grow"> | |
| <label for="keyword" class="block text-sm font-medium text-gray-700 mb-1">Mot-clé ou phrase</label> | |
| <div class="relative"> | |
| <input type="text" id="keyword" placeholder="Ex: foi, amour, paix..." | |
| class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-purple-500 focus:border-purple-500"> | |
| <button id="searchBtn" class="absolute right-2 top-2 text-purple-700 hover:text-purple-900"> | |
| <i class="fas fa-search"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="w-full md:w-48"> | |
| <label for="version" class="block text-sm font-medium text-gray-700 mb-1">Version</label> | |
| <select id="version" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-purple-500 focus:border-purple-500"> | |
| <option value="LSG">Louis Segond</option> | |
| <option value="KJV">King James</option> | |
| <option value="NIV">NIV</option> | |
| </select> | |
| </div> | |
| </div> | |
| <div class="mt-4 grid grid-cols-1 md:grid-cols-3 gap-4"> | |
| <div> | |
| <label for="testament" class="block text-sm font-medium text-gray-700 mb-1">Testament</label> | |
| <select id="testament" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-purple-500 focus:border-purple-500"> | |
| <option value="all">Tous</option> | |
| <option value="old">Ancien Testament</option> | |
| <option value="new">Nouveau Testament</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label for="book" class="block text-sm font-medium text-gray-700 mb-1">Livre</label> | |
| <select id="book" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-purple-500 focus:border-purple-500"> | |
| <option value="all">Tous</option> | |
| <!-- Books will be populated by JavaScript --> | |
| </select> | |
| </div> | |
| <div> | |
| <label for="theme" class="block text-sm font-medium text-gray-700 mb-1">Thème</label> | |
| <select id="theme" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-purple-500 focus:border-purple-500"> | |
| <option value="all">Tous</option> | |
| <option value="faith">Foi</option> | |
| <option value="love">Amour</option> | |
| <option value="salvation">Salut</option> | |
| <option value="repentance">Repentance</option> | |
| <option value="hope">Espérance</option> | |
| </select> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Results Area --> | |
| <div id="resultsArea" class="hidden"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h3 class="title-font text-lg md:text-xl font-semibold purple-text">Résultats de recherche</h3> | |
| <div class="text-sm text-gray-600"> | |
| <span id="resultsCount">0</span> versets trouvés | |
| </div> | |
| </div> | |
| <div id="versesContainer" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"> | |
| <!-- Verses will be inserted here by JavaScript --> | |
| </div> | |
| <div id="pagination" class="mt-8 flex justify-center"> | |
| <!-- Pagination will be inserted here by JavaScript --> | |
| </div> | |
| </div> | |
| <!-- Themes Section --> | |
| <div class="mt-12"> | |
| <h3 class="title-font text-xl md:text-2xl font-bold mb-6 purple-text text-center">Thèmes Bibliques</h3> | |
| <div class="grid grid-cols-2 md:grid-cols-4 gap-4"> | |
| <div class="theme-card bg-white rounded-lg shadow-md p-4 text-center cursor-pointer hover:bg-yellow-50 transition gold-border" data-theme="faith"> | |
| <i class="fas fa-cross text-3xl mb-2 text-purple-700"></i> | |
| <h4 class="font-semibold">Foi</h4> | |
| <p class="text-sm text-gray-600 mt-1">Versets sur la foi et la confiance</p> | |
| </div> | |
| <div class="theme-card bg-white rounded-lg shadow-md p-4 text-center cursor-pointer hover:bg-yellow-50 transition gold-border" data-theme="love"> | |
| <i class="fas fa-heart text-3xl mb-2 text-purple-700"></i> | |
| <h4 class="font-semibold">Amour</h4> | |
| <p class="text-sm text-gray-600 mt-1">L'amour de Dieu et du prochain</p> | |
| </div> | |
| <div class="theme-card bg-white rounded-lg shadow-md p-4 text-center cursor-pointer hover:bg-yellow-50 transition gold-border" data-theme="salvation"> | |
| <i class="fas fa-dove text-3xl mb-2 text-purple-700"></i> | |
| <h4 class="font-semibold">Salut</h4> | |
| <p class="text-sm text-gray-600 mt-1">Le plan du salut en Christ</p> | |
| </div> | |
| <div class="theme-card bg-white rounded-lg shadow-md p-4 text-center cursor-pointer hover:bg-yellow-50 transition gold-border" data-theme="repentance"> | |
| <i class="fas fa-hand-holding-heart text-3xl mb-2 text-purple-700"></i> | |
| <h4 class="font-semibold">Repentance</h4> | |
| <p class="text-sm text-gray-600 mt-1">Se tourner vers Dieu</p> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Sermons Section (Hidden by default) --> | |
| <section id="sermonsSection" class="hidden"> | |
| <div class="flex justify-between items-center mb-6"> | |
| <h2 class="title-font text-xl md:text-2xl font-bold purple-text">Mes Prédications</h2> | |
| <button id="newSermonBtn" class="bg-purple-700 hover:bg-purple-800 text-white px-4 py-2 rounded-md flex items-center space-x-2 transition"> | |
| <i class="fas fa-plus"></i> | |
| <span>Nouvelle Prédication</span> | |
| </button> | |
| </div> | |
| <!-- Sermons List --> | |
| <div id="sermonsList" class="grid grid-cols-1 gap-6"> | |
| <!-- Sermons will be inserted here by JavaScript --> | |
| <div class="text-center py-10 text-gray-500"> | |
| <i class="fas fa-book-open text-4xl mb-4"></i> | |
| <p>Vous n'avez pas encore de prédications enregistrées</p> | |
| </div> | |
| </div> | |
| <!-- New Sermon Modal --> | |
| <div id="sermonModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden"> | |
| <div class="bg-white rounded-lg shadow-xl w-full max-w-2xl max-h-[90vh] overflow-y-auto"> | |
| <div class="p-6"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h3 class="title-font text-xl font-bold purple-text">Nouvelle Prédication</h3> | |
| <button id="closeModalBtn" class="text-gray-500 hover:text-gray-700"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| <form id="sermonForm"> | |
| <div class="mb-4"> | |
| <label for="sermonTitle" class="block text-sm font-medium text-gray-700 mb-1">Titre</label> | |
| <input type="text" id="sermonTitle" required | |
| class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-purple-500 focus:border-purple-500"> | |
| </div> | |
| <div class="mb-4"> | |
| <label for="baseText" class="block text-sm font-medium text-gray-700 mb-1">Texte de base</label> | |
| <input type="text" id="baseText" | |
| class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-purple-500 focus:border-purple-500"> | |
| </div> | |
| <div class="mb-4"> | |
| <label for="keyPoints" class="block text-sm font-medium text-gray-700 mb-1">Points clés</label> | |
| <textarea id="keyPoints" rows="3" | |
| class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-purple-500 focus:border-purple-500"></textarea> | |
| <p class="text-xs text-gray-500 mt-1">Séparez chaque point par une nouvelle ligne</p> | |
| </div> | |
| <div class="mb-4"> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Versets utilisés</label> | |
| <div id="selectedVerses" class="border border-gray-300 rounded-md p-2 min-h-20"> | |
| <!-- Selected verses will appear here --> | |
| <p class="text-gray-500 text-sm">Aucun verset sélectionné</p> | |
| </div> | |
| <button type="button" id="addVersesBtn" class="mt-2 text-sm text-purple-700 hover:text-purple-900 flex items-center"> | |
| <i class="fas fa-plus mr-1"></i> Ajouter des versets | |
| </button> | |
| </div> | |
| <div class="mb-4"> | |
| <label for="sermonNotes" class="block text-sm font-medium text-gray-700 mb-1">Notes complémentaires</label> | |
| <textarea id="sermonNotes" rows="5" | |
| class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-purple-500 focus:border-purple-500"></textarea> | |
| </div> | |
| <div class="flex justify-end space-x-3 mt-6"> | |
| <button type="button" id="cancelSermonBtn" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-100 transition"> | |
| Annuler | |
| </button> | |
| <button type="submit" class="bg-purple-700 hover:bg-purple-800 text-white px-4 py-2 rounded-md transition"> | |
| Enregistrer | |
| </button> | |
| </div> | |
| </form> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Add Verses Modal --> | |
| <div id="versesModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden"> | |
| <div class="bg-white rounded-lg shadow-xl w-full max-w-4xl max-h-[90vh] overflow-hidden"> | |
| <div class="p-6"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h3 class="title-font text-xl font-bold purple-text">Sélectionner des versets</h3> | |
| <button id="closeVersesModalBtn" class="text-gray-500 hover:text-gray-700"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| <div class="mb-4"> | |
| <input type="text" id="searchVersesInput" placeholder="Rechercher des versets..." | |
| class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-purple-500 focus:border-purple-500"> | |
| </div> | |
| <div class="border rounded-md overflow-hidden"> | |
| <div class="grid grid-cols-12 bg-gray-100 p-2 font-medium text-sm"> | |
| <div class="col-span-1"></div> | |
| <div class="col-span-4">Référence</div> | |
| <div class="col-span-7">Texte</div> | |
| </div> | |
| <div id="versesSelectionList" class="max-h-[60vh] overflow-y-auto"> | |
| <!-- Verses for selection will appear here --> | |
| </div> | |
| </div> | |
| <div class="flex justify-end space-x-3 mt-6"> | |
| <button type="button" id="cancelVersesBtn" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-100 transition"> | |
| Annuler | |
| </button> | |
| <button type="button" id="confirmVersesBtn" class="bg-purple-700 hover:bg-purple-800 text-white px-4 py-2 rounded-md transition"> | |
| Confirmer la sélection | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| </main> | |
| <!-- Footer --> | |
| <footer class="bg-purple-900 text-white py-8 mt-12"> | |
| <div class="container mx-auto px-4"> | |
| <div class="flex flex-col md:flex-row justify-between items-center"> | |
| <div class="mb-4 md:mb-0"> | |
| <h2 class="title-font text-xl font-bold flex items-center"> | |
| <i class="fas fa-bible mr-2 text-yellow-400"></i> | |
| BibleSearch | |
| </h2> | |
| <p class="text-sm mt-1">Votre outil d'étude biblique et de préparation de prédications</p> | |
| </div> | |
| <div class="flex space-x-6"> | |
| <a href="#" class="hover:text-yellow-400 transition"><i class="fab fa-facebook-f"></i></a> | |
| <a href="#" class="hover:text-yellow-400 transition"><i class="fab fa-twitter"></i></a> | |
| <a href="#" class="hover:text-yellow-400 transition"><i class="fab fa-instagram"></i></a> | |
| </div> | |
| </div> | |
| <div class="border-t border-purple-700 mt-6 pt-6 text-sm text-center md:text-left"> | |
| <p>© 2023 BibleSearch. Tous droits réservés.</p> | |
| </div> | |
| </div> | |
| </footer> | |
| <script> | |
| // Sample Bible data (in a real app, this would come from an API or database) | |
| const bibleData = { | |
| LSG: { | |
| oldTestament: [ | |
| { book: "Genèse", chapters: 50, abbreviation: "Gen" }, | |
| { book: "Exode", chapters: 40, abbreviation: "Ex" }, | |
| // ... other OT books | |
| ], | |
| newTestament: [ | |
| { book: "Matthieu", chapters: 28, abbreviation: "Mat" }, | |
| { book: "Marc", chapters: 16, abbreviation: "Marc" }, | |
| // ... other NT books | |
| ], | |
| verses: [ | |
| { | |
| reference: "Jean 3:16", | |
| text: "Car Dieu a tant aimé le monde qu'il a donné son Fils unique, afin que quiconque croit en lui ne périsse point, mais qu'il ait la vie éternelle.", | |
| book: "Jean", chapter: 3, verse: 16, | |
| testament: "new", | |
| themes: ["love", "salvation"] | |
| }, | |
| { | |
| reference: "Hébreux 11:1", | |
| text: "Or la foi est une ferme assurance des choses qu'on espère, une démonstration de celles qu'on ne voit pas.", | |
| book: "Hébreux", chapter: 11, verse: 1, | |
| testament: "new", | |
| themes: ["faith"] | |
| }, | |
| { | |
| reference: "Psaumes 23:1", | |
| text: "L'Éternel est mon berger: je ne manquerai de rien.", | |
| book: "Psaumes", chapter: 23, verse: 1, | |
| testament: "old", | |
| themes: ["faith", "trust"] | |
| }, | |
| // ... more verses | |
| ] | |
| }, | |
| KJV: { | |
| // Similar structure for KJV version | |
| } | |
| }; | |
| // Sample sermons data | |
| let sermons = [ | |
| // { | |
| // id: 1, | |
| // title: "La puissance de la foi", | |
| // baseText: "Hébreux 11:1-6", | |
| // keyPoints: [ | |
| // "La foi est une assurance", | |
| // "La foi plaît à Dieu", | |
| // "Exemples de foi dans l'Écriture" | |
| // ], | |
| // verses: [ | |
| // { reference: "Hébreux 11:1", text: "Or la foi est une ferme assurance..." }, | |
| // { reference: "Hébreux 11:6", text: "Or sans la foi il est impossible..." } | |
| // ], | |
| // notes: "La foi est le fondement de notre relation avec Dieu...", | |
| // createdAt: "2023-05-15" | |
| // } | |
| ]; | |
| // DOM Elements | |
| const concordanceTab = document.getElementById('concordanceTab'); | |
| const sermonsTab = document.getElementById('sermonsTab'); | |
| const concordanceSection = document.getElementById('concordanceSection'); | |
| const sermonsSection = document.getElementById('sermonsSection'); | |
| const keywordInput = document.getElementById('keyword'); | |
| const searchBtn = document.getElementById('searchBtn'); | |
| const versionSelect = document.getElementById('version'); | |
| const testamentSelect = document.getElementById('testament'); | |
| const bookSelect = document.getElementById('book'); | |
| const themeSelect = document.getElementById('theme'); | |
| const resultsArea = document.getElementById('resultsArea'); | |
| const resultsCount = document.getElementById('resultsCount'); | |
| const versesContainer = document.getElementById('versesContainer'); | |
| const pagination = document.getElementById('pagination'); | |
| const themeCards = document.querySelectorAll('.theme-card'); | |
| const newSermonBtn = document.getElementById('newSermonBtn'); | |
| const sermonsList = document.getElementById('sermonsList'); | |
| const sermonModal = document.getElementById('sermonModal'); | |
| const closeModalBtn = document.getElementById('closeModalBtn'); | |
| const sermonForm = document.getElementById('sermonForm'); | |
| const selectedVerses = document.getElementById('selectedVerses'); | |
| const addVersesBtn = document.getElementById('addVersesBtn'); | |
| const versesModal = document.getElementById('versesModal'); | |
| const closeVersesModalBtn = document.getElementById('closeVersesModalBtn'); | |
| const searchVersesInput = document.getElementById('searchVersesInput'); | |
| const versesSelectionList = document.getElementById('versesSelectionList'); | |
| const cancelVersesBtn = document.getElementById('cancelVersesBtn'); | |
| const confirmVersesBtn = document.getElementById('confirmVersesBtn'); | |
| const cancelSermonBtn = document.getElementById('cancelSermonBtn'); | |
| const themeToggle = document.getElementById('themeToggle'); | |
| // State variables | |
| let currentTab = 'concordance'; | |
| let currentPage = 1; | |
| const versesPerPage = 9; | |
| let searchResults = []; | |
| let selectedVersesForSermon = []; | |
| let allVersesForSelection = []; | |
| // Initialize the app | |
| function init() { | |
| // Populate books dropdown | |
| populateBooksDropdown(); | |
| // Set up event listeners | |
| setupEventListeners(); | |
| // Load sermons from localStorage if available | |
| loadSermons(); | |
| } | |
| // Populate books dropdown based on selected testament | |
| function populateBooksDropdown() { | |
| const testament = testamentSelect.value; | |
| const version = versionSelect.value; | |
| bookSelect.innerHTML = '<option value="all">Tous</option>'; | |
| if (testament === 'all') { | |
| bibleData[version].oldTestament.forEach(book => { | |
| bookSelect.innerHTML += `<option value="${book.abbreviation}">${book.book}</option>`; | |
| }); | |
| bibleData[version].newTestament.forEach(book => { | |
| bookSelect.innerHTML += `<option value="${book.abbreviation}">${book.book}</option>`; | |
| }); | |
| } else if (testament === 'old') { | |
| bibleData[version].oldTestament.forEach(book => { | |
| bookSelect.innerHTML += `<option value="${book.abbreviation}">${book.book}</option>`; | |
| }); | |
| } else { | |
| bibleData[version].newTestament.forEach(book => { | |
| bookSelect.innerHTML += `<option value="${book.abbreviation}">${book.book}</option>`; | |
| }); | |
| } | |
| } | |
| // Set up all event listeners | |
| function setupEventListeners() { | |
| // Tab switching | |
| concordanceTab.addEventListener('click', () => switchTab('concordance')); | |
| sermonsTab.addEventListener('click', () => switchTab('sermons')); | |
| // Search functionality | |
| searchBtn.addEventListener('click', performSearch); | |
| keywordInput.addEventListener('keypress', (e) => { | |
| if (e.key === 'Enter') performSearch(); | |
| }); | |
| // Testament change updates books dropdown | |
| testamentSelect.addEventListener('change', populateBooksDropdown); | |
| // Theme cards click | |
| themeCards.forEach(card => { | |
| card.addEventListener('click', () => { | |
| const theme = card.dataset.theme; | |
| themeSelect.value = theme; | |
| keywordInput.value = ''; | |
| performSearch(); | |
| }); | |
| }); | |
| // Sermons functionality | |
| newSermonBtn.addEventListener('click', openNewSermonModal); | |
| closeModalBtn.addEventListener('click', closeSermonModal); | |
| sermonForm.addEventListener('submit', saveSermon); | |
| cancelSermonBtn.addEventListener('click', closeSermonModal); | |
| addVersesBtn.addEventListener('click', openVersesSelectionModal); | |
| closeVersesModalBtn.addEventListener('click', closeVersesSelectionModal); | |
| cancelVersesBtn.addEventListener('click', closeVersesSelectionModal); | |
| confirmVersesBtn.addEventListener('click', confirmVersesSelection); | |
| searchVersesInput.addEventListener('input', filterVersesForSelection); | |
| // Theme toggle | |
| themeToggle.addEventListener('click', toggleDarkMode); | |
| } | |
| // Switch between tabs | |
| function switchTab(tab) { | |
| currentTab = tab; | |
| if (tab === 'concordance') { | |
| concordanceTab.classList.add('tab-active'); | |
| sermonsTab.classList.remove('tab-active'); | |
| concordanceSection.classList.remove('hidden'); | |
| sermonsSection.classList.add('hidden'); | |
| } else { | |
| concordanceTab.classList.remove('tab-active'); | |
| sermonsTab.classList.add('tab-active'); | |
| concordanceSection.classList.add('hidden'); | |
| sermonsSection.classList.remove('hidden'); | |
| renderSermonsList(); | |
| } | |
| } | |
| // Perform search based on current filters | |
| function performSearch() { | |
| const keyword = keywordInput.value.trim().toLowerCase(); | |
| const version = versionSelect.value; | |
| const testament = testamentSelect.value; | |
| const book = bookSelect.value; | |
| const theme = themeSelect.value; | |
| // Filter verses based on criteria | |
| searchResults = bibleData[version].verses.filter(verse => { | |
| // Keyword search | |
| const keywordMatch = keyword === '' || | |
| verse.text.toLowerCase().includes(keyword) || | |
| verse.reference.toLowerCase().includes(keyword); | |
| // Testament filter | |
| const testamentMatch = testament === 'all' || | |
| (testament === 'old' && verse.testament === 'old') || | |
| (testament === 'new' && verse.testament === 'new'); | |
| // Book filter | |
| const bookMatch = book === 'all' || | |
| verse.book.toLowerCase().includes(book.toLowerCase()) || | |
| verse.reference.toLowerCase().includes(book.toLowerCase()); | |
| // Theme filter | |
| const themeMatch = theme === 'all' || | |
| (verse.themes && verse.themes.includes(theme)); | |
| return keywordMatch && testamentMatch && bookMatch && themeMatch; | |
| }); | |
| // Display results | |
| displaySearchResults(); | |
| } | |
| // Display search results with pagination | |
| function displaySearchResults() { | |
| if (searchResults.length === 0) { | |
| resultsArea.classList.add('hidden'); | |
| return; | |
| } | |
| resultsArea.classList.remove('hidden'); | |
| resultsCount.textContent = searchResults.length; | |
| // Calculate pagination | |
| const totalPages = Math.ceil(searchResults.length / versesPerPage); | |
| currentPage = Math.min(currentPage, totalPages); | |
| // Display verses for current page | |
| const startIndex = (currentPage - 1) * versesPerPage; | |
| const endIndex = Math.min(startIndex + versesPerPage, searchResults.length); | |
| const versesToDisplay = searchResults.slice(startIndex, endIndex); | |
| versesContainer.innerHTML = ''; | |
| versesToDisplay.forEach((verse, index) => { | |
| const verseElement = createVerseCard(verse, startIndex + index + 1); | |
| versesContainer.appendChild(verseElement); | |
| }); | |
| // Display pagination controls | |
| renderPagination(totalPages); | |
| } | |
| // Create a verse card element | |
| function createVerseCard(verse, index) { | |
| const card = document.createElement('div'); | |
| card.className = 'verse-card bg-white rounded-lg shadow-sm p-4 transition cursor-pointer gold-border fade-in'; | |
| card.innerHTML = ` | |
| <div class="flex justify-between items-start mb-2"> | |
| <span class="text-xs font-semibold bg-purple-100 text-purple-800 px-2 py-1 rounded">${verse.reference}</span> | |
| <button class="text-purple-700 hover:text-purple-900 add-to-sermon" data-ref="${verse.reference}" data-text="${verse.text}"> | |
| <i class="fas fa-plus-circle"></i> | |
| </button> | |
| </div> | |
| <p class="text-gray-800">${verse.text}</p> | |
| ${verse.themes && verse.themes.length > 0 ? | |
| `<div class="mt-3 flex flex-wrap gap-1"> | |
| ${verse.themes.map(theme => | |
| `<span class="text-xs bg-yellow-100 text-yellow-800 px-2 py-1 rounded">${getThemeName(theme)}</span>` | |
| ).join('')} | |
| </div>` : ''} | |
| `; | |
| // Add event listener to add to sermon button | |
| card.querySelector('.add-to-sermon').addEventListener('click', (e) => { | |
| e.stopPropagation(); | |
| addVerseToSermon(verse.reference, verse.text); | |
| }); | |
| return card; | |
| } | |
| // Get theme name for display | |
| function getThemeName(themeKey) { | |
| const themes = { | |
| 'faith': 'Foi', | |
| 'love': 'Amour', | |
| 'salvation': 'Salut', | |
| 'repentance': 'Repentance', | |
| 'trust': 'Confiance', | |
| 'hope': 'Espérance' | |
| }; | |
| return themes[themeKey] || themeKey; | |
| } | |
| // Render pagination controls | |
| function renderPagination(totalPages) { | |
| if (totalPages <= 1) { | |
| pagination.innerHTML = ''; | |
| return; | |
| } | |
| let html = '<div class="flex items-center space-x-1">'; | |
| // Previous button | |
| html += ` | |
| <button class="px-3 py-1 border rounded-md ${currentPage === 1 ? 'text-gray-400 cursor-not-allowed' : 'text-purple-700 hover:bg-purple-50'}" | |
| ${currentPage === 1 ? 'disabled' : ''} id="prevPage"> | |
| <i class="fas fa-chevron-left"></i> | |
| </button> | |
| `; | |
| // Page numbers | |
| for (let i = 1; i <= totalPages; i++) { | |
| html += ` | |
| <button class="px-3 py-1 border rounded-md ${currentPage === i ? 'bg-purple-700 text-white' : 'text-purple-700 hover:bg-purple-50'}" | |
| data-page="${i}" class="page-btn"> | |
| ${i} | |
| </button> | |
| `; | |
| } | |
| // Next button | |
| html += ` | |
| <button class="px-3 py-1 border rounded-md ${currentPage === totalPages ? 'text-gray-400 cursor-not-allowed' : 'text-purple-700 hover:bg-purple-50'}" | |
| ${currentPage === totalPages ? 'disabled' : ''} id="nextPage"> | |
| <i class="fas fa-chevron-right"></i> | |
| </button> | |
| `; | |
| html += '</div>'; | |
| pagination.innerHTML = html; | |
| // Add event listeners to pagination buttons | |
| document.getElementById('prevPage')?.addEventListener('click', () => { | |
| if (currentPage > 1) { | |
| currentPage--; | |
| displaySearchResults(); | |
| } | |
| }); | |
| document.getElementById('nextPage')?.addEventListener('click', () => { | |
| if (currentPage < totalPages) { | |
| currentPage++; | |
| displaySearchResults(); | |
| } | |
| }); | |
| document.querySelectorAll('.page-btn').forEach(btn => { | |
| btn.addEventListener('click', () => { | |
| currentPage = parseInt(btn.dataset.page); | |
| displaySearchResults(); | |
| }); | |
| }); | |
| } | |
| // Sermons functionality | |
| function openNewSermonModal() { | |
| selectedVersesForSermon = []; | |
| sermonForm.reset(); | |
| updateSelectedVersesDisplay(); | |
| sermonModal.classList.remove('hidden'); | |
| } | |
| function closeSermonModal() { | |
| sermonModal.classList.add('hidden'); | |
| } | |
| function openVersesSelectionModal() { | |
| // Prepare all verses for selection | |
| allVersesForSelection = [...bibleData[versionSelect.value].verses]; | |
| renderVersesForSelection(); | |
| versesModal.classList.remove('hidden'); | |
| } | |
| function closeVersesSelectionModal() { | |
| versesModal.classList.add('hidden'); | |
| } | |
| function renderVersesForSelection() { | |
| versesSelectionList.innerHTML = ''; | |
| allVersesForSelection.forEach(verse => { | |
| const isSelected = selectedVersesForSermon.some(v => v.reference === verse.reference); | |
| const verseElement = document.createElement('div'); | |
| verseElement.className = `grid grid-cols-12 p-2 border-b border-gray-100 hover:bg-purple-50 ${isSelected ? 'bg-purple-100' : ''}`; | |
| verseElement.innerHTML = ` | |
| <div class="col-span-1 flex items-center justify-center"> | |
| <input type="checkbox" class="verse-checkbox" data-ref="${verse.reference}" data-text="${verse.text}" ${isSelected ? 'checked' : ''}> | |
| </div> | |
| <div class="col-span-4 font-medium text-sm">${verse.reference}</div> | |
| <div class="col-span-7 text-sm">${verse.text}</div> | |
| `; | |
| versesSelectionList.appendChild(verseElement); | |
| }); | |
| } | |
| function filterVersesForSelection() { | |
| const searchTerm = searchVersesInput.value.trim().toLowerCase(); | |
| if (searchTerm === '') { | |
| renderVersesForSelection(); | |
| return; | |
| } | |
| const filteredVerses = allVersesForSelection.filter(verse => | |
| verse.text.toLowerCase().includes(searchTerm) || | |
| verse.reference.toLowerCase().includes(searchTerm) | |
| ); | |
| versesSelectionList.innerHTML = ''; | |
| filteredVerses.forEach(verse => { | |
| const isSelected = selectedVersesForSermon.some(v => v.reference === verse.reference); | |
| const verseElement = document.createElement('div'); | |
| verseElement.className = `grid grid-cols-12 p-2 border-b border-gray-100 hover:bg-purple-50 ${isSelected ? 'bg-purple-100' : ''}`; | |
| verseElement.innerHTML = ` | |
| <div class="col-span-1 flex items-center justify-center"> | |
| <input type="checkbox" class="verse-checkbox" data-ref="${verse.reference}" data-text="${verse.text}" ${isSelected ? 'checked' : ''}> | |
| </div> | |
| <div class="col-span-4 font-medium text-sm">${verse.reference}</div> | |
| <div class="col-span-7 text-sm">${verse.text}</div> | |
| `; | |
| versesSelectionList.appendChild(verseElement); | |
| }); | |
| } | |
| function confirmVersesSelection() { | |
| const checkboxes = versesSelectionList.querySelectorAll('.verse-checkbox:checked'); | |
| selectedVersesForSermon = Array.from(checkboxes).map(checkbox => ({ | |
| reference: checkbox.dataset.ref, | |
| text: checkbox.dataset.text | |
| })); | |
| updateSelectedVersesDisplay(); | |
| closeVersesSelectionModal(); | |
| } | |
| function addVerseToSermon(reference, text) { | |
| if (!selectedVersesForSermon.some(v => v.reference === reference)) { | |
| selectedVersesForSermon.push({ reference, text }); | |
| updateSelectedVersesDisplay(); | |
| // Show a toast notification | |
| showToast(`Verset ${reference} ajouté à la prédication`); | |
| } | |
| } | |
| function updateSelectedVersesDisplay() { | |
| if (selectedVersesForSermon.length === 0) { | |
| selectedVerses.innerHTML = '<p class="text-gray-500 text-sm">Aucun verset sélectionné</p>'; | |
| return; | |
| } | |
| selectedVerses.innerHTML = ''; | |
| selectedVersesForSermon.forEach(verse => { | |
| const verseElement = document.createElement('div'); | |
| verseElement.className = 'flex justify-between items-start mb-2 p-2 bg-purple-50 rounded'; | |
| verseElement.innerHTML = ` | |
| <div> | |
| <span class="text-xs font-semibold text-purple-800">${verse.reference}</span> | |
| <p class="text-xs text-gray-700 truncate">${verse.text}</p> | |
| </div> | |
| <button class="text-red-500 hover:text-red-700 remove-verse" data-ref="${verse.reference}"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| `; | |
| verseElement.querySelector('.remove-verse').addEventListener('click', (e) => { | |
| e.stopPropagation(); | |
| selectedVersesForSermon = selectedVersesForSermon.filter(v => v.reference !== verse.reference); | |
| updateSelectedVersesDisplay(); | |
| }); | |
| selectedVerses.appendChild(verseElement); | |
| }); | |
| } | |
| function saveSermon(e) { | |
| e.preventDefault(); | |
| const title = document.getElementById('sermonTitle').value.trim(); | |
| const baseText = document.getElementById('baseText').value.trim(); | |
| const keyPoints = document.getElementById('keyPoints').value.split('\n').filter(point => point.trim() !== ''); | |
| const notes = document.getElementById('sermonNotes').value.trim(); | |
| if (!title) { | |
| alert('Veuillez entrer un titre pour la prédication'); | |
| return; | |
| } | |
| const newSermon = { | |
| id: Date.now(), | |
| title, | |
| baseText, | |
| keyPoints, | |
| verses: [...selectedVersesForSermon], | |
| notes, | |
| createdAt: new Date().toISOString().split('T')[0] | |
| }; | |
| sermons.push(newSermon); | |
| saveSermonsToStorage(); | |
| renderSermonsList(); | |
| closeSermonModal(); | |
| showToast('Prédication enregistrée avec succès'); | |
| } | |
| function renderSermonsList() { | |
| if (sermons.length === 0) { | |
| sermonsList.innerHTML = ` | |
| <div class="text-center py-10 text-gray-500"> | |
| <i class="fas fa-book-open text-4xl mb-4"></i> | |
| <p>Vous n'avez pas encore de prédications enregistrées</p> | |
| </div> | |
| `; | |
| return; | |
| } | |
| sermonsList.innerHTML = ''; | |
| sermons.forEach(sermon => { | |
| const sermonElement = document.createElement('div'); | |
| sermonElement.className = 'bg-white rounded-lg shadow-md p-6 gold-border'; | |
| sermonElement.innerHTML = ` | |
| <div class="flex justify-between items-start mb-4"> | |
| <h3 class="title-font text-lg font-semibold purple-text">${sermon.title}</h3> | |
| <div class="flex space-x-2"> | |
| <button class="text-purple-700 hover:text-purple-900 export-btn" data-id="${sermon.id}" title="Exporter"> | |
| <i class="fas fa-file-export"></i> | |
| </button> | |
| <button class="text-red-500 hover:text-red-700 delete-btn" data-id="${sermon.id}" title="Supprimer"> | |
| <i class="fas fa-trash"></i> | |
| </button> | |
| </div> | |
| </div> | |
| ${sermon.baseText ? `<p class="text-sm font-medium text-gray-700 mb-2">Texte de base: <span class="font-normal">${sermon.baseText}</span></p>` : ''} | |
| <div class="mb-3"> | |
| <p class="text-sm font-medium text-gray-700">Points clés:</p> | |
| <ul class="list-disc list-inside text-sm text-gray-700 pl-2"> | |
| ${sermon.keyPoints.map(point => `<li>${point}</li>`).join('')} | |
| </ul> | |
| </div> | |
| <div class="mb-3"> | |
| <p class="text-sm font-medium text-gray-700">Versets utilisés (${sermon.verses.length}):</p> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-2 mt-2"> | |
| ${sermon.verses.slice(0, 4).map(verse => ` | |
| <div class="text-xs bg-purple-50 text-purple-800 px-2 py-1 rounded"> | |
| <span class="font-semibold">${verse.reference}</span>: ${verse.text.substring(0, 50)}... | |
| </div> | |
| `).join('')} | |
| ${sermon.verses.length > 4 ? `<div class="text-xs text-purple-700">+ ${sermon.verses.length - 4} autres versets...</div>` : ''} | |
| </div> | |
| </div> | |
| <div class="flex justify-between items-center text-xs text-gray-500 mt-4"> | |
| <span>Créé le: ${sermon.createdAt}</span> | |
| <button class="text-purple-700 hover:text-purple-900 text-sm view-btn" data-id="${sermon.id}"> | |
| Voir détails <i class="fas fa-chevron-right ml-1"></i> | |
| </button> | |
| </div> | |
| `; | |
| sermonsList.appendChild(sermonElement); | |
| // Add event listeners to buttons | |
| sermonElement.querySelector('.export-btn').addEventListener('click', (e) => { | |
| e.stopPropagation(); | |
| exportSermon(sermon.id); | |
| }); | |
| sermonElement.querySelector('.delete-btn').addEventListener('click', (e) => { | |
| e.stopPropagation(); | |
| deleteSermon(sermon.id); | |
| }); | |
| sermonElement.querySelector('.view-btn').addEventListener('click', (e) => { | |
| e.stopPropagation(); | |
| viewSermonDetails(sermon.id); | |
| }); | |
| }); | |
| } | |
| function viewSermonDetails(sermonId) { | |
| const sermon = sermons.find(s => s.id === sermonId); | |
| if (!sermon) return; | |
| // In a real app, you would show a detailed view modal | |
| alert(`Détails de la prédication: ${sermon.title}\n\nTexte de base: ${sermon.baseText || 'Non spécifié'}\n\nPoints clés:\n${sermon.keyPoints.join('\n')}\n\nNotes: ${sermon.notes || 'Aucune note supplémentaire'}`); | |
| } | |
| function deleteSermon(sermonId) { | |
| if (confirm('Êtes-vous sûr de vouloir supprimer cette prédication ?')) { | |
| sermons = sermons.filter(s => s.id !== sermonId); | |
| saveSermonsToStorage(); | |
| renderSermonsList(); | |
| showToast('Prédication supprimée'); | |
| } | |
| } | |
| function exportSermon(sermonId) { | |
| const sermon = sermons.find(s => s.id === sermonId); | |
| if (!sermon) return; | |
| // Simple export as text (in a real app, implement PDF/DOCX export) | |
| const exportText = ` | |
| PRÉDICATION: ${sermon.title} | |
| ==================================== | |
| Texte de base: ${sermon.baseText || 'Non spécifié'} | |
| Points clés: | |
| ${sermon.keyPoints.map((point, i) => `${i+1}. ${point}`).join('\n')} | |
| Versets utilisés: | |
| ${sermon.verses.map(verse => `${verse.reference}: ${verse.text}`).join('\n\n')} | |
| Notes complémentaires: | |
| ${sermon.notes || 'Aucune note supplémentaire'} | |
| ==================================== | |
| Créé le: ${sermon.createdAt} | |
| Exporté depuis BibleSearch | |
| `; | |
| // Create download link | |
| const blob = new Blob([exportText], { type: 'text/plain' }); | |
| const url = URL.createObjectURL(blob); | |
| const a = document.createElement('a'); | |
| a.href = url; | |
| a.download = `Predication_${sermon.title.replace(/[^a-z0-9]/gi, '_')}.txt`; | |
| document.body.appendChild(a); | |
| a.click(); | |
| document.body.removeChild(a); | |
| URL.revokeObjectURL(url); | |
| showToast('Prédication exportée'); | |
| } | |
| // Local storage functions | |
| function loadSermons() { | |
| const savedSermons = localStorage.getItem('bibleSearchSermons'); | |
| if (savedSermons) { | |
| sermons = JSON.parse(savedSermons); | |
| renderSermonsList(); | |
| } | |
| } | |
| function saveSermonsToStorage() { | |
| localStorage.setItem('bibleSearchSermons', JSON.stringify(sermons)); | |
| } | |
| // Helper functions | |
| function showToast(message) { | |
| const toast = document.createElement('div'); | |
| toast.className = 'fixed bottom-4 right-4 bg-purple-800 text-white px-4 py-2 rounded-md shadow-lg flex items-center space-x-2 animate-fade-in'; | |
| toast.innerHTML = ` | |
| <i class="fas fa-check-circle"></i> | |
| <span>${message}</span> | |
| `; | |
| document.body.appendChild(toast); | |
| setTimeout(() => { | |
| toast.classList.add('animate-fade-out'); | |
| setTimeout(() => toast.remove(), 300); | |
| }, 3000); | |
| } | |
| function toggleDarkMode() { | |
| document.documentElement.classList.toggle('dark'); | |
| const icon = themeToggle.querySelector('i'); | |
| if (document.documentElement.classList.contains('dark')) { | |
| icon.classList.replace('fa-moon', 'fa-sun'); | |
| themeToggle.classList.replace('bg-purple-700', 'bg-yellow-500'); | |
| themeToggle.classList.replace('hover:bg-purple-600', 'hover:bg-yellow-600'); | |
| } else { | |
| icon.classList.replace('fa-sun', 'fa-moon'); | |
| themeToggle.classList.replace('bg-yellow-500', 'bg-purple-700'); | |
| themeToggle.classList.replace('hover:bg-yellow-600', 'hover:bg-purple-600'); | |
| } | |
| } | |
| // Initialize the app | |
| init(); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=martianband1t/rech-bibli" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |