2025-08-14 19:27:48 +02:00
<!DOCTYPE html>
< html lang = "fr" >
< head >
< meta charset = "UTF-8" >
< title > {{TITLE}}< / title >
< meta name = "csrf-token" content = "{{CSRF_TOKEN}}" >
2025-09-27 16:20:25 +02:00
< link rel = "icon" href = "/autopost/favicon.ico" type = "image/svg+xml" >
2025-09-27 16:36:18 +02:00
< link rel = "stylesheet" href = "checkboxes.css" >
2025-08-14 19:27:48 +02:00
< script src = "js/index.global.js" > < / script >
< script src = "jquery/jquery.min.js" > < / script >
< link href = "https://fonts.googleapis.com/css?family=Roboto:400,700&display=swap" rel = "stylesheet" >
< / head >
< body class = "bg-{{BACKGROUND_CLASS}} text-white font-sans p-4" >
< div class = "w-full px-4" >
<!-- Header -->
< div class = "mb-6" >
< div class = "flex items-center justify-between" >
< h1 class = "text-2xl md:text-3xl font-extrabold tracking-tight bg-clip-text text-transparent bg-gradient-to-r from-blue-400 to-cyan-300" >
Suivi Autopost {{APP_NAME}}
< / h1 >
< a href = "/autopost/logout"
class="inline-flex items-center gap-2 px-3 py-2 rounded-xl bg-red-600/90 hover:bg-red-600 text-white shadow-lg shadow-red-900/20 transition">
< svg class = "w-4 h-4" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" >
< path stroke-linecap = "round" stroke-linejoin = "round" stroke-width = "2"
d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a2 2 0 01-2 2H6a2 2 0 01-2-2V7a2 2 0 012-2h5a2 2 0 012 2v1"/>
< / svg >
Déconnexion
< / a >
< / div >
< p class = "mt-1 text-sm text-gray-400" > Vue d’ ensemble des traitements en cours et de l’ état des envois.< / p >
< / div >
<!-- Stat cards -->
< div class = "grid grid-cols-2 md:grid-cols-4 gap-4 mb-6" >
<!-- En attente -->
< div class = "group rounded-2xl p-3 md:p-5 bg-gradient-to-br from-cyan-500 to-cyan-400 text-black shadow-xl ring-1 ring-white/10 transition transform hover:-translate-y-0.5 hover:shadow-2xl cursor-pointer filter-card" data-status = "0" >
< div class = "flex items-center gap-3" >
< div class = "rounded-xl bg-black/10 p-2" >
< svg class = "w-5 h-5" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" >
< path stroke-linecap = "round" stroke-linejoin = "round" stroke-width = "2"
d="M12 6v6l4 2"/>
< / svg >
< / div >
< div class = "text-sm/5 font-medium" > En attente< / div >
< / div >
< div class = "mt-3 text-3xl font-extrabold tabular-nums" > {{STAT_ATTENTE}}< / div >
< / div >
<!-- Terminé -->
< div class = "group rounded-2xl p-4 md:p-5 bg-gradient-to-br from-green-300 to-emerald-300 text-black shadow-xl ring-1 ring-white/10 transition transform hover:-translate-y-0.5 hover:shadow-2xl cursor-pointer filter-card" data-status = "1" >
< div class = "flex items-center gap-3" >
< div class = "rounded-xl bg-black/10 p-2" >
< svg class = "w-5 h-5" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" >
< path stroke-linecap = "round" stroke-linejoin = "round" stroke-width = "2"
d="M5 13l4 4L19 7"/>
< / svg >
< / div >
< div class = "text-sm/5 font-medium" > Terminé< / div >
< / div >
< div class = "mt-3 text-3xl font-extrabold tabular-nums" > {{STAT_TERMINE}}< / div >
< / div >
<!-- Erreur -->
< div class = "group rounded-2xl p-4 md:p-5 bg-gradient-to-br from-rose-300 to-red-300 text-black shadow-xl ring-1 ring-white/10 transition transform hover:-translate-y-0.5 hover:shadow-2xl cursor-pointer filter-card" data-status = "2" >
< div class = "flex items-center gap-3" >
< div class = "rounded-xl bg-black/10 p-2" >
< svg class = "w-5 h-5" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" >
< path stroke-linecap = "round" stroke-linejoin = "round" stroke-width = "2"
d="M12 9v3m0 4h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/>
< / svg >
< / div >
< div class = "text-sm/5 font-medium" > Erreur< / div >
< / div >
< div class = "mt-3 text-3xl font-extrabold tabular-nums" > {{STAT_ERREUR}}< / div >
< / div >
<!-- Déjà dispo -->
< div class = "group rounded-2xl p-4 md:p-5 bg-gradient-to-br from-pink-300 to-fuchsia-300 text-black shadow-xl ring-1 ring-white/10 transition transform hover:-translate-y-0.5 hover:shadow-2xl cursor-pointer filter-card" data-status = "3" >
< div class = "flex items-center gap-3" >
< div class = "rounded-xl bg-black/10 p-2" >
< svg class = "w-5 h-5" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" >
< path stroke-linecap = "round" stroke-linejoin = "round" stroke-width = "2"
d="M8 7h8M8 11h8M8 15h6"/>
< / svg >
< / div >
< div class = "text-sm/5 font-medium" > Déjà dispo< / div >
< / div >
< div class = "mt-3 text-3xl font-extrabold tabular-nums" > {{STAT_DEJA}}< / div >
< / div >
< / div >
<!-- Bouton réinitialiser -->
< div class = "mb-4 text-center" >
< button id = "showAll"
class="hidden px-5 py-2 rounded-xl bg-gradient-to-br from-gray-600 to-gray-800 text-white font-semibold shadow-lg hover:from-gray-500 hover:to-gray-700 transition transform hover:-translate-y-0.5">
Tout afficher
< / button >
< / div >
<!-- Search -->
< div class = "mb-4" >
< label for = "searchInput" class = "sr-only" > Rechercher< / label >
< div class = "relative" >
< span class = "pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3" >
< svg class = "w-5 h-5 text-gray-400" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" >
< path stroke-linecap = "round" stroke-linejoin = "round" stroke-width = "2"
d="M21 21l-4.35-4.35M10 18a8 8 0 1 1 0-16 8 8 0 0 1 0 16z"/>
< / svg >
< / span >
< input id = "searchInput" type = "text" placeholder = "Rechercher…"
class="w-full pl-10 pr-3 py-2 rounded-xl bg-gray-800/80 border border-gray-700 focus:border-blue-500 focus:ring-4 focus:ring-blue-500/20 outline-none transition placeholder:text-gray-400" />
< / div >
< / div >
< nav id = "pagination" aria-label = "Page navigation" class = "mb-4" >
{{PAGINATION_HTML}}
< / nav >
2025-09-27 15:06:16 +02:00
<!-- Boutons d'actions en lot -->
< div id = "bulkActions" class = "hidden mb-4 p-4 bg-gray-800 rounded-lg border border-gray-600" >
< div class = "flex items-center justify-between flex-wrap gap-3" >
< span id = "selectedCount" class = "text-gray-300 font-medium" > 0 élément sélectionné< / span >
< div class = "flex gap-2" >
< button id = "bulkEditBtn" class = "px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg font-semibold transition" >
✏️ Éditer la sélection
< / button >
< button id = "bulkDeleteBtn" class = "px-4 py-2 bg-red-600 hover:bg-red-700 text-white rounded-lg font-semibold transition" >
🗑️ Supprimer la sélection
< / button >
< / div >
< / div >
< / div >
2025-08-14 19:27:48 +02:00
< div class = "overflow-x-auto" >
< table class = "min-w-full border border-gray-700 shadow-lg rounded-lg overflow-hidden" >
< thead class = "bg-gray-900 text-gray-300 uppercase text-sm" >
< tr >
2025-09-27 15:06:16 +02:00
< th class = "px-4 py-2" >
2025-09-27 16:36:18 +02:00
< input type = "checkbox" id = "selectAll" class = "checkbox-custom" >
2025-09-27 15:06:16 +02:00
< / th >
2025-08-14 19:27:48 +02:00
< th class = "px-4 py-2" > Name< / th >
< th class = "px-4 py-2" > Status< / th >
< th class = "px-4 py-2" > ID< / th >
< th class = "px-4 py-2" > Actions< / th >
< / tr >
< / thead >
< tbody class = "divide-y divide-gray-700" >
{{TABLE_ROWS}}
< / tbody >
< / table >
< / div >
< / div >
<!-- Modales + Toast (inchangés) -->
<!-- Modale d'édition -->
< div id = "editModal" class = "hidden fixed inset-0 bg-black bg-opacity-60 backdrop-blur-sm flex items-center justify-center z-50" >
< div class = "bg-gray-900 p-6 rounded-2xl shadow-2xl w-full max-w-md transform transition-all scale-95" >
< button type = "button" class = "absolute top-4 right-4 text-gray-400 hover:text-white text-2xl font-bold close" > × < / button >
< h2 class = "text-2xl font-bold mb-6 text-center text-white" > ✏️ Éditer Release < span id = "modalReleaseId" class = "text-blue-400" > < / span > < / h2 >
< form id = "editForm" >
< label for = "statusSelect" class = "block mb-2 text-gray-300 font-medium" > Status :< / label >
< select id = "statusSelect" name = "status"
class="w-full p-3 mb-6 rounded-lg border border-gray-700 bg-gray-800 text-white focus:ring-2 focus:ring-blue-500 focus:outline-none">
< option value = "0" class = "text-cyan-400" > EN ATTENTE< / option >
< option value = "1" class = "text-green-400" > ENVOI TERMINÉ< / option >
< option value = "2" class = "text-red-400" > ERREUR< / option >
< option value = "3" class = "text-pink-400" > DEJA DISPONIBLE< / option >
< option value = "4" class = "text-yellow-400" > EN COURS< / option >
< / select >
< input type = "hidden" id = "releaseId" name = "id" value = "" / >
< button type = "submit" class = "w-full p-3 bg-gradient-to-r from-blue-600 to-blue-500 text-white font-semibold rounded-lg shadow hover:from-blue-500 hover:to-blue-400 transform hover:-translate-y-0.5 transition" > 💾 Mettre à jour< / button >
< / form >
< / div >
< / div >
<!-- Modale log -->
< div id = "logModal" class = "hidden fixed inset-0 bg-black bg-opacity-60 backdrop-blur-sm flex items-center justify-center z-50" >
< div class = "bg-gray-900 p-6 rounded-2xl shadow-2xl w-full max-w-7xl relative" >
< button type = "button" class = "absolute top-4 right-4 text-gray-400 hover:text-white text-2xl font-bold close log-close" > × < / button >
< h2 class = "text-2xl font-bold mb-6 text-center text-white" > 📄 Contenu du log< / h2 >
< pre id = "logContent" class = "max-h-[90vh] overflow-y-auto p-6 rounded-lg bg-gray-800 text-green-400 font-mono text-sm leading-relaxed border border-gray-700 shadow-inner whitespace-pre-wrap" > < / pre >
< / div >
< / div >
<!-- Modale mediainfo -->
< div id = "mediainfoModal" class = "hidden fixed inset-0 bg-black bg-opacity-60 backdrop-blur-sm flex items-center justify-center z-50" >
< div class = "bg-gray-900 p-6 rounded-2xl shadow-2xl w-full max-w-6xl relative" >
< button type = "button" class = "absolute top-4 right-4 text-gray-400 hover:text-white text-2xl font-bold close mediainfo-close" title = "Fermer" > × < / button >
< h2 class = "text-2xl font-bold text-white mb-4 pr-16" > 📄 Contenu du mediainfo< / h2 >
< div class = "mb-6" >
< button id = "copyMediainfoBtn" class = "bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg text-sm font-semibold shadow-md transition" > 📋 Copier JSON< / button >
< / div >
< pre id = "mediainfoContent" class = "max-h-[80vh] overflow-y-auto p-4 rounded-lg bg-gray-800 text-yellow-300 font-mono text-sm leading-relaxed border border-gray-700 shadow-inner whitespace-pre-wrap" > < / pre >
< / div >
< / div >
<!-- Modale confirmation suppression -->
< div id = "confirmDeleteModal" class = "hidden fixed inset-0 bg-black bg-opacity-60 backdrop-blur-sm flex items-center justify-center z-50" >
< div class = "bg-gray-900 p-6 rounded-2xl shadow-2xl w-full max-w-3xl md:max-w-4xl relative" >
< button type = "button" class = "absolute top-3 right-3 text-gray-400 hover:text-white text-xl font-bold" id = "confirmDeleteClose" aria-label = "Fermer" > × < / button >
< h3 class = "text-xl font-bold text-white mb-2" > Supprimer cet enregistrement ?< / h3 >
< p class = "text-gray-300 text-sm mb-6" > Vous êtes sur le point de supprimer < span id = "confirmItemName" class = "text-white font-semibold" > < / span > . Cette action est irréversible.< / p >
< div class = "flex justify-end gap-3" >
< button type = "button" id = "cancelDeleteBtn" class = "px-4 py-2 rounded-lg bg-gray-700 hover:bg-gray-600 text-white" > Annuler< / button >
< button type = "button" id = "confirmDeleteBtn" class = "px-4 py-2 rounded-lg bg-red-600 hover:bg-red-700 text-white font-semibold" > Supprimer< / button >
< / div >
< / div >
< / div >
2025-09-27 15:06:16 +02:00
<!-- Modal de confirmation de renvoi -->
< div id = "confirmResendModal" class = "hidden fixed inset-0 bg-black bg-opacity-60 backdrop-blur-sm flex items-center justify-center z-50" >
< div class = "bg-gray-900 p-6 rounded-2xl shadow-2xl w-full max-w-3xl md:max-w-4xl relative" >
< button type = "button" class = "absolute top-3 right-3 text-gray-400 hover:text-white text-xl font-bold" id = "confirmResendClose" aria-label = "Fermer" > × < / button >
< h3 class = "text-xl font-bold text-white mb-2" > Renvoyer cet enregistrement ?< / h3 >
< p class = "text-gray-300 text-sm mb-6" > Vous êtes sur le point de renvoyer < span id = "confirmResendItemName" class = "text-white font-semibold" > < / span > vers le site principal.< / p >
< div class = "flex justify-end gap-3" >
< button type = "button" id = "cancelResendBtn" class = "px-4 py-2 rounded-lg bg-gray-700 hover:bg-gray-600 text-white" > Annuler< / button >
< button type = "button" id = "confirmResendBtn" class = "px-4 py-2 rounded-lg bg-green-600 hover:bg-green-700 text-white font-semibold" > Renvoyer< / button >
< / div >
< / div >
< / div >
<!-- Modal d'édition en lot -->
< div id = "bulkEditModal" class = "hidden fixed inset-0 bg-black bg-opacity-60 backdrop-blur-sm flex items-center justify-center z-50" >
< div class = "bg-gray-900 p-6 rounded-2xl shadow-2xl w-full max-w-md relative" >
< button type = "button" class = "absolute top-4 right-4 text-gray-400 hover:text-white text-2xl font-bold" id = "bulkEditClose" > × < / button >
< h2 class = "text-2xl font-bold mb-6 text-center text-white" > ✏️ Éditer la sélection< / h2 >
< p class = "text-gray-300 text-sm mb-4" > Modifier le statut de < span id = "bulkEditCount" class = "text-white font-semibold" > 0< / span > élément(s) sélectionné(s).< / p >
< form id = "bulkEditForm" >
< label for = "bulkStatusSelect" class = "block mb-2 text-gray-300 font-medium" > Nouveau statut :< / label >
< select id = "bulkStatusSelect" name = "status"
class="w-full p-3 mb-6 rounded-lg border border-gray-700 bg-gray-800 text-white focus:ring-2 focus:ring-blue-500 focus:outline-none">
< option value = "0" class = "text-cyan-400" > EN ATTENTE< / option >
< option value = "1" class = "text-green-400" > ENVOI TERMINÉ< / option >
< option value = "2" class = "text-red-400" > ERREUR< / option >
< option value = "3" class = "text-pink-400" > DEJA DISPONIBLE< / option >
< option value = "4" class = "text-yellow-400" > EN COURS< / option >
< / select >
< button type = "submit" class = "w-full p-3 bg-gradient-to-r from-blue-600 to-blue-500 text-white font-semibold rounded-lg shadow hover:from-blue-500 hover:to-blue-400 transform hover:-translate-y-0.5 transition" > 💾 Mettre à jour la sélection< / button >
< / form >
< / div >
< / div >
<!-- Modal de confirmation de suppression en lot -->
< div id = "bulkDeleteModal" class = "hidden fixed inset-0 bg-black bg-opacity-60 backdrop-blur-sm flex items-center justify-center z-50" >
< div class = "bg-gray-900 p-6 rounded-2xl shadow-2xl w-full max-w-3xl md:max-w-4xl relative" >
< button type = "button" class = "absolute top-3 right-3 text-gray-400 hover:text-white text-xl font-bold" id = "bulkDeleteClose" aria-label = "Fermer" > × < / button >
< h3 class = "text-xl font-bold text-white mb-2" > Supprimer ces enregistrements ?< / h3 >
< p class = "text-gray-300 text-sm mb-4" > Vous êtes sur le point de supprimer < span id = "bulkDeleteCount" class = "text-white font-semibold" > 0< / span > élément(s) sélectionné(s).< / p >
< div id = "bulkDeleteList" class = "max-h-40 overflow-y-auto mb-6 p-3 bg-gray-800 rounded-lg border border-gray-700" >
<!-- Liste des éléments à supprimer -->
< / div >
< div class = "flex justify-end gap-3" >
< button type = "button" id = "cancelBulkDeleteBtn" class = "px-4 py-2 rounded-lg bg-gray-700 hover:bg-gray-600 text-white" > Annuler< / button >
< button type = "button" id = "confirmBulkDeleteBtn" class = "px-4 py-2 rounded-lg bg-red-600 hover:bg-red-700 text-white font-semibold" > Supprimer tout< / button >
< / div >
< / div >
< / div >
2025-08-14 19:27:48 +02:00
<!-- Toast -->
< div id = "toast" class = "hidden fixed bottom-6 left-1/2 -translate-x-1/2 px-4 py-2 rounded-lg bg-gray-900/95 text-white shadow-lg z-[60]" >
< span id = "toastMsg" > Supprimé.< / span >
< / div >
<!-- Bootstrap côté client (données initiales) -->
< script > window . _ _BOOTSTRAP _ _ = { { BOOTSTRAP _JSON } } ; < / script >
< script src = "autopost.js" defer > < / script >
< / body >
< / html >