Actualiser js/public.js
This commit is contained in:
+34
-52
@@ -7,40 +7,34 @@ let searchQuery = '';
|
|||||||
let currentPage = 1;
|
let currentPage = 1;
|
||||||
const itemsPerPage = 12;
|
const itemsPerPage = 12;
|
||||||
|
|
||||||
async function loadPublicData() {
|
// ── GÉNÉRATEUR D'ÉTOILES ─
|
||||||
try {
|
function getStarsHTML(rating) {
|
||||||
const response = await fetch(`${API_URL}?action=get_films`);
|
const r = parseFloat(rating) || 0;
|
||||||
films = await response.json();
|
const full = Math.floor(r);
|
||||||
generateStreamingSelect(); // Remplit le menu déroulant
|
const hasHalf = (r - full) >= 0.5;
|
||||||
renderPublicGrid();
|
const empty = 5 - Math.ceil(r);
|
||||||
} catch (error) {
|
let html = '★'.repeat(full);
|
||||||
console.error("Erreur de récupération :", error);
|
if (hasHalf) html += '<span class="half-star">★</span>';
|
||||||
}
|
html += `<span class="stars-muted">${'☆'.repeat(empty)}</span>`;
|
||||||
|
return html;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── GÉNÉRATION DU MENU DÉROULANT STREAMING ──
|
// ── GÉNÉRATION MENU STREAMING ──
|
||||||
function generateStreamingSelect() {
|
function generateStreamingSelect() {
|
||||||
const select = document.getElementById('pub-streaming-select');
|
const select = document.getElementById('pub-streaming-select');
|
||||||
if (!select) return;
|
if (!select) return;
|
||||||
|
|
||||||
// Extraire toutes les plateformes uniques
|
|
||||||
const platforms = new Set();
|
const platforms = new Set();
|
||||||
films.forEach(f => {
|
films.forEach(f => {
|
||||||
if (f.type === 'critique' && f.streaming &&
|
if (f.type === 'critique' && f.streaming &&
|
||||||
f.streaming !== 'Disponible en support physique ou Cinéma' &&
|
f.streaming !== 'Disponible en support physique ou Cinéma' &&
|
||||||
f.streaming.trim() !== '') {
|
f.streaming.trim() !== '') {
|
||||||
// Séparer par virgule si plusieurs plateformes
|
|
||||||
f.streaming.split(',').forEach(p => {
|
f.streaming.split(',').forEach(p => {
|
||||||
const platform = p.trim();
|
const platform = p.trim();
|
||||||
if (platform.length > 0) platforms.add(platform);
|
if (platform.length > 0) platforms.add(platform);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Trier alphabétiquement
|
|
||||||
const sortedPlatforms = Array.from(platforms).sort();
|
const sortedPlatforms = Array.from(platforms).sort();
|
||||||
|
|
||||||
// Conserver l'option "Toutes" et ajouter les plateformes
|
|
||||||
select.innerHTML = '<option value="">Toutes les plateformes</option>';
|
select.innerHTML = '<option value="">Toutes les plateformes</option>';
|
||||||
sortedPlatforms.forEach(platform => {
|
sortedPlatforms.forEach(platform => {
|
||||||
const option = document.createElement('option');
|
const option = document.createElement('option');
|
||||||
@@ -48,8 +42,6 @@ function generateStreamingSelect() {
|
|||||||
option.textContent = platform;
|
option.textContent = platform;
|
||||||
select.appendChild(option);
|
select.appendChild(option);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Écouteur d'événement
|
|
||||||
select.addEventListener('change', (e) => {
|
select.addEventListener('change', (e) => {
|
||||||
activeStreamingFilter = e.target.value;
|
activeStreamingFilter = e.target.value;
|
||||||
currentPage = 1;
|
currentPage = 1;
|
||||||
@@ -57,38 +49,43 @@ function generateStreamingSelect() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── CHARGEMENT ──
|
||||||
|
async function loadPublicData() {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${API_URL}?action=get_films`);
|
||||||
|
films = await response.json();
|
||||||
|
generateStreamingSelect();
|
||||||
|
renderPublicGrid();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erreur de récupération :", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── NAVIGATION ONGLETS ──
|
||||||
function switchPubTab(tabName) {
|
function switchPubTab(tabName) {
|
||||||
currentPubTab = tabName;
|
currentPubTab = tabName;
|
||||||
activeRatingFilter = 0;
|
activeRatingFilter = 0;
|
||||||
activeStreamingFilter = '';
|
activeStreamingFilter = '';
|
||||||
currentPage = 1;
|
currentPage = 1;
|
||||||
|
|
||||||
// Reset le select
|
|
||||||
const select = document.getElementById('pub-streaming-select');
|
const select = document.getElementById('pub-streaming-select');
|
||||||
if (select) select.value = '';
|
if (select) select.value = '';
|
||||||
|
|
||||||
const ratingBar = document.getElementById('rating-filter-bar');
|
const ratingBar = document.getElementById('rating-filter-bar');
|
||||||
if (ratingBar) ratingBar.style.display = (tabName === 'critique') ? 'flex' : 'none';
|
if (ratingBar) ratingBar.style.display = (tabName === 'critique') ? 'flex' : 'none';
|
||||||
|
|
||||||
// Cacher le select sur l'onglet vidéothèque
|
|
||||||
if (select) select.style.display = (tabName === 'critique') ? 'block' : 'none';
|
if (select) select.style.display = (tabName === 'critique') ? 'block' : 'none';
|
||||||
|
|
||||||
document.querySelectorAll('.rating-filter-btn').forEach(btn => {
|
document.querySelectorAll('.rating-filter-btn').forEach(btn => {
|
||||||
btn.classList.remove('active');
|
btn.classList.remove('active');
|
||||||
btn.querySelectorAll('.rf-star').forEach(s => s.classList.remove('filled'));
|
btn.querySelectorAll('.rf-star').forEach(s => s.classList.remove('filled'));
|
||||||
});
|
});
|
||||||
|
|
||||||
document.querySelectorAll('.tab-btn').forEach(btn => btn.classList.remove('active'));
|
document.querySelectorAll('.tab-btn').forEach(btn => btn.classList.remove('active'));
|
||||||
const activeBtn = document.getElementById(`tab-pub-${tabName}s`);
|
const activeBtn = document.getElementById(`tab-pub-${tabName}s`);
|
||||||
if (activeBtn) activeBtn.classList.add('active');
|
if (activeBtn) activeBtn.classList.add('active');
|
||||||
|
|
||||||
renderPublicGrid();
|
renderPublicGrid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── FILTRE PAR NOTE (regroupement : 5★ = 4.5+5, 4★ = 3.5+4, etc.) ──
|
||||||
function filterByRating(stars) {
|
function filterByRating(stars) {
|
||||||
if (currentPubTab !== 'critique') return;
|
if (currentPubTab !== 'critique') return;
|
||||||
activeRatingFilter = (activeRatingFilter === stars) ? 0 : stars;
|
activeRatingFilter = (activeRatingFilter === stars) ? 0 : stars;
|
||||||
|
|
||||||
document.querySelectorAll('.rating-filter-btn').forEach(btn => {
|
document.querySelectorAll('.rating-filter-btn').forEach(btn => {
|
||||||
const n = parseInt(btn.dataset.stars);
|
const n = parseInt(btn.dataset.stars);
|
||||||
btn.classList.toggle('active', n === activeRatingFilter);
|
btn.classList.toggle('active', n === activeRatingFilter);
|
||||||
@@ -99,6 +96,7 @@ function filterByRating(stars) {
|
|||||||
renderPublicGrid();
|
renderPublicGrid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── RENDU GRILLE ──
|
||||||
function renderPublicGrid() {
|
function renderPublicGrid() {
|
||||||
const grid = document.getElementById('grid');
|
const grid = document.getElementById('grid');
|
||||||
const emptyState = document.getElementById('empty-state');
|
const emptyState = document.getElementById('empty-state');
|
||||||
@@ -106,10 +104,8 @@ function renderPublicGrid() {
|
|||||||
if (!grid) return;
|
if (!grid) return;
|
||||||
grid.innerHTML = '';
|
grid.innerHTML = '';
|
||||||
|
|
||||||
// 1. Filtrage par type
|
|
||||||
let filtered = films.filter(f => f.type === currentPubTab);
|
let filtered = films.filter(f => f.type === currentPubTab);
|
||||||
|
|
||||||
// Filtre par note (regroupement : 5★ inclut 4.5, 4★ inclut 3.5, etc.)
|
|
||||||
if (currentPubTab === 'critique' && activeRatingFilter > 0) {
|
if (currentPubTab === 'critique' && activeRatingFilter > 0) {
|
||||||
filtered = filtered.filter(f => {
|
filtered = filtered.filter(f => {
|
||||||
const rating = parseFloat(f.rating) || 0;
|
const rating = parseFloat(f.rating) || 0;
|
||||||
@@ -117,18 +113,15 @@ function renderPublicGrid() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Filtre par plateforme (avec normalisation)
|
|
||||||
if (currentPubTab === 'critique' && activeStreamingFilter) {
|
if (currentPubTab === 'critique' && activeStreamingFilter) {
|
||||||
const filterLower = activeStreamingFilter.toLowerCase();
|
const filterLower = activeStreamingFilter.toLowerCase();
|
||||||
filtered = filtered.filter(f => {
|
filtered = filtered.filter(f => {
|
||||||
if (!f.streaming || f.streaming === 'Disponible en support physique ou Cinéma') return false;
|
if (!f.streaming || f.streaming === 'Disponible en support physique ou Cinéma') return false;
|
||||||
// On vérifie si la plateforme sélectionnée est présente dans le champ streaming
|
|
||||||
const platforms = f.streaming.split(',').map(p => p.trim().toLowerCase());
|
const platforms = f.streaming.split(',').map(p => p.trim().toLowerCase());
|
||||||
return platforms.includes(filterLower);
|
return platforms.includes(filterLower);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Recherche textuelle
|
|
||||||
if (searchQuery) {
|
if (searchQuery) {
|
||||||
const q = searchQuery.toLowerCase();
|
const q = searchQuery.toLowerCase();
|
||||||
filtered = filtered.filter(f =>
|
filtered = filtered.filter(f =>
|
||||||
@@ -148,13 +141,11 @@ function renderPublicGrid() {
|
|||||||
}
|
}
|
||||||
if (emptyState) emptyState.style.display = 'none';
|
if (emptyState) emptyState.style.display = 'none';
|
||||||
|
|
||||||
// 5. Pagination
|
|
||||||
const totalPages = Math.ceil(filtered.length / itemsPerPage) || 1;
|
const totalPages = Math.ceil(filtered.length / itemsPerPage) || 1;
|
||||||
if (currentPage > totalPages) currentPage = totalPages;
|
if (currentPage > totalPages) currentPage = totalPages;
|
||||||
const startIdx = (currentPage - 1) * itemsPerPage;
|
const startIdx = (currentPage - 1) * itemsPerPage;
|
||||||
const pageItems = filtered.slice(startIdx, startIdx + itemsPerPage);
|
const pageItems = filtered.slice(startIdx, startIdx + itemsPerPage);
|
||||||
|
|
||||||
// 6. Rendu
|
|
||||||
pageItems.forEach(f => {
|
pageItems.forEach(f => {
|
||||||
const card = document.createElement('div');
|
const card = document.createElement('div');
|
||||||
card.className = 'card';
|
card.className = 'card';
|
||||||
@@ -169,17 +160,12 @@ function renderPublicGrid() {
|
|||||||
if (f.streaming && f.streaming !== 'Disponible en support physique ou Cinéma') {
|
if (f.streaming && f.streaming !== 'Disponible en support physique ou Cinéma') {
|
||||||
streamingBadge = `<div class="card-streaming-badge" title="${f.streaming}">📺 ${f.streaming.split(',')[0]}</div>`;
|
streamingBadge = `<div class="card-streaming-badge" title="${f.streaming}">📺 ${f.streaming.split(',')[0]}</div>`;
|
||||||
} else {
|
} else {
|
||||||
streamingBadge = `<div class="card-physical-badge">️ Physique / Cinéma</div>`;
|
streamingBadge = `<div class="card-physical-badge">🎟️ Physique / Cinéma</div>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f.type === 'critique') {
|
if (f.type === 'critique') {
|
||||||
const rating = parseFloat(f.rating) || 0;
|
const starsHTML = getStarsHTML(f.rating) + `<span class="card-rating-badge">${parseFloat(f.rating).toFixed(1)}</span>`;
|
||||||
const fullStars = Math.floor(rating);
|
|
||||||
const emptyStars = 5 - Math.ceil(rating);
|
|
||||||
const starsHTML = '★'.repeat(fullStars) + `<span class="stars-muted">${'☆'.repeat(emptyStars)}</span>`;
|
|
||||||
const ratingNum = `<span class="card-rating-badge">${rating.toFixed(1)}</span>`;
|
|
||||||
|
|
||||||
card.innerHTML = `
|
card.innerHTML = `
|
||||||
${posterHTML}
|
${posterHTML}
|
||||||
${streamingBadge}
|
${streamingBadge}
|
||||||
@@ -187,7 +173,7 @@ function renderPublicGrid() {
|
|||||||
<h3 class="card-title" title="${f.title}">${f.title}</h3>
|
<h3 class="card-title" title="${f.title}">${f.title}</h3>
|
||||||
<p class="card-director">${f.director || 'Réalisateur inconnu'}</p>
|
<p class="card-director">${f.director || 'Réalisateur inconnu'}</p>
|
||||||
<p class="card-meta">${f.year || '-'}</p>
|
<p class="card-meta">${f.year || '-'}</p>
|
||||||
<div class="card-stars">${starsHTML}${ratingNum}</div>
|
<div class="card-stars">${starsHTML}</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
} else {
|
} else {
|
||||||
card.innerHTML = `
|
card.innerHTML = `
|
||||||
@@ -208,11 +194,11 @@ function renderPublicGrid() {
|
|||||||
renderPagination(totalPages);
|
renderPagination(totalPages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── PAGINATION ──
|
||||||
function renderPagination(totalPages) {
|
function renderPagination(totalPages) {
|
||||||
const container = document.getElementById('pub-pagination');
|
const container = document.getElementById('pub-pagination');
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
container.innerHTML = '';
|
container.innerHTML = '';
|
||||||
|
|
||||||
if (totalPages <= 1) return;
|
if (totalPages <= 1) return;
|
||||||
|
|
||||||
const info = document.createElement('span');
|
const info = document.createElement('span');
|
||||||
@@ -232,7 +218,6 @@ function renderPagination(totalPages) {
|
|||||||
if (endPage - startPage + 1 < maxButtons) {
|
if (endPage - startPage + 1 < maxButtons) {
|
||||||
startPage = Math.max(1, endPage - maxButtons + 1);
|
startPage = Math.max(1, endPage - maxButtons + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (startPage > 1) {
|
if (startPage > 1) {
|
||||||
container.appendChild(createPubPageBtn(1));
|
container.appendChild(createPubPageBtn(1));
|
||||||
if (startPage > 2) container.appendChild(createPubEllipsis());
|
if (startPage > 2) container.appendChild(createPubEllipsis());
|
||||||
@@ -244,7 +229,6 @@ function renderPagination(totalPages) {
|
|||||||
if (endPage < totalPages - 1) container.appendChild(createPubEllipsis());
|
if (endPage < totalPages - 1) container.appendChild(createPubEllipsis());
|
||||||
container.appendChild(createPubPageBtn(totalPages));
|
container.appendChild(createPubPageBtn(totalPages));
|
||||||
}
|
}
|
||||||
|
|
||||||
const nextBtn = document.createElement('button');
|
const nextBtn = document.createElement('button');
|
||||||
nextBtn.innerHTML = '<i class="ti ti-chevron-right"></i>';
|
nextBtn.innerHTML = '<i class="ti ti-chevron-right"></i>';
|
||||||
nextBtn.disabled = currentPage === totalPages;
|
nextBtn.disabled = currentPage === totalPages;
|
||||||
@@ -268,6 +252,7 @@ function createPubEllipsis() {
|
|||||||
return span;
|
return span;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── DÉTAIL ──
|
||||||
function openDetail(id) {
|
function openDetail(id) {
|
||||||
const f = films.find(item => item.id == id);
|
const f = films.find(item => item.id == id);
|
||||||
if (!f) return;
|
if (!f) return;
|
||||||
@@ -296,12 +281,9 @@ function openDetail(id) {
|
|||||||
|
|
||||||
if (dBody) {
|
if (dBody) {
|
||||||
if (f.type === 'critique') {
|
if (f.type === 'critique') {
|
||||||
const rating = parseFloat(f.rating) || 0;
|
const stars = getStarsHTML(f.rating) + `<span style="font-size:1rem; color:var(--muted); margin-left:0.5rem;">${parseFloat(f.rating).toFixed(1)}/5</span>`;
|
||||||
const fullStars = Math.floor(rating);
|
|
||||||
const emptyStars = 5 - Math.ceil(rating);
|
|
||||||
const stars = '★'.repeat(fullStars) + `<span class="stars-muted">${'☆'.repeat(emptyStars)}</span>`;
|
|
||||||
dBody.innerHTML = `
|
dBody.innerHTML = `
|
||||||
<div class="detail-stars">${stars} <span style="font-size:1rem; color:var(--muted); margin-left:0.5rem;">${rating.toFixed(1)}/5</span></div>
|
<div class="detail-stars">${stars}</div>
|
||||||
<div class="pub-review-card">
|
<div class="pub-review-card">
|
||||||
<div class="pub-review-quote-icon"><i class="ti ti-quote"></i></div>
|
<div class="pub-review-quote-icon"><i class="ti ti-quote"></i></div>
|
||||||
<p class="pub-review-text">${f.review ? f.review : 'Aucun texte rédigé pour le moment.'}</p>
|
<p class="pub-review-text">${f.review ? f.review : 'Aucun texte rédigé pour le moment.'}</p>
|
||||||
@@ -344,9 +326,9 @@ function closeDetail() {
|
|||||||
if (detailOverlay) detailOverlay.classList.remove('open');
|
if (detailOverlay) detailOverlay.classList.remove('open');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── INITIALISATION ──
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
loadPublicData();
|
loadPublicData();
|
||||||
|
|
||||||
const searchInput = document.getElementById('pub-search-input');
|
const searchInput = document.getElementById('pub-search-input');
|
||||||
if (searchInput) {
|
if (searchInput) {
|
||||||
searchInput.addEventListener('input', (e) => {
|
searchInput.addEventListener('input', (e) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user