diff --git a/js/public.js b/js/public.js index f4e0244..e58d081 100644 --- a/js/public.js +++ b/js/public.js @@ -2,7 +2,8 @@ let films = []; const API_URL = '../api.php'; let currentPubTab = 'critique'; let activeRatingFilter = 0; -let searchQuery = ''; +let activeStreamingFilter = ''; // Nouveau filtre +let searchQuery = ''; // Si vous avez ajouté la recherche let currentPage = 1; const itemsPerPage = 12; @@ -11,36 +12,82 @@ async function loadPublicData() { const response = await fetch(`${API_URL}?action=get_films`); films = await response.json(); renderPublicGrid(); + generateStreamingFilters(); // Générer les filtres dynamiquement } catch (error) { console.error("Erreur de récupération :", error); } } +// ── GÉNÉRATION DYNAMIQUE DES FILTRES STREAMING ── +function generateStreamingFilters() { + const container = document.getElementById('streaming-filter-buttons'); + if (!container) return; + + // Extraire toutes les plateformes uniques + const platforms = new Set(); + films.forEach(f => { + if (f.type === 'critique' && f.streaming && f.streaming !== 'Disponible en support physique ou Cinéma') { + // Séparer par virgule si plusieurs plateformes + f.streaming.split(',').forEach(p => { + const platform = p.trim(); + if (platform) platforms.add(platform); + }); + } + }); + + // Trier alphabétiquement + const sortedPlatforms = Array.from(platforms).sort(); + + // Bouton "Toutes" + const allBtn = document.createElement('button'); + allBtn.className = 'streaming-filter-btn active'; + allBtn.textContent = 'Toutes'; + allBtn.onclick = () => filterByStreaming(''); + container.appendChild(allBtn); + + // Boutons pour chaque plateforme + sortedPlatforms.forEach(platform => { + const btn = document.createElement('button'); + btn.className = 'streaming-filter-btn'; + btn.textContent = platform; + btn.onclick = () => filterByStreaming(platform); + container.appendChild(btn); + }); +} + function switchPubTab(tabName) { currentPubTab = tabName; activeRatingFilter = 0; + activeStreamingFilter = ''; // Reset currentPage = 1; - searchQuery = ''; - const searchInput = document.getElementById('pub-search-input'); - if (searchInput) searchInput.value = ''; const filterBar = document.getElementById('rating-filter-bar'); - if (filterBar) filterBar.style.display = (tabName === 'critique') ? 'flex' : 'none'; + if(filterBar) filterBar.style.display = (tabName === 'critique') ? 'flex' : 'none'; + + const streamingBar = document.getElementById('streaming-filter-bar'); + if(streamingBar) streamingBar.style.display = (tabName === 'critique') ? 'flex' : 'none'; document.querySelectorAll('.rating-filter-btn').forEach(btn => { btn.classList.remove('active'); btn.querySelectorAll('.rf-star').forEach(s => s.classList.remove('filled')); }); + + // Reset filtres streaming + document.querySelectorAll('.streaming-filter-btn').forEach(btn => { + btn.classList.remove('active'); + }); + const allBtn = document.querySelector('.streaming-filter-btn'); + if(allBtn) allBtn.classList.add('active'); + document.querySelectorAll('.tab-btn').forEach(btn => btn.classList.remove('active')); const activeBtn = document.getElementById(`tab-pub-${tabName}s`); - if (activeBtn) activeBtn.classList.add('active'); + if(activeBtn) activeBtn.classList.add('active'); renderPublicGrid(); } function filterByRating(stars) { if (currentPubTab !== 'critique') return; activeRatingFilter = (activeRatingFilter === stars) ? 0 : stars; - currentPage = 1; document.querySelectorAll('.rating-filter-btn').forEach(btn => { const n = parseInt(btn.dataset.stars); @@ -52,6 +99,18 @@ function filterByRating(stars) { renderPublicGrid(); } +// ── NOUVEAU : FILTRE PAR STREAMING ─ +function filterByStreaming(platform) { + if (currentPubTab !== 'critique') return; + activeStreamingFilter = platform; + + document.querySelectorAll('.streaming-filter-btn').forEach(btn => { + btn.classList.toggle('active', btn.textContent === (platform || 'Toutes')); + }); + + renderPublicGrid(); +} + function renderPublicGrid() { const grid = document.getElementById('grid'); const emptyState = document.getElementById('empty-state'); @@ -66,6 +125,14 @@ function renderPublicGrid() { filtered = filtered.filter(f => Math.round(parseFloat(f.rating)) === activeRatingFilter); } + // NOUVEAU : Filtre par plateforme + if (currentPubTab === 'critique' && activeStreamingFilter) { + filtered = filtered.filter(f => { + if (!f.streaming || f.streaming === 'Disponible en support physique ou Cinéma') return false; + return f.streaming.split(',').map(p => p.trim()).includes(activeStreamingFilter); + }); + } + if (searchQuery) { const q = searchQuery.toLowerCase(); filtered = filtered.filter(f => @@ -101,11 +168,10 @@ function renderPublicGrid() { ? `
${f.title}
` : `
Pas d'affiche
`; - // Badge streaming en haut à droite de l'affiche let streamingBadge = ''; if (f.type === 'critique') { if (f.streaming && f.streaming !== 'Disponible en support physique ou Cinéma') { - streamingBadge = `
📺 ${f.streaming.split(',')[0]}
`; + streamingBadge = `
${f.streaming.split(',')[0]}
`; } else { streamingBadge = `
🎟️ Physique / Cinéma
`; } @@ -154,20 +220,17 @@ function renderPagination(totalPages) { if (totalPages <= 1) return; - // Info const info = document.createElement('span'); info.className = 'pub-pagination-info'; info.textContent = `Page ${currentPage} / ${totalPages}`; container.appendChild(info); - // Prev const prevBtn = document.createElement('button'); prevBtn.innerHTML = ''; prevBtn.disabled = currentPage === 1; prevBtn.onclick = () => { currentPage--; renderPublicGrid(); window.scrollTo({ top: 0, behavior: 'smooth' }); }; container.appendChild(prevBtn); - // Pages intelligentes const maxButtons = 5; let startPage = Math.max(1, currentPage - Math.floor(maxButtons / 2)); let endPage = Math.min(totalPages, startPage + maxButtons - 1); @@ -187,7 +250,6 @@ function renderPagination(totalPages) { container.appendChild(createPubPageBtn(totalPages)); } - // Next const nextBtn = document.createElement('button'); nextBtn.innerHTML = ''; nextBtn.disabled = currentPage === totalPages; @@ -211,7 +273,7 @@ function createPubEllipsis() { return span; } -// ── DÉTAIL (inchangé, juste adapté aux nouvelles notes) ── +// ── DÉTAIL ── function openDetail(id) { const f = films.find(item => item.id == id); if (!f) return; @@ -288,17 +350,4 @@ function closeDetail() { if (detailOverlay) detailOverlay.classList.remove('open'); } -// ── INITIALISATION ── -document.addEventListener('DOMContentLoaded', () => { - loadPublicData(); - - // Écouteur de recherche - const searchInput = document.getElementById('pub-search-input'); - if (searchInput) { - searchInput.addEventListener('input', (e) => { - searchQuery = e.target.value; - currentPage = 1; - renderPublicGrid(); - }); - } -}); \ No newline at end of file +document.addEventListener('DOMContentLoaded', loadPublicData); \ No newline at end of file