rech-bibli / index.html
martianband1t's picture
Add 2 files
d1053a2 verified
<!DOCTYPE html>
<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>&copy; 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>