Actualiser js/admin.js

This commit is contained in:
2026-06-30 17:02:03 +02:00
parent c387933371
commit 40c8dd9a5e
+27 -23
View File
@@ -1,20 +1,25 @@
const API_URL = '../api.php'; const API_URL = '../api.php';
let allItems = [], currentAdminTab = 'critique', currentPage = 1, selectedIds = new Set(); let allItems = [];
let currentAdminTab = 'critique';
let currentPage = 1;
const itemsPerPage = 12;
let selectedIds = new Set();
let pendingDeleteAction = null;
// --- Utilitaires --- function getStarsHTML(rating) {
const getStarsHTML = (rating) => { let r = parseFloat(String(rating).replace(',', '.')) || 0;
let r = Math.min(Math.max(parseFloat(rating) || 0, 0), 5); r = Math.min(Math.max(r, 0), 5);
const full = Math.floor(r), hasHalf = (r - full) >= 0.5, empty = Math.max(0, 5 - Math.ceil(r)); const full = Math.floor(r);
return '★'.repeat(full) + (hasHalf ? '<span class="half-star">★</span>' : '') + `<span class="stars-muted">${'☆'.repeat(empty)}</span>`; const hasHalf = (r - full) >= 0.5;
}; const empty = Math.max(0, 5 - Math.ceil(r));
let html = '★'.repeat(full);
if (hasHalf) html += '<span class="half-star">★</span>';
html += `<span class="stars-muted">${'☆'.repeat(empty)}</span>`;
return html;
}
function parseCSV(text) { function parseCSV(text) {
if (text.charCodeAt(0) === 0xFEFF) text = text.slice(1); if (text.charCodeAt(0) === 0xFEFF) text = text.slice(1);
// ✅ NOUVEAU : Détection automatique du séparateur le plus utilisé sur la première ligne
const firstLine = text.split(/[\r\n]+/)[0] || '';
const sep = (firstLine.match(/;/g) || []).length > (firstLine.match(/,/g) || []).length ? ';' : ',';
const rows = []; const rows = [];
let col = '', row = [], inQuotes = false; let col = '', row = [], inQuotes = false;
for (let i = 0; i < text.length; i++) { for (let i = 0; i < text.length; i++) {
@@ -26,7 +31,7 @@ function parseCSV(text) {
} else col += c; } else col += c;
} else { } else {
if (c === '"') inQuotes = true; if (c === '"') inQuotes = true;
else if (c === sep) { row.push(col); col = ''; } // ✅ On utilise le séparateur détecté else if (c === ',') { row.push(col); col = ''; }
else if (c === '\n' || c === '\r') { else if (c === '\n' || c === '\r') {
if (c === '\r' && text[i+1] === '\n') i++; if (c === '\r' && text[i+1] === '\n') i++;
row.push(col); col = ''; row.push(col); col = '';
@@ -327,7 +332,6 @@ function openEditModal(id) {
function closeAdminModal() { document.getElementById('admin-modal').classList.remove('open'); } function closeAdminModal() { document.getElementById('admin-modal').classList.remove('open'); }
// Nettoyage Config Modal (Suppression Fanart)
async function openConfigModal() { async function openConfigModal() {
document.getElementById('config-modal').classList.add('open'); document.getElementById('config-modal').classList.add('open');
try { try {
@@ -407,19 +411,20 @@ async function handleCritiqueUpload(input) {
loadDashboardData(); loadDashboardData();
} }
// ✅ CORRECTION : Retourne l'EAN ET le titre du CSV
function normalizeVideothequeRow(row) { function normalizeVideothequeRow(row) {
let ean = row['ean_isbn13'] || row['EAN'] || row['ean'] || row['Barcode'] || row['UPC'] || row['upc_isbn10'] || ''; let ean = row['ean_isbn13'] || row['EAN'] || row['ean'] || row['Barcode'] || row['UPC'] || row['upc_isbn10'] || '';
if (ean) ean = String(ean).replace(/[^0-9]/g, ''); if (ean) ean = String(ean).replace(/[^0-9]/g, '');
// ✅ Tolérance sur le nom de la colonne // ✅ Récupérer le titre du CSV
let title = row['Title'] || row['title'] || row['Titre'] || row['titre'] || row['Name'] || row['name'] || ''; let title = row['title'] || row['Title'] || row['Titre'] || '';
title = String(title).trim(); title = String(title).trim();
if (!ean && !title) return null; if (!ean && !title) return null;
return { return {
ean: ean, ean: ean,
title: title title: title // ✅ Titre envoyé au backend
}; };
} }
@@ -432,9 +437,10 @@ function handleVideothequeUpload(input) {
const parsed = parseCSV(text); const parsed = parseCSV(text);
if (!parsed.length) { alert("❌ CSV vide."); return; } if (!parsed.length) { alert("❌ CSV vide."); return; }
const items = parsed.map(row => normalizeVideothequeRow(row)).filter(Boolean); // ✅ CORRECTION : Utiliser normalizeVideothequeRow qui retourne EAN + titre
const items = parsed.map(row => normalizeVideothequeRow(row)).filter(Boolean);
if (!items.length) { alert("❌ Aucun titre ou EAN valide trouvé."); return; } if (!items.length) { alert("❌ Aucun titre ou EAN valide trouvé."); return; }
showImportModal(items.length, 'videotheque'); showImportModal(items.length, 'videotheque');
let processed = 0, totalImp = 0, totalSkp = 0; let processed = 0, totalImp = 0, totalSkp = 0;
@@ -443,8 +449,6 @@ function handleVideothequeUpload(input) {
// ✅ Lots de 1 seul pour éviter le blocage Blu-ray.com // ✅ Lots de 1 seul pour éviter le blocage Blu-ray.com
for (let i = 0; i < items.length; i += 1) { for (let i = 0; i < items.length; i += 1) {
const batch = items.slice(i, i + 1); const batch = items.slice(i, i + 1);
// ✅ AJOUTEZ CECI POUR VOIR QUEL FILM BLOQUE
console.log("Tentative d'import de : ", batch[0].title);
const res = await fetch(`${API_URL}?action=import_batch`, { const res = await fetch(`${API_URL}?action=import_batch`, {
method: 'POST', method: 'POST',
headers: { 'Authorization': localStorage.getItem('token'), 'Content-Type': 'application/json' }, headers: { 'Authorization': localStorage.getItem('token'), 'Content-Type': 'application/json' },
@@ -459,7 +463,7 @@ function handleVideothequeUpload(input) {
totalSkp += data.skipped || 0; totalSkp += data.skipped || 0;
processed += batch.length; processed += batch.length;
updateImportModal(processed, items.length); updateImportModal(processed, items.length);
await new Promise(r => setTimeout(r, 500)); // Délai de 5.5s pour éviter le blocage await new Promise(r => setTimeout(r, 500)); // Délai de sécurité
} }
input.value = ''; input.value = '';
@@ -523,7 +527,7 @@ function updateImportInterface() {
const desc = document.getElementById('import-desc'); const desc = document.getElementById('import-desc');
if (currentAdminTab === 'videotheque') { if (currentAdminTab === 'videotheque') {
title.innerHTML = '<strong>Importer ma Vidéothèque</strong>'; title.innerHTML = '<strong>Importer ma Vidéothèque</strong>';
desc.textContent = 'Import CSV (EAN seul) : UPCitemdb/UPCMDB pour le physique, TMDB pour l\'affiche, le casting et le synopsis.'; desc.textContent = 'Import CSV (EAN + Titre) : Blu-ray.com pour le physique, TMDB pour l\'affiche, le casting et le synopsis.';
} else { } else {
title.innerHTML = '<strong>Importer Critiques & Notes</strong>'; title.innerHTML = '<strong>Importer Critiques & Notes</strong>';
desc.textContent = 'Sélectionnez vos fichiers "ratings.csv" et "reviews.csv" (Letterboxd).'; desc.textContent = 'Sélectionnez vos fichiers "ratings.csv" et "reviews.csv" (Letterboxd).';