Files
Lycostorrent/app/templates/admin.html
2026-03-23 20:59:26 +01:00

881 lines
45 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lycostorrent - Administration</title>
<!-- Chargement du thème (en premier pour éviter le flash) -->
<script src="/static/js/theme-loader.js"></script>
<!-- PWA Meta Tags -->
<meta name="theme-color" content="#e63946">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="Lycostorrent">
<!-- PWA Manifest -->
<link rel="manifest" href="/static/manifest.json">
<!-- Icons -->
<link rel="icon" type="image/png" sizes="192x192" href="/static/icons/icon-192x192.png">
<link rel="apple-touch-icon" href="/static/icons/icon-192x192.png">
<link rel="stylesheet" href="/static/css/style.css">
<link rel="stylesheet" href="/static/css/themes.css">
<link rel="stylesheet" href="/static/css/admin.css">
</head>
<body>
<div class="container">
<!-- Header -->
<header class="header">
<h1>⚙️ Administration</h1>
<p class="subtitle">Configuration de Lycostorrent</p>
<nav class="main-nav" id="mainNav">
<!-- Navigation générée dynamiquement -->
</nav>
</header>
<!-- Onglets -->
<div class="admin-tabs">
<button class="tab-btn active" data-tab="modules">
<span class="tab-icon">🧩</span>
<span class="tab-label">Modules</span>
</button>
<button class="tab-btn" data-tab="categories">
<span class="tab-icon">📂</span>
<span class="tab-label">Catégories</span>
</button>
<button class="tab-btn" data-tab="tags">
<span class="tab-icon">🏷️</span>
<span class="tab-label">Tags</span>
</button>
<button class="tab-btn" data-tab="filters">
<span class="tab-icon">🎛️</span>
<span class="tab-label">Filtres</span>
</button>
<button class="tab-btn" data-tab="rss">
<span class="tab-icon">📡</span>
<span class="tab-label">Flux RSS</span>
</button>
<button class="tab-btn" data-tab="cache">
<span class="tab-icon">🔄</span>
<span class="tab-label">Cache</span>
</button>
<button class="tab-btn" data-tab="torrent-client">
<span class="tab-icon">⬇️</span>
<span class="tab-label">Client Torrent</span>
</button>
<button class="tab-btn" data-tab="appearance">
<span class="tab-icon">🎨</span>
<span class="tab-label">Apparence</span>
</button>
</div>
<!-- Contenu des onglets -->
<div class="admin-content">
<!-- ═══════════════════════════════════════════════════════════
ONGLET MODULES
═══════════════════════════════════════════════════════════ -->
<div id="tab-modules" class="tab-content active">
<div class="tab-header">
<h2>🧩 Modules</h2>
<p>Activez ou désactivez les fonctionnalités de Lycostorrent.</p>
</div>
<div class="admin-card">
<h3>📱 Fonctionnalités disponibles</h3>
<p class="help-text">Cochez les modules que vous souhaitez activer. La navigation s'adaptera automatiquement.</p>
<div class="modules-list">
<div class="module-item">
<div class="module-toggle">
<input type="checkbox" id="module-search" checked>
<label for="module-search"></label>
</div>
<div class="module-info">
<div class="module-header">
<span class="module-icon">🔍</span>
<span class="module-name">Recherche</span>
</div>
<p class="module-description">Recherche de torrents sur vos trackers configurés (Jackett/Prowlarr).</p>
</div>
</div>
<div class="module-item">
<div class="module-toggle">
<input type="checkbox" id="module-latest" checked>
<label for="module-latest"></label>
</div>
<div class="module-info">
<div class="module-header">
<span class="module-icon">🎬</span>
<span class="module-name">Nouveautés</span>
</div>
<p class="module-description">Dernières sorties depuis vos trackers (Films, Séries, Anime, Musique).</p>
</div>
</div>
<div class="module-item">
<div class="module-toggle">
<input type="checkbox" id="module-discover">
<label for="module-discover"></label>
</div>
<div class="module-info">
<div class="module-header">
<span class="module-icon">🌟</span>
<span class="module-name">Découvrir</span>
<span class="module-badge">Nouveau</span>
</div>
<p class="module-description">Explorez les nouveautés cinéma et TV depuis TMDb, puis trouvez les torrents disponibles.</p>
</div>
</div>
</div>
<div class="action-bar">
<button id="saveModulesBtn" class="btn btn-primary">💾 Sauvegarder</button>
</div>
</div>
<!-- Configuration des trackers pour Discover -->
<div class="admin-card" id="discoverTrackersCard">
<h3>🌟 Trackers pour Découvrir</h3>
<p class="help-text">Sélectionnez les trackers à utiliser pour la recherche de torrents dans la page Découvrir.</p>
<div class="discover-trackers-list" id="discoverTrackersList">
<p class="loading">Chargement des trackers...</p>
</div>
<div class="action-bar">
<button id="selectAllDiscoverTrackers" class="btn btn-secondary">✅ Tout sélectionner</button>
<button id="selectNoneDiscoverTrackers" class="btn btn-secondary">❌ Tout désélectionner</button>
<button id="saveDiscoverTrackers" class="btn btn-primary">💾 Sauvegarder</button>
</div>
</div>
<div class="admin-card">
<h3> À propos des modules</h3>
<div class="module-help">
<p><strong>🔍 Recherche</strong> : Page d'accueil par défaut. Permet de rechercher des torrents par mots-clés sur tous vos trackers.</p>
<p><strong>🎬 Nouveautés</strong> : Affiche les derniers torrents publiés sur vos trackers, enrichis avec les métadonnées TMDb/Last.fm.</p>
<p><strong>🌟 Découvrir</strong> : Inverse la logique - part des nouveautés TMDb (films/séries récents) et recherche les torrents disponibles.</p>
</div>
</div>
</div>
<!-- ═══════════════════════════════════════════════════════════
ONGLET CATÉGORIES
═══════════════════════════════════════════════════════════ -->
<div id="tab-categories" class="tab-content">
<div class="tab-header">
<h2>📂 Configuration des Catégories</h2>
<p>Associez les catégories Jackett/Prowlarr à chaque type de contenu pour chaque tracker.</p>
</div>
<!-- Sélection du tracker -->
<div class="admin-card">
<h3>1. Sélectionner un tracker</h3>
<div id="trackerSelector" class="tracker-grid">
<p class="loading">Chargement des trackers...</p>
</div>
</div>
<!-- Catégories disponibles -->
<div id="categoriesSection" class="admin-card hidden">
<h3>2. Catégories disponibles sur <span id="selectedTrackerName" class="highlight"></span></h3>
<div id="availableCategories" class="categories-cloud">
<p class="loading">Chargement...</p>
</div>
</div>
<!-- Configuration -->
<div id="configSection" class="admin-card hidden">
<h3>3. Associer les catégories</h3>
<p class="help-text">Cliquez sur une catégorie ci-dessus pour l'ajouter, ou entrez les IDs manuellement.</p>
<div class="config-grid">
<div class="config-item">
<label>🎥 Films</label>
<input type="text" id="config-movies" placeholder="Ex: 2000,2010">
<div class="quick-add" data-target="movies"></div>
</div>
<div class="config-item">
<label>📺 Séries</label>
<input type="text" id="config-tv" placeholder="Ex: 5000,5010">
<div class="quick-add" data-target="tv"></div>
</div>
<div class="config-item">
<label>🎌 Anime</label>
<input type="text" id="config-anime" placeholder="Ex: 5070">
<div class="quick-add" data-target="anime"></div>
</div>
<div class="config-item">
<label>🎵 Musique</label>
<input type="text" id="config-music" placeholder="Ex: 3000">
<div class="quick-add" data-target="music"></div>
</div>
</div>
<div class="action-bar">
<button id="saveConfigBtn" class="btn btn-primary">💾 Sauvegarder</button>
<button id="resetConfigBtn" class="btn btn-secondary">🔄 Réinitialiser</button>
</div>
</div>
<!-- Résumé -->
<div class="admin-card">
<h3>📋 Configuration actuelle</h3>
<div id="configSummary" class="config-summary">
<p class="loading">Chargement...</p>
</div>
</div>
</div>
<!-- ═══════════════════════════════════════════════════════════
ONGLET TAGS
═══════════════════════════════════════════════════════════ -->
<div id="tab-tags" class="tab-content">
<div class="tab-header">
<h2>🏷️ Tags de Parsing</h2>
<p>Ces tags sont utilisés pour nettoyer les titres avant la recherche TMDb/Last.fm.</p>
</div>
<!-- Tags actuels -->
<div class="admin-card">
<h3>Tags de coupure</h3>
<p class="help-text">Le titre sera coupé au premier tag rencontré. Ex: <code>Avatar.2009.MULTi.1080p</code><code>Avatar 2009</code></p>
<div id="tagsList" class="tags-cloud editable">
<p class="loading">Chargement...</p>
</div>
<div class="add-form">
<input type="text" id="newTagInput" placeholder="Nouveau tag..." maxlength="30">
<button id="addTagBtn" class="btn btn-primary"> Ajouter</button>
</div>
<div class="action-bar">
<button id="saveTagsBtn" class="btn btn-primary">💾 Sauvegarder</button>
<button id="resetTagsBtn" class="btn btn-secondary">🔄 Réinitialiser</button>
</div>
</div>
<!-- Présets -->
<div class="admin-card">
<h3>📦 Ajouter des présets</h3>
<div class="presets-grid">
<button class="preset-btn" data-preset="langues">
🗣️ Langues
<small>VFF, VFQ, VOSTFR...</small>
</button>
<button class="preset-btn" data-preset="resolutions">
📺 Résolutions
<small>1080p, 720p, 4K...</small>
</button>
<button class="preset-btn" data-preset="sources">
📀 Sources
<small>BluRay, WEB, HDTV...</small>
</button>
<button class="preset-btn" data-preset="codecs">
🎬 Codecs
<small>x264, x265, HEVC...</small>
</button>
<button class="preset-btn" data-preset="audio">
🔊 Audio
<small>DTS, AC3, FLAC...</small>
</button>
</div>
</div>
<!-- Test -->
<div class="admin-card">
<h3>🧪 Tester le parsing</h3>
<div class="test-form">
<input type="text" id="testTitleInput" placeholder="Ex: Avatar.2009.MULTi.1080p.BluRay.x264">
<button id="testParsingBtn" class="btn btn-primary">Tester</button>
</div>
<div id="testResult" class="test-result hidden">
<div class="result-row">
<span class="label">Original:</span>
<span id="testOriginal" class="value"></span>
</div>
<div class="result-row success">
<span class="label">Nettoyé:</span>
<span id="testCleaned" class="value"></span>
</div>
</div>
</div>
</div>
<!-- ═══════════════════════════════════════════════════════════
ONGLET FILTRES
═══════════════════════════════════════════════════════════ -->
<div id="tab-filters" class="tab-content">
<div class="tab-header">
<h2>🎛️ Filtres de Recherche</h2>
<p>Configurez les mots-clés détectés dans les titres de torrents pour créer les filtres.</p>
</div>
<!-- Liste des filtres -->
<div class="admin-card">
<h3>Filtres configurés</h3>
<p class="help-text">Cliquez sur un filtre pour modifier ses valeurs. Les valeurs sont détectées dans les titres de torrents.</p>
<div id="filtersList" class="filters-editor">
<p class="loading">Chargement...</p>
</div>
<div class="action-bar">
<button id="saveFiltersBtn" class="btn btn-primary">💾 Sauvegarder</button>
<button id="resetFiltersBtn" class="btn btn-secondary">🔄 Réinitialiser</button>
<button id="addFilterBtn" class="btn btn-secondary"> Nouveau filtre</button>
</div>
</div>
<!-- Test -->
<div class="admin-card">
<h3>🧪 Tester la détection</h3>
<p class="help-text">Entrez un titre de torrent pour voir les filtres détectés.</p>
<div class="test-form">
<input type="text" id="testFilterInput" placeholder="Ex: Gojira.-.Fortitude.2021.FLAC.24bit.WEB.Album">
<button id="testFilterBtn" class="btn btn-primary">Tester</button>
</div>
<div id="filterTestResult" class="test-result hidden"></div>
</div>
<!-- Aide -->
<div class="admin-card collapsible collapsed">
<h3 class="collapsible-header">
❓ Aide - Comment ça marche
<span class="collapse-icon"></span>
</h3>
<div class="collapsible-content">
<div class="help-section">
<h4>Principe</h4>
<p>Le parser analyse les titres de torrents et cherche les mots-clés configurés. Chaque mot trouvé crée une option de filtre.</p>
<h4>Exemple</h4>
<p><code>Gojira.-.Fortitude.2021.FLAC.24bit.WEB.Album</code></p>
<p>→ Format Audio: <strong>FLAC, 24bit</strong> | Type: <strong>Album</strong> | Source: <strong>WEB</strong></p>
<h4>Conseils</h4>
<ul>
<li>Les mots-clés sont insensibles à la casse (FLAC = flac = Flac)</li>
<li>Évitez les mots trop courts ou trop communs</li>
<li>Testez vos modifications avant de sauvegarder</li>
</ul>
</div>
</div>
</div>
</div>
<!-- ═══════════════════════════════════════════════════════════
ONGLET RSS
═══════════════════════════════════════════════════════════ -->
<div id="tab-rss" class="tab-content">
<div class="tab-header">
<h2>📡 Flux RSS</h2>
<p>Ajoutez des flux RSS pour les trackers non disponibles dans Jackett/Prowlarr.</p>
</div>
<!-- Formulaire d'ajout -->
<div class="admin-card">
<h3> Ajouter un flux</h3>
<form id="add-feed-form" class="rss-form">
<div class="form-row">
<div class="form-group">
<label for="feed-name">Nom *</label>
<input type="text" id="feed-name" placeholder="Ex: YGG Films" required>
</div>
<div class="form-group">
<label for="feed-category">Catégorie *</label>
<select id="feed-category" required>
<option value="">-- Choisir --</option>
<option value="movies">🎬 Films</option>
<option value="tv">📺 Séries</option>
<option value="anime">🎌 Anime</option>
<option value="music">🎵 Musique</option>
<option value="all">📦 Toutes</option>
</select>
</div>
</div>
<div class="form-group">
<label for="feed-url">URL du flux RSS *</label>
<input type="url" id="feed-url" placeholder="https://tracker.xxx/rss?passkey={passkey}" required>
<small>Utilisez <code>{passkey}</code> comme placeholder</small>
</div>
<div class="form-group">
<label for="feed-passkey">Passkey</label>
<input type="text" id="feed-passkey" placeholder="Votre passkey privé">
</div>
<div class="form-row">
<div class="form-group checkbox-inline">
<label>
<input type="checkbox" id="feed-flaresolverr">
<span>🛡️ Flaresolverr</span>
</label>
<small>Anti-Cloudflare</small>
</div>
</div>
<div class="form-group">
<label for="feed-cookies">Cookies de session</label>
<textarea id="feed-cookies" rows="2" placeholder="ygg_=abc123; cf_clearance=xyz789"></textarea>
<small>Récupérez-les depuis DevTools (F12) → Application → Cookies</small>
</div>
<div class="action-bar">
<button type="button" id="test-feed-btn" class="btn btn-secondary">🧪 Tester</button>
<button type="submit" class="btn btn-primary"> Ajouter</button>
</div>
</form>
<div id="test-result" class="test-result hidden"></div>
</div>
<!-- Liste des flux -->
<div class="admin-card">
<h3>📋 Flux configurés</h3>
<div id="feeds-list" class="feeds-list">
<p class="loading">Chargement...</p>
</div>
</div>
<!-- Aide -->
<div class="admin-card collapsible">
<h3 class="collapsible-header">
❓ Aide - Comment configurer un flux RSS
<span class="collapse-icon"></span>
</h3>
<div class="collapsible-content">
<div class="help-section">
<h4>YGGTorrent</h4>
<ol>
<li>Connectez-vous à YGG</li>
<li>Profil → "Mon RSS"</li>
<li>Copiez l'URL avec votre passkey</li>
</ol>
<h4>Catégories YGG</h4>
<div class="help-table">
<span class="help-row"><code>id=2145</code> Films</span>
<span class="help-row"><code>id=2184</code> Séries</span>
<span class="help-row"><code>id=2179</code> Anime</span>
<span class="help-row"><code>id=2139</code> Musique</span>
</div>
</div>
</div>
</div>
</div>
<!-- ═══════════════════════════════════════════════════════════
ONGLET CACHE
═══════════════════════════════════════════════════════════ -->
<div id="tab-cache" class="tab-content">
<div class="tab-header">
<h2>🔄 Cache des données</h2>
<p>Pré-chargez les données Latest et Discover pour un affichage instantané.</p>
</div>
<!-- Statut du cache -->
<div class="admin-card">
<h3>📊 Statut du cache</h3>
<div id="cacheStatus" class="cache-status">
<div class="status-row">
<span class="status-label">État :</span>
<span id="cacheStatusBadge" class="status-badge">Chargement...</span>
</div>
<div class="status-row">
<span class="status-label">Dernier refresh :</span>
<span id="cacheLastRefresh">-</span>
</div>
<div class="status-row">
<span class="status-label">Prochain refresh :</span>
<span id="cacheNextRefresh">-</span>
</div>
<div class="status-row">
<span class="status-label">Taille du cache :</span>
<span id="cacheSizeDisplay">-</span>
</div>
</div>
<div class="action-bar" style="margin-top: 15px;">
<button id="refreshCacheBtn" class="btn btn-primary">🔄 Forcer le refresh maintenant</button>
<button id="clearCacheBtn" class="btn btn-secondary">🗑️ Vider le cache</button>
</div>
</div>
<!-- Configuration -->
<div class="admin-card">
<h3>⚙️ Configuration</h3>
<div class="form-row">
<div class="form-group">
<label for="cacheEnabled">
<input type="checkbox" id="cacheEnabled">
Activer le cache automatique
</label>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="cacheInterval">Intervalle de refresh</label>
<select id="cacheInterval">
<option value="15">15 minutes</option>
<option value="30">30 minutes</option>
<option value="60" selected>1 heure</option>
<option value="120">2 heures</option>
<option value="240">4 heures</option>
<option value="360">6 heures</option>
</select>
</div>
</div>
</div>
<!-- Configuration Latest -->
<div class="admin-card">
<h3>📥 Cache Latest (Nouveautés)</h3>
<div class="form-row">
<div class="form-group">
<label for="cacheLatestEnabled">
<input type="checkbox" id="cacheLatestEnabled" checked>
Activer le cache Latest
</label>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label>Catégories à cacher :</label>
<div class="checkbox-group">
<label><input type="checkbox" id="cacheLatestMovies" checked> 🎥 Films</label>
<label><input type="checkbox" id="cacheLatestTv" checked> 📺 Séries</label>
<label><input type="checkbox" id="cacheLatestAnime"> 🎌 Anime</label>
<label><input type="checkbox" id="cacheLatestMusic"> 🎵 Musique</label>
</div>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="cacheLatestLimit">Nombre de résultats par catégorie</label>
<select id="cacheLatestLimit">
<option value="30">30</option>
<option value="50" selected>50</option>
<option value="100">100</option>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label>Trackers à utiliser :</label>
<p class="help-text">Laissez vide pour utiliser tous les trackers actifs</p>
<div id="cacheTrackersList" class="checkbox-group trackers-checkboxes">
<!-- Rempli dynamiquement -->
</div>
</div>
</div>
</div>
<!-- Configuration Discover -->
<div class="admin-card">
<h3>🎬 Cache Discover</h3>
<div class="form-row">
<div class="form-group">
<label for="cacheDiscoverEnabled">
<input type="checkbox" id="cacheDiscoverEnabled" checked>
Activer le cache Discover
</label>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="cacheDiscoverLimit">Nombre de films/séries à cacher</label>
<select id="cacheDiscoverLimit">
<option value="20">20</option>
<option value="30" selected>30</option>
<option value="50">50</option>
</select>
</div>
</div>
</div>
<!-- Sauvegarder -->
<div class="admin-card">
<div class="action-bar">
<button id="saveCacheConfigBtn" class="btn btn-primary">💾 Sauvegarder la configuration</button>
</div>
</div>
</div>
<!-- ═══════════════════════════════════════════════════════════
ONGLET CLIENT TORRENT
═══════════════════════════════════════════════════════════ -->
<div id="tab-torrent-client" class="tab-content">
<div class="tab-header">
<h2>⬇️ Client Torrent</h2>
<p>Configurez votre client torrent pour envoyer directement les téléchargements.</p>
</div>
<!-- Statut -->
<div class="admin-card">
<h3>📊 Statut</h3>
<div id="torrentClientStatus" class="client-status">
<span class="status-loading">Chargement...</span>
</div>
</div>
<!-- Configuration -->
<div class="admin-card">
<h3>⚙️ Configuration</h3>
<div class="form-row">
<div class="form-group">
<label for="tcEnabled">
<input type="checkbox" id="tcEnabled">
Activer le client torrent
</label>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="tcPlugin">Client</label>
<select id="tcPlugin">
<option value="">-- Sélectionner --</option>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="tcHost">Hôte</label>
<input type="text" id="tcHost" placeholder="geco.useed.me ou 192.168.1.x">
<small class="form-help">Domaine ou IP (sans http://)</small>
</div>
<div class="form-group">
<label for="tcPort">Port</label>
<input type="number" id="tcPort" placeholder="8080 ou vide">
<small class="form-help">Laisser vide si port par défaut</small>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="tcPath">Chemin (optionnel)</label>
<input type="text" id="tcPath" placeholder="/qbittorrent">
<small class="form-help">Si derrière un reverse proxy</small>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="tcUsername">Utilisateur</label>
<input type="text" id="tcUsername" placeholder="admin">
</div>
<div class="form-group">
<label for="tcPassword">Mot de passe</label>
<input type="password" id="tcPassword" placeholder="••••••••">
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="tcSSL">
<input type="checkbox" id="tcSSL">
Utiliser SSL (HTTPS)
</label>
</div>
</div>
<div class="action-bar">
<button id="testTorrentClientBtn" class="btn btn-secondary">🔌 Tester la connexion</button>
<button id="saveTorrentClientBtn" class="btn btn-primary">💾 Sauvegarder</button>
</div>
<div id="tcTestResult" class="test-result hidden"></div>
</div>
<!-- Catégories personnalisées -->
<div class="admin-card">
<h3>📁 Catégories & Dossiers</h3>
<p class="help-text">Définissez vos catégories avec leur dossier de destination par défaut.</p>
<div id="customCategoriesList" class="custom-categories-list">
<!-- Rempli dynamiquement -->
</div>
<div class="add-category-form">
<div class="form-row">
<div class="form-group">
<label for="newCategoryName">Nom de la catégorie</label>
<input type="text" id="newCategoryName" placeholder="Films, Séries, Musique...">
</div>
<div class="form-group">
<label for="newCategoryPath">Chemin de destination</label>
<input type="text" id="newCategoryPath" placeholder="/downloads/films">
</div>
<div class="form-group form-group-btn">
<button id="addCategoryBtn" class="btn btn-success"> Ajouter</button>
</div>
</div>
</div>
<div class="action-bar">
<button id="syncCategoriesBtn" class="btn btn-secondary">🔄 Synchroniser avec le client</button>
<button id="saveCategoriesBtn" class="btn btn-primary">💾 Sauvegarder</button>
</div>
</div>
<!-- Plugins disponibles -->
<div class="admin-card collapsible collapsed">
<h3 class="collapsible-header">
🔌 Plugins disponibles
<span class="collapse-icon"></span>
</h3>
<div class="collapsible-content">
<div id="pluginsList" class="plugins-list">
<p class="loading">Chargement...</p>
</div>
<p class="help-text">
Pour ajouter un nouveau client, créez un plugin dans <code>plugins/torrent_clients/</code>
</p>
</div>
</div>
</div>
<!-- ═══════════════════════════════════════════════════════════
ONGLET APPARENCE
═══════════════════════════════════════════════════════════ -->
<div id="tab-appearance" class="tab-content">
<div class="tab-header">
<h2>🎨 Apparence</h2>
<p>Personnalisez l'apparence de Lycostorrent.</p>
</div>
<!-- Sélection du thème -->
<div class="admin-card">
<h3>🎭 Thème</h3>
<p class="help-text">Choisissez un thème pour l'interface.</p>
<div class="theme-grid">
<div class="theme-card" data-theme="dark">
<div class="theme-preview theme-preview-dark">
<div class="preview-header"></div>
<div class="preview-content">
<div class="preview-card"></div>
<div class="preview-card"></div>
</div>
</div>
<span class="theme-name">🌙 Sombre</span>
</div>
<div class="theme-card" data-theme="light">
<div class="theme-preview theme-preview-light">
<div class="preview-header"></div>
<div class="preview-content">
<div class="preview-card"></div>
<div class="preview-card"></div>
</div>
</div>
<span class="theme-name">☀️ Clair</span>
</div>
<div class="theme-card" data-theme="ocean">
<div class="theme-preview theme-preview-ocean">
<div class="preview-header"></div>
<div class="preview-content">
<div class="preview-card"></div>
<div class="preview-card"></div>
</div>
</div>
<span class="theme-name">🌊 Océan</span>
</div>
<div class="theme-card" data-theme="purple">
<div class="theme-preview theme-preview-purple">
<div class="preview-header"></div>
<div class="preview-content">
<div class="preview-card"></div>
<div class="preview-card"></div>
</div>
</div>
<span class="theme-name">💜 Violet</span>
</div>
<div class="theme-card" data-theme="nature">
<div class="theme-preview theme-preview-nature">
<div class="preview-header"></div>
<div class="preview-content">
<div class="preview-card"></div>
<div class="preview-card"></div>
</div>
</div>
<span class="theme-name">🌿 Nature</span>
</div>
<div class="theme-card" data-theme="sunset">
<div class="theme-preview theme-preview-sunset">
<div class="preview-header"></div>
<div class="preview-content">
<div class="preview-card"></div>
<div class="preview-card"></div>
</div>
</div>
<span class="theme-name">🌅 Sunset</span>
</div>
<div class="theme-card" data-theme="cyberpunk">
<div class="theme-preview theme-preview-cyberpunk">
<div class="preview-header"></div>
<div class="preview-content">
<div class="preview-card"></div>
<div class="preview-card"></div>
</div>
</div>
<span class="theme-name">🤖 Cyberpunk</span>
</div>
<div class="theme-card" data-theme="nord">
<div class="theme-preview theme-preview-nord">
<div class="preview-header"></div>
<div class="preview-content">
<div class="preview-card"></div>
<div class="preview-card"></div>
</div>
</div>
<span class="theme-name">❄️ Nord</span>
</div>
</div>
</div>
</div>
</div>
<!-- Message toast -->
<div id="toast" class="toast hidden"></div>
<!-- Footer -->
<footer class="app-footer">
<span>Lycostorrent v<span id="app-version">1.0.0</span></span>
</footer>
</div>
<script src="/static/js/admin.js"></script>
<script src="/static/js/nav.js"></script>
<script>
fetch('/api/version').then(r => r.json()).then(data => {
if (data.version) document.getElementById('app-version').textContent = data.version;
}).catch(() => {});
</script>
</body>
</html>