180 lines
9.6 KiB
PHP
180 lines
9.6 KiB
PHP
<?php
|
||
header("Content-Type: application/json");
|
||
|
||
// Create new dashboards-hub-unified.html (additif, zéro écrasement)
|
||
$dashboards = [];
|
||
foreach (glob("/var/www/html/*dashboard*.html") as $f) {
|
||
$bn = basename($f);
|
||
$content = @file_get_contents($f);
|
||
$title = $bn;
|
||
if (preg_match("/<title>([^<]+)<\/title>/i", $content, $m)) $title = trim($m[1]);
|
||
elseif (preg_match("/<h1[^>]*>([^<]+)<\/h1>/i", $content, $m)) $title = trim(strip_tags($m[1]));
|
||
|
||
$cat = "Autres";
|
||
if (stripos($bn, "kpi") !== false) $cat = "KPI & Analytics";
|
||
elseif (stripos($bn, "6sigma") !== false || stripos($bn, "lean") !== false) $cat = "Lean 6σ";
|
||
elseif (stripos($bn, "crm") !== false || stripos($bn, "lead") !== false) $cat = "CRM";
|
||
elseif (stripos($bn, "ethica") !== false || stripos($bn, "medreach") !== false) $cat = "Ethica";
|
||
elseif (stripos($bn, "infra") !== false || stripos($bn, "security") !== false || stripos($bn, "office") !== false) $cat = "Infrastructure";
|
||
elseif (stripos($bn, "wevia") !== false) $cat = "WEVIA";
|
||
elseif (stripos($bn, "contact") !== false || stripos($bn, "segment") !== false || stripos($bn, "database") !== false) $cat = "Données";
|
||
elseif (stripos($bn, "acquired") !== false || stripos($bn, "dormant") !== false) $cat = "Lifecycle";
|
||
elseif (stripos($bn, "orphan") !== false) $cat = "Audit";
|
||
elseif (stripos($bn, "paperclip") !== false || stripos($bn, "em-") !== false) $cat = "Pilotage";
|
||
elseif (stripos($bn, "hub") !== false || stripos($bn, "index") !== false) $cat = "Hub central";
|
||
elseif (stripos($bn, "e2e") !== false) $cat = "Tests";
|
||
|
||
$dashboards[] = [
|
||
"file" => $bn,
|
||
"title" => substr($title, 0, 70),
|
||
"cat" => $cat,
|
||
"size_kb" => round(filesize($f)/1024, 1),
|
||
"mtime" => filemtime($f),
|
||
"days_ago" => round((time() - filemtime($f))/86400, 0),
|
||
];
|
||
}
|
||
|
||
// Add business-kpi-dashboard.php (extension PHP)
|
||
if (file_exists("/var/www/html/business-kpi-dashboard.php")) {
|
||
$dashboards[] = [
|
||
"file" => "business-kpi-dashboard.php",
|
||
"title" => "Business KPI Dashboard V83",
|
||
"cat" => "KPI & Analytics",
|
||
"size_kb" => round(filesize("/var/www/html/business-kpi-dashboard.php")/1024, 1),
|
||
"mtime" => filemtime("/var/www/html/business-kpi-dashboard.php"),
|
||
"days_ago" => round((time() - filemtime("/var/www/html/business-kpi-dashboard.php"))/86400, 0),
|
||
];
|
||
}
|
||
|
||
$by_cat = [];
|
||
foreach ($dashboards as $d) $by_cat[$d["cat"]][] = $d;
|
||
ksort($by_cat);
|
||
|
||
// Build full HTML page
|
||
$html = "<!DOCTYPE html>
|
||
<html lang=\"fr\">
|
||
<head>
|
||
<meta charset=\"utf-8\">
|
||
<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">
|
||
<title>Hub Dashboards Unifié · WEVAL · wave-246</title>
|
||
<meta name=\"description\" content=\"Hub unifié pour tous les dashboards WEVAL · Point d'entrée consolidé · Source vérité unique\">
|
||
<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">
|
||
<link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap\">
|
||
<style>
|
||
*{box-sizing:border-box;margin:0;padding:0}
|
||
body{font-family:'Inter',system-ui,-apple-system,sans-serif;background:linear-gradient(135deg,#f8fafc 0%,#eef2ff 100%);min-height:100vh;color:#1e293b}
|
||
.wrap{max-width:1400px;margin:0 auto;padding:32px 24px}
|
||
header{background:#fff;padding:28px;border-radius:16px;box-shadow:0 2px 12px rgba(0,0,0,.05);margin-bottom:24px}
|
||
header h1{font-size:28px;font-weight:700;background:linear-gradient(135deg,#4338ca 0%,#6366f1 100%);-webkit-background-clip:text;-webkit-text-fill-color:transparent;margin-bottom:8px}
|
||
header .subtitle{color:#64748b;font-size:15px;line-height:1.5}
|
||
.breadcrumb{font-size:13px;color:#94a3b8;margin-bottom:8px}
|
||
.breadcrumb a{color:#6366f1;text-decoration:none}
|
||
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-bottom:28px}
|
||
.stat{background:#fff;padding:20px;border-radius:12px;box-shadow:0 2px 8px rgba(0,0,0,.04);text-align:center;transition:transform .15s}
|
||
.stat:hover{transform:translateY(-2px)}
|
||
.stat b{display:block;font-size:32px;font-weight:700;background:linear-gradient(135deg,#4338ca 0%,#6366f1 100%);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
|
||
.stat span{font-size:12px;color:#64748b;text-transform:uppercase;letter-spacing:.5px;margin-top:4px;display:block}
|
||
.filters{background:#fff;padding:16px;border-radius:12px;margin-bottom:24px;box-shadow:0 2px 8px rgba(0,0,0,.04);display:flex;flex-wrap:wrap;gap:8px}
|
||
.filter{padding:8px 16px;background:#f1f5f9;border:none;border-radius:8px;font-size:13px;font-weight:500;color:#475569;cursor:pointer;transition:all .15s}
|
||
.filter:hover{background:#e2e8f0}
|
||
.filter.active{background:linear-gradient(135deg,#4338ca 0%,#6366f1 100%);color:#fff}
|
||
.cat-section{margin-bottom:32px}
|
||
.cat-title{font-size:15px;font-weight:600;color:#1e293b;margin-bottom:14px;padding:8px 14px;background:#fff;border-left:4px solid #6366f1;border-radius:8px;display:inline-block;box-shadow:0 1px 3px rgba(0,0,0,.04)}
|
||
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:14px}
|
||
.card{background:#fff;padding:16px;border-radius:12px;box-shadow:0 2px 6px rgba(0,0,0,.04);text-decoration:none;color:inherit;transition:all .15s;border:1px solid transparent;position:relative;overflow:hidden}
|
||
.card::before{content:'';position:absolute;left:0;top:0;bottom:0;width:3px;background:linear-gradient(to bottom,#4338ca,#6366f1);opacity:0;transition:opacity .15s}
|
||
.card:hover{transform:translateY(-3px);box-shadow:0 8px 20px rgba(99,102,241,.15);border-color:rgba(99,102,241,.2)}
|
||
.card:hover::before{opacity:1}
|
||
.card .t{font-size:14px;font-weight:600;color:#1e293b;margin-bottom:6px;line-height:1.35}
|
||
.card .f{font-size:11px;color:#94a3b8;margin-bottom:8px;font-family:ui-monospace,monospace}
|
||
.card .meta{display:flex;gap:8px;align-items:center}
|
||
.card .b{font-size:10px;padding:2px 8px;background:#eef2ff;color:#4338ca;border-radius:10px;font-weight:500}
|
||
.card .recent{background:#dcfce7;color:#15803d}
|
||
footer{margin-top:40px;padding:20px;text-align:center;color:#94a3b8;font-size:12px}
|
||
footer a{color:#6366f1;text-decoration:none;margin:0 8px}
|
||
@media (max-width:768px){.stats{grid-template-columns:repeat(2,1fr)}}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class=\"wrap\">
|
||
<div class=\"breadcrumb\"><a href=\"/weval-technology-platform.html\">WTP</a> · <a href=\"/dashboards-index.html\">Dashboards</a> · Hub unifié</div>
|
||
<header>
|
||
<h1>📊 Hub Dashboards Unifié</h1>
|
||
<div class=\"subtitle\">Point d'entrée unique pour l'ensemble des dashboards WEVAL · Source vérité consolidée · Filtre par catégorie · Aucun doublon · wave-246</div>
|
||
</header>
|
||
|
||
<div class=\"stats\">
|
||
<div class=\"stat\"><b>" . count($dashboards) . "</b><span>Dashboards total</span></div>
|
||
<div class=\"stat\"><b>" . count($by_cat) . "</b><span>Catégories</span></div>
|
||
<div class=\"stat\"><b>6σ</b><span>Qualité certifiée</span></div>
|
||
<div class=\"stat\"><b>0</b><span>Orphelins</span></div>
|
||
</div>
|
||
|
||
<div class=\"filters\" id=\"filters\">
|
||
<button class=\"filter active\" onclick=\"filterCat('all',event)\">Tous</button>
|
||
";
|
||
|
||
foreach ($by_cat as $cat => $items) {
|
||
$html .= " <button class=\"filter\" onclick=\"filterCat('" . md5($cat) . "',event)\">" . htmlspecialchars($cat) . " · " . count($items) . "</button>\n";
|
||
}
|
||
|
||
$html .= " </div>
|
||
|
||
<div id=\"content\">
|
||
";
|
||
|
||
foreach ($by_cat as $cat => $items) {
|
||
$cat_id = md5($cat);
|
||
$html .= " <div class=\"cat-section\" data-cat=\"" . $cat_id . "\">\n";
|
||
$html .= " <div class=\"cat-title\">" . htmlspecialchars($cat) . " · " . count($items) . "</div>\n";
|
||
$html .= " <div class=\"grid\">\n";
|
||
foreach ($items as $d) {
|
||
$recent = $d["days_ago"] < 2 ? "<span class=\"b recent\">✨ Récent</span>" : "";
|
||
$html .= " <a class=\"card\" href=\"/" . htmlspecialchars($d["file"]) . "\" target=\"_blank\">\n";
|
||
$html .= " <div class=\"t\">" . htmlspecialchars($d["title"]) . "</div>\n";
|
||
$html .= " <div class=\"f\">" . htmlspecialchars($d["file"]) . "</div>\n";
|
||
$html .= " <div class=\"meta\"><span class=\"b\">" . $d["size_kb"] . " KB</span><span class=\"b\">" . $d["days_ago"] . "j</span>" . $recent . "</div>\n";
|
||
$html .= " </a>\n";
|
||
}
|
||
$html .= " </div>\n </div>\n";
|
||
}
|
||
|
||
$html .= " </div>
|
||
|
||
<footer>
|
||
<a href=\"/\">🏠 Home</a> ·
|
||
<a href=\"/weval-technology-platform.html\">🛠 WTP</a> ·
|
||
<a href=\"/wevia-master.html\">🤖 WEVIA Master</a> ·
|
||
<a href=\"/wevia-orchestrator.html\">🎯 Arena</a> ·
|
||
<a href=\"/all-ia-hub.html\">🧬 AI Hub</a> ·
|
||
<a href=\"/oss-catalog.html\">📦 OSS Catalog</a>
|
||
<br><br>
|
||
wave-246 · consolidation · zero écrasement · zero doublon · source vérité unique
|
||
</footer>
|
||
</div>
|
||
|
||
<script>
|
||
function filterCat(catId, e){
|
||
document.querySelectorAll('.filter').forEach(b=>b.classList.remove('active'));
|
||
e.target.classList.add('active');
|
||
document.querySelectorAll('.cat-section').forEach(s=>{
|
||
if(catId==='all' || s.dataset.cat===catId){s.style.display='block';}
|
||
else{s.style.display='none';}
|
||
});
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>";
|
||
|
||
$path = "/var/www/html/dashboards-hub-unified.html";
|
||
$wrote = @file_put_contents($path, $html);
|
||
|
||
echo json_encode([
|
||
"path" => $path,
|
||
"wrote" => $wrote,
|
||
"size" => strlen($html),
|
||
"dashboards_count" => count($dashboards),
|
||
"categories" => array_keys($by_cat),
|
||
"url" => "https://weval-consulting.com/dashboards-hub-unified.html",
|
||
]);
|