517 lines
25 KiB
PHP
Executable File
517 lines
25 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* WEVAL - Index Centralisé des Pages Standalone
|
|
* Auto-mise à jour: Scanne automatiquement les fichiers
|
|
*/
|
|
|
|
// Configuration des catégories (patterns de détection)
|
|
$categories = [
|
|
'monitoring' => [
|
|
'name' => 'Administration & Monitoring',
|
|
'icon' => 'fa-tachometer-alt',
|
|
'color' => '#22d3ee',
|
|
'patterns' => ['system-', 'monitoring', 'security', 'session', 'console', 'whitelist', 'api-security', 'quick-access', 'audit']
|
|
],
|
|
'huawei' => [
|
|
'name' => 'Huawei Cloud',
|
|
'icon' => 'fa-cloud',
|
|
'color' => '#ef4444',
|
|
'patterns' => ['huawei-']
|
|
],
|
|
'office' => [
|
|
'name' => 'Office 365 / Microsoft',
|
|
'icon' => 'fa-microsoft',
|
|
'color' => '#0078d4',
|
|
'patterns' => ['office-', 'microsoft-', 'azure-']
|
|
],
|
|
'cloudflare' => [
|
|
'name' => 'Cloudflare & DNS',
|
|
'icon' => 'fa-shield-alt',
|
|
'color' => '#f59e0b',
|
|
'patterns' => ['cloudflare-', 'domain', 'freedns', 'dkim', 'ptr', 'dns-']
|
|
],
|
|
'tracking' => [
|
|
'name' => 'Tracking & Analytics',
|
|
'icon' => 'fa-chart-line',
|
|
'color' => '#10b981',
|
|
'patterns' => ['tracking-', 'stats-', 'analytics-']
|
|
],
|
|
'email' => [
|
|
'name' => 'Email & Delivery',
|
|
'icon' => 'fa-envelope',
|
|
'color' => '#8b5cf6',
|
|
'patterns' => ['email-', 'smtp-', 'deliverability', 'bounce-', 'warmup-', 'pmta-']
|
|
],
|
|
'database' => [
|
|
'name' => 'Base de Données',
|
|
'icon' => 'fa-database',
|
|
'color' => '#06b6d4',
|
|
'patterns' => ['adminer', 'database-', 'db-', 'test-bd', 'sql-', 'postgres-']
|
|
],
|
|
'chatbot' => [
|
|
'name' => 'Chatbot & AI',
|
|
'icon' => 'fa-robot',
|
|
'color' => '#ec4899',
|
|
'patterns' => ['chatbot-', 'ai-', 'ollama-', 'gpt-']
|
|
],
|
|
'tools' => [
|
|
'name' => 'Outils & Utilitaires',
|
|
'icon' => 'fa-tools',
|
|
'color' => '#64748b',
|
|
'patterns' => ['tool-', 'util-', 'helper-', 'check', 's3_', 'upload', 'import', 'export']
|
|
],
|
|
'docs' => [
|
|
'name' => 'Documentation',
|
|
'icon' => 'fa-book',
|
|
'color' => '#a855f7',
|
|
'patterns' => ['doc', 'architecture', 'help-', 'guide-', 'readme']
|
|
],
|
|
'auth' => [
|
|
'name' => 'Authentification',
|
|
'icon' => 'fa-lock',
|
|
'color' => '#eab308',
|
|
'patterns' => ['login', 'auth-', 'logout', 'password', 'register']
|
|
],
|
|
'test' => [
|
|
'name' => 'Tests & Debug',
|
|
'icon' => 'fa-flask',
|
|
'color' => '#f97316',
|
|
'patterns' => ['test', 'debug', 'phpinfo', 'error_', 'check-']
|
|
],
|
|
];
|
|
|
|
// Fichiers à exclure
|
|
$excludeFiles = [
|
|
'index.php',
|
|
'standalone-index.php',
|
|
'.htaccess',
|
|
'click.php', // 404
|
|
'lead.php', // 404
|
|
'open.php', // endpoint tracking
|
|
'unsub.php', // endpoint tracking
|
|
];
|
|
|
|
// Fichiers endpoints (tracking) - à afficher séparément
|
|
$endpointFiles = ['open.php', 'unsub.php', 'click.php', 'lead.php', 'pixel.php', 'redirect.php'];
|
|
|
|
// Scanner le répertoire
|
|
function scanPublicFiles($dir, $excludeFiles) {
|
|
$files = [];
|
|
$items = scandir($dir);
|
|
|
|
foreach ($items as $item) {
|
|
if ($item[0] === '.') continue;
|
|
|
|
$path = $dir . '/' . $item;
|
|
if (is_file($path)) {
|
|
$ext = pathinfo($item, PATHINFO_EXTENSION);
|
|
if (in_array($ext, ['php', 'html']) && !in_array($item, $excludeFiles)) {
|
|
$files[] = [
|
|
'name' => $item,
|
|
'path' => $path,
|
|
'ext' => $ext,
|
|
'size' => filesize($path),
|
|
'modified' => filemtime($path),
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
return $files;
|
|
}
|
|
|
|
// Catégoriser un fichier
|
|
function categorizeFile($filename, $categories) {
|
|
$filename_lower = strtolower($filename);
|
|
|
|
foreach ($categories as $key => $cat) {
|
|
foreach ($cat['patterns'] as $pattern) {
|
|
if (strpos($filename_lower, strtolower($pattern)) !== false) {
|
|
return $key;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 'other';
|
|
}
|
|
|
|
// Vérifier l'accessibilité
|
|
function checkFileAccessibility($filename) {
|
|
$url = "http://127.0.0.1:5821/" . $filename;
|
|
$ch = curl_init($url);
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_NOBODY => true,
|
|
CURLOPT_TIMEOUT => 2,
|
|
CURLOPT_FOLLOWLOCATION => false,
|
|
]);
|
|
curl_exec($ch);
|
|
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
curl_close($ch);
|
|
return $code;
|
|
}
|
|
|
|
// Générer une description basée sur le nom
|
|
function generateDescription($filename) {
|
|
$name = pathinfo($filename, PATHINFO_FILENAME);
|
|
$name = str_replace(['-', '_'], ' ', $name);
|
|
$name = ucwords($name);
|
|
return $name;
|
|
}
|
|
|
|
// Scanner les fichiers
|
|
$publicDir = __DIR__;
|
|
$allFiles = scanPublicFiles($publicDir, $excludeFiles);
|
|
|
|
// Organiser par catégorie
|
|
$categorizedFiles = [];
|
|
foreach ($categories as $key => $cat) {
|
|
$categorizedFiles[$key] = [];
|
|
}
|
|
$categorizedFiles['other'] = [];
|
|
|
|
foreach ($allFiles as $file) {
|
|
$category = categorizeFile($file['name'], $categories);
|
|
$file['description'] = generateDescription($file['name']);
|
|
$categorizedFiles[$category][] = $file;
|
|
}
|
|
|
|
// Trier chaque catégorie
|
|
foreach ($categorizedFiles as &$files) {
|
|
usort($files, function($a, $b) {
|
|
return strcmp($a['name'], $b['name']);
|
|
});
|
|
}
|
|
|
|
// Statistiques
|
|
$totalFiles = count($allFiles);
|
|
$lastUpdate = date('d/m/Y H:i:s');
|
|
$serverIp = '89.167.40.150';
|
|
$port = '5821';
|
|
|
|
// AJAX pour vérification status
|
|
if (isset($_GET['check']) && isset($_GET['file'])) {
|
|
header('Content-Type: application/json');
|
|
$code = checkFileAccessibility($_GET['file']);
|
|
echo json_encode(['code' => $code, 'status' => ($code == 200 || $code == 302) ? 'ok' : 'error']);
|
|
exit;
|
|
}
|
|
|
|
// Recherche
|
|
$searchQuery = $_GET['q'] ?? '';
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>WEVAL - Index des Pages</title>
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
|
<style>
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
body { font-family: 'Segoe UI', sans-serif; background: linear-gradient(135deg, #0f172a, #1e293b); min-height: 100vh; color: #e2e8f0; }
|
|
|
|
.header { background: linear-gradient(135deg, #0891b2, #0e7490); padding: 20px 30px; position: sticky; top: 0; z-index: 100; }
|
|
.header-content { max-width: 1600px; margin: 0 auto; display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 15px; }
|
|
.header h1 { font-size: 24px; display: flex; align-items: center; gap: 12px; }
|
|
.header-stats { display: flex; gap: 20px; align-items: center; }
|
|
.stat-pill { background: rgba(255,255,255,0.15); padding: 8px 16px; border-radius: 20px; font-size: 13px; display: flex; align-items: center; gap: 8px; }
|
|
.stat-pill i { color: #22d3ee; }
|
|
|
|
.search-box { display: flex; gap: 10px; }
|
|
.search-box input { padding: 10px 15px; border-radius: 8px; border: none; background: rgba(255,255,255,0.1); color: #fff; width: 250px; font-size: 14px; }
|
|
.search-box input::placeholder { color: rgba(255,255,255,0.5); }
|
|
.search-box input:focus { outline: none; background: rgba(255,255,255,0.2); }
|
|
|
|
.btn { padding: 10px 18px; border: none; border-radius: 8px; cursor: pointer; font-size: 13px; font-weight: 600; text-decoration: none; display: inline-flex; align-items: center; gap: 8px; transition: all 0.2s; }
|
|
.btn-primary { background: rgba(255,255,255,0.15); color: #fff; }
|
|
.btn-primary:hover { background: rgba(255,255,255,0.25); }
|
|
|
|
.container { max-width: 1600px; margin: 0 auto; padding: 25px; }
|
|
|
|
.quick-links { display: flex; gap: 10px; margin-bottom: 25px; flex-wrap: wrap; }
|
|
.quick-link { padding: 8px 16px; background: linear-gradient(135deg, #1e293b, #334155); border-radius: 8px; color: #94a3b8; text-decoration: none; font-size: 12px; border: 1px solid rgba(255,255,255,0.1); transition: all 0.2s; display: flex; align-items: center; gap: 6px; }
|
|
.quick-link:hover { border-color: #22d3ee; color: #22d3ee; }
|
|
.quick-link i { font-size: 14px; }
|
|
|
|
.category { margin-bottom: 25px; }
|
|
.category-header { display: flex; align-items: center; gap: 12px; padding: 15px 20px; background: linear-gradient(135deg, #1e293b, #334155); border-radius: 12px 12px 0 0; border: 1px solid rgba(255,255,255,0.1); border-bottom: none; cursor: pointer; }
|
|
.category-header:hover { background: linear-gradient(135deg, #334155, #475569); }
|
|
.category-icon { width: 40px; height: 40px; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 18px; }
|
|
.category-title { font-size: 16px; font-weight: 600; flex: 1; }
|
|
.category-count { background: rgba(255,255,255,0.1); padding: 4px 12px; border-radius: 12px; font-size: 12px; color: #94a3b8; }
|
|
.category-toggle { color: #64748b; transition: transform 0.3s; }
|
|
.category-toggle.collapsed { transform: rotate(-90deg); }
|
|
|
|
.category-content { background: rgba(15, 23, 42, 0.5); border: 1px solid rgba(255,255,255,0.1); border-top: none; border-radius: 0 0 12px 12px; overflow: hidden; }
|
|
.category-content.hidden { display: none; }
|
|
|
|
.file-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 1px; background: rgba(255,255,255,0.05); }
|
|
|
|
.file-item { background: #1e293b; padding: 15px; display: flex; align-items: center; gap: 12px; transition: all 0.2s; }
|
|
.file-item:hover { background: #334155; }
|
|
.file-icon { width: 36px; height: 36px; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 14px; flex-shrink: 0; }
|
|
.file-icon.php { background: linear-gradient(135deg, #8b5cf6, #7c3aed); }
|
|
.file-icon.html { background: linear-gradient(135deg, #f59e0b, #d97706); }
|
|
|
|
.file-info { flex: 1; min-width: 0; }
|
|
.file-name { font-size: 13px; font-weight: 600; color: #f8fafc; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
.file-desc { font-size: 11px; color: #64748b; margin-top: 2px; }
|
|
.file-meta { font-size: 10px; color: #475569; margin-top: 4px; display: flex; gap: 10px; }
|
|
|
|
.file-actions { display: flex; gap: 6px; }
|
|
.file-btn { width: 32px; height: 32px; border-radius: 6px; border: none; cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 12px; transition: all 0.2s; }
|
|
.file-btn-open { background: #10b981; color: #fff; }
|
|
.file-btn-open:hover { background: #059669; }
|
|
.file-btn-copy { background: #3b82f6; color: #fff; }
|
|
.file-btn-copy:hover { background: #2563eb; }
|
|
.file-btn-new { background: #8b5cf6; color: #fff; }
|
|
.file-btn-new:hover { background: #7c3aed; }
|
|
|
|
.status-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
|
|
.status-ok { background: #10b981; }
|
|
.status-error { background: #ef4444; }
|
|
.status-checking { background: #f59e0b; animation: pulse 1s infinite; }
|
|
|
|
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
|
|
|
|
.empty-category { padding: 30px; text-align: center; color: #64748b; font-size: 13px; }
|
|
|
|
.footer { text-align: center; padding: 30px; color: #64748b; font-size: 12px; }
|
|
|
|
.toast { position: fixed; bottom: 20px; right: 20px; background: #10b981; color: #fff; padding: 12px 20px; border-radius: 8px; font-size: 13px; display: none; z-index: 1000; }
|
|
.toast.show { display: block; animation: slideIn 0.3s ease; }
|
|
@keyframes slideIn { from { transform: translateX(100px); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
|
|
|
|
.new-badge { background: #ef4444; color: #fff; font-size: 9px; padding: 2px 6px; border-radius: 4px; margin-left: 8px; animation: pulse 2s infinite; }
|
|
|
|
@media (max-width: 768px) {
|
|
.header-content { flex-direction: column; text-align: center; }
|
|
.file-grid { grid-template-columns: 1fr; }
|
|
.search-box input { width: 100%; }
|
|
}
|
|
</style>
|
|
|
|
</head>
|
|
<body>
|
|
<div class="header">
|
|
<div class="header-content">
|
|
<h1><i class="fas fa-th-large"></i> WEVAL - Index des Pages</h1>
|
|
<div class="header-stats">
|
|
<div class="stat-pill"><i class="fas fa-file-code"></i> <?= $totalFiles ?> fichiers</div>
|
|
<div class="stat-pill"><i class="fas fa-clock"></i> <?= $lastUpdate ?></div>
|
|
</div>
|
|
<div class="search-box">
|
|
<input type="text" id="searchInput" placeholder="Rechercher..." value="<?= htmlspecialchars($searchQuery) ?>">
|
|
<a href="dashboard.html" class="btn btn-primary"><i class="fas fa-home"></i> Dashboard</a>
|
|
<button class="btn btn-primary" onclick="checkAllStatus()"><i class="fas fa-sync"></i> Vérifier</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="container">
|
|
<!-- Quick Links -->
|
|
<div class="quick-links">
|
|
<a href="system-monitoring.php" class="quick-link"><i class="fas fa-chart-line" style="color:#22d3ee"></i> Monitoring</a>
|
|
<a href="documentation.php" class="quick-link"><i class="fas fa-book" style="color:#a855f7"></i> Documentation</a>
|
|
<a href="huawei-accounts.php" class="quick-link"><i class="fas fa-cloud" style="color:#ef4444"></i> Huawei</a>
|
|
<a href="office-management.php" class="quick-link"><i class="fab fa-microsoft" style="color:#0078d4"></i> Office 365</a>
|
|
<a href="cloudflare-accounts.php" class="quick-link"><i class="fas fa-shield-alt" style="color:#f59e0b"></i> Cloudflare</a>
|
|
<a href="tracking-dashboard.php" class="quick-link"><i class="fas fa-chart-bar" style="color:#10b981"></i> Tracking</a>
|
|
<a href="wevupadminer.php" class="quick-link"><i class="fas fa-database" style="color:#06b6d4"></i> Adminer</a>
|
|
<a href="security-report.php" class="quick-link"><i class="fas fa-shield-alt" style="color:#ef4444"></i> Sécurité</a>
|
|
</div>
|
|
|
|
<!-- Categories -->
|
|
<?php foreach ($categories as $catKey => $catInfo): ?>
|
|
<?php if (!empty($categorizedFiles[$catKey])): ?>
|
|
<div class="category" data-category="<?= $catKey ?>">
|
|
<div class="category-header" onclick="toggleCategory('<?= $catKey ?>')">
|
|
<div class="category-icon" style="background: <?= $catInfo['color'] ?>20; color: <?= $catInfo['color'] ?>">
|
|
<i class="fas <?= $catInfo['icon'] ?>"></i>
|
|
</div>
|
|
<div class="category-title"><?= $catInfo['name'] ?></div>
|
|
<div class="category-count"><?= count($categorizedFiles[$catKey]) ?> fichiers</div>
|
|
<i class="fas fa-chevron-down category-toggle" id="toggle-<?= $catKey ?>"></i>
|
|
</div>
|
|
<div class="category-content" id="content-<?= $catKey ?>">
|
|
<div class="file-grid">
|
|
<?php foreach ($categorizedFiles[$catKey] as $file): ?>
|
|
<?php
|
|
$isNew = (time() - $file['modified']) < 86400; // Nouveau si < 24h
|
|
$sizeKb = round($file['size'] / 1024, 1);
|
|
?>
|
|
<div class="file-item" data-filename="<?= htmlspecialchars($file['name']) ?>">
|
|
<div class="status-dot status-checking" id="status-<?= md5($file['name']) ?>"></div>
|
|
<div class="file-icon <?= $file['ext'] ?>">
|
|
<i class="fas <?= $file['ext'] === 'php' ? 'fa-php' : 'fa-code' ?>"></i>
|
|
</div>
|
|
<div class="file-info">
|
|
<div class="file-name">
|
|
<?= htmlspecialchars($file['name']) ?>
|
|
<?php if ($isNew): ?><span class="new-badge">NEW</span><?php endif; ?>
|
|
</div>
|
|
<div class="file-desc"><?= htmlspecialchars($file['description']) ?></div>
|
|
<div class="file-meta">
|
|
<span><i class="fas fa-weight"></i> <?= $sizeKb ?> KB</span>
|
|
<span><i class="fas fa-clock"></i> <?= date('d/m H:i', $file['modified']) ?></span>
|
|
</div>
|
|
</div>
|
|
<div class="file-actions">
|
|
<a href="<?= htmlspecialchars($file['name']) ?>" class="file-btn file-btn-open" title="Ouvrir"><i class="fas fa-external-link-alt"></i></a>
|
|
<button class="file-btn file-btn-copy" onclick="copyUrl('<?= htmlspecialchars($file['name']) ?>')" title="Copier URL"><i class="fas fa-copy"></i></button>
|
|
<a href="<?= htmlspecialchars($file['name']) ?>" target="_blank" class="file-btn file-btn-new" title="Nouvel onglet"><i class="fas fa-plus"></i></a>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
<?php endforeach; ?>
|
|
|
|
<!-- Other (non catégorisé) -->
|
|
<?php if (!empty($categorizedFiles['other'])): ?>
|
|
<div class="category" data-category="other">
|
|
<div class="category-header" onclick="toggleCategory('other')">
|
|
<div class="category-icon" style="background: rgba(100,116,139,0.2); color: #64748b">
|
|
<i class="fas fa-folder"></i>
|
|
</div>
|
|
<div class="category-title">Autres</div>
|
|
<div class="category-count"><?= count($categorizedFiles['other']) ?> fichiers</div>
|
|
<i class="fas fa-chevron-down category-toggle" id="toggle-other"></i>
|
|
</div>
|
|
<div class="category-content" id="content-other">
|
|
<div class="file-grid">
|
|
<?php foreach ($categorizedFiles['other'] as $file): ?>
|
|
<?php
|
|
$isNew = (time() - $file['modified']) < 86400;
|
|
$sizeKb = round($file['size'] / 1024, 1);
|
|
?>
|
|
<div class="file-item" data-filename="<?= htmlspecialchars($file['name']) ?>">
|
|
<div class="status-dot status-checking" id="status-<?= md5($file['name']) ?>"></div>
|
|
<div class="file-icon <?= $file['ext'] ?>">
|
|
<i class="fas <?= $file['ext'] === 'php' ? 'fa-php' : 'fa-code' ?>"></i>
|
|
</div>
|
|
<div class="file-info">
|
|
<div class="file-name">
|
|
<?= htmlspecialchars($file['name']) ?>
|
|
<?php if ($isNew): ?><span class="new-badge">NEW</span><?php endif; ?>
|
|
</div>
|
|
<div class="file-desc"><?= htmlspecialchars($file['description']) ?></div>
|
|
<div class="file-meta">
|
|
<span><i class="fas fa-weight"></i> <?= $sizeKb ?> KB</span>
|
|
<span><i class="fas fa-clock"></i> <?= date('d/m H:i', $file['modified']) ?></span>
|
|
</div>
|
|
</div>
|
|
<div class="file-actions">
|
|
<a href="<?= htmlspecialchars($file['name']) ?>" class="file-btn file-btn-open" title="Ouvrir"><i class="fas fa-external-link-alt"></i></a>
|
|
<button class="file-btn file-btn-copy" onclick="copyUrl('<?= htmlspecialchars($file['name']) ?>')" title="Copier URL"><i class="fas fa-copy"></i></button>
|
|
<a href="<?= htmlspecialchars($file['name']) ?>" target="_blank" class="file-btn file-btn-new" title="Nouvel onglet"><i class="fas fa-plus"></i></a>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div class="footer">
|
|
<p>Index auto-généré • <?= $totalFiles ?> fichiers détectés • Serveur: <?= $serverIp ?>:<?= $port ?></p>
|
|
<p style="margin-top:5px;">Dernière mise à jour: <?= $lastUpdate ?></p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="toast" id="toast">URL copiée!</div>
|
|
|
|
<script>
|
|
const baseUrl = 'http://<?= $serverIp ?>:<?= $port ?>/';
|
|
|
|
// Toggle catégorie
|
|
function toggleCategory(cat) {
|
|
const content = document.getElementById('content-' + cat);
|
|
const toggle = document.getElementById('toggle-' + cat);
|
|
content.classList.toggle('hidden');
|
|
toggle.classList.toggle('collapsed');
|
|
}
|
|
|
|
// Copier URL
|
|
function copyUrl(filename) {
|
|
const url = baseUrl + filename;
|
|
navigator.clipboard.writeText(url).then(() => {
|
|
showToast('URL copiée: ' + filename);
|
|
});
|
|
}
|
|
|
|
// Toast
|
|
function showToast(msg) {
|
|
const toast = document.getElementById('toast');
|
|
toast.textContent = msg;
|
|
toast.classList.add('show');
|
|
setTimeout(() => toast.classList.remove('show'), 2000);
|
|
}
|
|
|
|
// Vérifier status d'un fichier
|
|
async function checkStatus(filename) {
|
|
const hash = '<?php echo "' + md5('" + filename + "') + '"; ?>';
|
|
// Simplified: use md5 hash calculation in JS
|
|
const statusDot = document.querySelector(`[data-filename="${filename}"] .status-dot`);
|
|
if (!statusDot) return;
|
|
|
|
try {
|
|
const response = await fetch(`?check=1&file=${encodeURIComponent(filename)}`);
|
|
const data = await response.json();
|
|
statusDot.className = 'status-dot ' + (data.status === 'ok' ? 'status-ok' : 'status-error');
|
|
} catch (e) {
|
|
statusDot.className = 'status-dot status-error';
|
|
}
|
|
}
|
|
|
|
// Vérifier tous les status
|
|
async function checkAllStatus() {
|
|
const items = document.querySelectorAll('.file-item');
|
|
for (const item of items) {
|
|
const filename = item.dataset.filename;
|
|
await checkStatus(filename);
|
|
await new Promise(r => setTimeout(r, 50)); // Délai pour éviter surcharge
|
|
}
|
|
showToast('Vérification terminée!');
|
|
}
|
|
|
|
// Recherche
|
|
document.getElementById('searchInput').addEventListener('input', function(e) {
|
|
const query = e.target.value.toLowerCase();
|
|
document.querySelectorAll('.file-item').forEach(item => {
|
|
const filename = item.dataset.filename.toLowerCase();
|
|
const match = filename.includes(query);
|
|
item.style.display = match ? 'flex' : 'none';
|
|
});
|
|
|
|
// Afficher/masquer catégories vides
|
|
document.querySelectorAll('.category').forEach(cat => {
|
|
const visibleItems = cat.querySelectorAll('.file-item[style="display: flex"], .file-item:not([style])');
|
|
const hasVisible = Array.from(cat.querySelectorAll('.file-item')).some(item =>
|
|
item.style.display !== 'none'
|
|
);
|
|
cat.style.display = hasVisible ? 'block' : 'none';
|
|
});
|
|
});
|
|
|
|
// Vérification initiale au chargement
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
// Vérifier les 10 premiers fichiers automatiquement
|
|
const items = Array.from(document.querySelectorAll('.file-item')).slice(0, 10);
|
|
items.forEach((item, i) => {
|
|
setTimeout(() => checkStatus(item.dataset.filename), i * 100);
|
|
});
|
|
});
|
|
</script>
|
|
<div id="chatbot-container"></div>
|
|
<link rel="stylesheet" href="/styles/chatbot.css">
|
|
<script src="/js/chatbot.js"></script>
|
|
<script>document.addEventListener("DOMContentLoaded", function() { WEVAL_Chat.init(); });</script>
|
|
<?php include("includes/chatbot-widget.php"); ?>
|
|
|
|
</body>
|
|
</html>
|