Actualiser js/admin.js

This commit is contained in:
2026-06-19 15:50:15 +02:00
parent 6e159fa81b
commit 2976eed987
+52 -16
View File
@@ -84,25 +84,22 @@ function renderAdminTable() {
const startIdx = (currentPage - 1) * itemsPerPage; const startIdx = (currentPage - 1) * itemsPerPage;
const pageItems = filtered.slice(startIdx, startIdx + itemsPerPage); const pageItems = filtered.slice(startIdx, startIdx + itemsPerPage);
// 3. Rendu — 7 cellules pour correspondre aux 7 <th> // 3. Rendu
pageItems.forEach(f => { pageItems.forEach(f => {
const tr = document.createElement('tr'); const tr = document.createElement('tr');
let infoHtml = ''; let infoHtml = '';
if (currentAdminTab === 'critique') { if (currentAdminTab === 'critique') {
// 🌟 Gestion précise des notes Letterboxd (0.5 à 5)
const rating = parseFloat(f.rating) || 0; const rating = parseFloat(f.rating) || 0;
const fullStars = Math.floor(rating); // partie entière const fullStars = Math.floor(rating);
const emptyStars = 5 - Math.ceil(rating); // étoiles vides const emptyStars = 5 - Math.ceil(rating);
const stars = '★'.repeat(fullStars) + '☆'.repeat(emptyStars); const stars = '★'.repeat(fullStars) + '☆'.repeat(emptyStars);
infoHtml = ` infoHtml = `
<div style="display:flex; align-items:center; gap:0.6rem; flex-wrap:wrap;"> <div style="display:flex; align-items:center; gap:0.6rem; flex-wrap:wrap;">
<span class="tbl-stars" style="font-size:1.05rem;">${stars}</span> <span class="tbl-stars" style="font-size:1.05rem;">${stars}</span>
<span class="rating-badge">${rating.toFixed(1)}</span> <span class="rating-badge">${rating.toFixed(1)}</span>
</div>`; </div>`;
// Badge streaming
if (f.streaming && f.streaming !== 'Disponible en support physique ou Cinéma') { if (f.streaming && f.streaming !== 'Disponible en support physique ou Cinéma') {
infoHtml += `<span class="streaming-badge" title="${f.streaming}">${f.streaming}</span>`; infoHtml += `<span class="streaming-badge" title="${f.streaming}">${f.streaming}</span>`;
} else { } else {
@@ -113,10 +110,9 @@ function renderAdminTable() {
if(f.length) infoHtml += `<span style="font-size:0.8rem; color:var(--muted); margin-left:0.4rem;">${f.length}</span>`; if(f.length) infoHtml += `<span style="font-size:0.8rem; color:var(--muted); margin-left:0.4rem;">${f.length}</span>`;
} }
// ✅ 7 cellules <td> pour 7 colonnes <th>
tr.innerHTML = ` tr.innerHTML = `
<td style="text-align:center; width:40px;"> <td style="text-align:center; width:40px;">
<input type="checkbox" class="film-checkbox" value="${f.id}" onclick="updateBulkBar()"> <input type="checkbox" class="film-checkbox" value="${f.id}" onclick="toggleSingleSelect('${f.id}', this)">
</td> </td>
<td style="width:60px; text-align:center;"> <td style="width:60px; text-align:center;">
${f.poster ? `<img src="${f.poster}" class="thumb" alt="Affiche">` : '<div class="thumb-ph"><i class="ti ti-photo"></i></div>'} ${f.poster ? `<img src="${f.poster}" class="thumb" alt="Affiche">` : '<div class="thumb-ph"><i class="ti ti-photo"></i></div>'}
@@ -132,9 +128,31 @@ function renderAdminTable() {
tbody.appendChild(tr); tbody.appendChild(tr);
}); });
// ✅ Synchronise les checkboxes avec selectedIds après rendu
document.querySelectorAll('.film-checkbox').forEach(cb => {
cb.checked = selectedIds.has(cb.value);
});
renderPagination(totalPages, filtered.length); renderPagination(totalPages, filtered.length);
} }
// ── SÉLECTION INDIVIDUELLE ──
function toggleSingleSelect(id, checkbox) {
if (checkbox.checked) {
selectedIds.add(String(id));
} else {
selectedIds.delete(String(id));
}
updateBulkBar();
// Met à jour le checkbox "select all"
const selectAll = document.getElementById('select-all-checkbox');
const filtered = allItems.filter(item => item.type === currentAdminTab);
if (selectAll) {
selectAll.checked = filtered.length > 0 && filtered.every(f => selectedIds.has(String(f.id)));
}
}
// ── FONCTIONS DE PAGINATION ── // ── FONCTIONS DE PAGINATION ──
function renderPagination(totalPages, totalItems) { function renderPagination(totalPages, totalItems) {
const container = document.getElementById('pagination-container'); const container = document.getElementById('pagination-container');
@@ -205,23 +223,37 @@ function createEllipsis() {
return span; return span;
} }
// ── GESTION DE MASSE // ── GESTION DE MASSE AMÉLIORÉE
let selectedIds = new Set(); // Stocke tous les IDs sélectionnés (toutes pages)
function toggleSelectAll(source) { function toggleSelectAll(source) {
document.querySelectorAll('.film-checkbox').forEach(cb => cb.checked = source.checked); // Sélectionne tous les films de la catégorie actuelle (pas juste la page)
const filtered = allItems.filter(item => item.type === currentAdminTab);
if (source.checked) {
filtered.forEach(f => selectedIds.add(String(f.id)));
} else {
filtered.forEach(f => selectedIds.delete(String(f.id)));
}
// Met à jour visuellement les checkboxes de la page courante
document.querySelectorAll('.film-checkbox').forEach(cb => {
cb.checked = selectedIds.has(cb.value);
});
updateBulkBar(); updateBulkBar();
} }
function updateBulkBar() { function updateBulkBar() {
const checked = document.querySelectorAll('.film-checkbox:checked');
const bulkBar = document.getElementById('bulk-actions-bar'); const bulkBar = document.getElementById('bulk-actions-bar');
const bulkCount = document.getElementById('bulk-count'); const bulkCount = document.getElementById('bulk-count');
const selectAll = document.getElementById('select-all-checkbox');
if (checked.length > 0) { if (selectedIds.size > 0) {
if(bulkBar) bulkBar.style.display = 'flex'; if(bulkBar) bulkBar.style.display = 'flex';
if(bulkCount) bulkCount.textContent = checked.length; if(bulkCount) bulkCount.textContent = selectedIds.size;
} else { } else {
if(bulkBar) bulkBar.style.display = 'none'; if(bulkBar) bulkBar.style.display = 'none';
const selectAll = document.getElementById('select-all-checkbox');
if(selectAll) selectAll.checked = false; if(selectAll) selectAll.checked = false;
} }
} }
@@ -243,18 +275,22 @@ function closeConfirmModal() {
// ── ACTIONS CRUD (SUPPRESSION SÉCURISÉE) ── // ── ACTIONS CRUD (SUPPRESSION SÉCURISÉE) ──
async function executeBulkDelete() { async function executeBulkDelete() {
const ids = Array.from(document.querySelectorAll('.film-checkbox:checked')).map(cb => cb.value); const ids = Array.from(selectedIds);
if (ids.length === 0) return; if (ids.length === 0) return;
showConfirmModal(async () => { showConfirmModal(async () => {
try { try {
const res = await fetch(`${API_URL}?action=bulk_delete`, { const res = await fetch(`${API_URL}?action=bulk_delete`, {
method: 'POST', method: 'POST',
headers: { 'Authorization': localStorage.getItem('token'), 'Content-Type': 'application/json' }, headers: {
'Authorization': localStorage.getItem('token'),
'Content-Type': 'application/json'
},
body: JSON.stringify({ ids, type: currentAdminTab }) body: JSON.stringify({ ids, type: currentAdminTab })
}); });
if (!res.ok) throw new Error("Erreur serveur lors de la suppression multiple."); if (!res.ok) throw new Error("Erreur serveur lors de la suppression multiple.");
selectedIds.clear();
document.getElementById('bulk-actions-bar').style.display = 'none'; document.getElementById('bulk-actions-bar').style.display = 'none';
const selectAll = document.getElementById('select-all-checkbox'); const selectAll = document.getElementById('select-all-checkbox');
if(selectAll) selectAll.checked = false; if(selectAll) selectAll.checked = false;