Files
html/owner-actions-tracker.html
opus d5edaa769c
Some checks failed
WEVAL NonReg / nonreg (push) Has been cancelled
auto-sync via WEVIA git_sync_all intent 2026-04-21T14:56:43+02:00
2026-04-21 14:56:43 +02:00

190 lines
9.9 KiB
HTML
Raw 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">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<title>👤 Owner Actions Tracker — Yacine's Physical Actions · WEVAL</title>
<style>
*,*::before,*::after{box-sizing:border-box}
body{margin:0;background:linear-gradient(135deg,#0a0e1a 0%,#1a1f3a 100%);color:#e2e8f0;font-family:-apple-system,'Segoe UI',sans-serif;min-height:100vh;padding:20px}
.wrap{max-width:1400px;margin:0 auto}
.header{display:flex;align-items:center;justify-content:space-between;padding:20px 24px;background:rgba(99,102,241,0.08);border:1px solid rgba(99,102,241,0.25);border-radius:12px;margin-bottom:20px}
.header h1{margin:0;font-size:22px;font-weight:600}
.header p{margin:4px 0 0;color:#94a3b8;font-size:13px}
.badges{display:flex;gap:10px}
.badge{padding:6px 14px;background:rgba(16,185,129,0.15);border:1px solid rgba(16,185,129,0.4);border-radius:20px;font-size:12px;font-weight:600;color:#10b981}
.badge.warn{background:rgba(245,158,11,0.15);border-color:rgba(245,158,11,0.4);color:#f59e0b}
.badge.crit{background:rgba(239,68,68,0.15);border-color:rgba(239,68,68,0.4);color:#ef4444}
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:14px;margin-bottom:24px}
.stat{padding:18px 20px;background:rgba(30,41,59,0.5);border:1px solid rgba(99,102,241,0.15);border-radius:10px}
.stat-v{font-size:32px;font-weight:700;color:#22d3ee;line-height:1}
.stat-l{color:#94a3b8;font-size:11px;text-transform:uppercase;letter-spacing:0.5px;margin-top:6px}
.items{display:grid;gap:16px}
.item{background:rgba(30,41,59,0.6);border:1px solid rgba(99,102,241,0.2);border-radius:12px;padding:20px 24px;transition:all 0.2s}
.item:hover{border-color:rgba(99,102,241,0.5);transform:translateX(4px)}
.item.critical{border-left:4px solid #ef4444}
.item.high{border-left:4px solid #f59e0b}
.item.medium{border-left:4px solid #22d3ee}
.item.low{border-left:4px solid #64748b}
.item-head{display:flex;align-items:center;gap:12px;margin-bottom:10px}
.item-icon{font-size:28px}
.item-title{flex:1;font-size:16px;font-weight:600;color:#f1f5f9}
.item-prio{padding:3px 10px;border-radius:12px;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:0.8px}
.item-prio.critical{background:rgba(239,68,68,0.2);color:#ef4444}
.item-prio.high{background:rgba(245,158,11,0.2);color:#f59e0b}
.item-prio.medium{background:rgba(34,211,238,0.2);color:#22d3ee}
.item-prio.low{background:rgba(100,116,139,0.2);color:#94a3b8}
.item-cat{display:inline-block;margin:0 0 10px;padding:2px 8px;background:rgba(99,102,241,0.15);border-radius:6px;font-size:11px;color:#a78bfa}
.item-why{color:#cbd5e1;font-size:14px;line-height:1.5;margin:10px 0 14px;padding:12px;background:rgba(15,23,42,0.6);border-radius:8px;border-left:3px solid #a78bfa}
.item-why b{color:#f1f5f9}
.actions-list{list-style:none;padding:0;margin:10px 0}
.actions-list li{padding:8px 0 8px 28px;position:relative;color:#e2e8f0;font-size:13.5px;line-height:1.5}
.actions-list li::before{content:'▸';position:absolute;left:8px;color:#22d3ee;font-weight:700}
.item-footer{display:flex;flex-wrap:wrap;gap:16px;margin-top:14px;padding-top:12px;border-top:1px solid rgba(99,102,241,0.15);font-size:12px;color:#94a3b8}
.item-footer strong{color:#f1f5f9}
.item-footer .eta{color:#f59e0b}
.item-footer .value{color:#10b981;font-weight:600}
.cta-row{display:flex;gap:10px;margin-top:14px}
.cta{padding:8px 16px;background:rgba(99,102,241,0.2);border:1px solid rgba(99,102,241,0.4);border-radius:8px;color:#a78bfa;text-decoration:none;font-size:12px;font-weight:600;transition:all 0.2s;cursor:pointer;display:inline-block}
.cta:hover{background:rgba(99,102,241,0.35);transform:translateY(-1px)}
.cta.done{background:rgba(16,185,129,0.2);border-color:rgba(16,185,129,0.4);color:#10b981}
.cta.done:hover{background:rgba(16,185,129,0.35)}
.note{padding:10px 14px;background:rgba(16,185,129,0.08);border:1px dashed rgba(16,185,129,0.3);border-radius:8px;font-size:12px;color:#86efac;margin-top:10px}
.loading{padding:40px;text-align:center;color:#94a3b8}
.back{display:inline-block;margin-top:20px;padding:10px 18px;background:rgba(99,102,241,0.15);border:1px solid rgba(99,102,241,0.3);border-radius:8px;color:#a78bfa;text-decoration:none;font-size:13px}
.back:hover{background:rgba(99,102,241,0.3)}
.summary-box{padding:16px 20px;background:rgba(16,185,129,0.08);border:1px solid rgba(16,185,129,0.3);border-radius:10px;margin-bottom:20px;color:#86efac;font-size:13.5px;line-height:1.6}
</style>
</head>
<body>
<div class="wrap">
<div class="header">
<div>
<h1>👤 Owner Actions Tracker</h1>
<p>Les seules actions qui nécessitent Yacine physiquement — tout le reste est automatisé à 100% (6σ)</p>
</div>
<div class="badges">
<span class="badge">19/19 automatable DONE</span>
<span id="blocked-count" class="badge warn">— blocked</span>
</div>
</div>
<div class="summary-box">
<strong>🎯 État actuel</strong> : l'écosystème WEVAL est à <b>100% sur tout ce qui est automatable</b> (Plan 19/19 done · Risk 100% · NonReg 153/153 · Heatmap 144/144 · Qdrant 0 empty · Bias 20/20 · Alignment 10/10). Les items ci-dessous sont <b>strictement user-action-required</b> — doctrine #4 honnête.
</div>
<div class="stats" id="stats"></div>
<div id="items-container" class="loading">Loading owner actions…</div>
<a href="/weval-technology-platform.html" class="back">← Retour WTP (point d'entrée unique)</a>
</div>
<script>
async function load() {
try {
const r = await fetch('/api/wevia-owner-actions-tracker.php?t=' + Date.now());
const d = await r.json();
renderStats(d);
renderItems(d.items);
document.getElementById('blocked-count').textContent = d.total + ' blocked (Yacine-only)';
} catch(e) {
document.getElementById('items-container').innerHTML = '<div class="loading">❌ Erreur: '+e.message+'</div>';
}
}
function renderStats(d) {
const s = d.summary || {};
const byP = d.by_priority || {};
document.getElementById('stats').innerHTML = `
<div class="stat">
<div class="stat-v">${d.total}</div>
<div class="stat-l">Owner actions pending</div>
</div>
<div class="stat">
<div class="stat-v" style="color:#10b981">${s.automatable_closed || '—'}</div>
<div class="stat-l">Automatable closed</div>
</div>
<div class="stat">
<div class="stat-v" style="color:#ef4444">${byP.critical || 0}</div>
<div class="stat-l">Critical priority</div>
</div>
<div class="stat">
<div class="stat-v" style="color:#f59e0b">${byP.high || 0}</div>
<div class="stat-l">High priority</div>
</div>
<div class="stat">
<div class="stat-v" style="color:#10b981">${(d.total_value_keur || 0)}k€</div>
<div class="stat-l">Total pipeline value</div>
</div>
`;
}
function renderItems(items) {
const c = document.getElementById('items-container');
c.className = 'items';
c.innerHTML = items.map(it => {
const actions = (it.action_required || []).map(a => `<li>${escapeHtml(a)}</li>`).join('');
const prio = it.priority || 'medium';
const ctaRow = buildCTA(it);
const noteBlock = it.note ? `<div class="note"> ${escapeHtml(it.note)}</div>` : '';
return `
<div class="item ${prio}">
<div class="item-head">
<span class="item-icon">${it.icon || '📌'}</span>
<div class="item-title">${escapeHtml(it.title || '?')}</div>
<span class="item-prio ${prio}">${prio}</span>
</div>
${it.category ? `<span class="item-cat">${escapeHtml(it.category)}</span>` : ''}
<div class="item-why"><b>Pourquoi bloqué :</b> ${escapeHtml(it.why_blocked || '')}</div>
${actions ? `<div><b style="font-size:12px;color:#94a3b8;text-transform:uppercase;letter-spacing:0.5px">Action requise :</b><ul class="actions-list">${actions}</ul></div>` : ''}
<div class="item-footer">
${it.contact ? `<span>👤 <strong>${escapeHtml(it.contact)}</strong></span>` : ''}
${it.eta_realistic ? `<span class="eta">⏱️ ETA: ${escapeHtml(it.eta_realistic)}</span>` : ''}
${it.value_keur ? `<span class="value">💰 ${it.value_keur}k€ value</span>` : ''}
</div>
${ctaRow}
${noteBlock}
</div>
`;
}).join('');
}
function buildCTA(it) {
const buttons = [];
if (it.compose_template) buttons.push(`<a href="${it.compose_template}" class="cta" target="_blank">📧 Open compose template</a>`);
if (it.id === 'act_69e53d5d5e09c') buttons.push(`<a href="https://portal.azure.com" class="cta" target="_blank">🔗 Open Azure Portal</a>`);
if (it.id === 'act_69e53d5d9aa8d') buttons.push(`<a href="https://www.ovh.com/manager" class="cta" target="_blank">🔗 Open OVH Manager</a>`);
if (it.id === 'blade_razer_wake') buttons.push(`<a href="/tasks-live-opus5.html" class="cta" target="_blank">📊 Verify Blade status</a>`);
buttons.push(`<button class="cta done" onclick="markDone('${it.id}')" title="Mark as done once action completed">✅ Mark done (once done)</button>`);
return `<div class="cta-row">${buttons.join('')}</div>`;
}
async function markDone(id) {
if (!confirm('Mark ' + id + ' as done ? (update plan)')) return;
try {
const r = await fetch('/api/wevia-v71-risk-halu-plan.php?action=plan_update&id=' + encodeURIComponent(id) + '&status=done');
const j = await r.json();
if (j.ok) {
alert('✅ Marked done');
load();
} else alert('❌ Error: ' + JSON.stringify(j));
} catch(e) { alert('❌ ' + e.message); }
}
function escapeHtml(s) {
return String(s).replace(/[&<>"']/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
}
load();
// Auto-refresh every 60s
setInterval(load, 60000);
</script>
<script src="/api/a11y-auto-enhancer.js" defer></script>
<!-- WTP_UDOCK_V1 (Opus 21-avr t34final) --><script src="/wtp-unified-dock.js" defer></script>
<script src="/opus-antioverlap-doctrine.js?v=1776776094" defer></script>
</body>
</html>