diff --git a/js/admin.js b/js/admin.js index 987a929..28bd890 100644 --- a/js/admin.js +++ b/js/admin.js @@ -443,6 +443,7 @@ async function handleCsvUpload(input) { if (!input.files || input.files.length === 0) return; let allData = []; + // 1. Lecture de tous les fichiers for (const file of input.files) { try { const text = await file.text(); @@ -453,55 +454,83 @@ async function handleCsvUpload(input) { } } - input.value = ''; + input.value = ''; // Reset l'input file if (allData.length === 0) { alert('❌ Fichiers vides ou mal formatés.'); return; } - const mergedMap = new Map(); - allData.forEach(row => { - const title = (row['Title'] || row['Name'] || '').trim(); - const dateStr = (row['Date'] || row['Year'] || row['year'] || '').toString(); - const year = dateStr.match(/(\d{4})/)?.[1] || ''; - const key = `${title.toLowerCase()}|${year}`; + // 🔥 CORRECTION : Mapping intelligent pour votre format CSV spécifique + let finalData = allData.map(row => { + // 1. Titre (gestion des guillemets et espaces) + const rawTitle = (row['title'] || row['Title'] || row['Name'] || '').trim(); - if (!mergedMap.has(key)) { - mergedMap.set(key, { ...row }); - } else { - const existing = mergedMap.get(key); - if ((row['Rating'] || row['rating']) && !existing['Rating']) existing['Rating'] = row['Rating']; - if ((row['Review'] || row['review']) && !existing['Review']) existing['Review'] = row['Review']; + // 2. Année (extraction depuis publish_date au format YYYY-MM-DD) + let year = ''; + const dateStr = (row['publish_date'] || row['Date'] || row['Year'] || '').toString(); + const yearMatch = dateStr.match(/(\d{4})/); + if (yearMatch) year = yearMatch[1]; + + // 3. Nettoyage du titre (enlever les mentions [Blu-ray], (DVD), etc.) + let cleanTitle = rawTitle.replace(/\s*\[(Blu-ray|DVD|4K|Coffret|Combo).*?\]/gi, '').trim(); + cleanTitle = cleanTitle.replace(/\s*\(.*?DVD.*?\)/gi, '').trim(); + if (!cleanTitle) cleanTitle = rawTitle; + + // 4. Déduction automatique du format physique + let format = 'Support Physique'; + if (rawTitle.match(/Blu-ray|Blu-Ray/i)) format = 'Blu-ray'; + else if (rawTitle.match(/DVD/i)) format = 'DVD'; + else if (rawTitle.match(/4K|UHD/i)) format = '4K UHD'; + + // 5. Extraction du Réalisateur / Casting principal + let director = ''; + if (row['director']) { + director = row['director']; + } else if (row['first_name'] && row['last_name']) { + director = `${row['first_name']} ${row['last_name']}`; + } else if (row['creators']) { + // Prendre le premier nom de la liste des créateurs/acteurs + director = row['creators'].split(',')[0].trim(); } - }); - - let finalData = Array.from(mergedMap.values()); - - // 🔥 CORRECTION : Mapping des champs CSV vers les champs attendus par le Backend - finalData = finalData.map(row => { - const title = (row['Title'] || row['Name'] || '').trim(); - const dateStr = (row['Date'] || row['Year'] || row['year'] || '').toString(); - const year = dateStr.match(/(\d{4})/)?.[1] || ''; - - const existingDb = allItems.find(f => - f.title.toLowerCase().trim() === title.toLowerCase() && - String(f.year) === String(year) && - f.type === currentAdminTab - ); + // 6. Construction de l'objet final avec les NOMS DE CHAMPS ATTENDUS PAR LE BACKEND return { - ...row, // Garde les données brutes au cas où - // Mappe vers les noms de colonnes BDD - title: title, + title: cleanTitle, year: year, - rating: (row['Rating'] || row['rating']) || (existingDb ? existingDb.rating : ''), - review: (row['Review'] || row['review']) || (existingDb ? existingDb.review : '') + director: director, + format: format, + length: row['length'] || '', + publisher: row['publisher'] || '', + aspect_ratio: row['aspect_ratio'] || '', + ean_isbn13: row['ean_isbn13'] || '', + number_of_discs: row['number_of_discs'] || 1, + description: row['description'] || '' }; }); + // Filtrer les lignes sans titre + finalData = finalData.filter(item => item.title !== ''); + + if (finalData.length === 0) { + alert('❌ Aucun titre valide trouvé dans le fichier.'); + return; + } + + // Dédoublonnage en mémoire + const mergedMap = new Map(); + finalData.forEach(row => { + const key = `${row.title.toLowerCase()}|${row.year}`; + if (!mergedMap.has(key)) { + mergedMap.set(key, row); + } + }); + finalData = Array.from(mergedMap.values()); + + // Lancement de la modale de progression showImportModal(finalData.length, currentAdminTab); + // Envoi par lots de 10 const batchSize = 10; let processed = 0; @@ -523,6 +552,7 @@ async function handleCsvUpload(input) { updateImportModal(processed, finalData.length); } + // Finalisation closeImportModal(); alert(`✅ Import terminé ! ${finalData.length} élément(s) traité(s).`); loadDashboardData();