{% extends 'base.html.twig' %}{% block title %}Munganyo - Actes Exécutifs de l'Union des Comores{% endblock %}{% block body %}<!-- Hero Section Munganyo --><section class="relative bg-gradient-to-br from-[#006633] via-[#008040] to-[#00994d] text-white overflow-hidden"><div class="absolute inset-0 opacity-20"><div class="absolute top-20 left-10 w-64 h-64 bg-[#006633] rounded-full blur-3xl"></div><div class="absolute bottom-20 right-10 w-96 h-96 bg-[#008040] rounded-full blur-3xl"></div></div><div class="container mx-auto px-4 py-12 md:py-20 relative z-10"><div class="max-w-4xl mx-auto text-center"><div class="inline-flex items-center bg-white/20 backdrop-blur-sm rounded-full px-4 md:px-5 py-1.5 md:py-2 mb-4 md:mb-6 border border-white/30"><i class="fas fa-file-alt mr-1 md:mr-2 text-sm md:text-base"></i><span class="text-xs md:text-sm font-medium text-white">Plateforme des actes exécutifs</span></div><h1 class="text-3xl md:text-5xl lg:text-6xl font-bold mb-4 md:mb-6 text-white">Munganyo<span class="block text-white text-xl md:text-2xl lg:text-3xl">Actes du Gouvernement</span></h1><p class="text-base md:text-xl text-white/90 mb-6 md:mb-8 max-w-2xl mx-auto leading-relaxed hidden sm:block">La plateforme officielle de consultation des décrets, arrêtés et circulairesen vigueur de l'Union des Comores</p><!-- Barre de recherche --><div class="max-w-2xl mx-auto"><div class="relative"><i class="fas fa-search absolute left-3 md:left-5 top-1/2 transform -translate-y-1/2 text-gray-400 text-sm md:text-lg"></i><input type="text"id="searchInput"placeholder="Rechercher un décret, un arrêté, une circulaire..."class="w-full pl-9 md:pl-14 pr-24 md:pr-36 py-3 md:py-5 text-gray-800 text-sm md:text-lg rounded-full border-none shadow-2xl focus:outline-none focus:ring-4 focus:ring-[#006633]/50 focus:shadow-xl transition-all duration-300"><button id="searchBtn" class="absolute right-1 md:right-2 top-1/2 transform -translate-y-1/2 bg-gradient-to-r from-[#006633] to-[#008040] text-white px-3 md:px-6 py-1.5 md:py-2.5 rounded-full font-semibold hover:from-[#008040] hover:to-[#00994d] transition-all duration-300 shadow-md hover:shadow-lg text-sm md:text-base"><i class="fas fa-search md:mr-1"></i><span class="hidden md:inline">Rechercher</span></button></div></div><!-- Filtres rapides --><div class="mt-6 md:mt-10 flex flex-wrap justify-center gap-2 md:gap-3"><button onclick="applyQuickFilter('all')" class="quick-filter px-4 md:px-5 py-2 md:py-2.5 bg-gradient-to-r from-[#006633] to-[#008040] hover:from-[#004d26] hover:to-[#006633] rounded-full text-xs md:text-sm font-semibold text-white transition-all duration-200 shadow-md hover:shadow-lg flex items-center gap-1 md:gap-2"><i class="fas fa-th-large text-xs md:text-sm"></i>Tous les actes</button><button onclick="applyQuickFilter('decret')" class="quick-filter px-4 md:px-5 py-2 md:py-2.5 bg-gradient-to-r from-[#006633] to-[#008040] hover:from-[#004d26] hover:to-[#006633] rounded-full text-xs md:text-sm font-semibold text-white transition-all duration-200 shadow-md hover:shadow-lg flex items-center gap-1 md:gap-2"><i class="fas fa-gavel text-xs md:text-sm"></i>Décrets</button><button onclick="applyQuickFilter('arrete')" class="quick-filter px-4 md:px-5 py-2 md:py-2.5 bg-gradient-to-r from-[#006633] to-[#008040] hover:from-[#004d26] hover:to-[#006633] rounded-full text-xs md:text-sm font-semibold text-white transition-all duration-200 shadow-md hover:shadow-lg flex items-center gap-1 md:gap-2"><i class="fas fa-clipboard-list text-xs md:text-sm"></i>Arrêtés</button><button onclick="applyQuickFilter('circulaire')" class="quick-filter px-4 md:px-5 py-2 md:py-2.5 bg-gradient-to-r from-[#006633] to-[#008040] hover:from-[#004d26] hover:to-[#006633] rounded-full text-xs md:text-sm font-semibold text-white transition-all duration-200 shadow-md hover:shadow-lg flex items-center gap-1 md:gap-2"><i class="fas fa-envelope text-xs md:text-sm"></i>Circulaires</button><button onclick="applyQuickFilter('instruction')" class="quick-filter px-4 md:px-5 py-2 md:py-2.5 bg-gradient-to-r from-[#006633] to-[#008040] hover:from-[#004d26] hover:to-[#006633] rounded-full text-xs md:text-sm font-semibold text-white transition-all duration-200 shadow-md hover:shadow-lg flex items-center gap-1 md:gap-2"><i class="fas fa-tasks text-xs md:text-sm"></i>Instructions</button></div></div></div><div class="absolute bottom-0 left-0 right-0"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320" class="w-full"><path fill="#f3f4f6" fill-opacity="1" d="M0,96L48,112C96,128,192,160,288,160C384,160,480,128,576,122.7C672,117,768,139,864,154.7C960,171,1056,181,1152,170.7C1248,160,1344,128,1392,112L1440,96L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z"></path></svg></div></section><!-- Section Statistiques --><section class="py-12 md:py-16 bg-gray-50"><div class="container mx-auto px-4"><div class="grid grid-cols-2 md:grid-cols-4 gap-4 md:gap-6"><div class="bg-white rounded-2xl shadow-lg p-4 md:p-6 text-center transform hover:-translate-y-2 transition-all"><div class="w-10 h-10 md:w-14 md:h-14 bg-[#006633]/10 rounded-full flex items-center justify-center mx-auto mb-2 md:mb-4"><i class="fas fa-file-signature text-xl md:text-2xl text-[#006633]"></i></div><div class="text-2xl md:text-3xl font-bold text-gray-800 mb-0.5 md:mb-1" id="totalActs">0</div><div class="text-gray-600 font-medium text-xs md:text-base">Actes exécutifs</div><div class="text-xs text-gray-400 mt-1 hidden md:block">Décrets, arrêtés, circulaires</div></div><div class="bg-white rounded-2xl shadow-lg p-4 md:p-6 text-center transform hover:-translate-y-2 transition-all"><div class="w-10 h-10 md:w-14 md:h-14 bg-[#006633]/10 rounded-full flex items-center justify-center mx-auto mb-2 md:mb-4"><i class="fas fa-gavel text-xl md:text-2xl text-[#006633]"></i></div><div class="text-2xl md:text-3xl font-bold text-gray-800 mb-0.5 md:mb-1" id="totalDecrets">0</div><div class="text-gray-600 font-medium text-xs md:text-base">Décrets</div><div class="text-xs text-gray-400 mt-1 hidden md:block">En vigueur</div></div><div class="bg-white rounded-2xl shadow-lg p-4 md:p-6 text-center transform hover:-translate-y-2 transition-all"><div class="w-10 h-10 md:w-14 md:h-14 bg-[#006633]/10 rounded-full flex items-center justify-center mx-auto mb-2 md:mb-4"><i class="fas fa-clipboard-list text-xl md:text-2xl text-[#006633]"></i></div><div class="text-2xl md:text-3xl font-bold text-gray-800 mb-0.5 md:mb-1" id="totalArretes">0</div><div class="text-gray-600 font-medium text-xs md:text-base">Arrêtés</div><div class="text-xs text-gray-400 mt-1 hidden md:block">Interministériels et ministériels</div></div><div class="bg-white rounded-2xl shadow-lg p-4 md:p-6 text-center transform hover:-translate-y-2 transition-all"><div class="w-10 h-10 md:w-14 md:h-14 bg-[#006633]/10 rounded-full flex items-center justify-center mx-auto mb-2 md:mb-4"><i class="fas fa-chart-line text-xl md:text-2xl text-[#006633]"></i></div><div class="text-2xl md:text-3xl font-bold text-gray-800 mb-0.5 md:mb-1" id="totalVigueur">0</div><div class="text-gray-600 font-medium text-xs md:text-base">En vigueur</div><div class="text-xs text-gray-400 mt-1 hidden md:block">Actes actuellement valides</div></div></div></div></section><!-- Filtres avancés --><section class="py-6 md:py-8 bg-white border-b"><div class="container mx-auto px-4"><div class="bg-gray-50 rounded-2xl p-4 md:p-6"><div class="flex flex-col md:flex-row md:flex-wrap md:items-center justify-between gap-3 md:gap-4"><div class="flex items-center space-x-2 md:space-x-3"><i class="fas fa-filter text-gray-400 text-sm md:text-base"></i><span class="font-medium text-gray-700 text-sm md:text-base">Filtres :</span></div><div class="flex flex-wrap gap-2 md:gap-3"><select id="filterType" class="px-3 md:px-4 py-1.5 md:py-2 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-[#006633] focus:border-[#006633] text-sm"><option value="">Tous les types</option><option value="decret">Décrets</option><option value="arrete">Arrêtés</option><option value="circulaire">Circulaires</option><option value="instruction">Instructions</option></select><select id="filterInstitution" class="px-3 md:px-4 py-1.5 md:py-2 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-[#006633] focus:border-[#006633] text-sm"><option value="">Toutes les institutions</option><option value="Présidence">Présidence</option><option value="Finances">Ministère des Finances</option><option value="Justice">Ministère de la Justice</option><option value="Secrétariat">Secrétariat Général</option></select><select id="filterYear" class="px-3 md:px-4 py-1.5 md:py-2 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-[#006633] focus:border-[#006633] text-sm"><option value="">Toutes les années</option><option value="2026">2026</option><option value="2025">2025</option><option value="2024">2024</option></select><select id="filterStatus" class="px-3 md:px-4 py-1.5 md:py-2 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-[#006633] focus:border-[#006633] text-sm"><option value="">Statut juridique</option><option value="vigueur">En vigueur</option><option value="modifie">Modifié</option><option value="abroge">Abrogé</option></select><button id="applyFiltersBtn" class="bg-gradient-to-r from-[#006633] to-[#008040] text-white px-4 md:px-6 py-1.5 md:py-2 rounded-xl hover:from-[#004d26] hover:to-[#006633] transition text-sm"><i class="fas fa-search mr-1 md:mr-2"></i>Appliquer</button></div></div></div></div></section><!-- Section des résultats avec ID pour l'ancrage --><section id="resultsSection" class="py-12 md:py-16 bg-gray-50 scroll-mt-20"><div class="container mx-auto px-4"><div class="flex flex-col md:flex-row md:justify-between md:items-center mb-6 md:mb-8 gap-3"><div><h2 class="text-2xl md:text-3xl font-bold text-gray-800">Derniers actes publiés</h2><p class="text-gray-600 text-sm md:text-base mt-1">Les décrets et arrêtés les plus récents du Journal Officiel</p></div><div class="flex space-x-2"><button id="tableViewBtn" class="px-3 md:px-4 py-1.5 md:py-2 bg-gradient-to-r from-[#006633] to-[#008040] text-white rounded-lg shadow-sm text-sm"><i class="fas fa-table"></i></button><button id="listViewBtn" class="px-3 md:px-4 py-1.5 md:py-2 bg-white rounded-lg shadow-sm hover:bg-gray-50 transition text-sm"><i class="fas fa-list"></i></button></div></div><!-- Bandeau de résultat de filtre --><div id="filterResultBadge" class="mb-4 hidden"><div class="bg-blue-50 border-l-4 border-blue-500 rounded-lg p-3 flex items-center justify-between"><div class="flex items-center gap-2"><i class="fas fa-filter text-blue-500"></i><span class="text-sm text-gray-700" id="filterResultText"></span></div><button onclick="resetFilters()" class="text-blue-600 hover:text-blue-800 text-sm font-medium"><i class="fas fa-times mr-1"></i>Effacer les filtres</button></div></div><!-- Vue Tableau --><div id="tableView" class="bg-white rounded-2xl shadow-lg overflow-hidden"><div class="overflow-x-auto"><table class="min-w-[800px] md:min-w-full divide-y divide-gray-200"><thead class="bg-gradient-to-r from-gray-50 to-gray-100"><tr><th class="px-4 md:px-6 py-3 md:py-4 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Type</th><th class="px-4 md:px-6 py-3 md:py-4 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Numéro</th><th class="px-4 md:px-6 py-3 md:py-4 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Titre</th><th class="px-4 md:px-6 py-3 md:py-4 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Institution</th><th class="px-4 md:px-6 py-3 md:py-4 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Date</th><th class="px-4 md:px-6 py-3 md:py-4 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Statut</th><th class="px-4 md:px-6 py-3 md:py-4 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Actions</th></tr></thead><tbody id="actsTableBody" class="bg-white divide-y divide-gray-100"><tr><td colspan="7" class="px-6 py-8 text-center text-gray-500"><i class="fas fa-spinner fa-spin text-2xl mb-2"></i><p>Chargement des données...</p></td></tr></tbody></table></div></div><!-- Vue Liste --><div id="listView" style="display: none;" class="space-y-4"><div id="actsListBody" class="space-y-4"><!-- Les données seront insérées ici --></div></div><div class="mt-6 bg-gray-50 px-4 md:px-6 py-3 md:py-4 border-t rounded-b-2xl"><div class="flex flex-col sm:flex-row sm:items-center justify-between gap-3"><div class="text-xs md:text-sm text-gray-600" id="paginationInfo">Affichage de <span id="startCount">0</span> à <span id="endCount">0</span> sur <span id="totalCount">0</span> actes</div><div class="flex flex-wrap gap-1 md:gap-2" id="paginationControls"></div></div></div></div></section><!-- Modal Détails --><div id="detailModal" class="fixed inset-0 bg-black bg-opacity-50 z-50 hidden items-center justify-center p-4" style="display: none;"><div class="bg-white rounded-2xl max-w-3xl w-full max-h-[90vh] overflow-y-auto"><div class="sticky top-0 bg-white border-b px-6 py-4 flex justify-between items-center"><h3 class="text-xl font-bold text-gray-800">Détails de l'acte</h3><button onclick="closeModal()" class="text-gray-400 hover:text-gray-600"><i class="fas fa-times text-2xl"></i></button></div><div class="p-6" id="modalContent"><!-- Contenu dynamique --></div></div></div><!-- Section Alertes --><section class="py-12 md:py-16 bg-gradient-to-r from-[#006633] to-[#008040] text-white"><div class="container mx-auto px-4"><div class="grid grid-cols-1 lg:grid-cols-2 gap-8 md:gap-12 items-center"><div><i class="fas fa-bell text-3xl md:text-4xl mb-3 md:mb-4 opacity-80"></i><h2 class="text-2xl md:text-3xl font-bold mb-3 md:mb-4">Restez informé des nouveaux actes</h2><p class="text-white/90 mb-4 md:mb-6 leading-relaxed text-sm md:text-base">Recevez une notification par email dès qu'un nouveau décret ou arrêté est publié.</p><ul class="space-y-2 md:space-y-3 mb-6 md:mb-8"><li class="flex items-center text-sm md:text-base"><i class="fas fa-check-circle text-emerald-300 mr-2 md:mr-3"></i><span>Alertes personnalisables par institution</span></li><li class="flex items-center text-sm md:text-base"><i class="fas fa-check-circle text-emerald-300 mr-2 md:mr-3"></i><span>Notification en temps réel des publications</span></li></ul><a href="#" class="inline-flex items-center bg-white text-[#006633] px-5 md:px-6 py-2.5 md:py-3 rounded-xl font-semibold hover:bg-gray-100 transition shadow-lg text-sm md:text-base"><i class="fas fa-envelope mr-2"></i>S'abonner aux alertes</a></div><div class="bg-white/10 backdrop-blur-sm rounded-2xl p-5 md:p-6"><h3 class="text-lg md:text-xl font-bold mb-3 md:mb-4">Dernières alertes envoyées</h3><div class="space-y-3 md:space-y-4"><div class="flex items-start space-x-2 md:space-x-3"><div class="w-6 h-6 md:w-8 md:h-8 bg-emerald-500 rounded-full flex items-center justify-center flex-shrink-0"><i class="fas fa-gavel text-white text-xs"></i></div><div><p class="text-xs md:text-sm font-medium">Nouveau décret publié</p><p class="text-xs text-emerald-200">Décret n°2026-045/PR - 01 mars 2026</p></div></div><div class="flex items-start space-x-2 md:space-x-3"><div class="w-6 h-6 md:w-8 md:h-8 bg-teal-500 rounded-full flex items-center justify-center flex-shrink-0"><i class="fas fa-file-alt text-white text-xs"></i></div><div><p class="text-xs md:text-sm font-medium">Nouvel arrêté publié</p><p class="text-xs text-emerald-200">Arrêté n°2026-089/MF - 25 février 2026</p></div></div></div></div></div></div></section><script>// Donnéeslet allActs = {{ acts|json_encode|raw }};let filteredActs = [...allActs];let currentView = 'table';let currentPage = 1;let itemsPerPage = 5;let activeFilters = { type: '', institution: '', year: '', status: '', search: '' };// Initialisationdocument.addEventListener('DOMContentLoaded', function() {updateStats();renderActs();// Événementsdocument.getElementById('searchBtn').addEventListener('click', function() {performSearch();scrollToResults();});document.getElementById('searchInput').addEventListener('keypress', function(e) {if(e.key === 'Enter') {performSearch();scrollToResults();}});document.getElementById('applyFiltersBtn').addEventListener('click', function() {applyAdvancedFilters();scrollToResults();});document.getElementById('tableViewBtn').addEventListener('click', () => setView('table'));document.getElementById('listViewBtn').addEventListener('click', () => setView('list'));});// Fonction pour scroller vers les résultatsfunction scrollToResults() {const resultsSection = document.getElementById('resultsSection');if(resultsSection) {const offset = 80;const elementPosition = resultsSection.getBoundingClientRect().top;const offsetPosition = elementPosition + window.pageYOffset - offset;window.scrollTo({top: offsetPosition,behavior: 'smooth'});}}// Mise à jour du bandeau de filtrefunction updateFilterBadge() {const badge = document.getElementById('filterResultBadge');const filterText = document.getElementById('filterResultText');let filters = [];if(activeFilters.search) filters.push(`Recherche: "${activeFilters.search}"`);if(activeFilters.type) {const typeNames = { decret: 'Décrets', arrete: 'Arrêtés', circulaire: 'Circulaires', instruction: 'Instructions' };filters.push(`Type: ${typeNames[activeFilters.type] || activeFilters.type}`);}if(activeFilters.institution) filters.push(`Institution: ${activeFilters.institution}`);if(activeFilters.year) filters.push(`Année: ${activeFilters.year}`);if(activeFilters.status) {const statusNames = { vigueur: 'En vigueur', modifie: 'Modifié', abroge: 'Abrogé' };filters.push(`Statut: ${statusNames[activeFilters.status] || activeFilters.status}`);}if(filters.length > 0) {filterText.innerHTML = `<i class="fas fa-chart-line mr-1"></i> Filtres actifs : ${filters.join(' • ')} - ${filteredActs.length} résultat(s) trouvé(s)`;badge.classList.remove('hidden');} else {badge.classList.add('hidden');}}// Réinitialiser les filtresfunction resetFilters() {document.getElementById('filterType').value = '';document.getElementById('filterInstitution').value = '';document.getElementById('filterYear').value = '';document.getElementById('filterStatus').value = '';document.getElementById('searchInput').value = '';activeFilters = { type: '', institution: '', year: '', status: '', search: '' };filteredActs = [...allActs];currentPage = 1;renderActs();updateStats();updateFilterBadge();scrollToResults();}// Recherchefunction performSearch() {const searchTerm = document.getElementById('searchInput').value.toLowerCase();activeFilters.search = searchTerm;if(searchTerm === '') {filteredActs = [...allActs];} else {filteredActs = allActs.filter(act => {return act.numero.toLowerCase().includes(searchTerm) ||act.titre.toLowerCase().includes(searchTerm) ||act.description.toLowerCase().includes(searchTerm);});}// Réappliquer les autres filtresapplyCurrentFilters();}// Filtre rapidefunction applyQuickFilter(type) {document.getElementById('filterType').value = type === 'all' ? '' : type;activeFilters.type = type === 'all' ? '' : type;applyAdvancedFilters();}// Appliquer les filtres actuelsfunction applyCurrentFilters() {let results = [...allActs];if(activeFilters.search) {results = results.filter(act => {return act.numero.toLowerCase().includes(activeFilters.search) ||act.titre.toLowerCase().includes(activeFilters.search) ||act.description.toLowerCase().includes(activeFilters.search);});}if(activeFilters.type) {results = results.filter(act => act.type === activeFilters.type);}if(activeFilters.institution) {results = results.filter(act => act.institution.includes(activeFilters.institution));}if(activeFilters.year) {results = results.filter(act => act.date.startsWith(activeFilters.year));}if(activeFilters.status) {results = results.filter(act => act.status === activeFilters.status);}filteredActs = results;currentPage = 1;renderActs();updateStats();updateFilterBadge();}// Filtres avancésfunction applyAdvancedFilters() {activeFilters.type = document.getElementById('filterType').value;activeFilters.institution = document.getElementById('filterInstitution').value;activeFilters.year = document.getElementById('filterYear').value;activeFilters.status = document.getElementById('filterStatus').value;applyCurrentFilters();}// Changer l'affichagefunction setView(view) {currentView = view;const tableView = document.getElementById('tableView');const listView = document.getElementById('listView');const tableViewBtn = document.getElementById('tableViewBtn');const listViewBtn = document.getElementById('listViewBtn');if(view === 'table') {tableView.style.display = 'block';listView.style.display = 'none';tableViewBtn.className = 'px-3 md:px-4 py-1.5 md:py-2 bg-gradient-to-r from-[#006633] to-[#008040] text-white rounded-lg shadow-sm text-sm';listViewBtn.className = 'px-3 md:px-4 py-1.5 md:py-2 bg-white rounded-lg shadow-sm hover:bg-gray-50 transition text-sm';} else {tableView.style.display = 'none';listView.style.display = 'block';listViewBtn.className = 'px-3 md:px-4 py-1.5 md:py-2 bg-gradient-to-r from-[#006633] to-[#008040] text-white rounded-lg shadow-sm text-sm';tableViewBtn.className = 'px-3 md:px-4 py-1.5 md:py-2 bg-white rounded-lg shadow-sm hover:bg-gray-50 transition text-sm';}renderActs();}// Rendu des actesfunction renderActs() {const start = (currentPage - 1) * itemsPerPage;const end = start + itemsPerPage;const pageActs = filteredActs.slice(start, end);const totalPages = Math.ceil(filteredActs.length / itemsPerPage);// Rendu tableauconst tableBody = document.getElementById('actsTableBody');if(pageActs.length === 0) {tableBody.innerHTML = `<tr><td colspan="7" class="px-6 py-8 text-center text-gray-500"><i class="fas fa-search text-2xl mb-2"></i><p>Aucun acte trouvé</p><p class="text-sm mt-2">Essayez de modifier vos critères de recherche</p></td></tr>`;} else {tableBody.innerHTML = pageActs.map(act => `<tr class="hover:bg-gray-50 transition cursor-pointer"><td class="px-4 md:px-6 py-3 md:py-4 whitespace-nowrap"><span class="px-2 md:px-3 py-0.5 md:py-1 text-xs font-semibold rounded-full bg-[#006633]/10 text-[#006633]"><i class="fas ${act.typeIcon} mr-1"></i> ${act.typeLabel}</span></td><td class="px-4 md:px-6 py-3 md:py-4 whitespace-nowrap font-mono text-xs md:text-sm font-semibold text-gray-800">${act.numero}</td><td class="px-4 md:px-6 py-3 md:py-4"><div class="text-xs md:text-sm font-medium text-gray-900">${act.titre}</div><div class="text-xs text-gray-500 mt-1 hidden md:block">${act.description}</div></td><td class="px-4 md:px-6 py-3 md:py-4 whitespace-nowrap"><div class="text-xs md:text-sm text-gray-700">${act.institution}</div></td><td class="px-4 md:px-6 py-3 md:py-4 whitespace-nowrap"><div class="text-xs md:text-sm text-gray-700">${act.dateFormatted}</div></td><td class="px-4 md:px-6 py-3 md:py-4 whitespace-nowrap"><span class="px-2 py-0.5 md:py-1 text-xs font-semibold rounded-full bg-green-100 text-green-700"><i class="fas ${act.statusIcon} mr-1"></i> ${act.statusLabel}</span></td><td class="px-4 md:px-6 py-3 md:py-4 whitespace-nowrap"><div class="flex space-x-2"><button onclick="showDetails(${act.id})" class="text-[#006633] hover:text-[#008040]"><i class="fas fa-eye"></i></button><button onclick="generatePDF(${act.id})" class="text-gray-600 hover:text-gray-800"><i class="fas fa-download"></i></button></div></td></tr>`).join('');}// Rendu listeconst listBody = document.getElementById('actsListBody');if(pageActs.length === 0) {listBody.innerHTML = `<div class="bg-white rounded-2xl shadow-lg p-8 text-center text-gray-500"><i class="fas fa-search text-3xl mb-3"></i><p>Aucun acte trouvé</p><p class="text-sm mt-2">Essayez de modifier vos critères de recherche</p></div>`;} else {listBody.innerHTML = pageActs.map(act => `<div class="bg-white rounded-2xl shadow-lg p-6 hover:shadow-xl transition cursor-pointer"><div class="flex flex-col md:flex-row md:items-start md:justify-between gap-4"><div class="flex-1"><div class="flex items-center gap-2 mb-3"><span class="px-3 py-1 text-xs font-semibold rounded-full bg-[#006633]/10 text-[#006633]"><i class="fas ${act.typeIcon} mr-1"></i> ${act.typeLabel}</span><span class="px-3 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-700"><i class="fas ${act.statusIcon} mr-1"></i> ${act.statusLabel}</span></div><h3 class="text-lg font-bold text-gray-800 mb-2">${act.titre}</h3><p class="text-gray-600 text-sm mb-3">${act.description}</p><div class="flex flex-wrap gap-4 text-sm text-gray-500"><span><i class="fas fa-hashtag mr-1"></i> ${act.numero}</span><span><i class="fas fa-building mr-1"></i> ${act.institution}</span><span><i class="fas fa-calendar mr-1"></i> ${act.dateFormatted}</span></div></div><div class="flex gap-2"><button onclick="showDetails(${act.id})" class="px-4 py-2 bg-[#006633]/10 text-[#006633] rounded-lg hover:bg-[#006633]/20 transition"><i class="fas fa-eye mr-1"></i> Voir</button><button onclick="generatePDF(${act.id})" class="px-4 py-2 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 transition"><i class="fas fa-download mr-1"></i> PDF</button></div></div></div>`).join('');}// Paginationdocument.getElementById('startCount').textContent = filteredActs.length === 0 ? 0 : start + 1;document.getElementById('endCount').textContent = Math.min(end, filteredActs.length);document.getElementById('totalCount').textContent = filteredActs.length;const paginationDiv = document.getElementById('paginationControls');if(totalPages > 1) {let html = '';html += `<button onclick="changePage(${currentPage - 1})" class="px-2 md:px-3 py-1 border rounded-lg hover:bg-gray-100 transition" ${currentPage === 1 ? 'disabled style="opacity:0.5"' : ''}>Précédent</button>`;let startPage = Math.max(1, currentPage - 2);let endPage = Math.min(totalPages, startPage + 4);startPage = Math.max(1, endPage - 4);for(let i = startPage; i <= endPage; i++) {html += `<button onclick="changePage(${i})" class="px-3 md:px-4 py-1 ${currentPage === i ? 'bg-gradient-to-r from-[#006633] to-[#008040] text-white' : 'border hover:bg-gray-100'} rounded-lg text-sm">${i}</button>`;}if(endPage < totalPages) {html += `<span class="px-2">...</span>`;html += `<button onclick="changePage(${totalPages})" class="px-3 md:px-4 py-1 border rounded-lg hover:bg-gray-100 text-sm">${totalPages}</button>`;}html += `<button onclick="changePage(${currentPage + 1})" class="px-2 md:px-3 py-1 border rounded-lg hover:bg-gray-100 transition" ${currentPage === totalPages ? 'disabled style="opacity:0.5"' : ''}>Suivant</button>`;paginationDiv.innerHTML = html;} else {paginationDiv.innerHTML = '';}}// Changer de pagefunction changePage(page) {const totalPages = Math.ceil(filteredActs.length / itemsPerPage);if(page < 1 || page > totalPages) return;currentPage = page;renderActs();}// Afficher les détailsfunction showDetails(id) {const act = allActs.find(a => a.id === id);if(!act) return;const modalContent = document.getElementById('modalContent');modalContent.innerHTML = `<div class="space-y-6"><div class="flex items-center gap-3 pb-4 border-b"><div class="w-16 h-16 bg-[#006633]/10 rounded-2xl flex items-center justify-center"><i class="fas ${act.typeIcon} text-3xl text-[#006633]"></i></div><div><div class="flex items-center gap-2 mb-2"><span class="px-3 py-1 text-xs font-semibold rounded-full bg-[#006633]/10 text-[#006633]">${act.typeLabel}</span><span class="px-3 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-700">${act.statusLabel}</span></div><h2 class="text-2xl font-bold text-gray-800">${act.titre}</h2></div></div><div class="grid grid-cols-1 md:grid-cols-2 gap-4 p-4 bg-gray-50 rounded-xl"><div><p class="text-sm text-gray-500">Numéro</p><p class="font-mono font-semibold text-gray-800">${act.numero}</p></div><div><p class="text-sm text-gray-500">Date de publication</p><p class="font-semibold text-gray-800">${act.dateFormatted}</p></div><div><p class="text-sm text-gray-500">Institution</p><p class="font-semibold text-gray-800">${act.institution}</p><p class="text-sm text-gray-500">${act.institutionDetail}</p></div><div><p class="text-sm text-gray-500">Statut juridique</p><p class="font-semibold text-green-700">${act.statusLabel}</p></div></div><div><h4 class="font-bold text-gray-800 mb-3">Contenu de l'acte</h4><div class="bg-gray-50 rounded-xl p-4"><pre class="whitespace-pre-wrap font-sans text-sm text-gray-700">${act.content}</pre></div></div><div class="flex gap-3 pt-4 border-t"><button onclick="generatePDF(${act.id}); closeModal();" class="flex-1 px-6 py-3 bg-gradient-to-r from-[#006633] to-[#008040] text-white rounded-xl font-semibold hover:from-[#004d26] hover:to-[#006633] transition"><i class="fas fa-download mr-2"></i>Télécharger en PDF</button><button onclick="closeModal()" class="px-6 py-3 border border-gray-300 rounded-xl hover:bg-gray-50 transition">Fermer</button></div></div>`;document.getElementById('detailModal').style.display = 'flex';}// Fermer le modalfunction closeModal() {document.getElementById('detailModal').style.display = 'none';}// Génération PDFfunction generatePDF(id) {const act = allActs.find(a => a.id === id);if(act) {const content = `${act.typeLabel.toUpperCase()} N°${act.numero}\n\n${act.titre}\n\n${act.content}\n\n---\nPublié le ${act.dateFormatted}\nInstitution: ${act.institution} - ${act.institutionDetail}\nStatut: ${act.statusLabel}`;const blob = new Blob([content], {type: 'application/pdf'});const url = URL.createObjectURL(blob);const a = document.createElement('a');a.href = url;a.download = `${act.typeLabel}_${act.numero}.pdf`;document.body.appendChild(a);a.click();document.body.removeChild(a);URL.revokeObjectURL(url);// Notification légèreconst notification = document.createElement('div');notification.className = 'fixed bottom-4 right-4 bg-green-500 text-white px-4 py-2 rounded-lg shadow-lg z-50';notification.innerHTML = `<i class="fas fa-check-circle mr-2"></i>Téléchargement du PDF démarré`;document.body.appendChild(notification);setTimeout(() => notification.remove(), 3000);}}// Mettre à jour les statistiquesfunction updateStats() {const total = allActs.length;const decrets = allActs.filter(a => a.type === 'decret').length;const arretes = allActs.filter(a => a.type === 'arrete').length;const enVigueur = allActs.filter(a => a.status === 'vigueur').length;document.getElementById('totalActs').textContent = total;document.getElementById('totalDecrets').textContent = decrets;document.getElementById('totalArretes').textContent = arretes;document.getElementById('totalVigueur').textContent = enVigueur;}// Fermer le modal en cliquant en dehorsdocument.getElementById('detailModal').addEventListener('click', function(e) {if(e.target === this) {closeModal();}});</script>{% endblock %}