Actualiser js/admin.js

This commit is contained in:
2026-07-01 10:41:30 +02:00
parent 9b073b78b5
commit 817627dca7
+70 -36
View File
@@ -412,15 +412,15 @@ async function handleCritiqueUpload(input) {
} }
function normalizeVideothequeRow(row) { function normalizeVideothequeRow(row) {
// Recherche de l'EAN dans plusieurs colonnes possibles
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'] || '';
ean = String(ean).replace(/[^0-9]/g, ''); ean = String(ean).replace(/[^0-9]/g, '');
// Essayer plusieurs clés pour le titre // Recherche du titre dans plusieurs colonnes
let title = row['title'] || row['Title'] || row['Titre'] || row['titre'] || row['nom'] || row['Nom'] || ''; let title = row['title'] || row['Title'] || row['Titre'] || row['titre'] || row['nom'] || row['Nom'] || '';
title = String(title).trim(); title = String(title).trim();
// Si on a un EAN mais pas de titre, on peut utiliser le titre du fichier ? Non, on laisse vide mais on ne skip pas. // Si on n'a ni EAN ni titre, on ignore
// On retourne quand même l'objet si l'EAN est valide, même sans titre (pour tenter de récupérer via Blu-ray.com)
if (!ean && !title) return null; if (!ean && !title) return null;
return { ean, title }; return { ean, title };
@@ -429,52 +429,86 @@ function normalizeVideothequeRow(row) {
function handleVideothequeUpload(input) { function handleVideothequeUpload(input) {
const file = input.files[0]; const file = input.files[0];
if (!file) return; if (!file) return;
const reader = new FileReader(); const reader = new FileReader();
reader.onload = async (e) => { reader.onload = async (e) => {
const text = e.target.result; const text = e.target.result;
const parsed = parseCSV(text); const parsed = parseCSV(text);
if (!parsed.length) { alert("❌ CSV vide."); return; } if (!parsed.length) {
alert("❌ CSV vide ou mal formaté.");
// ✅ CORRECTION : Utiliser normalizeVideothequeRow qui retourne EAN + titre input.value = '';
return;
}
// Transformer chaque ligne en objet {ean, title}
const items = parsed.map(row => normalizeVideothequeRow(row)).filter(Boolean); const items = parsed.map(row => normalizeVideothequeRow(row)).filter(Boolean);
console.log('Lignes parsées :', parsed.length); if (!items.length) {
console.log('Items valides :', items.length); alert("❌ Aucun titre ou EAN valide trouvé dans le CSV.");
console.log('Premier item :', items[0]); input.value = '';
if (!items.length) { alert("❌ Aucun titre ou EAN valide trouvé."); return; } return;
}
console.log(`Lignes parsées : ${parsed.length}, items valides : ${items.length}`);
// Ouvrir la modale de progression
showImportModal(items.length, 'videotheque'); showImportModal(items.length, 'videotheque');
let processed = 0, totalImp = 0, totalSkp = 0; let processed = 0;
let totalImported = 0;
let totalSkipped = 0;
// Taille du lot : 10 films par requête
const BATCH_SIZE = 10;
try { try {
// ✅ Lots de 1 seul pour éviter le blocage Blu-ray.com for (let i = 0; i < items.length; i += BATCH_SIZE) {
const batchSize = 5; // ou 10 selon la puissance du serveur const batch = items.slice(i, i + BATCH_SIZE);
for (let i = 0; i < items.length; i += batchSize) { const response = await fetch(`${API_URL}?action=import_batch`, {
const batch = items.slice(i, i + batchSize);
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'
},
body: JSON.stringify({ type: 'videotheque', items: batch }) body: JSON.stringify({ type: 'videotheque', items: batch })
}); });
// ... traitement de la réponse
// Petit délai optionnel (100 ms) pour éviter de saturer le serveur if (!response.ok) {
await new Promise(r => setTimeout(r, 100)); throw new Error(`Erreur HTTP ${response.status} - ${response.statusText}`);
} }
input.value = ''; const result = await response.json();
closeImportModal(); if (!result.success) {
const msg = totalSkp > 0 ? ` (${totalSkp} ignoré(s))` : ''; throw new Error(result.error || "Erreur inconnue lors de l'import.");
showSuccessModal(`${totalImp} édition(s) importée(s).${msg}`); }
loadDashboardData();
} catch (err) { totalImported += result.imported || 0;
console.error(err); totalSkipped += result.skipped || 0;
closeImportModal(); processed += batch.length;
alert("❌ Échec import : " + err.message);
input.value = ''; // Mise à jour de la barre de progression
} updateImportModal(processed, items.length);
};
reader.readAsText(file); // Petit délai pour éviter de saturer le serveur
await new Promise(resolve => setTimeout(resolve, 200));
} }
// Fermer la modale
closeImportModal();
input.value = '';
const msg = totalSkipped > 0 ? ` (${totalSkipped} ignoré(s))` : '';
showSuccessModal(`${totalImported} film(s) importé(s) avec succès.${msg}`);
loadDashboardData();
} catch (err) {
console.error(err);
closeImportModal();
alert(`❌ Échec de l'import : ${err.message}`);
input.value = '';
}
};
reader.readAsText(file);
}
function showImportModal(total, type) { function showImportModal(total, type) {
document.getElementById('import-modal-title').innerHTML = type === 'critique' ? '<i class="ti ti-star"></i> Import Critiques' : '<i class="ti ti-video"></i> Import Vidéothèque'; document.getElementById('import-modal-title').innerHTML = type === 'critique' ? '<i class="ti ti-star"></i> Import Critiques' : '<i class="ti ti-video"></i> Import Vidéothèque';
document.getElementById('import-modal-desc').textContent = `Traitement de ${total} élément(s)...`; document.getElementById('import-modal-desc').textContent = `Traitement de ${total} élément(s)...`;