Actualiser js/admin.js
This commit is contained in:
+41
-112
@@ -332,31 +332,18 @@ 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 {
|
||||||
const res = await fetch(`${API_URL}?action=get_config_keys`, {
|
const res = await fetch(`${API_URL}?action=get_config_keys`, { headers: { 'Authorization': localStorage.getItem('token') } });
|
||||||
headers: { 'Authorization': localStorage.getItem('token') }
|
|
||||||
});
|
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
|
|
||||||
const tmdbInput = document.getElementById('tmdb-key-input');
|
const tmdbIn = document.getElementById('tmdb-key-input');
|
||||||
if (tmdbInput) {
|
if (tmdbIn) tmdbIn.placeholder = data.tmdb_api_key ? '✅ Clé TMDB configurée' : 'Entrez votre clé TMDB';
|
||||||
tmdbInput.value = '';
|
|
||||||
tmdbInput.placeholder = data.tmdb_api_key ? '✅ Clé TMDB configurée (laisser vide pour garder)' : 'Entrez votre clé TMDB';
|
|
||||||
}
|
|
||||||
|
|
||||||
const fanartInput = document.getElementById('fanart-key-input');
|
const upcIn = document.getElementById('upcmdb-key-input');
|
||||||
if (fanartInput) {
|
if (upcIn) upcIn.placeholder = data.upcmdb_api_key ? '✅ Clé UPCMDB configurée' : 'Clé gratuite sur upcmdb.com';
|
||||||
fanartInput.value = '';
|
|
||||||
fanartInput.placeholder = data.fanart_api_key ? '✅ Clé Fanart.tv configurée (laisser vide pour garder)' : 'Entrez votre clé Fanart.tv';
|
|
||||||
}
|
|
||||||
|
|
||||||
const upcmdbInput = document.getElementById('upcmdb-key-input');
|
|
||||||
if (upcmdbInput) {
|
|
||||||
upcmdbInput.value = '';
|
|
||||||
upcmdbInput.placeholder = data.upcmdb_api_key ? '✅ Clé UPCMDB configurée (laisser vide pour garder)' : 'Gratuite sur upcmdb.com — fallback EAN';
|
|
||||||
}
|
|
||||||
} catch(e) { console.error(e); }
|
} catch(e) { console.error(e); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -425,89 +412,65 @@ async function handleCritiqueUpload(input) {
|
|||||||
loadDashboardData();
|
loadDashboardData();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extraction EAN uniquement depuis le CSV vidéothèque
|
// Extraction stricte de l'EAN uniquement
|
||||||
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, '');
|
||||||
return { ean };
|
return { ean };
|
||||||
}
|
}
|
||||||
|
|
||||||
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 parsedData = parseCSV(text);
|
const parsed = parseCSV(text);
|
||||||
|
if (!parsed.length) { alert("❌ CSV vide."); return; }
|
||||||
|
|
||||||
if (parsedData.length === 0) {
|
const items = parsed.map(row => {
|
||||||
alert("❌ Fichier CSV vide ou invalide.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const items = parsedData.map(row => {
|
|
||||||
const { ean } = normalizeVideothequeRow(row);
|
const { ean } = normalizeVideothequeRow(row);
|
||||||
if (!ean || ean.length < 8) return null;
|
return (ean && ean.length >= 8) ? { ean } : null;
|
||||||
return { ean };
|
}).filter(Boolean);
|
||||||
}).filter(item => item !== null);
|
|
||||||
|
if (!items.length) { alert("❌ Aucun EAN valide trouvé."); return; }
|
||||||
if (items.length === 0) {
|
|
||||||
alert("❌ Aucun code EAN valide trouvé dans le fichier CSV.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
showImportModal(items.length, 'videotheque');
|
showImportModal(items.length, 'videotheque');
|
||||||
let processed = 0;
|
let processed = 0, totalImp = 0, totalSkp = 0;
|
||||||
|
|
||||||
let totalImported = 0;
|
|
||||||
let totalSkipped = 0;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Lots de 2 : UPCitemdb impose ~2 s entre chaque requête EAN
|
// Lots de 2 pour respecter les limites UPCitemdb (2s/requête)
|
||||||
for (let i = 0; i < items.length; i += 2) {
|
for (let i = 0; i < items.length; i += 2) {
|
||||||
const batch = items.slice(i, i + 2);
|
const batch = items.slice(i, i + 2);
|
||||||
|
const res = await fetch(`${API_URL}?action=import_batch`, {
|
||||||
const response = await fetch(`${API_URL}?action=import_batch`, {
|
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: { 'Authorization': localStorage.getItem('token'), 'Content-Type': 'application/json' },
|
||||||
'Authorization': localStorage.getItem('token'),
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ type: 'videotheque', items: batch })
|
body: JSON.stringify({ type: 'videotheque', items: batch })
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!res.ok) throw new Error(`Erreur HTTP ${res.status}`);
|
||||||
throw new Error(`Erreur serveur ${response.status}`);
|
const data = await res.json();
|
||||||
}
|
if (!data.success) throw new Error(data.error || "Échec API");
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
if (!data.success) {
|
|
||||||
throw new Error(data.error || "Erreur inconnue");
|
|
||||||
}
|
|
||||||
|
|
||||||
totalImported += data.imported || 0;
|
|
||||||
totalSkipped += data.skipped || 0;
|
|
||||||
|
|
||||||
|
totalImp += data.imported || 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, 1500)); // Délai de sécurité
|
||||||
}
|
}
|
||||||
|
|
||||||
input.value = '';
|
input.value = '';
|
||||||
closeImportModal();
|
closeImportModal();
|
||||||
const skipMsg = totalSkipped > 0 ? ` (${totalSkipped} EAN ignoré(s) — introuvable dans UPCitemdb/UPCMDB)` : '';
|
const msg = totalSkp > 0 ? ` (${totalSkp} EAN ignoré(s) — introuvables UPC/TMDB)` : '';
|
||||||
showSuccessModal(`${totalImported} édition(s) importée(s) (UPCitemdb + UPCMDB + TMDB).${skipMsg}`);
|
showSuccessModal(`${totalImp} édition(s) importée(s) (UPC + TMDB).${msg}`);
|
||||||
loadDashboardData();
|
loadDashboardData();
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Erreur d'importation : ", err);
|
console.error(err);
|
||||||
closeImportModal();
|
closeImportModal();
|
||||||
alert("❌ Échec de l'import : " + err.message);
|
alert("❌ Échec import : " + err.message);
|
||||||
input.value = '';
|
input.value = '';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
reader.readAsText(file);
|
reader.readAsText(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -528,49 +491,15 @@ function updateImportModal(current, total) {
|
|||||||
function closeImportModal() { document.getElementById('import-progress-modal').classList.remove('open'); }
|
function closeImportModal() { document.getElementById('import-progress-modal').classList.remove('open'); }
|
||||||
|
|
||||||
async function saveConfigKeys() {
|
async function saveConfigKeys() {
|
||||||
const tmdbKeyValue = document.getElementById('tmdb-key-input').value.trim();
|
const tmdb = document.getElementById('tmdb-key-input').value.trim();
|
||||||
const fanartKeyValue = document.getElementById('fanart-key-input').value.trim();
|
const upcmdb = document.getElementById('upcmdb-key-input').value.trim();
|
||||||
const upcmdbKeyValue = document.getElementById('upcmdb-key-input').value.trim();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (tmdbKeyValue) {
|
if (tmdb) await fetch(`${API_URL}?action=save_config`, { method:'POST', headers:{'Authorization':localStorage.getItem('token'),'Content-Type':'application/json'}, body:JSON.stringify({key_name:'tmdb_api_key',key_value:tmdb}) });
|
||||||
await fetch(`${API_URL}?action=save_config`, {
|
if (upcmdb) await fetch(`${API_URL}?action=save_config`, { method:'POST', headers:{'Authorization':localStorage.getItem('token'),'Content-Type':'application/json'}, body:JSON.stringify({key_name:'upcmdb_api_key',key_value:upcmdb}) });
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Authorization': localStorage.getItem('token'),
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ key_name: 'tmdb_api_key', key_value: tmdbKeyValue })
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (upcmdbKeyValue) {
|
|
||||||
await fetch(`${API_URL}?action=save_config`, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Authorization': localStorage.getItem('token'),
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ key_name: 'upcmdb_api_key', key_value: upcmdbKeyValue })
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fanartKeyValue) {
|
|
||||||
await fetch(`${API_URL}?action=save_config`, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Authorization': localStorage.getItem('token'),
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ key_name: 'fanart_api_key', key_value: fanartKeyValue })
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
alert('✅ Clés sauvegardées !');
|
alert('✅ Clés sauvegardées !');
|
||||||
closeConfigModal();
|
closeConfigModal();
|
||||||
} catch (err) {
|
} catch(e) { alert('Erreur serveur.'); }
|
||||||
alert('Erreur serveur.');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function saveNewPassword() {
|
async function saveNewPassword() {
|
||||||
@@ -589,12 +518,12 @@ async function saveNewPassword() {
|
|||||||
function updateImportInterface() {
|
function updateImportInterface() {
|
||||||
const title = document.getElementById('import-title');
|
const title = document.getElementById('import-title');
|
||||||
const desc = document.getElementById('import-desc');
|
const desc = document.getElementById('import-desc');
|
||||||
if (currentAdminTab === 'critique') {
|
if (currentAdminTab === 'videotheque') {
|
||||||
|
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.';
|
||||||
|
} 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).';
|
||||||
} else {
|
|
||||||
title.innerHTML = '<strong>Importer ma Vidéothèque</strong>';
|
|
||||||
desc.textContent = 'Import CSV (EAN seul) : UPCitemdb puis UPCMDB en secours, TMDB pour affiche/synopsis/réalisateur/acteurs.';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user