From ec815787ede7eea32dd916f73b3a3266a3e1c9f3 Mon Sep 17 00:00:00 2001 From: Cedric Date: Tue, 16 Jun 2026 20:49:43 +0200 Subject: [PATCH] Actualiser js/admin.js --- js/admin.js | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/js/admin.js b/js/admin.js index 101038f..bbae855 100644 --- a/js/admin.js +++ b/js/admin.js @@ -5,7 +5,7 @@ * ========================================================================= */ -// ── PARSEUR CSV UNIVERSEL (Gestion avancée des guillemets et séparateurs) ── +// ── PARSEUR CSV UNIVERSEL (Gestion des guillemets et séparateurs) ── function parseFlexibleCSV(text) { const rows = []; let row = [""]; @@ -42,7 +42,7 @@ function parseFlexibleCSV(text) { return rows; } -// ── FONCTION D'IMPORTATION REVISITÉE ── +// ── FONCTION D'IMPORTATION SÉCURISÉE (Latin-1 / Multi-formats) ── function importFromCSV(input) { const file = input.files[0]; if (!file) return; @@ -58,11 +58,11 @@ function importFromCSV(input) { return; } - // Nettoyage et normalisation des entêtes pour ignorer les accents et la casse + // Nettoyage et normalisation des en-têtes (ignore les accents et la casse) const cleanHeader = (h) => h.trim().toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, ""); const headers = rows[0].map(cleanHeader); - // Mappage ultra-large des colonnes (gère vos deux structures de fichiers) + // Mappage des colonnes (gère 'importcinetest.csv' et votre catalogue global) const idxTitle = headers.findIndex(h => h === 'titre' || h === 'title' || h === 'name'); const idxYear = headers.findIndex(h => h === 'annee' || h === 'year' || h === 'publish_date'); const idxDirector = headers.findIndex(h => h === 'realisateur' || h === 'director' || h === 'creators'); @@ -71,7 +71,7 @@ function importFromCSV(input) { const idxPoster = headers.findIndex(h => h === 'url_affiche' || h === 'url'); if (idxTitle === -1) { - alert("Erreur : Impossible de trouver la colonne des titres. Entêtes détectés : " + rows[0].join(', ')); + alert("Erreur : Impossible de trouver la colonne des titres."); input.value = ''; return; } @@ -86,10 +86,10 @@ function importFromCSV(input) { const titleRaw = cols[idxTitle]?.trim(); if (!titleRaw) continue; - // Nettoyage des chaînes parasites + // Nettoyage des suffixes d'éditions let title = titleRaw.replace(/\s*\[.*?\]/g, "").replace(/\s*- Édition.*/gi, ""); - // Année (on extrait les 4 premiers chiffres) + // Extraction propre de l'année (4 chiffres) let year = ''; if (idxYear >= 0 && cols[idxYear]) { const match = cols[idxYear].trim().match(/\d{4}/); @@ -102,7 +102,7 @@ function importFromCSV(input) { director = cols[idxDirector].split(',')[0].trim(); } - // Note (de 1 à 5) + // Note (Normalisée entre 1 et 5) let rating = 0; if (idxRating >= 0 && cols[idxRating]) { const ratingRaw = parseFloat(cols[idxRating]); @@ -110,15 +110,15 @@ function importFromCSV(input) { rating = Math.round(Math.min(5, Math.max(1, ratingRaw))); } } - if (rating === 0) rating = 3; // Note par défaut + if (rating === 0) rating = 3; - // Critique ou description longue + // Critique ou description de l'œuvre let review = idxReview >= 0 && cols[idxReview] ? cols[idxReview].trim() : ''; - // Lien vers l'affiche + // URL de l'affiche let filePoster = idxPoster >= 0 && cols[idxPoster] ? cols[idxPoster].trim() : ''; - // Vérification des doublons élargie (titre + année identiques, peu importe le type) + // Déduplication (titre + année) const alreadyExists = films.some( f => f.title.toLowerCase() === title.toLowerCase() && (year === '' || f.year === year) ); @@ -132,7 +132,7 @@ function importFromCSV(input) { } if (toImport.length === 0) { - alert(`Aucun nouveau film inséré.\n⚠️ ${duplicateCount} doublon(s) filtré(s) ou lignes vides.`); + alert(`Aucun nouveau film inséré.\n⚠️ ${duplicateCount} doublon(s) filtré(s).`); input.value = ''; return; } @@ -149,7 +149,6 @@ function importFromCSV(input) { let poster = filePoster; let streaming = "Disponible sur vos étagères ou au cinéma"; - // Si l'affiche locale manque et que TMDB est configuré, on interroge l'API if (!poster && hasTmdb) { const details = await fetchTmdbDetails(title, year); poster = details.poster; @@ -160,11 +159,11 @@ function importFromCSV(input) { if (details.streaming) streaming = details.streaming; } - // Structure globale unifiée pour 'critique' ou 'film' + // Injection forcée en type 'critique' pour correspondre à votre vue principale films.push({ id: Date.now() + Math.floor(Math.random() * 1000) + i, title, - type: 'critique', // Forcer le type attendu par l'affichage principal de vos onglets + type: 'critique', year, director, rating, @@ -180,7 +179,6 @@ function importFromCSV(input) { await new Promise(r => setTimeout(r, 300)); hideImportProgress(); - // Tri et persistance immédiate films.sort((a, b) => b.id - a.id); persist(); switchTab('critique'); @@ -189,11 +187,11 @@ function importFromCSV(input) { input.value = ''; }; - // Utilisation de ISO-8859-1 (Latin-1) pour lire sans encombre les exports Windows/Excel contenant des accents + // Utilisation obligatoire de ISO-8859-1 (Latin-1) pour préserver les accents sous Excel / Windows reader.readAsText(file, 'ISO-8859-1'); } -// ── COMPOSANTS ET OUTILS DE SUIVI DE L'IMPORT ── +// ── COMPOSANTS INTERFACES DE PROGRESSION ── function showImportProgress(total) { let overlay = document.getElementById('import-overlay'); if (!overlay) { @@ -269,7 +267,7 @@ function persist() { } } -// ── COMMUTATION DE L'ONGLET ACTIF ── +// ── NAVIGATION ONGLETS ── function switchTab(tabName) { document.querySelectorAll('.tab-content').forEach(el => el.classList.remove('active')); document.querySelectorAll('.tab-btn').forEach(el => el.classList.remove('active'));