Actualiser js/admin.js
This commit is contained in:
+63
-33
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user