Some checks failed
WEVAL NonReg / nonreg (push) Has been cancelled
4 pages timeout fix: - architecture-live (47KB) enrichie via cascade Cerebras - agents-valuechain (29KB) enrichie via cascade Cerebras - growth-engine-v2 (162KB) injection directe Python (bypass 200KB limit) - enterprise-model (207KB) injection directe Python (bypass 200KB limit) Nouveau handler: - /var/www/html/api/inject-d60-direct.py - Bypass Cerebras pour pages lourdes - CSS+JS doctrine 60 minimal mais complet - GOLD backups + chattr handling auto Total session: - 49 pages UX doctrine 60 (45 + 4 pages lourdes) - 38 tags Opus push dual - 24 doctrines vault (146-177)
1958 lines
160 KiB
HTML
1958 lines
160 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="fr">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Growth Engine v3 — WEVAL Consulting</title>
|
||
<link href="https://fonts.googleapis.com/css2?family=DM+Serif+Display:ital@0;1&family=Outfit:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||
<style>
|
||
:root{--bg:#06090f;--bg2:#0c1120;--bg3:#131b2e;--bg4:#1a2540;--gold:#d4a853;--gold2:#e8c36a;--gd:rgba(212,168,83,.12);--em:#34d399;--ed:rgba(52,211,153,.12);--sa:#3b82f6;--sd:rgba(59,130,246,.12);--co:#f97066;--cld:rgba(249,112,102,.12);--vi:#a78bfa;--vd:rgba(167,139,250,.12);--cy:#22d3ee;--cyd:rgba(34,211,238,.12);--ro:#fb7185;--rd:rgba(251,113,133,.12);--am:#fbbf24;--ad:rgba(251,191,36,.12);--t1:#f0ece4;--t2:#9ca3af;--t3:#4b5563;--brd:#1e293b;--r:10px;--fd:'DM Serif Display',Georgia,serif;--fb:'Outfit',system-ui,sans-serif;--fm:'JetBrains Mono',monospace}
|
||
*{box-sizing:border-box;margin:0;padding:0}body{font-family:var(--fb);background:var(--bg);color:var(--t1);min-height:100vh;overflow-x:hidden}
|
||
.amb{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden}.orb{position:absolute;border-radius:50%;filter:blur(120px);opacity:.12;animation:dr 20s ease-in-out infinite}.o1{width:600px;height:600px;background:var(--gold);top:-10%;left:-5%}.o2{width:500px;height:500px;background:var(--sa);bottom:-10%;right:-5%;animation-delay:-7s}.o3{width:400px;height:400px;background:var(--em);top:40%;left:50%;animation-delay:-14s}@keyframes dr{0%,100%{transform:translate(0,0)}33%{transform:translate(30px,-20px)}66%{transform:translate(-20px,30px)}}
|
||
.nz{position:fixed;inset:0;z-index:1;pointer-events:none;opacity:.03;background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}
|
||
.wr{position:relative;z-index:2}
|
||
.hd{display:flex;align-items:center;gap:14px;padding:12px 20px;background:rgba(12,17,32,.9);backdrop-filter:blur(20px);border-bottom:1px solid var(--brd);position:relative;z-index:10}
|
||
.hd-l{font-family:var(--fd);font-size:20px;color:var(--gold)}.hd-l span{color:var(--t3);font-size:11px;font-family:var(--fb);margin-left:6px}
|
||
.hd-k{display:flex;gap:10px;margin-left:auto}.hd-k a{color:var(--t3);font-size:9px;text-decoration:none;font-weight:600;letter-spacing:.5px;text-transform:uppercase;transition:.2s}.hd-k a:hover{color:var(--gold)}
|
||
.sb{padding:5px 12px;border-radius:6px;border:1px solid var(--gd);background:var(--gd);color:var(--gold);font-size:10px;font-family:var(--fb);font-weight:600;cursor:pointer;transition:.3s;display:flex;align-items:center;gap:4px}.sb:hover{background:var(--gold);color:var(--bg)}.sb .ic{transition:transform .4s}.sb:hover .ic{transform:rotate(180deg)}
|
||
.nv{display:flex;gap:0;padding:0 12px;background:rgba(12,17,32,.7);backdrop-filter:blur(12px);border-bottom:1px solid var(--brd);overflow-x:auto}.nv::-webkit-scrollbar{display:none}
|
||
.vt{padding:9px 12px;font-size:10px;color:var(--t3);cursor:pointer;border-bottom:2px solid transparent;transition:.2s;white-space:nowrap;font-weight:500;display:flex;align-items:center;gap:4px}.vt .dt{width:4px;height:4px;border-radius:50%}.vt.on{color:var(--t1);border-bottom-color:var(--gold);font-weight:600}.vt:hover{color:var(--t1)}.vt .ct{font-size:8px;font-family:var(--fm);background:var(--bg4);padding:1px 4px;border-radius:3px}
|
||
.mn{max-width:1440px;margin:0 auto;padding:18px 20px}.sc{display:none}.sc.on{display:block;animation:fi .3s ease}@keyframes fi{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}
|
||
.mr{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:7px;margin-bottom:18px}.mc{background:var(--bg2);border:1px solid var(--brd);border-radius:8px;padding:10px;position:relative;overflow:hidden}.mc::before{content:'';position:absolute;top:0;left:0;right:0;height:2px}
|
||
.mc.g::before{background:linear-gradient(90deg,var(--gold),transparent)}.mc.e::before{background:linear-gradient(90deg,var(--em),transparent)}.mc.s::before{background:linear-gradient(90deg,var(--sa),transparent)}.mc.c::before{background:linear-gradient(90deg,var(--co),transparent)}.mc.v::before{background:linear-gradient(90deg,var(--vi),transparent)}.mc.cy::before{background:linear-gradient(90deg,var(--cy),transparent)}.mc.r::before{background:linear-gradient(90deg,var(--ro),transparent)}.mc.a::before{background:linear-gradient(90deg,var(--am),transparent)}
|
||
.mc-l{font-size:8px;text-transform:uppercase;letter-spacing:.6px;color:var(--t3);margin-bottom:3px;font-weight:600}.mc-v{font-size:20px;font-weight:700;font-family:var(--fm);line-height:1}.mc-s{font-size:8px;color:var(--t2);margin-top:3px}
|
||
.cg{display:grid;grid-template-columns:repeat(auto-fill,minmax(270px,1fr));gap:9px;margin-bottom:18px}.cd{background:var(--bg2);border:1px solid var(--brd);border-radius:8px;padding:12px;transition:.2s}.cd:hover{border-color:rgba(212,168,83,.25);transform:translateY(-1px);box-shadow:0 4px 16px rgba(0,0,0,.25)}.cd-h{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:5px}.cd-t{font-size:12px;font-weight:600}.cd-d{font-size:9px;color:var(--t2);line-height:1.5;margin-bottom:7px}
|
||
.bd{font-size:8px;padding:2px 6px;border-radius:4px;font-weight:600}.bw{background:var(--gd);color:var(--gold)}.bp{background:var(--sd);color:var(--sa)}.bi{background:var(--vd);color:var(--vi)}.bh{background:var(--cld);color:var(--co)}.bs{background:var(--ed);color:var(--em)}
|
||
.rv{display:flex;align-items:center;gap:5px;margin-top:5px}.rv-b{flex:1;height:3px;border-radius:2px;background:var(--bg4);overflow:hidden}.rv-f{height:100%;border-radius:2px;transition:width .5s}.rv-v{font-size:9px;font-family:var(--fm);color:var(--gold);min-width:35px;text-align:right}
|
||
.ca{margin-top:6px;display:flex;flex-wrap:wrap;gap:3px}.at{font-size:8px;padding:2px 5px;border-radius:3px;background:var(--bg3);color:var(--t2);cursor:pointer;transition:.15s;border:1px solid transparent}.at:hover{border-color:var(--gold);color:var(--gold)}.at.dn{text-decoration:line-through;opacity:.3}
|
||
.kb{display:grid;grid-template-columns:repeat(4,1fr);gap:7px;margin-bottom:18px}@media(max-width:900px){.kb{grid-template-columns:1fr 1fr}}@media(max-width:600px){.kb{grid-template-columns:1fr}}
|
||
.kc{background:var(--bg2);border:1px solid var(--brd);border-radius:8px;overflow:hidden}.kh{padding:8px 9px;border-bottom:1px solid var(--brd);display:flex;align-items:center;gap:4px;font-size:10px;font-weight:600}.kh .n{font-family:var(--fm);font-size:8px;color:var(--t3);margin-left:auto}.kh.si{border-left:3px solid var(--vi)}.kh.sp{border-left:3px solid var(--sa)}.kh.sw{border-left:3px solid var(--gold)}.kh.ss{border-left:3px solid var(--em)}
|
||
.ki{padding:5px 9px;border-bottom:1px solid rgba(30,41,59,.25);font-size:9px;color:var(--t2);transition:.12s}.ki:hover{background:var(--bg3);color:var(--t1)}.ki .tg{font-size:7px;padding:1px 3px;border-radius:2px;margin-left:2px;background:rgba(255,255,255,.04);color:var(--t3)}
|
||
.cns{display:grid;grid-template-columns:repeat(auto-fill,minmax(165px,1fr));gap:5px;margin-bottom:18px}.cn{background:var(--bg2);border:1px solid var(--brd);border-radius:7px;padding:8px;display:flex;align-items:center;gap:7px;transition:.15s;font-size:10px}.cn:hover{border-color:var(--em)}.cn-d{width:5px;height:5px;border-radius:50%;flex-shrink:0}.cn-d.up{background:var(--em);box-shadow:0 0 4px var(--em)}.cn-d.dn{background:var(--co);box-shadow:0 0 4px var(--co)}.cn-d.wr{background:var(--gold);box-shadow:0 0 4px var(--gold)}.cn-n{font-weight:500}.cn-p{font-size:8px;font-family:var(--fm);color:var(--t3);margin-left:auto}
|
||
.cb{background:var(--bg2);border:1px solid var(--brd);border-radius:8px;margin-bottom:18px;overflow:hidden}.ch{padding:10px 12px;border-bottom:1px solid var(--brd);display:flex;align-items:center;gap:6px;font-size:11px;font-weight:600}.ch .lv{width:5px;height:5px;border-radius:50%;background:var(--em);animation:gl 2s infinite}@keyframes gl{0%,100%{box-shadow:0 0 2px var(--em)}50%{box-shadow:0 0 7px var(--em)}}
|
||
.cm{padding:10px 12px;max-height:220px;overflow-y:auto;font-size:10px;line-height:1.6}.cm::-webkit-scrollbar{width:2px}.cm::-webkit-scrollbar-thumb{background:var(--bg4)}.mg{margin-bottom:7px;padding:6px 9px;border-radius:5px;animation:mi .2s ease}.mg.sy{background:var(--bg3);color:var(--t3);font-size:9px}.mg.ai{background:rgba(212,168,83,.05);border-left:2px solid var(--gold)}.mg.us{background:var(--bg4);text-align:right}@keyframes mi{from{opacity:0;transform:translateX(-4px)}to{opacity:1;transform:translateX(0)}}
|
||
.ci{display:flex;gap:6px;padding:8px 12px;border-top:1px solid var(--brd)}.ci input{flex:1;background:var(--bg3);border:1px solid var(--brd);border-radius:5px;padding:7px 9px;color:var(--t1);font-size:10px;font-family:var(--fb);outline:none;transition:.2s}.ci input:focus{border-color:var(--gold)}.ci button{padding:7px 14px;border-radius:5px;border:none;background:var(--gold);color:var(--bg);font-weight:600;font-size:10px;cursor:pointer}.ci button:hover{background:var(--gold2)}
|
||
.st{font-family:var(--fd);font-size:15px;color:var(--t1);margin-bottom:12px;display:flex;align-items:center;gap:6px}.st .ln{flex:1;height:1px;background:var(--brd)}
|
||
.tbl{width:100%;border-collapse:collapse;margin-bottom:14px;font-size:9px}.tbl th{text-align:left;padding:6px 7px;font-size:7px;text-transform:uppercase;letter-spacing:.6px;color:var(--t3);border-bottom:1px solid var(--brd);font-weight:600}.tbl td{padding:6px 7px;border-bottom:1px solid rgba(30,41,59,.25);color:var(--t2)}.tbl tr:hover td{background:var(--bg3);color:var(--t1)}
|
||
.sr{background:var(--bg2);border:1px solid var(--brd);border-radius:8px;padding:10px;margin-bottom:18px}.si2{padding:6px 0;border-bottom:1px solid rgba(30,41,59,.2)}.si2:last-child{border:none}.si2-t{font-size:10px;font-weight:500;color:var(--sa)}.si2-u{font-size:7px;font-family:var(--fm);color:var(--t3)}.si2-s{font-size:9px;color:var(--t2);margin-top:2px;line-height:1.4}
|
||
.spnr{display:inline-block;width:10px;height:10px;border:2px solid var(--brd);border-top-color:var(--gold);border-radius:50%;animation:spi .5s linear infinite}@keyframes spi{to{transform:rotate(360deg)}}
|
||
/* Plan90 */
|
||
.p90-w{margin-bottom:14px}.p90-h{font-weight:600;font-size:11px;color:var(--gold);margin-bottom:6px;padding-bottom:4px;border-bottom:1px solid var(--brd)}.p90-a{display:flex;align-items:center;gap:6px;padding:4px 0;font-size:9px;color:var(--t2)}.p90-a input{accent-color:var(--gold)}.p90-a.done{text-decoration:line-through;opacity:.4}
|
||
/* Social */
|
||
.soc{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:8px;margin-bottom:18px}.soc-c{background:var(--bg2);border:1px solid var(--brd);border-radius:8px;padding:12px;transition:.2s}.soc-c:hover{border-color:var(--sa)}.soc-h{font-size:11px;font-weight:600;margin-bottom:6px;display:flex;align-items:center;gap:6px}.soc-h .soc-ico{font-size:14px}.soc-stat{font-size:9px;color:var(--t2);line-height:1.6}.soc-api{font-size:8px;font-family:var(--fm);color:var(--t3);margin-top:6px;padding-top:4px;border-top:1px solid var(--brd)}
|
||
@media(max-width:768px){.hd{padding:8px 12px}.hd-l{font-size:16px}.hd-k{display:none}.nv{padding:0 8px}.vt{padding:7px 7px;font-size:9px}.mn{padding:10px}.mr{grid-template-columns:repeat(2,1fr)}.cg{grid-template-columns:1fr}}
|
||
|
||
/*WAVE-REPAIR-23AVR-V1-opus · patch minimal doctrine enrichir pas ecraser*/
|
||
html,body{overflow-x:hidden;overflow-y:auto;scrollbar-width:auto;scrollbar-color:#d4a853 #0c1120}
|
||
html::-webkit-scrollbar,body::-webkit-scrollbar{width:14px;height:14px}
|
||
html::-webkit-scrollbar-track,body::-webkit-scrollbar-track{background:#0c1120;border-left:1px solid rgba(212,168,83,.1)}
|
||
html::-webkit-scrollbar-thumb,body::-webkit-scrollbar-thumb{background:linear-gradient(180deg,#d4a853,#a57f2e);border-radius:7px;border:2px solid #0c1120;box-shadow:inset 0 0 3px rgba(0,0,0,.3)}
|
||
html::-webkit-scrollbar-thumb:hover,body::-webkit-scrollbar-thumb:hover{background:linear-gradient(180deg,#e6ba6a,#b8923a)}
|
||
.mn{padding-bottom:100px;overflow:visible}
|
||
#s-advisor{padding-bottom:160px;overflow:visible}
|
||
#s-advisor > div{overflow:visible}
|
||
#s-advisor pre{max-height:min(60vh,500px);overflow:auto;overscroll-behavior:auto;scrollbar-width:thin;scrollbar-color:#d4a853 #1a1f2e}
|
||
#s-advisor pre::-webkit-scrollbar{width:8px;height:8px}
|
||
#s-advisor pre::-webkit-scrollbar-track{background:#1a1f2e}
|
||
#s-advisor pre::-webkit-scrollbar-thumb{background:#d4a853;border-radius:4px}
|
||
/* Relax max-height v2 aggressifs (pour que contenus scrollables ne bloquent pas) */
|
||
#s-advisor [style*="max-height"]{max-height:none!important;overscroll-behavior:auto!important}
|
||
/* PAS DE background/border/padding sur #advisor-content > div !!! */
|
||
/* Laisse buildAdvisor garder ses styles inline */
|
||
/*/WAVE-REPAIR-23AVR-V1-opus*/
|
||
|
||
/* WAVE 306 opus-x-btn hide - doctrine zero chevauchement TR/BR */
|
||
.opus-x-btn{display:none!important;visibility:hidden!important;pointer-events:none!important}
|
||
|
||
/* WAVE 306 opus-x-btn hide - doctrine zero chevauchement TR/BR */
|
||
.opus-x-btn{display:none!important;visibility:hidden!important;pointer-events:none!important}
|
||
</style>
|
||
<script src="/widgets/audit-banner.js" defer></script>
|
||
<!-- DOCTRINE-60-UX-ENRICH direct-inject-20260424-130137 -->
|
||
<style id="doctrine60-ux-direct">
|
||
|
||
/* DOCTRINE-60-UX-ENRICH injected-direct */
|
||
body::before {
|
||
content: '';
|
||
position: fixed;
|
||
top: 0; left: 0; width: 100vw; height: 100vh;
|
||
background: radial-gradient(circle at 50% 50%, rgba(100,180,255,0.08), transparent 60%);
|
||
pointer-events: none;
|
||
z-index: -1;
|
||
}
|
||
.card, .kpi, .panel, .btn {
|
||
transition: all 0.3s cubic-bezier(0.2,0,0.1,1);
|
||
}
|
||
.card:hover, .kpi:hover, .panel:hover {
|
||
box-shadow: 0 4px 20px rgba(100,180,255,0.2);
|
||
border-color: rgba(100,180,255,0.5);
|
||
}
|
||
@keyframes pulseD60 {
|
||
0%,100% { opacity: 1; transform: scale(1); }
|
||
50% { opacity: 0.7; transform: scale(1.05); }
|
||
}
|
||
.pulse, .live-indicator, .active, .online {
|
||
animation: pulseD60 3s ease-in-out infinite;
|
||
}
|
||
.modal, .chat, .speech, .overlay {
|
||
backdrop-filter: blur(12px);
|
||
-webkit-backdrop-filter: blur(12px);
|
||
}
|
||
.enter-stagger {
|
||
animation: enterStagD60 0.5s cubic-bezier(0.2,0,0.1,1) forwards;
|
||
}
|
||
@keyframes enterStagD60 {
|
||
from { opacity: 0; transform: translateY(20px); }
|
||
to { opacity: 1; transform: translateY(0); }
|
||
}
|
||
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="amb"><div class="orb o1"></div><div class="orb o2"></div><div class="orb o3"></div></div>
|
||
<div class="nz"></div>
|
||
<div class="wr">
|
||
<div class="hd">
|
||
<div class="hd-l">Growth Engine <span>v3 — WEVAL Consulting</span></div>
|
||
<div class="hd-k"><a href="/wevia-master.html">Master</a><a href="/director.html">Director</a><a href="/crm.html">CRM</a><a href="/growth-engine.html">v1</a><a href="/growth-advisor-v3.html" style="color:#d4a853;font-weight:600">Advisor v3</a></div>
|
||
<button class="sb" onclick="fullScan()"><span class="ic">↻</span> Scan All</button>
|
||
</div>
|
||
<div class="nv" id="nav"></div>
|
||
<div class="mn" id="mn"></div>
|
||
</div>
|
||
<script>
|
||
const API='/api/growth-engine-api.php',WV='/api/wevia-master-api.php';
|
||
const SN={idea:'Idées',plan:'Planifié',wip:'En cours',sign:'Signé'};
|
||
const SC={idea:'si',plan:'sp',wip:'sw',sign:'ss'};
|
||
|
||
// ═══════════ 8 VERTICALS — ENRICHED FROM V1+V2+ARCHI ═══════════
|
||
const V={
|
||
consulting:{l:'Consulting',ic:'em',o:[
|
||
{n:'Vistex SAP Maghreb',d:'Lead protection + conseil SAP pricing. Cosumar, Carrefour, OCP. Addendum Section 8.B + Section 3.d. Contacts: Olga Vanurina, Joe Golemba, Udo Hannemann.',r:200000,s:'wip',b:'bh',a:['Signer Lead Protection Addendum','RDV Olga Vanurina','Proposition Cosumar','Section 6.c.i Portal argument']},
|
||
{n:'Audit Maturité Digitale PME',d:'Framework McKinsey DQ adapté Maroc. Assessment 0-100 benchmark sectoriel. BCG DAI + DQ combo.',r:80000,s:'plan',b:'bp',a:['Framework scoring','Landing page','LinkedIn prospection','Template rapport']},
|
||
{n:'Consulting Cloud Migration',d:'Migration on-prem → cloud. Arrow/Scaleway partnership. Omar Belchkar, Julien Bossu contacts.',r:120000,s:'wip',b:'bw',a:['Onboarding ArrowSphere','Offre packagée','3 prospects','Cheikh Gassama Scaleway']},
|
||
{n:'Conseil Stratégie IA PME',d:'Diagnostic IA + roadmap. 50K MAD/mission. Cible: industriels Maghreb.',r:60000,s:'idea',b:'bi',a:['Offre diagnostic','3 PME pilotes','Webinaire CGEM']},
|
||
{n:'Value Stream Mapping',d:'VSM consulting pour optimisation processus. Page VSM existante dans Arsenal.',r:40000,s:'idea',b:'bi',a:['Connecter vsm-pipelines.html','Template VSM client','Offre packagée 30K']}
|
||
],m:[{l:'Pipeline',v:'500K',s:'5 deals',c:'e'},{l:'Partenaires',v:'3',s:'Vistex·Arrow·Scaleway',c:'g'},{l:'Conversion',v:'40%',s:'2/5 closing',c:'s'}]},
|
||
|
||
digital:{l:'Digital',ic:'sa',o:[
|
||
{n:'WEVIA SaaS freemium',d:'Arena multi-LLM + chat autonome. 626 tools. Free 100 msgs → 99€/mois. Blade v2.0 connecté.',r:200000,s:'plan',b:'bp',a:['Landing WeviaAI.ma','Setup Stripe','Beta 10 users','Blade v2 demo']},
|
||
{n:'API HCP Maghreb (Ethica)',d:'157K HCPs, 120K emails, 18K phones, 64K Google verified. 3000€/15K/mois. Pilot DRY_RUN prêt 7611 MG DZ.',r:300000,s:'wip',b:'bh',a:['Enrichir spécialités DZ','Scraper CNAM TN + CROMC','3 labos pilotes Kaouther','Consent.wevup.app']},
|
||
{n:'White-label WEVIA',d:'WEVIA brandé pour cabinets RH/legal/finance. Setup 5000€ + 500€/mois.',r:80000,s:'idea',b:'bi',a:['Package technique','Mockup client','5 cabinets cibles']},
|
||
{n:'SEO Module Hub',d:'Audit SEO auto via Plausible + SearXNG. Rapport client automatique.',r:40000,s:'plan',b:'bp',a:['SEO Module Hub page','Plausible bearer token','Template rapport']},
|
||
{n:'Dev Apps sur mesure',d:'Apps web/mobile stack WEVAL (React, Node, PG). 3000 MAD/jour.',r:100000,s:'idea',b:'bi',a:['Portfolio case-studies.html','Pricing grid','Landing développement']},
|
||
{n:'Solution Finder IA',d:'solution-finder.html existant. Recommandation IA des solutions WEVAL pour prospects.',r:30000,s:'plan',b:'bp',a:['Enrichir solution-finder','Connecter WEVIA Master','A/B test conversion']}
|
||
],m:[{l:'Pipeline',v:'750K',s:'6 opportunités',c:'s'},{l:'HCPs',v:'157K',s:'120K emails · 72K verified',c:'e'},{l:'Pages',v:'279',s:'+ 488 Arsenal = 767 total',c:'g'},{l:'APIs',v:'730',s:'Toutes live',c:'v'}]},
|
||
|
||
cloud:{l:'Cloud & Infra',ic:'cy',o:[
|
||
{n:'Arrow/Scaleway Reseller',d:'1er partenaire Scaleway Maroc via Arrow. Marge 15-25%. ArrowSphere onboarding.',r:100000,s:'wip',b:'bw',a:['Finaliser ArrowSphere','Offre packagée','10 prospects','Julien Bossu contact']},
|
||
{n:'Managed Hosting',d:'Hébergement managé Hetzner/OVH. Kuma + Prometheus + Grafana monitoring.',r:50000,s:'plan',b:'bp',a:['Pricing S/M/L','SLA document','Dashboard client Kuma']},
|
||
{n:'IaC Consulting',d:'DevOps/IaC PME. 17 Docker, CI/CD, Gitea, monitoring souverain.',r:60000,s:'idea',b:'bi',a:['Template Docker Compose','Workshop DevOps','3 prospects']},
|
||
{n:'Résolution Huawei Cloud',d:'Litige facturation. Comptes gelés + overconsumption. Ray Wu, Chris Cen, Yanhao.',r:0,s:'wip',b:'bh',a:['Document facturation anormale','Escalade Ray Wu','Deadline résolution']},
|
||
{n:'Cloudflare Management',d:'~25 comptes CF Brahim. Service gestion DNS/CDN/WAF pour clients.',r:30000,s:'idea',b:'bi',a:['Packager offre CF','Dashboard multi-compte','5 clients cibles']}
|
||
],m:[{l:'Pipeline',v:'240K',s:'5 opps',c:'cy'},{l:'Serveurs',v:'6+',s:'S95·S204·4 ECS Huawei',c:'e'},{l:'Docker',v:'19',s:'Tous UP',c:'s'},{l:'Uptime',v:'99.7%',s:'Kuma 24/7',c:'g'}]},
|
||
|
||
ia:{l:'IA & Data',ic:'vi',o:[
|
||
{n:'IA Souveraine aaS',d:'LiteLLM cascade 0€: Cerebras 5ms + Groq 12ms + Mistral + Gemini. Sovereign-api port 4000.',r:120000,s:'plan',b:'bp',a:['Offre cascade packagée','Benchmark latence','Landing IA Souveraine','HF Space yace222 déployé']},
|
||
{n:'Agent Builder WEVIA',d:'74 agents live. Blade v2.0 agent loop. Qdrant 5 collections. 199€/mois.',r:150000,s:'idea',b:'bi',a:['Interface builder drag&drop','5 templates agents','Doc API agents']},
|
||
{n:'Data Enrichment Service',d:'Ethica stack: RichScraper Playwright DabaDoc 50 TN/min. 8 crons actifs.',r:80000,s:'wip',b:'bw',a:['API enrichissement REST','Pricing volume','3 clients pilotes']},
|
||
{n:'Qdrant RAG Service',d:'5 collections Qdrant + 5751 training dataset HF. RAG clé-en-main B2B.',r:40000,s:'idea',b:'bi',a:['Package RAG','Demo searchable KB','Pricing tiers']},
|
||
{n:'WEVIA Deep Research',d:'wevia-deep-research.php existant. Rapports IA approfondis pour clients.',r:50000,s:'plan',b:'bp',a:['Packager deep research','Interface client','Pricing par rapport']}
|
||
],m:[{l:'Pipeline',v:'440K',s:'5 opps',c:'v'},{l:'Providers',v:'7',s:'Cascade 0€ 24/7',c:'e'},{l:'Agents',v:'74',s:'Live + Arena',c:'g'},{l:'Ollama',v:'5',s:'brain-v3·qwen3·nomic·minilm',c:'s'},{l:'Tools',v:'275',s:'Dynamic Resolver v7.1',c:'a'}]},
|
||
|
||
marketing:{l:'Marketing',ic:'co',o:[
|
||
{n:'Ethica Email Campaigns',d:'HCP Maghreb. 3000€/15K/mois. Contrat Kaouther Najar actif. Pilot DRY_RUN 7611.',r:180000,s:'wip',b:'bh',a:['Lancer pilot MG+DZ','Enrichir consent','Rapport ROI','ecm.py 4 actions']},
|
||
{n:'WEVADS Brain Engine',d:'646 configs, 9 SACRED winners. O365 PMTA 97% inbox. 77K emails/j capacité.',r:200000,s:'wip',b:'bw',a:['Volume warmup 1783 comptes','Conversions pull auto','Optimiser 9 winners','VMTAs 186-189']},
|
||
{n:'Newsletter B2B Premium',d:'Newsletter IA+pharma+tech Maghreb. LinkedIn + Telegram distribution.',r:30000,s:'idea',b:'bi',a:['Template newsletter','500 subscribers','2 sponsors','Telegram @wevia_cyber_bot']},
|
||
{n:'Social Media B2B',d:'LinkedIn scraper B2B (DSI/CTO Maroc). YouTube Factory. WhatsApp Business API.',r:60000,s:'plan',b:'bp',a:['LinkedIn B2B scraper actif','YouTube Factory setup','WhatsApp Business','Plausible tracking']},
|
||
{n:'MedReach Campaigns',d:'medreach-dashboard.html + medreach-campaign.html existants. Campagnes pharma ciblées.',r:50000,s:'plan',b:'bp',a:['Activer MedReach','Connecter Ethica data','Template campagne pharma']}
|
||
],m:[{l:'Pipeline',v:'520K',s:'5 opps',c:'c'},{l:'Brain Configs',v:'646',s:'9 SACRED winners',c:'g'},{l:'Emails/j',v:'77K',s:'Warmup 1783 comptes',c:'s'},{l:'Inbox Rate',v:'97%',s:'O365 PMTA',c:'e'}]},
|
||
|
||
recruitment:{l:'Recrutement',ic:'ro',o:[
|
||
{n:'Recrutement DevOps/Cloud',d:'LinkedIn B2B scraper DSI/CTO/DG Maroc actif. Fee 15-20% annuel.',r:100000,s:'plan',b:'bp',a:['LinkedIn scraper pw_linkedin_b2b.py','Base CV','Partenariat APEBI','5 postes']},
|
||
{n:'IA/Data Scientists',d:'ML Engineers, Data Scientists, NLP. Fee premium 25%. Marché tendu.',r:80000,s:'idea',b:'bi',a:['Mapping Maroc/TN/DZ','Partnership universités','Pipeline candidats']},
|
||
{n:'Portage Salarial Tech',d:'Portage freelances tech. Marge 8-12%. Structure juridique nécessaire.',r:50000,s:'idea',b:'bi',a:['Structure juridique','Contrat type','Prospection freelances']},
|
||
{n:'Talent Assessment IA',d:'Assessment via WEVIA (tests techniques + soft skills IA). 49€/test.',r:60000,s:'idea',b:'bi',a:['Tests techniques auto','Scoring IA WEVIA','Landing assessment']}
|
||
],m:[{l:'Pipeline',v:'290K',s:'4 opps',c:'r'},{l:'LinkedIn Scraper',v:'Actif',s:'DSI/CTO/DG Maroc',c:'e'},{l:'Fee moyen',v:'20%',s:'Annuel',c:'g'}]},
|
||
|
||
erp:{l:'ERP & SAP',ic:'am',o:[
|
||
{n:'Vistex SAP Pricing',d:'Extension Vistex. SAP pricing industriels Maghreb. OCP, Cosumar, Carrefour.',r:200000,s:'wip',b:'bh',a:['Addendum Section 8.B','Prospects OCP/Cosumar','Formation Vistex','Section 3.d']},
|
||
{n:'ERP Cloud Migration',d:'Migration legacy → cloud (S/4HANA, Odoo). PME 100-500 employés.',r:150000,s:'plan',b:'bp',a:['Partnership Odoo Maroc','Benchmark S/4 vs Odoo','3 prospects industriels']},
|
||
{n:'Process Optimization',d:'Audit processus + ERP. Value Stream Mapping (vsm-pipelines.html).',r:60000,s:'idea',b:'bi',a:['Template audit','Connecter VSM','Offre packagée']},
|
||
{n:'Integration API ERP-CRM',d:'Twenty CRM ↔ ERP clients. Middleware WEVAL. booking.html existant.',r:40000,s:'idea',b:'bi',a:['Connecteur Twenty↔SAP','API middleware','Demo intégration']}
|
||
],m:[{l:'Pipeline',v:'450K',s:'4 opps',c:'a'},{l:'Partnership',v:'Vistex',s:'SAP Pricing Maghreb',c:'g'},{l:'Prospects',v:'3',s:'OCP·Cosumar·Carrefour',c:'e'}]},
|
||
|
||
formation:{l:'Formation',ic:'gold',o:[
|
||
{n:'IA pour Dirigeants',d:'Programme 2j pratique WEVIA. DG/DSI privé. 15K MAD/session.',r:90000,s:'plan',b:'bp',a:['Programme 2j','Salle Casa','Prospection CGEM','Support WEVIA Arena']},
|
||
{n:'Bootcamp DevOps/Cloud',d:'5j Docker, CI/CD, K8s, monitoring. Stack souveraine WEVAL. 8K MAD/participant.',r:60000,s:'idea',b:'bi',a:['Curriculum 5j','Lab Docker WEVAL','Certification']},
|
||
{n:'Email Marketing Pro',d:'Formation WEVADS Brain Engine 2j. Deliverability + PMTA. 12K MAD.',r:40000,s:'idea',b:'bi',a:['Contenu deliverability','Cas pratiques','Support post-formation']},
|
||
{n:'Academy WEVAL Online',d:'E-learning IA, Cloud, Data, DevOps. 29€/mois. LMS à déployer.',r:80000,s:'idea',b:'bi',a:['Plateforme LMS','5 cours','Landing academy.weval.ma']},
|
||
{n:'Certification WEVIA Expert',d:'Certif consultants partenaires. 500€/certification. Réseau.',r:30000,s:'idea',b:'bi',a:['Programme certif','Examen online','Réseau certifiés']}
|
||
],m:[{l:'Pipeline',v:'300K',s:'5 opps',c:'g'},{l:'Programmes',v:'5',s:'IA·DevOps·Email·LMS·Certif',c:'a'},{l:'Cible',v:'CGEM',s:'+APEBI+universités',c:'s'}]}
|
||
};
|
||
|
||
// PLAN 90 JOURS (from V1 enriched)
|
||
const P90=[
|
||
{w:'Semaine 1-2',acts:['Signer Vistex Lead Protection Addendum','Lancer Ethica Pilot DRY_RUN 7611 MG+DZ','Finaliser onboarding ArrowSphere','LinkedIn B2B scraper 50 profils DSI','Landing page WeviaAI.ma mockup','Résolution Huawei Cloud: documenter + escalade']},
|
||
{w:'Semaine 3-4',acts:['3 labos pilotes Ethica (Kaouther)','Offre Scaleway packagée + 10 prospects','Setup Stripe pour WEVIA SaaS','Programme formation IA 2j finalisé','MedReach: connecter Ethica data','Package consulting Cloud Migration']},
|
||
{w:'Semaine 5-6',acts:['Beta WEVIA SaaS 10 users','SEO Module Hub live + Plausible API','Newsletter B2B: template + 500 subs','Framework Audit Maturité Digitale','Bootcamp DevOps: curriculum 5j','WhatsApp Business API activer']},
|
||
{w:'Semaine 7-8',acts:['WEVIA White-label: mockup client','ERP Cloud Migration: partnership Odoo','Deep Research: packager offre','Certification WEVIA: programme','Talent Assessment IA: tests auto','Academy WEVAL: plateforme LMS']},
|
||
{w:'Semaine 9-10',acts:['Prospection CGEM 3 formations','Qdrant RAG: package + demo','Cloudflare management: offre client','YouTube Factory: premiers contenus','Value Stream Mapping: offre client','LinkedIn posts: stratégie B2B content']},
|
||
{w:'Semaine 11-12',acts:['Bilan Q1: pipeline signé vs objectif','Ajuster pricing toutes offres','Scale WEVADS: +5 winners brain','Réseau certifiés WEVIA: 5 premiers','Solution Finder: A/B test conversion','Growth Engine v4: auto-enrichissement IA']}
|
||
];
|
||
|
||
// SOCIAL CHANNELS
|
||
const SOC=[
|
||
{name:'LinkedIn B2B',ico:'🔗',status:'Actif',desc:'Scraper Playwright pw_linkedin_b2b.py. Cibles: DSI, CTO, DG Maghreb. DuckDuckGo/Bing profiles sans login.',api:'pw_linkedin_b2b.py + linkedin-posts.php',color:'var(--sa)'},
|
||
{name:'YouTube Factory',ico:'▶',status:'Setup',desc:'youtube-factory.php + youtube-factory/api.php. Production contenu IA/Cloud/Consulting.',api:'youtube-factory.php (mode demo)',color:'var(--co)'},
|
||
{name:'Telegram Bot',ico:'✈',status:'Actif',desc:'@wevia_cyber_bot, chat_id 7605775322. Alertes monitoring + notifications.',api:'blade-telegram.php + wedroid-telegram-alert.php',color:'var(--sa)'},
|
||
{name:'WhatsApp Business',ico:'💬',status:'Config',desc:'Meta Graph API v22.0. Actions: status, send, send_bulk, templates.',api:'whatsapp-api.php (4 actions)',color:'var(--em)'},
|
||
{name:'Mattermost',ico:'💜',status:'Live',desc:'Docker port 8065. Communication interne équipe + webhooks.',api:'blade-mattermost.php',color:'var(--vi)'},
|
||
{name:'Email Marketing',ico:'📧',status:'Live',desc:'WEVADS Brain Engine 646 configs. PMTA O365. 8 seeds Videotron+T-Online.',api:'wevia-email-api.php + Brain Engine',color:'var(--gold)'},
|
||
{name:'Plausible Analytics',ico:'📊',status:'Live',desc:'Docker port 8000. Analytics souverain. Nécessite bearer token config.',api:'Plausible API :8000',color:'var(--em)'},
|
||
{name:'Twenty CRM',ico:'🏢',status:'Live',desc:'Docker port 3000. CRM complet pour pipeline commercial.',api:'Twenty :3000 (GraphQL)',color:'var(--cy)'}
|
||
];
|
||
|
||
// CONNECTIONS (21 services)
|
||
const CN=[
|
||
{n:'Twenty CRM',p:':3000',s:'up'},{n:'Plausible',p:':8000',s:'up'},{n:'SearXNG',p:':8888',s:'up'},
|
||
{n:'Mattermost',p:':8065',s:'up'},{n:'Vaultwarden',p:':8222',s:'up'},{n:'Uptime Kuma',p:':3001',s:'up'},
|
||
{n:'Qdrant',p:':6333',s:'up'},{n:'Langfuse',p:':3100',s:'up'},{n:'Gitea',p:':3400',s:'up'},
|
||
{n:'Prometheus',p:':9090',s:'up'},{n:'WEVIA Master',p:':5899',s:'up'},{n:'Sentinel',p:':5890',s:'up'},
|
||
{n:'LiteLLM',p:':4001',s:'up'},{n:'Sovereign API',p:':4000',s:'up'},{n:'PostgreSQL',p:':5432',s:'up'},
|
||
{n:'Brain Engine',p:':5821',s:'up'},{n:'Arsenal',p:':5890',s:'up'},{n:'Paperclip',p:'—',s:'dn'},
|
||
{n:'MiroFish',p:'—',s:'dn'},{n:'n8n',p:':5678',s:'wr'},{n:'Ollama 5 mod.',p:':11434',s:'up'}
|
||
];
|
||
|
||
const TABS=['dashboard','advisor','consulting','digital','cloud','ia','marketing','recruitment','erp','formation','pipeline','plan90','social','scout','predict','connections'];
|
||
|
||
function mc(m){return `<div class="mc ${m.c}" data-k="${m.k||m.l}" onclick="v87Drill(this.dataset.k)" style="cursor:pointer;transition:transform .15s"><div class="mc-l">${m.l}</div><div class="mc-v">${m.v}</div><div class="mc-s">${m.s}</div></div>`;}/*V87-drill*/
|
||
function cd(o,mx){
|
||
const p=mx?Math.round(o.r/mx*100):0;
|
||
const cl=o.b==='bh'?'var(--co)':o.b==='bw'?'var(--gold)':o.b==='bp'?'var(--sa)':'var(--vi)';
|
||
let aa='';if(o.a)o.a.forEach(x=>{aa+=`<span class="at" onclick="this.classList.toggle('dn')">${x}</span>`;});
|
||
return `<div class="cd"><div class="cd-h"><div class="cd-t">${o.n}</div><span class="bd ${o.b}">${SN[o.s]||o.s}</span></div><div class="cd-d">${o.d}</div>${o.r?`<div class="rv"><div class="rv-b"><div class="rv-f" style="width:${p}%;background:${cl}"></div></div><div class="rv-v">${(o.r/1000|0)}K</div></div>`:''}<div class="ca">${aa}</div></div>`;
|
||
}
|
||
function buildKB(ops){
|
||
const by={idea:[],plan:[],wip:[],sign:[]};ops.forEach(o=>{if(by[o.s])by[o.s].push(o);});
|
||
let h='<div class="kb">';
|
||
['idea','plan','wip','sign'].forEach(k=>{
|
||
const it=by[k]||[];
|
||
h+=`<div class="kc"><div class="kh ${SC[k]}">${SN[k]} <span class="n">${it.length}</span></div>`;
|
||
it.forEach(o=>{h+=`<div class="ki">${o.n}${o.vl?`<span class="tg">${o.vl}</span>`:''}</div>`;});
|
||
if(!it.length)h+=`<div class="ki" style="color:var(--t3)">—</div>`;h+=`</div>`;
|
||
});return h+'</div>';
|
||
}
|
||
|
||
function build(){
|
||
const nav=document.getElementById('nav');
|
||
const tabLabels={dashboard:'Dashboard',advisor:'🎯 Conversion Advisor',pipeline:'Pipeline CRM',plan90:'Plan 90J',social:'Réseaux & Canaux',scout:'Dark Scout',predict:'WePredict',connections:'Connexions'};
|
||
const tabColors={dashboard:'var(--gold)',advisor:'#22d3ee',pipeline:'var(--em)',plan90:'var(--am)',social:'var(--sa)',scout:'var(--cy)',predict:'var(--ro)',connections:'var(--vi)'};/*V86*/
|
||
let nh='';
|
||
TABS.forEach((t,i)=>{
|
||
const on=i===0?' on':'';
|
||
if(V[t])nh+=`<div class="vt${on}" data-v="${t}"><span class="dt" style="background:var(--${V[t].ic})"></span>${V[t].l} <span class="ct">${V[t].o.length}</span></div>`;
|
||
else nh+=`<div class="vt${on}" data-v="${t}"><span class="dt" style="background:${tabColors[t]||'var(--t3)'}"></span>${tabLabels[t]||t}</div>`;
|
||
});
|
||
nav.innerHTML=nh;
|
||
nav.querySelectorAll('.vt').forEach(t=>{t.onclick=()=>{
|
||
nav.querySelectorAll('.vt').forEach(x=>x.classList.remove('on'));t.classList.add('on');
|
||
document.querySelectorAll('.sc').forEach(s=>s.classList.remove('on'));
|
||
const s=document.getElementById('s-'+t.dataset.v);if(s){s.classList.add('on');window.scrollTo({top:0,behavior:'smooth'});setTimeout(function(){var n=document.getElementById('nav');if(n){var y=n.getBoundingClientRect().bottom+window.scrollY;window.scrollTo({top:y-8,behavior:'smooth'});}},180);}
|
||
};});
|
||
|
||
const mn=document.getElementById('mn');
|
||
const all=Object.entries(V).flatMap(([k,v])=>v.o.map(o=>({...o,vl:v.l})));
|
||
const tot=all.reduce((s,o)=>s+o.r,0);
|
||
const byS={idea:0,plan:0,wip:0,sign:0};all.forEach(o=>{if(byS[o.s]!==undefined)byS[o.s]++;});
|
||
const VC={consulting:'var(--em)',digital:'var(--sa)',cloud:'var(--cy)',ia:'var(--vi)',marketing:'var(--co)',recruitment:'var(--ro)',erp:'var(--am)',formation:'var(--gold)'};
|
||
|
||
let h=`<div class="sc on" id="s-dashboard">`;
|
||
h+=`<div class="mr">${mc({k:'pipeline_total',l:'Pipeline Total',v:(tot/1000|0)+'K MAD',s:all.length+' opps · 8 verticaux',c:'g'})}${mc({k:'en_cours',l:'En cours',v:byS.wip+'',s:'Deals actifs',c:'e'})}${mc({k:'planifie',l:'Planifié',v:byS.plan+'',s:'Préparation',c:'s'})}${mc({k:'idees',l:'Idées',v:byS.idea+'',s:'À explorer',c:'v'})}${mc({k:'hcps_ethica',l:'HCPs Ethica',v:'157K',s:'120K emails · 72K verified',c:'c'})}${mc({k:'docker',l:'Docker',v:'19',s:'Tous UP',c:'cy'})}${mc({k:'tools_wevia',l:'Tools WEVIA',v:'626',s:'Resolver v8 · DP+V57+V60',c:'v'})}${mc({k:'pages_apis',l:'Pages + APIs',v:'656',s:'279 pages · 730 APIs',c:'a'})}${mc({k:'ia_cascade',l:'IA Cascade',v:'0€',s:'17 providers 24/7',c:'r'})}${mc({k:'crons',l:'Crons',v:'34',s:'Actifs S95+S204',c:'g'})}</div>`;
|
||
|
||
h+=`<div class="cb"><div class="ch"><span class="lv"></span> WEVIA Master — Growth Advisor</div><div class="cm" id="cM"><div class="mg sy">Connecté — 8 verticaux · 626 tools · 730 APIs · 17 providers IA · 157K HCPs. Question ?</div></div><div class="ci"><input id="cI" placeholder="Pricing API HCP ? ROI formation ? Plan recrutement ? Stratégie ERP ?" onkeydown="if(event.key==='Enter')chat()"><button onclick="chat()">Envoyer</button></div></div>`;
|
||
|
||
h+=`<div class="st">Pipeline global <span class="ln"></span></div>${buildKB(all)}`;
|
||
h+=`<div class="st">Revenus par vertical <span class="ln"></span></div>`;
|
||
Object.entries(V).forEach(([k,v])=>{
|
||
const vr=v.o.reduce((s,o)=>s+o.r,0);const p=tot?Math.round(vr/tot*100):0;
|
||
h+=`<div style="display:flex;align-items:center;gap:7px;margin-bottom:5px"><span style="font-size:10px;min-width:75px;color:var(--t2)">${v.l}</span><div class="rv-b" style="flex:1"><div class="rv-f" style="width:${p}%;background:${VC[k]}"></div></div><span class="rv-v">${(vr/1000|0)}K</span></div>`;
|
||
});h+=`</div>`;
|
||
|
||
// VERTICAL SECTIONS
|
||
Object.entries(V).forEach(([k,v])=>{
|
||
const mx=Math.max(...v.o.map(o=>o.r),1);
|
||
h+=`<div class="sc" id="s-${k}"><div class="st">${v.l} <span class="ln"></span></div><div class="mr">${v.m.map(m=>mc(m)).join('')}</div><div class="cg">${v.o.map(o=>cd(o,mx)).join('')}</div></div>`;
|
||
});
|
||
|
||
// CONVERSION ADVISOR container (fix overlap: fallback body>div sinon)
|
||
h+=`<div class="sc" id="s-advisor"><div style="padding:24px;color:#22d3ee">Loading Deep Conversion Advisor...</div></div>`;
|
||
|
||
// PIPELINE CRM
|
||
h+=`<div class="sc" id="s-pipeline"><div class="st">Pipeline Commercial — Twenty CRM + WEVAL CRM <span class="ln"></span></div>${buildKB(all)}`;
|
||
h+=`<div class="st">Top opportunités par revenu <span class="ln"></span></div><table class="tbl"><thead><tr><th>Opportunité</th><th>Vertical</th><th>Valeur</th><th>Stage</th></tr></thead><tbody>`;
|
||
all.filter(o=>o.r>0).sort((a,b)=>b.r-a.r).forEach(o=>{
|
||
h+=`<tr><td style="color:var(--t1);font-weight:500">${o.n}</td><td>${o.vl}</td><td style="font-family:var(--fm);color:var(--gold)">${(o.r/1000|0)}K</td><td><span class="bd ${o.b}">${SN[o.s]}</span></td></tr>`;
|
||
});h+=`</tbody></table></div>`;
|
||
|
||
// PLAN 90J
|
||
h+=`<div class="sc" id="s-plan90"><div class="st">Plan d'Action — 90 Jours <span class="ln"></span></div>`;
|
||
P90.forEach(w=>{
|
||
h+=`<div class="p90-w"><div class="p90-h">${w.w}</div>`;
|
||
w.acts.forEach(a=>{h+=`<div class="p90-a"><input type="checkbox" onchange="this.parentElement.classList.toggle('done')"><span>${a}</span></div>`;});
|
||
h+=`</div>`;
|
||
});h+=`</div>`;
|
||
|
||
// SOCIAL & CHANNELS
|
||
h+=`<div class="sc" id="s-social"><div class="st">Réseaux Sociaux & Canaux de Distribution <span class="ln"></span></div><div class="soc">`;
|
||
SOC.forEach(s=>{
|
||
const stCls=s.status==='Actif'||s.status==='Live'?'bs':s.status==='Setup'||s.status==='Config'?'bw':'bi';
|
||
h+=`<div class="soc-c"><div class="soc-h"><span class="soc-ico">${s.ico}</span>${s.name}<span class="bd ${stCls}" style="margin-left:auto">${s.status}</span></div><div class="soc-stat">${s.desc}</div><div class="soc-api">API: ${s.api}</div></div>`;
|
||
});h+=`</div></div>`;
|
||
|
||
// DARK SCOUT
|
||
h+=`<div class="sc" id="s-scout"><div class="st">Dark Scout — SearXNG Intelligence <span class="ln"></span></div><div style="display:flex;gap:6px;margin-bottom:12px"><input id="sQ" placeholder="consulting SAP Maroc, email pharma, recrutement DevOps, ERP migration..." style="flex:1;background:var(--bg3);border:1px solid var(--brd);border-radius:5px;padding:7px 9px;color:var(--t1);font-size:10px;font-family:var(--fb);outline:none" onkeydown="if(event.key==='Enter')scout()"><button onclick="scout()" style="padding:7px 14px;border-radius:5px;border:none;background:var(--sa);color:#fff;font-weight:600;font-size:10px;cursor:pointer">Scan</button></div><div class="sr" id="sR"><div style="color:var(--t3);font-size:10px">SearXNG: veille concurrentielle multi-sources</div></div></div>`;
|
||
|
||
|
||
// V86 WEPREDICT DASHBOARD
|
||
h+=`<div class="sc" id="s-predict"><div class="st"> WePredict Predictive Analytics <span class="ln"></span></div>
|
||
<div class="mr" id="predictKPIs">
|
||
<div class="mc" style="border-left:3px solid var(--ro)"><div class="mcl">Load Predicted (next 1h)</div><div class="mcv" id="predLoad">...</div><div class="mcs" id="predLoadSub">regression slope</div></div>
|
||
<div class="mc" style="border-left:3px solid var(--am)"><div class="mcl">Alert Threshold</div><div class="mcv" id="predAlert">...</div><div class="mcs">auto-heal armed</div></div>
|
||
<div class="mc" style="border-left:3px solid var(--cy)"><div class="mcl">Cache Hit Rate</div><div class="mcv" id="predCache">...</div><div class="mcs" id="predCacheSub">hits/gets</div></div>
|
||
<div class="mc" style="border-left:3px solid var(--em)"><div class="mcl">Samples Analyzed</div><div class="mcv" id="predSamples">...</div><div class="mcs">rolling window</div></div>
|
||
<div class="mc" style="border-left:3px solid var(--vi)"><div class="mcl">Top Patterns</div><div class="mcv" id="predPatterns">...</div><div class="mcs">auto-learned</div></div>
|
||
<div class="mc" style="border-left:3px solid var(--sa)"><div class="mcl">Trend</div><div class="mcv" id="predTrend">...</div><div class="mcs" id="predTrendSub">slope direction</div></div>
|
||
</div>
|
||
<div class="st" style="margin-top:15px">Top 5 Query Patterns (auto-learned) <span class="ln"></span></div>
|
||
<div id="predPatternsList" style="background:var(--bg3);padding:12px;border-radius:6px;font-family:var(--fm);font-size:10px;color:var(--t2)">Loading WePredict data...</div>
|
||
<div class="st" style="margin-top:15px">Recommended Actions <span class="ln"></span></div>
|
||
<div id="predActions" style="background:var(--bg3);padding:12px;border-radius:6px;font-size:11px;color:var(--t2)">Loading...</div>
|
||
</div>`;
|
||
|
||
// CONNECTIONS
|
||
h+=`<div class="sc" id="s-connections"><div class="st">21 Services connectés <span class="ln"></span></div><div class="cns">${CN.map(c=>`<div class="cn"><div class="cn-d ${c.s}"></div><div class="cn-n">${c.n}</div><div class="cn-p">${c.p}</div></div>`).join('')}</div>`;
|
||
h+=`<div class="st">Assets Registry (${new Date().toLocaleDateString('fr')}) <span class="ln"></span></div><table class="tbl"><thead><tr><th>Asset</th><th>Type</th><th>Status</th><th>Mat.</th></tr></thead><tbody id="aB"><tr><td colspan="4" style="color:var(--t3)"><span class="spnr"></span> Chargement registry...</td></tr></tbody></table></div>`;
|
||
|
||
mn.innerHTML=h;
|
||
}
|
||
|
||
async function loadAssets(){try{const r=await fetch(API+'?action=registry');const d=await r.json();if(d.assets){const b=document.getElementById('aB');if(b)b.innerHTML=d.assets.map(a=>`<tr><td style="color:var(--t1);font-weight:500">${a.name}</td><td>${a.type||'?'}</td><td><span class="bd ${a.status==='live'||a.status==='up'?'bs':'bh'}">${a.status}</span></td><td style="font-family:var(--fm)">${a.maturity||'?'}%</td></tr>`).join('');}}catch(e){}}
|
||
|
||
async function chat(){const inp=document.getElementById('cI'),q=inp.value.trim();if(!q)return;inp.value='';const m=document.getElementById('cM');m.innerHTML+=`<div class="mg us">${q}</div><div class="mg ai" id="cL"><span class="spnr"></span></div>`;m.scrollTop=m.scrollHeight;try{const r=await fetch(WV,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({message:q,context:'Growth Engine v3. 8 verticaux (consulting/digital/cloud/IA/marketing/recrutement/ERP/formation). Pipeline '+(Object.values(V).reduce((s,v)=>s+v.o.reduce((ss,o)=>ss+o.r,0),0)/1000|0)+'K MAD. 279 pages, 730 APIs, 626 tools, 17 Docker, 57 crons, 7 IA providers 0€, 157K HCPs, 74 agents, 5 Ollama models. Partenaires: Vistex SAP, Arrow/Scaleway, Ethica Kaouther. Social: LinkedIn scraper, YouTube Factory, Telegram bot, WhatsApp Business, Mattermost.',session:'growth-v3'})});const d=await r.json();const el=document.getElementById('cL');if(el)el.outerHTML=`<div class="mg ai">${(d.content||d.response||'—').replace(/\n/g,'<br>')}</div>`;}catch(e){const el=document.getElementById('cL');if(el)el.outerHTML=`<div class="mg ai" style="color:var(--co)">Erreur WEVIA</div>`;}m.scrollTop=m.scrollHeight;}
|
||
|
||
async function scout(){const q=document.getElementById('sQ').value.trim();if(!q)return;const b=document.getElementById('sR');b.innerHTML='<span class="spnr"></span> SearXNG...';try{const r=await fetch(API+'?action=dark_scout&q='+encodeURIComponent(q));const d=await r.json();if(d.results&&d.results.length)b.innerHTML=d.results.map(r=>`<div class="si2"><div class="si2-t">${r.title||''}</div><div class="si2-u">${r.url||''}</div><div class="si2-s">${r.content||r.snippet||''}</div></div>`).join('');else b.innerHTML=`<div style="color:var(--t3)">0 résultats</div>`;}catch(e){b.innerHTML=`<div style="color:var(--co)">Erreur</div>`;}}
|
||
|
||
async function fullScan(){const btn=document.querySelector('.sb');btn.innerHTML='<span class="spnr"></span>';btn.disabled=true;try{const r=await fetch(API+'?action=scan');const d=await r.json();const m=document.getElementById('cM');if(m&&d){m.innerHTML+=`<div class="mg ai"><strong>Scan ✓</strong><br>${(d.proposal||d.summary||JSON.stringify(d).substring(0,500)).replace(/\n/g,'<br>')}</div>`;m.scrollTop=m.scrollHeight;}}catch(e){}btn.innerHTML='<span class="ic">↻</span> Scan All';btn.disabled=false;loadAssets();loadPredict();/*V86*/}
|
||
|
||
build();loadAssets();
|
||
</script>
|
||
|
||
<!-- === OPUS UNIVERSAL DRILL-DOWN v1 19avr — append-only, doctrine #14 === -->
|
||
<script>
|
||
(function(){
|
||
if (window.__opusUniversalDrill) return; window.__opusUniversalDrill = true;
|
||
var d = document;
|
||
var m = d.createElement('div');
|
||
m.id = 'opus-udrill';
|
||
m.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.82);backdrop-filter:blur(6px);display:none;align-items:center;justify-content:center;z-index:99995;padding:20px;cursor:pointer';
|
||
var inner = d.createElement('div');
|
||
inner.id = 'opus-udrill-in';
|
||
inner.style.cssText = 'max-width:900px;width:100%;max-height:90vh;overflow:auto;background:#0b0d15;border:1px solid rgba(99,102,241,0.35);border-radius:14px;padding:28px;cursor:default;box-shadow:0 20px 60px rgba(0,0,0,0.6);color:#e2e8f0;font:14px/1.55 Inter,system-ui,sans-serif';
|
||
inner.addEventListener('click', function(e){ e.stopPropagation(); });
|
||
m.appendChild(inner);
|
||
m.addEventListener('click', function(){ m.style.display='none'; });
|
||
d.addEventListener('keydown', function(e){ if(e.key==='Escape') m.style.display='none'; });
|
||
(d.body || d.documentElement).appendChild(m);
|
||
|
||
function openCard(card) {
|
||
// Clone card content + show close btn + increase font-size
|
||
var html = '<div style="display:flex;justify-content:flex-end;margin-bottom:14px"><button id="opus-udrill-close" style="padding:6px 14px;background:#171b2a;border:1px solid rgba(99,102,241,0.25);color:#e2e8f0;border-radius:8px;cursor:pointer;font-size:12px">✕ Fermer (Esc)</button></div>';
|
||
html += '<div style="transform-origin:top left;font-size:1.05em">' + card.outerHTML + '</div>';
|
||
inner.innerHTML = html;
|
||
d.getElementById('opus-udrill-close').onclick = function(){ m.style.display='none'; };
|
||
m.style.display = 'flex';
|
||
}
|
||
|
||
function wire(root) {
|
||
var sels = '.card,[class*="card"],.kpi,[class*="kpi"],.stat,[class*="stat"],.tile,[class*="tile"],.metric,[class*="metric"],.widget,[class*="widget"]';
|
||
var cards = root.querySelectorAll(sels);
|
||
for (var i = 0; i < cards.length; i++) {
|
||
var c = cards[i];
|
||
if (c.__opusWired) continue;
|
||
if (c.closest('button, a, input, select, textarea, #opus-udrill')) continue;
|
||
var r = c.getBoundingClientRect();
|
||
if (r.width < 60 || r.height < 40) continue;
|
||
c.__opusWired = true;
|
||
c.style.cursor = 'pointer';
|
||
c.setAttribute('role','button');
|
||
c.setAttribute('tabindex','0');
|
||
c.addEventListener('click', function(ev){
|
||
// If a more-specific drill is already active (e.g. pp-card custom), let it handle
|
||
if (ev.target.closest('[data-pp-id]') && window.__opusDrillInit) return;
|
||
if (ev.target.closest('a,button,input,select')) return;
|
||
ev.preventDefault(); ev.stopPropagation();
|
||
openCard(this);
|
||
});
|
||
c.addEventListener('keydown', function(ev){ if(ev.key==='Enter'||ev.key===' '){ev.preventDefault();openCard(this);} });
|
||
}
|
||
}
|
||
|
||
// Initial + mutation observer
|
||
var initRun = function(){ wire(d.body || d.documentElement); };
|
||
if (d.readyState === 'loading') d.addEventListener('DOMContentLoaded', initRun);
|
||
else initRun();
|
||
var mo = new MutationObserver(function(muts){
|
||
var newCard = false;
|
||
for (var i=0;i<muts.length;i++) if (muts[i].addedNodes.length) { newCard = true; break; }
|
||
if (newCard) initRun();
|
||
});
|
||
mo.observe(d.body || d.documentElement, {childList:true, subtree:true});
|
||
})();
|
||
|
||
// V86 WePredict loader
|
||
async function loadPredict(){
|
||
try{
|
||
const r=await fetch('/api/dsh-predict-api.php');
|
||
const d=await r.json();
|
||
if(!d || !d.ok) return;
|
||
const loadData=d.load||{};
|
||
const cacheData=d.cache||{};
|
||
const el=(id,v)=>{const e=document.getElementById(id);if(e)e.textContent=v;};
|
||
el('predLoad', (loadData.predicted_next_hour||0).toFixed(2));
|
||
el('predLoadSub', 'slope: '+(loadData.regression_slope||0).toExponential(2));
|
||
el('predAlert', (loadData.threshold||5)+' '+(loadData.alert?'ARMED':'OK'));
|
||
el('predCache', (cacheData.hit_rate_pct||0).toFixed(1)+'%');
|
||
el('predCacheSub', (cacheData.hits||0)+' / '+(cacheData.gets||0));
|
||
el('predSamples', loadData.n_samples||0);
|
||
el('predPatterns', cacheData.patterns_count||0);
|
||
const slope=loadData.regression_slope||0;
|
||
el('predTrend', slope<0?'DECLINING':slope>0?'RISING':'STABLE');
|
||
el('predTrendSub', 'n='+(loadData.n_samples||0));
|
||
const plEl=document.getElementById('predPatternsList');
|
||
if(plEl && cacheData.top_patterns){
|
||
const tp=Object.entries(cacheData.top_patterns).slice(0,5);
|
||
plEl.innerHTML=tp.map(([q,cnt],i)=>`<div style="padding:4px 0;border-bottom:1px solid var(--brd)">${i+1}. <span style="color:var(--t1)">${q}</span> <span style="color:var(--gold)">(${cnt} hits)</span></div>`).join('');
|
||
}
|
||
const acEl=document.getElementById('predActions');
|
||
if(acEl){
|
||
const acts=loadData.recommended_actions||[];
|
||
acEl.innerHTML=acts.length>0 ? acts.map(a=>`<div style="padding:4px 0">${loadData.alert?'ALERT':''} <code style="color:var(--cy)">${a}</code></div>`).join('') : '<span style="color:var(--t3)">No actions needed - system healthy</span>';
|
||
}
|
||
}catch(e){console.error('WePredict load error:',e);}
|
||
}
|
||
// Auto-load on tab switch
|
||
const _origShow=window.show;window.show=function(k){if(_origShow)_origShow(k);if(k==='predict')loadPredict();};
|
||
// Auto-load on first render
|
||
setTimeout(loadPredict, 1500);
|
||
|
||
</script>
|
||
<!-- === OPUS UNIVERSAL DRILL-DOWN END === -->
|
||
|
||
<div id="v87-modal" style="position:fixed;inset:0;background:rgba(0,0,0,.85);backdrop-filter:blur(4px);z-index:999999;display:none;align-items:center;justify-content:center;padding:20px"><div style="background:var(--bg2);border:1px solid var(--brd);border-radius:12px;padding:24px;max-width:720px;width:100%;max-height:85vh;overflow-y:auto"><div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:16px"><div id="v87-title" style="font-size:18px;font-weight:700;color:var(--t1)">Drill-down</div><button onclick="v87Close()" style="background:none;border:0;color:var(--t3);font-size:28px;cursor:pointer;line-height:1">×</button></div><div id="v87-content" style="color:var(--t2);font-size:12px;line-height:1.7"><span class="spnr"></span> Loading...</div></div></div><script>
|
||
const V87_DRILL_MAP={pipeline_total:{title:'Pipeline Total 3490K MAD',intent:'drill toc'},en_cours:{title:'Deals En cours (9)',intent:'drill funnel'},planifie:{title:'Opportunites Planifiees (12)',intent:'drill funnel'},idees:{title:'Ideas a explorer (18)',intent:'implement plan'},hcps_ethica:{title:'157K HCPs Ethica',intent:'ethica live'},docker:{title:'19 Docker containers UP',intent:'v82 unified status'},tools_wevia:{title:'626 Tools WEVIA',intent:'v77 oss discovery enriched'},pages_apis:{title:'656 Pages + APIs',intent:'drill hub'},ia_cascade:{title:'IA Cascade 17 providers 0eur',intent:'sovereign status'},crons:{title:'34 Crons actifs',intent:'cron failed'}};
|
||
async function v87Drill(key){
|
||
const map=V87_DRILL_MAP[key]||{title:key,intent:key};
|
||
const modal=document.getElementById('v87-modal');
|
||
document.getElementById('v87-title').textContent=map.title;
|
||
const content=document.getElementById('v87-content');
|
||
modal.style.display='flex';
|
||
content.innerHTML='<span class="spnr"></span> Querying WEVIA Master...';
|
||
try{
|
||
const r=await fetch('/api/wevia-autonomous.php',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({message:map.intent,session:'growth-drill'})});
|
||
const raw=await r.text();
|
||
// Parse SSE or JSON
|
||
let answer='';
|
||
raw.split('\n').forEach(l=>{if(l.startsWith('data: ')){try{const j=JSON.parse(l.slice(6));if(j.type==='answer'||j.text||j.content)answer+=(j.text||j.content||'');}catch(e){}}});
|
||
if(!answer)answer=raw.slice(0,2000);
|
||
let pretty=answer;
|
||
try{const j=JSON.parse(answer);pretty='<pre style=\"background:var(--bg3);padding:14px;border-radius:6px;overflow-x:auto;font-size:11px\">'+JSON.stringify(j,null,2)+'</pre>';}catch(e){pretty='<div style=\"white-space:pre-wrap\">'+answer.replace(/</g,'<')+'</div>';}
|
||
content.innerHTML='<div style=\"margin-bottom:10px;font-size:11px;color:var(--t3)\">via WEVIA intent: <code style=\"color:var(--cy)\">'+map.intent+'</code></div>'+pretty;
|
||
}catch(e){content.innerHTML='<div style=\"color:var(--co)\">Error: '+e.message+'</div>';}
|
||
}
|
||
function v87Close(){document.getElementById('v87-modal').style.display='none';}
|
||
document.addEventListener('keydown',e=>{if(e.key==='Escape')v87Close();});
|
||
document.addEventListener('click',e=>{if(e.target.id==='v87-modal')v87Close();});
|
||
document.addEventListener('DOMContentLoaded',()=>{const s=document.createElement('style');s.textContent='.mc[data-k]:hover{transform:translateY(-2px);border-color:var(--gold)!important;box-shadow:0 4px 12px rgba(212,175,55,.2)}';document.head.appendChild(s);});
|
||
</script>
|
||
<script src="/api/a11y-auto-enhancer.js" defer></script>
|
||
<!-- WTP_UDOCK_V1 (Opus 21-avr t32b4) --><script src="/wtp-unified-dock.js" defer></script>
|
||
<script src="/opus-antioverlap-doctrine.js?v=1776776094" defer></script>
|
||
|
||
|
||
|
||
|
||
|
||
<!-- WAVE 229 · Deep Conversion Advisor V2 LIVE -->
|
||
<script>
|
||
(function(){
|
||
if (window.__wevalAdvisorV3Init) return;
|
||
window.__wevalAdvisorV3Init = true;
|
||
|
||
function renderAdvisor() {
|
||
var content = document.getElementById('s-advisor');
|
||
if (!content) content = document.getElementById('content') || document.querySelector('.content, main, body > div');
|
||
if (!content) return;
|
||
content.innerHTML = '<div style="padding:24px"><div id="advisor-loading" style="color:#22d3ee">Loading Deep Conversion Advisor V2 LIVE · fetching Paperclip + Dark Scout + WePredict + LLM…</div><div id="advisor-content"></div></div>';
|
||
|
||
// Main fetch (fast - no LLM)
|
||
fetch('/api/growth-conversion-advisor.php?cb='+Date.now())
|
||
.then(function(r){return r.json();})
|
||
.then(function(d){
|
||
var loading = document.getElementById('advisor-loading');
|
||
if (loading) loading.remove();
|
||
var body = document.getElementById('advisor-content');
|
||
if (body) body.innerHTML = buildAdvisor(d);
|
||
|
||
// Trigger LLM reco async (slower ~20-40s)
|
||
var llmBox = document.getElementById('advisor-llm-box');
|
||
if (llmBox) {
|
||
llmBox.innerHTML = '<div style="color:#a855f7;padding:8px"><span class="spnr"></span> Querying Cerebras → Groq → Mistral cascade…</div>';
|
||
fetch('/api/growth-conversion-advisor.php?llm=1&cb='+Date.now())
|
||
.then(function(r){return r.json();})
|
||
.then(function(dd){
|
||
var reco = dd.llm_reco;
|
||
if (reco && reco.raw) {
|
||
var raw = reco.raw;
|
||
// Try parse JSON
|
||
var match = raw.match(/\{[\s\S]*\}/);
|
||
if (match) {
|
||
try {
|
||
var j = JSON.parse(match[0]);
|
||
var html = '<div style="font-size:11px;color:#c4b5fd;margin-bottom:10px">✨ Provider: <b>'+reco.provider+'</b></div>';
|
||
(j.actions||[]).forEach(function(a){
|
||
html += '<div style="padding:10px;margin-bottom:8px;background:rgba(168,85,247,.08);border:1px solid rgba(168,85,247,.25);border-radius:8px">';
|
||
html += '<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px"><b style="color:#a855f7;font-size:16px">#'+a.rank+'</b><span style="color:#ddd6fe;font-weight:700;font-size:13px">'+(a.title||'?')+'</span><span style="margin-left:auto;color:#fde68a;font-size:11px">'+(a.revenue_est_mad?Math.round(a.revenue_est_mad/1000)+'K MAD':'')+'</span></div>';
|
||
html += '<div style="font-size:10.5px;color:#94a3b8;margin-bottom:4px">⏱ '+(a.timeline||'')+'</div>';
|
||
(a.steps||[]).forEach(function(s){
|
||
html += '<div style="font-size:11px;color:#e0e7ff;padding:3px 8px 3px 16px;position:relative"><span style="position:absolute;left:4px;color:#10b981">→</span>'+s+'</div>';
|
||
});
|
||
html += '</div>';
|
||
});
|
||
llmBox.innerHTML = html;
|
||
return;
|
||
} catch(e){}
|
||
}
|
||
llmBox.innerHTML = '<div style="font-size:11px;color:#c4b5fd;margin-bottom:8px">✨ '+reco.provider+'</div><pre style="white-space:pre-wrap;color:#ddd6fe;font-size:11px;max-height:280px;overflow-y:auto">'+raw.slice(0,2000)+'</pre>';
|
||
} else {
|
||
llmBox.innerHTML = '<div style="color:#94a3b8;font-size:11px;padding:8px">LLM cascade unavailable - add ?llm=1 manually</div>';
|
||
}
|
||
})
|
||
.catch(function(e){
|
||
llmBox.innerHTML = '<div style="color:#ef4444;font-size:11px;padding:8px">LLM err: '+e.message+'</div>';
|
||
});
|
||
}
|
||
})
|
||
.catch(function(e){
|
||
var body = document.getElementById('advisor-content');
|
||
if (body) body.innerHTML = '<div style="color:#ef4444">Err: '+e.message+'</div>';
|
||
});
|
||
}
|
||
|
||
function oppRow(o, col) {
|
||
var emoji = {in_progress:'🟡', plan:'🔵', idea:'💡'}[o.status] || '⚪';
|
||
var llBadge = '';
|
||
if (o.live_lead) {
|
||
var mql = o.live_lead.mql;
|
||
var bgcol = mql>=90?'#10b981':(mql>=70?'#fbbf24':'#94a3b8');
|
||
llBadge = ' <span style="padding:1px 5px;border-radius:6px;background:'+bgcol+'22;color:'+bgcol+';font-size:9px;font-weight:700" title="MQL score from Paperclip DB">MQL '+mql+(o.live_lead.sql_qualified?' ✅SQL':'')+'</span>';
|
||
}
|
||
return '<div style="padding:6px 8px;margin-bottom:4px;background:rgba(0,0,0,.25);border-radius:4px;font-size:11px">'
|
||
+ '<div style="display:flex;align-items:center;gap:6px;color:#e0e7ff">'+emoji+' <b>'+o.name+'</b>'+llBadge
|
||
+ '<span style="margin-left:auto;color:'+col+';font-weight:700">'+Math.round(o.revenue_mad/1000)+'K MAD</span></div>'
|
||
+ '<div style="font-size:10px;color:#94a3b8;margin-top:2px">effort '+o.effort+'/10 · impact '+o.impact+'/10 · ~'+o.time_days+'j</div>'
|
||
+ '</div>';
|
||
}
|
||
|
||
function buildAdvisor(d) {
|
||
var ll = d.live_leads || {};
|
||
var sc = d.live_scout || {};
|
||
var pr = d.live_predict || {};
|
||
var cap = d.capacity_plan || {};
|
||
|
||
var h = '<div style="display:flex;align-items:center;gap:12px;margin-bottom:16px;flex-wrap:wrap">';
|
||
h += '<h2 style="margin:0;color:#22d3ee;font-size:20px;font-weight:700">🎯 Deep Conversion Advisor V2 · LIVE</h2>';
|
||
h += '<span style="padding:4px 12px;border-radius:12px;background:linear-gradient(135deg,#22d3ee,#a855f7);color:#fff;font-size:10px;font-weight:800">WAVE 229</span>';
|
||
h += '<span style="margin-left:auto;color:#94a3b8;font-size:12px">'+ll.total+' leads · '+sc.total_scans+' scout scans · patterns '+pr.patterns+'</span>';
|
||
h += '</div>';
|
||
|
||
// === LIVE FEEDS row (new wave 229) ===
|
||
h += '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:10px;margin-bottom:16px">';
|
||
// Paperclip leads live
|
||
h += '<div style="padding:14px;background:linear-gradient(135deg,rgba(16,185,129,.15),rgba(16,185,129,.05));border:1px solid rgba(16,185,129,.3);border-radius:10px">';
|
||
h += '<div style="font-size:10px;color:#6ee7b7;text-transform:uppercase;font-weight:700">📊 Paperclip Leads LIVE</div>';
|
||
h += '<div style="font-size:24px;color:#10b981;font-weight:800">'+ll.total+'</div>';
|
||
h += '<div style="font-size:11px;color:#6ee7b7">avg MQL '+ll.avg_mql+' · '+Object.keys(ll.by_country||{}).length+' pays · '+(ll.active_customer||0)+' actifs</div>';
|
||
h += '</div>';
|
||
// WePredict live
|
||
var alertBg = pr.alert ? 'rgba(239,68,68,.15)' : 'rgba(34,211,238,.15)';
|
||
var alertBd = pr.alert ? 'rgba(239,68,68,.3)' : 'rgba(34,211,238,.3)';
|
||
var alertCol = pr.alert ? '#ef4444' : '#22d3ee';
|
||
h += '<div style="padding:14px;background:linear-gradient(135deg,'+alertBg+','+alertBg.replace('.15','.05')+');border:1px solid '+alertBd+';border-radius:10px">';
|
||
h += '<div style="font-size:10px;color:#a5f3fc;text-transform:uppercase;font-weight:700">⚡ WePredict LIVE</div>';
|
||
h += '<div style="font-size:24px;color:'+alertCol+';font-weight:800">load '+(pr.load_next_hour!==null?pr.load_next_hour:'?')+'</div>';
|
||
h += '<div style="font-size:11px;color:#a5f3fc">'+(pr.alert?'🚨 ALERT: '+(cap.plan_recommendation||'scale up'):'✅ OK : capacity normal')+'</div>';
|
||
h += '</div>';
|
||
// Dark Scout live
|
||
h += '<div style="padding:14px;background:linear-gradient(135deg,rgba(139,92,246,.15),rgba(139,92,246,.05));border:1px solid rgba(139,92,246,.3);border-radius:10px">';
|
||
h += '<div style="font-size:10px;color:#c4b5fd;text-transform:uppercase;font-weight:700">🕵 Dark Scout LIVE</div>';
|
||
h += '<div style="font-size:24px;color:#a855f7;font-weight:800">'+sc.total_scans+'</div>';
|
||
h += '<div style="font-size:11px;color:#c4b5fd">scans · '+Object.keys(sc.presets||{}).length+' presets actifs</div>';
|
||
h += '</div>';
|
||
// Revenue totals
|
||
h += '<div style="padding:14px;background:linear-gradient(135deg,rgba(251,191,36,.15),rgba(251,191,36,.05));border:1px solid rgba(251,191,36,.3);border-radius:10px">';
|
||
h += '<div style="font-size:10px;color:#fde68a;text-transform:uppercase;font-weight:700">💰 Pipeline MAD</div>';
|
||
h += '<div style="font-size:24px;color:#fbbf24;font-weight:800">'+Math.round(((d.matrix_revenue.quick_wins_mad||0)+(d.matrix_revenue.big_bets_mad||0))/1000)+'K</div>';
|
||
h += '<div style="font-size:11px;color:#fde68a">QW '+Math.round(d.matrix_revenue.quick_wins_mad/1000)+'K + BB '+Math.round(d.matrix_revenue.big_bets_mad/1000)+'K</div>';
|
||
h += '</div>';
|
||
h += '</div>';
|
||
|
||
// === TOP 5 ===
|
||
h += '<div style="padding:16px;background:rgba(0,0,0,.35);border:1px solid rgba(34,211,238,.2);border-radius:10px;margin-bottom:16px">';
|
||
h += '<div style="font-size:12px;color:#22d3ee;text-transform:uppercase;font-weight:700;margin-bottom:10px">🚀 TOP 5 actions prioritaires</div>';
|
||
(d.recommendations||[]).forEach(function(r){
|
||
h += '<div style="display:grid;grid-template-columns:40px 1fr;gap:10px;padding:8px;border-bottom:1px solid rgba(255,255,255,.04)">';
|
||
h += '<div style="font-size:20px;font-weight:800;color:#22d3ee">#'+r.rank+'</div>';
|
||
h += '<div><div style="font-size:13px;color:#e0f2fe;font-weight:600">'+r.action+'</div><div style="font-size:11px;color:#94a3b8;margin-top:2px">'+r.why+'</div><div style="font-size:10px;color:#64748b">🔗 '+r.deps+'</div></div>';
|
||
h += '</div>';
|
||
});
|
||
h += '</div>';
|
||
|
||
// === LLM-powered reco (new wave 229) ===
|
||
h += '<div style="padding:16px;background:linear-gradient(135deg,rgba(168,85,247,.08),rgba(34,211,238,.08));border:1px solid rgba(168,85,247,.25);border-radius:10px;margin-bottom:16px">';
|
||
h += '<div style="display:flex;align-items:center;gap:8px;margin-bottom:10px">';
|
||
h += '<div style="font-size:12px;color:#a855f7;text-transform:uppercase;font-weight:700">🤖 LLM-powered recommendations</div>';
|
||
h += '<span style="padding:2px 6px;border-radius:8px;background:rgba(168,85,247,.2);color:#c4b5fd;font-size:9.5px;font-weight:700">Cerebras → Groq → Mistral</span>';
|
||
h += '</div>';
|
||
h += '<div id="advisor-llm-box">loading async…</div>';
|
||
h += '</div>';
|
||
|
||
// === Social Signals Hub (NEW WAVE 230) ===
|
||
h += '<div style="padding:16px;background:linear-gradient(135deg,rgba(59,130,246,.12),rgba(168,85,247,.08));border:1px solid rgba(59,130,246,.25);border-radius:10px;margin-bottom:16px">';
|
||
h += '<div style="display:flex;align-items:center;gap:8px;margin-bottom:10px">';
|
||
h += '<div style="font-size:12px;color:#60a5fa;text-transform:uppercase;font-weight:700">📡 Social Signals Hub · conversion ideas adaptées</div>';
|
||
h += '<span style="padding:2px 6px;border-radius:8px;background:rgba(59,130,246,.2);color:#93c5fd;font-size:9.5px;font-weight:700">WAVE 230</span>';
|
||
h += '<button onclick="refreshSocialHub()" style="margin-left:auto;padding:4px 10px;border-radius:8px;background:rgba(59,130,246,.15);color:#bfdbfe;border:1px solid rgba(59,130,246,.3);font-size:10px;cursor:pointer;font-weight:600">🔄 Refresh + LLM</button>';
|
||
h += '</div>';
|
||
h += '<div id="advisor-social-box" style="font-size:11px;color:#94a3b8">Loading LinkedIn + HackerNews + Reddit + YouTube signals…</div>';
|
||
h += '</div>';
|
||
|
||
// === WAVE 254 · MULTI-AGENT ORCHESTRATOR BADGE ===
|
||
h += '<div id="wevia-multiagent-badge" style="padding:12px 14px;background:linear-gradient(90deg,rgba(16,185,129,.15),rgba(34,211,238,.15),rgba(168,85,247,.12));border:1px solid rgba(16,185,129,.4);border-radius:10px;margin-bottom:12px;display:flex;align-items:center;gap:10px;flex-wrap:wrap">';
|
||
h += '<span style="font-size:15px">✅🧠</span>';
|
||
h += '<span style="font-size:12px;color:#67e8f9;font-weight:700">WEVIA Master · Multi-Agent Orchestrator · 0 hallucination</span>';
|
||
h += '<span style="font-size:10px;color:#94a3b8">Pattern CLAUDE 7 phases (Thinking→Plan→Dispatch PARALLEL→Ground→Synthesize→Tests→Response)</span>';
|
||
h += '<button onclick="testMultiAgent()" style="margin-left:auto;padding:4px 10px;border-radius:6px;background:rgba(34,211,238,.25);color:#67e8f9;border:1px solid rgba(34,211,238,.5);font-size:10px;cursor:pointer;font-weight:700">🧪 Test multiagent</button>';
|
||
h += '<button onclick="testWeviaGrounded()" style="padding:4px 10px;border-radius:6px;background:rgba(16,185,129,.2);color:#6ee7b7;border:1px solid rgba(16,185,129,.4);font-size:10px;cursor:pointer;font-weight:700">🔍 Grounding</button>';
|
||
h += '<button onclick="launchMaxParallel()" style="padding:4px 10px;border-radius:6px;background:linear-gradient(135deg,rgba(236,72,153,.3),rgba(168,85,247,.3));color:#fbcfe8;border:1px solid rgba(236,72,153,.5);font-size:10px;cursor:pointer;font-weight:800">🚀 MAX 30 Agents</button>';
|
||
h += '</div>';
|
||
|
||
// === WAVE 253 · WEVIA GROUNDED BADGE (anti-hallucination proof) ===
|
||
h += '<div id="wevia-grounded-badge" style="padding:10px 14px;background:linear-gradient(90deg,rgba(16,185,129,.15),rgba(34,211,238,.08));border:1px solid rgba(16,185,129,.35);border-radius:8px;margin-bottom:12px;display:flex;align-items:center;gap:10px;flex-wrap:wrap">';
|
||
h += '<span style="font-size:14px">✅</span>';
|
||
h += '<span style="font-size:12px;color:#6ee7b7;font-weight:700">WEVIA Master · Grounded data · 0 hallucination</span>';
|
||
h += '<span style="font-size:10px;color:#94a3b8">Chat WEVIA connecté live à Paperclip (48 leads) + Scanner (10 solutions) + DB tasks · wave 253</span>';
|
||
h += '<button onclick="testWeviaGrounded()" style="margin-left:auto;padding:3px 10px;border-radius:6px;background:rgba(16,185,129,.2);color:#6ee7b7;border:1px solid rgba(16,185,129,.4);font-size:10px;cursor:pointer;font-weight:700">🧪 Test grounding</button>';
|
||
h += '</div>';
|
||
|
||
// === WAVE 252 · PREDICTIVE SOLUTION SCANNER ===
|
||
h += '<div style="padding:20px;background:linear-gradient(135deg,rgba(34,211,238,.15),rgba(168,85,247,.08),rgba(16,185,129,.08));border:2px solid rgba(34,211,238,.4);border-radius:14px;margin-bottom:18px;box-shadow:0 10px 40px rgba(34,211,238,.12)">';
|
||
h += '<div style="display:flex;align-items:center;gap:10px;margin-bottom:14px;flex-wrap:wrap">';
|
||
h += '<div style="font-size:16px;color:#67e8f9;text-transform:uppercase;font-weight:800;letter-spacing:.5px">🧠 Système Décisionnel · Predictive Solution Scanner</div>';
|
||
h += '<span style="padding:4px 10px;border-radius:10px;background:linear-gradient(135deg,#22d3ee,#a855f7);color:#fff;font-size:10px;font-weight:800;letter-spacing:.5px">WAVE 252 · AI PREDICT</span>';
|
||
h += '<button onclick="loadSolutionScanner()" style="margin-left:auto;padding:5px 12px;border-radius:8px;background:rgba(34,211,238,.2);color:#67e8f9;border:1px solid rgba(34,211,238,.4);font-size:11px;cursor:pointer;font-weight:700">🔄 Ré-analyser</button>';
|
||
h += '</div>';
|
||
h += '<div style="font-size:11px;color:#94a3b8;margin-bottom:12px">WePredict analyse tes 48 leads Paperclip + maturité produits + capabilities gaps → dit QUOI développer, QUOI lancer, combien de jours dev, gaps à combler pour ready multi-user web</div>';
|
||
h += '<div id="advisor-solution-scanner" style="color:#94a3b8">Loading predictive analysis…</div>';
|
||
h += '</div>';
|
||
|
||
// === WAVE 251 · DECISIONAL MATRIX · Effort vs Rendement + Benchmarks concurrence ===
|
||
h += '<div style="padding:18px;background:linear-gradient(135deg,rgba(236,72,153,.12),rgba(168,85,247,.08),rgba(16,185,129,.05));border:2px solid rgba(236,72,153,.4);border-radius:14px;margin-bottom:16px;box-shadow:0 8px 32px rgba(236,72,153,.1)">';
|
||
h += '<div style="display:flex;align-items:center;gap:10px;margin-bottom:14px">';
|
||
h += '<div style="font-size:15px;color:#f0abfc;text-transform:uppercase;font-weight:800;letter-spacing:.5px">🎯 Décisionnel · Solutions les plus matures à sortir au marché</div>';
|
||
h += '<span style="padding:3px 10px;border-radius:10px;background:linear-gradient(135deg,#ec4899,#a855f7);color:#fff;font-size:10px;font-weight:800;letter-spacing:.5px">WAVE 251 · BENCHMARK</span>';
|
||
h += '<span style="margin-left:auto;font-size:10px;color:#94a3b8">Classement: effort ↗ · rendement ↗ · maturité marché</span>';
|
||
h += '</div>';
|
||
|
||
// Build decisional matrix with real benchmarks
|
||
h += '<div id="advisor-decisional-matrix" style="color:#94a3b8"></div>';
|
||
h += '</div>';
|
||
|
||
// === WAVE 246 · KPI Dashboard Charts ===
|
||
h += '<div style="padding:16px;background:linear-gradient(135deg,rgba(16,185,129,.1),rgba(251,191,36,.05));border:1px solid rgba(16,185,129,.25);border-radius:10px;margin-bottom:16px">';
|
||
h += '<div style="display:flex;align-items:center;gap:8px;margin-bottom:10px">';
|
||
h += '<div style="font-size:12px;color:#10b981;text-transform:uppercase;font-weight:700">📊 KPI Dashboard · live charts</div>';
|
||
h += '<span style="padding:2px 6px;border-radius:8px;background:rgba(16,185,129,.2);color:#6ee7b7;font-size:9.5px;font-weight:700">WAVE 246</span>';
|
||
h += '<button onclick="loadKpiDashboard()" style="margin-left:auto;padding:4px 10px;border-radius:8px;background:rgba(16,185,129,.15);color:#6ee7b7;border:1px solid rgba(16,185,129,.3);font-size:10px;cursor:pointer;font-weight:600">🔄 Refresh</button>';
|
||
h += '</div>';
|
||
h += '<div id="advisor-kpi-box" style="color:#94a3b8">Loading KPI charts…</div>';
|
||
h += '</div>';
|
||
|
||
// === WAVE 247 · Kanban Board (NEW) ===
|
||
h += '<div style="padding:16px;background:linear-gradient(135deg,rgba(168,85,247,.08),rgba(34,211,238,.05));border:1px solid rgba(168,85,247,.25);border-radius:10px;margin-bottom:16px">';
|
||
h += '<div style="display:flex;align-items:center;gap:8px;margin-bottom:10px">';
|
||
h += '<div style="font-size:12px;color:#a855f7;text-transform:uppercase;font-weight:700">📋 Kanban Board · tasks par status</div>';
|
||
h += '<span style="padding:2px 6px;border-radius:8px;background:rgba(168,85,247,.2);color:#c4b5fd;font-size:9.5px;font-weight:700">WAVE 247</span>';
|
||
h += '<button onclick="loadKanban()" style="margin-left:auto;padding:4px 10px;border-radius:8px;background:rgba(168,85,247,.15);color:#c4b5fd;border:1px solid rgba(168,85,247,.3);font-size:10px;cursor:pointer;font-weight:600">🔄 Refresh</button>';
|
||
h += '</div>';
|
||
h += '<div id="advisor-kanban-box" style="color:#94a3b8">Loading kanban…</div>';
|
||
h += '</div>';
|
||
|
||
// === WAVE 248 · Pipeline Stages (NEW) ===
|
||
h += '<div style="padding:16px;background:linear-gradient(135deg,rgba(59,130,246,.1),rgba(16,185,129,.05));border:1px solid rgba(59,130,246,.25);border-radius:10px;margin-bottom:16px">';
|
||
h += '<div style="display:flex;align-items:center;gap:8px;margin-bottom:10px">';
|
||
h += '<div style="font-size:12px;color:#60a5fa;text-transform:uppercase;font-weight:700">🔁 Pipeline Stages · deal flow</div>';
|
||
h += '<span style="padding:2px 6px;border-radius:8px;background:rgba(59,130,246,.2);color:#93c5fd;font-size:9.5px;font-weight:700">WAVE 248</span>';
|
||
h += '<button onclick="loadPipelineStages()" style="margin-left:auto;padding:4px 10px;border-radius:8px;background:rgba(59,130,246,.15);color:#bfdbfe;border:1px solid rgba(59,130,246,.3);font-size:10px;cursor:pointer;font-weight:600">🔄 Refresh</button>';
|
||
h += '</div>';
|
||
h += '<div id="advisor-pipeline-box" style="color:#94a3b8">Loading pipeline…</div>';
|
||
h += '</div>';
|
||
|
||
// === WAVE 249 · Activity Timeline (NEW) ===
|
||
h += '<div style="padding:16px;background:linear-gradient(135deg,rgba(251,191,36,.08),rgba(236,72,153,.05));border:1px solid rgba(251,191,36,.25);border-radius:10px;margin-bottom:16px">';
|
||
h += '<div style="display:flex;align-items:center;gap:8px;margin-bottom:10px">';
|
||
h += '<div style="font-size:12px;color:#fbbf24;text-transform:uppercase;font-weight:700">🕒 Activity Timeline · unified feed</div>';
|
||
h += '<span style="padding:2px 6px;border-radius:8px;background:rgba(251,191,36,.2);color:#fde68a;font-size:9.5px;font-weight:700">WAVE 249</span>';
|
||
h += '<button onclick="loadActivityTimeline()" style="margin-left:auto;padding:4px 10px;border-radius:8px;background:rgba(251,191,36,.15);color:#fde68a;border:1px solid rgba(251,191,36,.3);font-size:10px;cursor:pointer;font-weight:600">🔄 Refresh</button>';
|
||
h += '</div>';
|
||
h += '<div id="advisor-timeline-box" style="color:#94a3b8">Loading timeline…</div>';
|
||
h += '</div>';
|
||
|
||
// === WAVE 250 · Task Search (NEW) ===
|
||
h += '<div style="padding:16px;background:linear-gradient(135deg,rgba(236,72,153,.08),rgba(34,211,238,.05));border:1px solid rgba(236,72,153,.25);border-radius:10px;margin-bottom:16px">';
|
||
h += '<div style="display:flex;align-items:center;gap:8px;margin-bottom:10px">';
|
||
h += '<div style="font-size:12px;color:#ec4899;text-transform:uppercase;font-weight:700">🔎 Task Search · filter by text/status/MAD</div>';
|
||
h += '<span style="padding:2px 6px;border-radius:8px;background:rgba(236,72,153,.2);color:#fbcfe8;font-size:9.5px;font-weight:700">WAVE 250</span>';
|
||
h += '</div>';
|
||
h += '<div style="display:flex;gap:6px;margin-bottom:10px;flex-wrap:wrap">';
|
||
h += '<input type="text" id="search-q" placeholder="🔎 title or opportunity…" style="flex:1;min-width:180px;padding:7px 10px;border-radius:6px;background:rgba(0,0,0,.4);color:#e0e7ff;border:1px solid rgba(236,72,153,.3);font-size:12px" onkeydown="if(event.key===\'Enter\')runSearch()">';
|
||
h += '<select id="search-status" style="padding:7px 10px;border-radius:6px;background:rgba(0,0,0,.4);color:#e0e7ff;border:1px solid rgba(236,72,153,.3);font-size:12px"><option value="">All statuses</option><option value="proposed">proposed</option><option value="in_progress">in_progress</option><option value="done">done</option><option value="cancelled">cancelled</option><option value="blocked">blocked</option></select>';
|
||
h += '<input type="number" id="search-min-mad" placeholder="Min MAD" style="width:100px;padding:7px 10px;border-radius:6px;background:rgba(0,0,0,.4);color:#e0e7ff;border:1px solid rgba(236,72,153,.3);font-size:12px">';
|
||
h += '<button onclick="runSearch()" style="padding:7px 14px;border-radius:6px;background:rgba(236,72,153,.2);color:#fbcfe8;border:1px solid rgba(236,72,153,.4);font-size:11px;cursor:pointer;font-weight:700">Search</button>';
|
||
h += '</div>';
|
||
h += '<div id="advisor-search-results" style="color:#94a3b8;font-size:11px">Type a query + enter to search…</div>';
|
||
h += '</div>';
|
||
|
||
// === Matrix ===
|
||
h += '<div style="padding:16px;background:rgba(0,0,0,.35);border:1px solid rgba(168,85,247,.2);border-radius:10px;margin-bottom:16px">';
|
||
h += '<div style="font-size:12px;color:#a855f7;text-transform:uppercase;font-weight:700;margin-bottom:10px">📊 Matrice Effort × Impact (Eisenhower)</div>';
|
||
h += '<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px">';
|
||
h += '<div style="padding:12px;background:rgba(16,185,129,.08);border:1px solid rgba(16,185,129,.25);border-radius:8px"><div style="font-size:11px;color:#6ee7b7;font-weight:700;margin-bottom:6px">✅ QUICK WINS · FAIS MAINTENANT</div>'+(d.matrix.quick_wins||[]).map(function(o){return oppRow(o,'#10b981');}).join('')+'</div>';
|
||
h += '<div style="padding:12px;background:rgba(168,85,247,.08);border:1px solid rgba(168,85,247,.25);border-radius:8px"><div style="font-size:11px;color:#c4b5fd;font-weight:700;margin-bottom:6px">🎯 BIG BETS · PLANIFIE</div>'+(d.matrix.big_bets||[]).map(function(o){return oppRow(o,'#a855f7');}).join('')+'</div>';
|
||
h += '<div style="padding:12px;background:rgba(251,191,36,.08);border:1px solid rgba(251,191,36,.25);border-radius:8px"><div style="font-size:11px;color:#fde68a;font-weight:700;margin-bottom:6px">💡 FILL-INS · DELEGUE</div>'+((d.matrix.fill_ins||[]).length?(d.matrix.fill_ins||[]).map(function(o){return oppRow(o,'#fbbf24');}).join(''):'<div style="color:#94a3b8;font-size:11px">(aucune)</div>')+'</div>';
|
||
h += '<div style="padding:12px;background:rgba(239,68,68,.08);border:1px solid rgba(239,68,68,.25);border-radius:8px"><div style="font-size:11px;color:#fca5a5;font-weight:700;margin-bottom:6px">⛔ THANKLESS · EVITE</div>'+((d.matrix.thankless||[]).length?(d.matrix.thankless||[]).map(function(o){return oppRow(o,'#ef4444');}).join(''):'<div style="color:#94a3b8;font-size:11px">(aucune)</div>')+'</div>';
|
||
h += '</div></div>';
|
||
|
||
// === Sovereign IA 9 cards ===
|
||
h += '<div style="padding:16px;background:rgba(0,0,0,.35);border:1px solid rgba(251,191,36,.2);border-radius:10px;margin-bottom:16px">';
|
||
h += '<div style="font-size:12px;color:#fbbf24;text-transform:uppercase;font-weight:700;margin-bottom:10px">🧠 '+d.sovereign_ia_count+' IA Souveraines · live state</div>';
|
||
h += '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:10px">';
|
||
(d.sovereign_ia||[]).forEach(function(s){
|
||
h += '<div style="padding:12px;background:rgba(0,0,0,.25);border:1px solid rgba(251,191,36,.15);border-radius:8px">';
|
||
h += '<div style="display:flex;align-items:center;gap:6px;margin-bottom:4px"><a href="'+s.url+'" target="_blank" style="color:#fde68a;font-weight:700;font-size:13px;text-decoration:none">'+s.name+' ↗</a><span style="margin-left:auto;padding:1px 6px;border-radius:8px;background:rgba(16,185,129,.2);color:#6ee7b7;font-size:9.5px;font-weight:700">live</span></div>';
|
||
h += '<div style="font-size:10px;color:#94a3b8;text-transform:uppercase;margin-bottom:3px">'+s.category+'</div>';
|
||
h += '<div style="font-size:11px;color:#fde68a;margin-bottom:4px">'+s.capability+'</div>';
|
||
if (s.live_state) h += '<div style="font-size:10px;color:#22d3ee;padding:3px 5px;background:rgba(34,211,238,.05);border-radius:3px;margin-bottom:4px">🔴 '+s.live_state+'</div>';
|
||
h += '<div style="font-size:10.5px;color:#10b981;padding:3px 5px;background:rgba(16,185,129,.05);border-radius:3px;border-left:2px solid #10b981">💡 '+s.use_for_conversion+'</div>';
|
||
h += '<div style="margin-top:4px;height:3px;background:rgba(255,255,255,.04);border-radius:2px;overflow:hidden"><div style="height:100%;width:'+s.maturity+'%;background:linear-gradient(90deg,#fbbf24,#10b981)"></div></div>';
|
||
h += '</div>';
|
||
});
|
||
h += '</div></div>';
|
||
|
||
// === Competitors enriched with Dark Scout scans ===
|
||
h += '<div style="padding:16px;background:rgba(0,0,0,.35);border:1px solid rgba(236,72,153,.2);border-radius:10px;margin-bottom:16px">';
|
||
h += '<div style="font-size:12px;color:#ec4899;text-transform:uppercase;font-weight:700;margin-bottom:10px">🥊 Concurrence · scout scans integrated</div>';
|
||
h += '<div style="display:flex;flex-direction:column;gap:6px">';
|
||
(d.competitors||[]).forEach(function(c){
|
||
var tc = {low:'#10b981', medium:'#fbbf24', high:'#ef4444'}[c.threat] || '#94a3b8';
|
||
h += '<div style="padding:9px 11px;background:rgba(0,0,0,.2);border:1px solid rgba(236,72,153,.15);border-left:3px solid '+tc+';border-radius:6px">';
|
||
h += '<div style="display:flex;align-items:center;gap:8px;flex-wrap:wrap"><b style="color:#fbcfe8;font-size:12px">'+c.category+'</b><span style="padding:1px 6px;border-radius:8px;background:'+tc+'22;color:'+tc+';font-size:9px;font-weight:700">threat '+c.threat+'</span>';
|
||
if (c.scout_scans) h += '<span style="padding:1px 6px;border-radius:8px;background:rgba(139,92,246,.15);color:#c4b5fd;font-size:9px;font-weight:700">🕵 '+c.scout_scans+' scout scans</span>';
|
||
h += '</div>';
|
||
h += '<div style="font-size:11px;color:#94a3b8;margin-top:3px">vs: '+c.competitors.join(' · ')+'</div>';
|
||
h += '<div style="font-size:11px;color:#6ee7b7;margin-top:3px">💪 edge: '+c.weval_edge+'</div>';
|
||
h += '</div>';
|
||
});
|
||
h += '</div></div>';
|
||
|
||
// === Leads preview (new wave 229) ===
|
||
if (ll.top_leads && ll.top_leads.length) {
|
||
h += '<div style="padding:16px;background:rgba(0,0,0,.35);border:1px solid rgba(16,185,129,.2);border-radius:10px;margin-bottom:16px">';
|
||
h += '<div style="font-size:12px;color:#10b981;text-transform:uppercase;font-weight:700;margin-bottom:10px">📋 Top 10 leads · Paperclip live</div>';
|
||
h += '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:8px">';
|
||
ll.top_leads.forEach(function(l){
|
||
var mc = l.mql>=90?'#10b981':(l.mql>=70?'#fbbf24':'#94a3b8');
|
||
h += '<div style="padding:8px 10px;background:rgba(0,0,0,.2);border:1px solid rgba(255,255,255,.04);border-left:3px solid '+mc+';border-radius:6px">';
|
||
h += '<div style="display:flex;align-items:center;gap:6px"><b style="color:#e0e7ff;font-size:12px">'+l.company+'</b><span style="margin-left:auto;font-size:11px;color:'+mc+';font-weight:700">MQL '+l.mql+(l.sql_qualified?' ✅':'')+'</span></div>';
|
||
h += '<div style="font-size:10px;color:#94a3b8;margin-top:2px">'+l.contact+' · '+l.industry+' · '+l.country+'</div>';
|
||
if (l.notes) h += '<div style="font-size:10px;color:#64748b;margin-top:2px">'+l.notes.slice(0,80)+'</div>';
|
||
h += '</div>';
|
||
});
|
||
h += '</div></div>';
|
||
}
|
||
|
||
// === Ask WEVIA prompts ===
|
||
h += '<div style="padding:14px;background:linear-gradient(135deg,rgba(34,211,238,.08),rgba(168,85,247,.08));border:1px solid rgba(34,211,238,.25);border-radius:10px">';
|
||
h += '<div style="font-size:12px;color:#22d3ee;font-weight:700;margin-bottom:8px">💬 Ask WEVIA Master (orchestration multi-agent)</div>';
|
||
h += '<div style="display:flex;flex-wrap:wrap;gap:6px">';
|
||
var prompts = [
|
||
['→ Plan 7j Vistex Cosumar','Plan 7 jours pour closer Vistex Cosumar: objections + contre-propositions + steps','#6ee7b7'],
|
||
['→ Pricing API HCP','Pricing API HCP Maghreb 3 tiers + Stripe integration','#c4b5fd'],
|
||
['→ LinkedIn outbound','Séquence LinkedIn outbound Blade+WEVADS 9 winners 20 prospects','#a5f3fc'],
|
||
['→ Freemium plan','Plan lancement SaaS Freemium: landing + pricing + onboarding 45j','#fde68a'],
|
||
['→ Scout pharma','Dark Scout intelligence pharma Maroc + concurrent signals','#fbcfe8']
|
||
];
|
||
prompts.forEach(function(p){
|
||
h += '<button onclick="var i=document.getElementById(\'cI\');if(i){i.value=\''+p[1].replace(/\x27/g,"\\\x27")+'\';i.focus();}" style="padding:6px 12px;border-radius:8px;background:'+p[2]+'22;color:'+p[2]+';border:1px solid '+p[2]+'55;font-size:11px;cursor:pointer;font-weight:600">'+p[0]+'</button>';
|
||
});
|
||
h += '</div></div>';
|
||
|
||
return h;
|
||
}
|
||
|
||
document.addEventListener('click', function(e) {
|
||
var t = e.target.closest && e.target.closest('[data-v="advisor"]');
|
||
if (t) setTimeout(renderAdvisor, 200);
|
||
});
|
||
// Also expose global for debug
|
||
|
||
|
||
function refreshSocialHub() {
|
||
var box = document.getElementById('advisor-social-box');
|
||
if (!box) return;
|
||
box.innerHTML = '<div style="color:#60a5fa">🔍 Scanning LinkedIn + HackerNews + Reddit + YouTube + LLM cascade (15-30s)…</div>';
|
||
fetch('/api/social-signals-hub.php?llm=1&topics=SaaS%20conversion,LinkedIn%20outbound,pharma%20digital&cb='+Date.now())
|
||
.then(function(r){return r.json();})
|
||
.then(function(d){ box.innerHTML = buildSocialHub(d); })
|
||
.catch(function(e){ box.innerHTML = '<div style="color:#ef4444">Err: '+e.message+'</div>'; });
|
||
}
|
||
|
||
function buildSocialHub(d) {
|
||
var html = '';
|
||
// Channel summary cards
|
||
html += '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));gap:8px;margin-bottom:12px">';
|
||
var icons = {linkedin:'💼', hackernews:'🟧', reddit:'🔴', youtube:'📹'};
|
||
var cols = {linkedin:'#60a5fa', hackernews:'#f97316', reddit:'#ef4444', youtube:'#dc2626'};
|
||
Object.keys(d.channels || {}).forEach(function(ch){
|
||
var c = d.channels[ch];
|
||
html += '<div style="padding:8px;background:rgba(0,0,0,.25);border:1px solid '+(cols[ch]||'#94a3b8')+'33;border-radius:6px">';
|
||
html += '<div style="font-size:10px;color:'+(cols[ch]||'#94a3b8')+';font-weight:700">'+(icons[ch]||'●')+' '+ch+'</div>';
|
||
html += '<div style="font-size:18px;color:#e0e7ff;font-weight:800">'+(c.count||0)+'</div>';
|
||
html += '<div style="font-size:9px;color:#64748b">'+(c.source||'')+'</div>';
|
||
html += '</div>';
|
||
});
|
||
html += '</div>';
|
||
|
||
// LLM conversion ideas (if any)
|
||
var llm = d.llm_conversion_ideas;
|
||
if (llm && llm.raw) {
|
||
html += '<div style="padding:12px;background:rgba(139,92,246,.08);border:1px solid rgba(139,92,246,.25);border-radius:8px;margin-bottom:12px">';
|
||
html += '<div style="font-size:11px;color:#a855f7;font-weight:700;margin-bottom:8px">✨ LLM Conversion Ideas ('+llm.provider+')</div>';
|
||
var m = llm.raw.match(/\{[\s\S]*\}/);
|
||
if (m) {
|
||
try {
|
||
var j = JSON.parse(m[0]);
|
||
(j.ideas || []).forEach(function(idea){
|
||
html += '<div style="padding:9px;margin-bottom:6px;background:rgba(0,0,0,.25);border-left:3px solid #a855f7;border-radius:6px" data-idea-idx="'+idea.rank+'">';
|
||
html += '<div style="display:flex;align-items:center;gap:6px"><b style="color:#c4b5fd;font-size:12px">#'+idea.rank+' '+idea.title+'</b>';
|
||
html += '<span style="margin-left:auto;color:#fbbf24;font-size:11px;font-weight:700">'+(idea.estimated_mad?Math.round(idea.estimated_mad/1000)+'K MAD':'')+'</span>';
|
||
html += '<button onclick="createTaskFromIdea('+JSON.stringify(idea).replace(/"/g,""")+')" style="padding:3px 8px;margin-left:4px;border-radius:6px;background:rgba(16,185,129,.2);color:#6ee7b7;border:1px solid rgba(16,185,129,.4);font-size:10px;cursor:pointer;font-weight:700">+ Task</button>';
|
||
html += '<button onclick="askWeviaFromIdea('+JSON.stringify(idea).replace(/"/g,""")+')" style="padding:3px 8px;margin-left:4px;border-radius:6px;background:rgba(34,211,238,.2);color:#a5f3fc;border:1px solid rgba(34,211,238,.4);font-size:10px;cursor:pointer;font-weight:700">💬 Ask WEVIA</button>';
|
||
html += '</div>';
|
||
html += '<div style="font-size:10px;color:#94a3b8;margin-top:3px">🎯 '+(idea.opportunity||'')+' · 📡 '+(idea.channel||'')+'</div>';
|
||
html += '<div style="font-size:10px;color:#64748b;margin-top:2px">🔧 '+((idea.tools_used||[]).join(' · '))+'</div>';
|
||
(idea.first_steps||[]).forEach(function(s){
|
||
html += '<div style="font-size:10.5px;color:#e0e7ff;padding:2px 0 2px 14px;position:relative"><span style="position:absolute;left:2px;color:#10b981">→</span>'+s+'</div>';
|
||
});
|
||
if (idea.kpi) html += '<div style="font-size:10px;color:#6ee7b7;margin-top:2px">📊 KPI: '+idea.kpi+'</div>';
|
||
if (idea.inspired_by) html += '<div style="font-size:9.5px;color:#60a5fa;margin-top:2px;font-style:italic">💡 inspired: '+idea.inspired_by+'</div>';
|
||
html += '</div>';
|
||
});
|
||
} catch(e) { html += '<pre style="color:#ddd6fe;white-space:pre-wrap;font-size:10px;max-height:220px;overflow-y:auto">'+llm.raw.slice(0,1800)+'</pre>'; }
|
||
} else { html += '<pre style="color:#ddd6fe;white-space:pre-wrap;font-size:10px;max-height:220px;overflow-y:auto">'+llm.raw.slice(0,1800)+'</pre>'; }
|
||
html += '</div>';
|
||
}
|
||
|
||
// Top signals 4 channels horizontal
|
||
html += '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px">';
|
||
Object.keys(d.channels || {}).forEach(function(ch){
|
||
var c = d.channels[ch];
|
||
if (!c.items || !c.items.length) return;
|
||
html += '<div style="padding:10px;background:rgba(0,0,0,.25);border:1px solid rgba(255,255,255,.04);border-radius:6px">';
|
||
html += '<div style="font-size:10px;color:'+(cols[ch]||'#94a3b8')+';font-weight:700;margin-bottom:6px">'+(icons[ch]||'●')+' '+ch.toUpperCase()+' TOP</div>';
|
||
c.items.slice(0,5).forEach(function(item){
|
||
var meta = '';
|
||
if (item.points !== undefined) meta = '★'+item.points;
|
||
else if (item.likes !== undefined) meta = '♥'+item.likes+' 👁'+(item.views||0);
|
||
else if (item.score !== undefined) meta = '↑'+item.score;
|
||
html += '<a href="'+(item.url||'#')+'" target="_blank" style="display:block;padding:4px 0;border-bottom:1px solid rgba(255,255,255,.04);color:#cbd5e1;font-size:10.5px;text-decoration:none">';
|
||
html += (item.title||'').slice(0,70);
|
||
if (meta) html += ' <span style="color:#64748b;font-size:9px">'+meta+'</span>';
|
||
html += '</a>';
|
||
});
|
||
html += '</div>';
|
||
});
|
||
html += '</div>';
|
||
|
||
return html;
|
||
}
|
||
|
||
// Auto-load social hub when advisor tab opened - call after buildAdvisor
|
||
var origRender = renderAdvisor;
|
||
renderAdvisor = function() {
|
||
origRender();
|
||
setTimeout(refreshSocialHub, 800);
|
||
};
|
||
|
||
|
||
// Wave 231: Auto-create Paperclip task from LLM idea
|
||
window.createTaskFromIdea = function(idea) {
|
||
var btn = event && event.target;
|
||
if (btn) { btn.disabled = true; btn.textContent = '...'; }
|
||
fetch('/api/social-signals-hub.php?action=create_task', {
|
||
method: 'POST',
|
||
headers: {'Content-Type': 'application/json'},
|
||
body: JSON.stringify({
|
||
title: idea.title,
|
||
source: 'advisor-wave231',
|
||
source_ref: 'growth-engine-v2',
|
||
category: idea.channel || 'conversion',
|
||
opportunity: idea.opportunity || '',
|
||
tools_used: idea.tools_used || [],
|
||
first_steps: idea.first_steps || [],
|
||
kpi: idea.kpi || '',
|
||
estimated_mad: idea.estimated_mad || 0,
|
||
inspired_by: idea.inspired_by || '',
|
||
})
|
||
})
|
||
.then(function(r){return r.json();})
|
||
.then(function(d){
|
||
if (btn) {
|
||
btn.textContent = d.ok ? '✓ #' + d.task_id : '✗ err';
|
||
btn.style.background = d.ok ? 'rgba(16,185,129,.4)' : 'rgba(239,68,68,.3)';
|
||
}
|
||
setTimeout(loadWave231Tasks, 500);
|
||
})
|
||
.catch(function(e){
|
||
if (btn) { btn.textContent = '✗'; btn.style.background = 'rgba(239,68,68,.3)'; }
|
||
});
|
||
};
|
||
|
||
window.loadWave231Tasks = function() {
|
||
var box = document.getElementById('wave231Tasks');
|
||
if (!box) return;
|
||
box.innerHTML = '<div style="color:#94a3b8;font-size:11px">Loading Paperclip tasks…</div>';
|
||
fetch('/api/social-signals-hub.php?action=list_tasks&cb='+Date.now())
|
||
.then(function(r){return r.json();})
|
||
.then(function(d){
|
||
if (!d.ok || !d.tasks.length) {
|
||
box.innerHTML = '<div style="color:#64748b;font-size:11px;padding:8px">No tasks yet · click + Task on any LLM idea above to create</div>';
|
||
return;
|
||
}
|
||
var html = '<div style="font-size:11px;color:#6ee7b7;margin-bottom:8px;font-weight:700">📋 '+d.count+' tasks · ';
|
||
if (d.by_status) {
|
||
Object.keys(d.by_status).forEach(function(s){
|
||
var c = {proposed:'#fbbf24',in_progress:'#22d3ee',done:'#10b981',cancelled:'#94a3b8',blocked:'#ef4444'}[s] || '#94a3b8';
|
||
html += '<span style="padding:1px 6px;margin-right:4px;border-radius:6px;background:'+c+'22;color:'+c+';font-size:10px">'+s+': '+d.by_status[s]+'</span>';
|
||
});
|
||
}
|
||
html += '</div>';
|
||
d.tasks.forEach(function(t){
|
||
var colStatus = {proposed:'#fbbf24',in_progress:'#22d3ee',done:'#10b981',cancelled:'#94a3b8',blocked:'#ef4444'}[t.status] || '#94a3b8';
|
||
html += '<div class="wave232StatusBtns" style="padding:8px 10px;margin-bottom:4px;background:rgba(0,0,0,.2);border:1px solid rgba(16,185,129,.15);border-left:3px solid '+colStatus+';border-radius:6px">';
|
||
html += '<div style="display:flex;align-items:center;gap:6px;flex-wrap:wrap"><b style="color:#e0e7ff;font-size:11.5px">#'+t.id+' '+t.title+'</b>';
|
||
html += '<span style="margin-left:auto;padding:1px 6px;border-radius:6px;background:'+colStatus+'22;color:'+colStatus+';font-size:9px;font-weight:700">'+t.status+'</span></div>';
|
||
html += '<div style="font-size:10px;color:#94a3b8;margin-top:3px">🎯 '+(t.opportunity||'')+' · '+(t.estimated_mad?Math.round(t.estimated_mad/1000)+'K MAD':'')+' · '+((t.created_at||'').slice(0,16))+'</div>';
|
||
if (t.tools_used) html += '<div style="font-size:10px;color:#64748b;margin-top:2px">🔧 '+t.tools_used.replace(/\|/g,' · ')+'</div>';
|
||
if (t.kpi) html += '<div style="font-size:10px;color:#6ee7b7;margin-top:2px">📊 '+t.kpi+'</div>';
|
||
// Wave 232: status workflow buttons
|
||
html += '<div style="display:flex;gap:4px;margin-top:5px;flex-wrap:wrap">';
|
||
['proposed','in_progress','done','cancelled','blocked'].forEach(function(s){
|
||
if (s === t.status) return;
|
||
var sc = {proposed:'#fbbf24',in_progress:'#22d3ee',done:'#10b981',cancelled:'#94a3b8',blocked:'#ef4444'}[s];
|
||
html += '<button onclick="updateTaskStatus('+t.id+', \''+s+'\')" style="padding:2px 7px;border-radius:5px;background:'+sc+'15;color:'+sc+';border:1px solid '+sc+'44;font-size:9px;cursor:pointer;font-weight:600">→ '+s+'</button>';
|
||
});
|
||
html += '</div>';
|
||
html += '</div>';
|
||
});
|
||
box.innerHTML = html;
|
||
})
|
||
.catch(function(e){
|
||
box.innerHTML = '<div style="color:#ef4444;font-size:11px">Err: '+e.message+'</div>';
|
||
});
|
||
};
|
||
|
||
// Wave 232: Update task status workflow
|
||
window.updateTaskStatus = function(taskId, newStatus) {
|
||
fetch('/api/social-signals-hub.php?action=update_status', {
|
||
method: 'POST',
|
||
headers: {'Content-Type': 'application/json'},
|
||
body: JSON.stringify({task_id: taskId, status: newStatus})
|
||
})
|
||
.then(function(r){return r.json();})
|
||
.then(function(d){
|
||
if (d.ok) { setTimeout(loadWave231Tasks, 300); }
|
||
});
|
||
};
|
||
|
||
// Wave 232: SSE stream visualization
|
||
window.startWave232SSE = function() {
|
||
var sseBox = document.getElementById('wave232SSE');
|
||
if (!sseBox) return;
|
||
sseBox.innerHTML = '<div style="color:#a855f7;font-size:11px">🔴 SSE stream connecting…</div>';
|
||
try {
|
||
var es = new EventSource('/api/social-signals-hub.php?action=stream&cb='+Date.now());
|
||
var events = [];
|
||
function render() {
|
||
var html = '<div style="font-size:11px;color:#c4b5fd;margin-bottom:6px">🔴 Live stream · '+events.length+' events</div>';
|
||
events.slice(-8).forEach(function(e){
|
||
var col = {hello:'#10b981',channel:'#22d3ee',tasks:'#fbbf24',done:'#a855f7'}[e.event] || '#94a3b8';
|
||
html += '<div style="padding:4px 8px;margin-bottom:3px;border-left:2px solid '+col+';background:rgba(0,0,0,.2);font-size:10px;color:#e0e7ff"><span style="color:'+col+';font-weight:700">'+e.event+'</span> · ';
|
||
if (e.data.name) html += '<b>'+e.data.name+'</b> count='+(e.data.count||0)+' · '+(e.data.top||'').slice(0,50);
|
||
else if (e.data.by_status) html += 'tasks: '+JSON.stringify(e.data.by_status);
|
||
else if (e.data.msg) html += e.data.msg;
|
||
else if (e.data.total_channels) html += 'done · '+e.data.total_channels+' channels streamed';
|
||
html += '</div>';
|
||
});
|
||
sseBox.innerHTML = html;
|
||
}
|
||
['hello','channel','tasks','done'].forEach(function(evName){
|
||
es.addEventListener(evName, function(e){
|
||
events.push({event: evName, data: JSON.parse(e.data)});
|
||
render();
|
||
if (evName === 'done') setTimeout(function(){es.close();}, 1000);
|
||
});
|
||
});
|
||
es.onerror = function(){ sseBox.innerHTML += '<div style="color:#94a3b8;font-size:10px">stream closed</div>'; es.close(); };
|
||
} catch(e) {
|
||
sseBox.innerHTML = '<div style="color:#ef4444">SSE err: '+e.message+'</div>';
|
||
}
|
||
};
|
||
|
||
// Inject tasks section after advisor renders
|
||
var origBuildSocial = buildSocialHub;
|
||
buildSocialHub = function(d) {
|
||
var h = origBuildSocial(d);
|
||
h += '<div style="margin-top:14px;padding:12px;background:rgba(16,185,129,.06);border:1px solid rgba(16,185,129,.25);border-radius:8px">';
|
||
h += '<div style="display:flex;align-items:center;gap:8px;margin-bottom:8px"><b style="color:#10b981;font-size:11px;text-transform:uppercase">📋 Paperclip Tasks · Auto-created</b>';
|
||
h += '<span style="padding:2px 6px;border-radius:6px;background:rgba(16,185,129,.2);color:#6ee7b7;font-size:9px;font-weight:700">WAVE 231</span>';
|
||
h += '<button onclick="loadWave231Tasks()" style="margin-left:auto;padding:3px 8px;border-radius:6px;background:rgba(16,185,129,.15);color:#6ee7b7;border:1px solid rgba(16,185,129,.3);font-size:10px;cursor:pointer">🔄 Refresh</button></div>';
|
||
h += '<div id="wave231Tasks">loading…</div>';
|
||
h += '</div>';
|
||
// Wave 232: SSE live stream panel
|
||
h += '<div style="margin-top:12px;padding:12px;background:rgba(168,85,247,.06);border:1px solid rgba(168,85,247,.25);border-radius:8px">';
|
||
h += '<div style="display:flex;align-items:center;gap:8px;margin-bottom:8px"><b style="color:#a855f7;font-size:11px;text-transform:uppercase">🔴 Live SSE Stream · channels + tasks</b>';
|
||
h += '<span style="padding:2px 6px;border-radius:6px;background:rgba(168,85,247,.2);color:#c4b5fd;font-size:9px;font-weight:700">WAVE 232</span>';
|
||
h += '<button onclick="startWave232SSE()" style="margin-left:auto;padding:3px 8px;border-radius:6px;background:rgba(168,85,247,.15);color:#c4b5fd;border:1px solid rgba(168,85,247,.3);font-size:10px;cursor:pointer">▶ Start stream</button></div>';
|
||
h += '<div id="wave232SSE"><div style="color:#64748b;font-size:10px">Click ▶ Start stream to connect SSE endpoint</div></div>';
|
||
h += '</div>';
|
||
setTimeout(loadWave231Tasks, 600);
|
||
return h;
|
||
};
|
||
|
||
|
||
|
||
// WAVE 233: Toast notification system
|
||
window.__wevalToast = function(msg, color) {
|
||
color = color || '#10b981';
|
||
var t = document.createElement('div');
|
||
t.style.cssText = 'position:fixed;bottom:20px;right:20px;padding:12px 18px;border-radius:10px;background:rgba(0,0,0,.9);color:'+color+';border:2px solid '+color+';font-size:13px;font-weight:600;z-index:99999;box-shadow:0 8px 24px rgba(0,0,0,.5);transition:opacity .3s;max-width:400px';
|
||
t.textContent = msg;
|
||
document.body.appendChild(t);
|
||
setTimeout(function(){ t.style.opacity = '0'; setTimeout(function(){ t.remove(); }, 400); }, 3500);
|
||
};
|
||
|
||
// WAVE 233: Ask WEVIA button handler
|
||
window.askWeviaFromIdea = function(idea) {
|
||
var btn = event && event.target;
|
||
if (btn) { btn.disabled = true; btn.textContent = '💬 ...'; }
|
||
__wevalToast('💬 Querying WEVIA Master multi-agent...', '#22d3ee');
|
||
|
||
fetch('/api/social-signals-hub.php?action=ask_wevia', {
|
||
method: 'POST',
|
||
headers: {'Content-Type': 'application/json'},
|
||
body: JSON.stringify({idea: idea})
|
||
})
|
||
.then(function(r){return r.json();})
|
||
.then(function(d){
|
||
if (btn) { btn.textContent = '💬 Ask WEVIA'; btn.disabled = false; }
|
||
if (!d.ok) { __wevalToast('WEVIA err: '+(d.error||'?'), '#ef4444'); return; }
|
||
|
||
// Open modal with WEVIA response
|
||
var resp = d.wevia_response;
|
||
var respText = '';
|
||
if (typeof resp === 'string') respText = resp;
|
||
else if (resp && resp.response) respText = resp.response;
|
||
else respText = JSON.stringify(resp, null, 2);
|
||
|
||
var overlay = document.createElement('div');
|
||
overlay.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,.85);z-index:99998;display:flex;align-items:center;justify-content:center;padding:20px';
|
||
overlay.onclick = function(e){ if(e.target===overlay) overlay.remove(); };
|
||
|
||
var modal = document.createElement('div');
|
||
modal.style.cssText = 'max-width:800px;max-height:85vh;overflow:auto;background:#0e1424;border:2px solid #22d3ee;border-radius:14px;padding:20px;color:#e0e7ff;box-shadow:0 20px 60px rgba(0,0,0,.8)';
|
||
modal.innerHTML = '<div style="display:flex;align-items:center;gap:10px;margin-bottom:14px;border-bottom:1px solid rgba(34,211,238,.25);padding-bottom:10px"><h3 style="margin:0;color:#22d3ee;font-size:16px">💬 WEVIA Master · Plan exécutable</h3><span style="padding:2px 8px;border-radius:8px;background:rgba(34,211,238,.2);color:#a5f3fc;font-size:10px;font-weight:700">'+(d.fallback||'WEVIA Master')+'</span><button onclick="this.closest(\'div[style*=inset]\').remove()" style="margin-left:auto;padding:6px 12px;border-radius:8px;background:rgba(239,68,68,.2);color:#fca5a5;border:1px solid rgba(239,68,68,.4);font-size:12px;cursor:pointer;font-weight:700">✕ Fermer</button></div><div style="font-size:11px;color:#94a3b8;margin-bottom:10px;padding:8px;background:rgba(0,0,0,.3);border-radius:6px;border-left:3px solid #22d3ee"><b>Contexte idea:</b> '+(idea.title||'')+' · '+(idea.opportunity||'')+' · '+(idea.estimated_mad?Math.round(idea.estimated_mad/1000)+'K MAD':'')+'</div><pre style="white-space:pre-wrap;font-family:system-ui;font-size:12.5px;line-height:1.6;color:#e0e7ff;margin:0">'+respText.replace(/</g,'<')+'</pre>';
|
||
overlay.appendChild(modal);
|
||
document.body.appendChild(overlay);
|
||
__wevalToast('✓ WEVIA plan généré', '#10b981');
|
||
})
|
||
.catch(function(e){
|
||
if (btn) { btn.textContent = '💬 Ask WEVIA'; btn.disabled = false; }
|
||
__wevalToast('Err: '+e.message, '#ef4444');
|
||
});
|
||
};
|
||
|
||
// WAVE 233: Patch createTaskFromIdea for toast + auto-refresh tasks
|
||
var origCreateTask = window.createTaskFromIdea;
|
||
window.createTaskFromIdea = function(idea) {
|
||
var btn = event && event.target;
|
||
if (btn) { btn.disabled = true; btn.textContent = '...'; }
|
||
fetch('/api/social-signals-hub.php?action=create_task', {
|
||
method: 'POST',
|
||
headers: {'Content-Type': 'application/json'},
|
||
body: JSON.stringify({
|
||
title: idea.title, source: 'advisor-wave233', source_ref: 'growth-engine-v2',
|
||
category: idea.channel || 'conversion', opportunity: idea.opportunity || '',
|
||
tools_used: idea.tools_used || [], first_steps: idea.first_steps || [],
|
||
kpi: idea.kpi || '', estimated_mad: idea.estimated_mad || 0, inspired_by: idea.inspired_by || ''
|
||
})
|
||
})
|
||
.then(function(r){return r.json();})
|
||
.then(function(d){
|
||
if (btn) {
|
||
btn.textContent = d.ok ? '✓ #'+d.task_id : '✗';
|
||
btn.style.background = d.ok ? 'rgba(16,185,129,.4)' : 'rgba(239,68,68,.3)';
|
||
}
|
||
if (d.ok) {
|
||
var msg = 'Task #'+d.task_id+' created';
|
||
if (d.lead_linked) msg += ' · 📌 Linked: '+d.lead_linked.company+' (MQL '+d.lead_linked.mql_score+')';
|
||
__wevalToast('✓ '+msg, '#10b981');
|
||
}
|
||
setTimeout(loadWave231Tasks, 400);
|
||
})
|
||
.catch(function(e){
|
||
if (btn) { btn.textContent = '✗'; btn.style.background = 'rgba(239,68,68,.3)'; }
|
||
__wevalToast('Err: '+e.message, '#ef4444');
|
||
});
|
||
};
|
||
|
||
// WAVE 233: Add workflow status buttons + lead badges to task cards
|
||
var origLoadTasks = window.loadWave231Tasks;
|
||
window.loadWave231Tasks = function() {
|
||
var box = document.getElementById('wave231Tasks');
|
||
if (!box) return;
|
||
box.innerHTML = '<div style="color:#94a3b8;font-size:11px">Loading Paperclip tasks…</div>';
|
||
fetch('/api/social-signals-hub.php?action=list_tasks&cb='+Date.now())
|
||
.then(function(r){return r.json();})
|
||
.then(function(d){
|
||
if (!d.ok || !d.tasks.length) {
|
||
box.innerHTML = '<div style="color:#64748b;font-size:11px;padding:8px">No tasks yet</div>';
|
||
return;
|
||
}
|
||
var agg = d.by_status || {};
|
||
var aggStr = Object.keys(agg).map(function(k){return k+':'+agg[k];}).join(' · ');
|
||
var linked = d.linked_count || 0;
|
||
var html = '<div style="font-size:11px;color:#6ee7b7;margin-bottom:8px;font-weight:700">📋 '+d.count+' tasks '+(aggStr?('· '+aggStr):'')+(linked?' · 📌 '+linked+' linked':'')+'</div>';
|
||
d.tasks.forEach(function(t){
|
||
var colStatus = {proposed:'#fbbf24',in_progress:'#22d3ee',done:'#10b981',cancelled:'#94a3b8',blocked:'#ef4444'}[t.status] || '#94a3b8';
|
||
html += '<div style="padding:8px 10px;margin-bottom:4px;background:rgba(0,0,0,.2);border:1px solid rgba(16,185,129,.15);border-left:3px solid '+colStatus+';border-radius:6px">';
|
||
html += '<div style="display:flex;align-items:center;gap:6px;flex-wrap:wrap"><b style="color:#e0e7ff;font-size:11.5px">#'+t.id+' '+(t.title||'?').slice(0,60)+'</b>';
|
||
html += '<span style="padding:1px 6px;border-radius:6px;background:'+colStatus+'22;color:'+colStatus+';font-size:9px;font-weight:700">'+t.status+'</span>';
|
||
// WAVE 233: lead badge
|
||
if (t.lead_company) {
|
||
var mql = parseInt(t.lead_mql||0);
|
||
var mqlCol = mql>=90?'#10b981':(mql>=70?'#fbbf24':'#94a3b8');
|
||
html += '<span style="padding:1px 6px;border-radius:6px;background:'+mqlCol+'22;color:'+mqlCol+';font-size:9px;font-weight:700">📌 '+t.lead_company+' MQL '+mql+(t.lead_sql==='t'?' ✅':'')+'</span>';
|
||
}
|
||
html += '<span style="margin-left:auto;color:#fbbf24;font-size:10px;font-weight:700">'+(t.estimated_mad?Math.round(t.estimated_mad/1000)+'K':'')+'</span></div>';
|
||
html += '<div style="font-size:10px;color:#94a3b8;margin-top:3px">🎯 '+(t.opportunity||'')+' · '+((t.created_at||'').slice(5,16))+'</div>';
|
||
if (t.tools_used) html += '<div style="font-size:10px;color:#64748b;margin-top:2px">🔧 '+t.tools_used.replace(/\|/g,' · ')+'</div>';
|
||
if (t.kpi) html += '<div style="font-size:10px;color:#6ee7b7;margin-top:2px">📊 '+t.kpi+'</div>';
|
||
// Workflow buttons
|
||
html += '<div style="margin-top:6px;display:flex;gap:4px;flex-wrap:wrap">';
|
||
['proposed','in_progress','done','cancelled','blocked'].forEach(function(s){
|
||
if (s === t.status) return;
|
||
var c = {proposed:'#fbbf24',in_progress:'#22d3ee',done:'#10b981',cancelled:'#94a3b8',blocked:'#ef4444'}[s];
|
||
html += '<button onclick="updateTaskStatus('+t.id+',\''+s+'\')" style="padding:2px 6px;border-radius:4px;background:'+c+'11;color:'+c+';border:1px solid '+c+'33;font-size:9px;cursor:pointer">→ '+s+'</button>';
|
||
});
|
||
html += '</div></div>';
|
||
});
|
||
box.innerHTML = html;
|
||
})
|
||
.catch(function(e){ box.innerHTML = '<div style="color:#ef4444;font-size:11px">Err: '+e.message+'</div>'; });
|
||
};
|
||
|
||
// WAVE 233: Update task status with toast
|
||
window.updateTaskStatus = function(taskId, newStatus) {
|
||
fetch('/api/social-signals-hub.php?action=update_status', {
|
||
method: 'POST',
|
||
headers: {'Content-Type': 'application/json'},
|
||
body: JSON.stringify({task_id: taskId, status: newStatus})
|
||
})
|
||
.then(function(r){return r.json();})
|
||
.then(function(d){
|
||
if (d.ok) {
|
||
__wevalToast('Task #'+taskId+' → '+d.new_status, '#22d3ee');
|
||
setTimeout(loadWave231Tasks, 300);
|
||
} else { __wevalToast('Err: '+(d.error||'?'), '#ef4444'); }
|
||
})
|
||
.catch(function(e){ __wevalToast('Err: '+e.message, '#ef4444'); });
|
||
};
|
||
|
||
// WAVE 233: Auto-poll tasks every 30s
|
||
if (!window.__w233TaskPoller) {
|
||
window.__w233TaskPoller = setInterval(function(){
|
||
if (document.getElementById('wave231Tasks')) { loadWave231Tasks(); }
|
||
}, 30000);
|
||
}
|
||
|
||
// WAVE 233: Add CSV export button
|
||
window.exportTasksCsv = function() {
|
||
window.open('/api/social-signals-hub.php?action=export_csv', '_blank');
|
||
__wevalToast('📥 CSV download started', '#10b981');
|
||
};
|
||
|
||
|
||
|
||
// =====================================================================
|
||
// WAVE 246-250: NEW UI functions consuming new endpoints
|
||
// =====================================================================
|
||
|
||
// WAVE 255: MAX parallel launch · 12 agents mobilisés en même temps via Factory
|
||
window.launchMaxParallel = function() {
|
||
var badge = document.getElementById('wevia-multiagent-badge');
|
||
if (badge) badge.style.background = 'linear-gradient(90deg,rgba(236,72,153,.3),rgba(168,85,247,.3),rgba(34,211,238,.2))';
|
||
__wevalToast && __wevalToast('🚀 Launching MAX 12 agents in parallel...', '#ec4899');
|
||
|
||
var t0 = Date.now();
|
||
fetch('/api/wevia-factory.php?action=run', {
|
||
method:'POST',
|
||
headers:{'Content-Type':'application/json'},
|
||
body: JSON.stringify({
|
||
message: "Audit complet global: solutions · leads · tasks · social · predict · enterprise · quality · infrastructure",
|
||
max_agents: 30,
|
||
session: "max-"+Date.now()
|
||
})
|
||
})
|
||
.then(function(r){return r.json();})
|
||
.then(function(d){
|
||
var dur = Date.now() - t0;
|
||
var overlay = document.createElement('div');
|
||
overlay.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,.9);z-index:99999;display:flex;align-items:center;justify-content:center;padding:15px';
|
||
overlay.onclick = function(e){ if(e.target===overlay) overlay.remove(); };
|
||
|
||
var modal = document.createElement('div');
|
||
modal.style.cssText = 'max-width:1100px;width:100%;background:#0a0f1a;border:2px solid #ec4899;border-radius:14px;padding:22px;color:#e0e7ff;max-height:90vh;overflow:auto;box-shadow:0 20px 80px rgba(236,72,153,.3)';
|
||
|
||
var html = '<div style="display:flex;align-items:center;gap:12px;margin-bottom:14px;padding-bottom:10px;border-bottom:2px solid rgba(236,72,153,.3)">';
|
||
html += '<span style="font-size:24px">🚀</span>';
|
||
html += '<h3 style="margin:0;color:#fbcfe8;font-size:17px">MAX Parallel Launch · '+d.agents_parallel+' agents mobilisés (12 builtin + 18 custom)</h3>';
|
||
html += '<span style="padding:4px 10px;border-radius:12px;background:'+(d.grade==="A"?"#10b981":"#fbbf24")+';color:#0a0f1a;font-size:12px;font-weight:800">grade '+d.grade+'</span>';
|
||
html += '<span style="padding:4px 10px;border-radius:12px;background:rgba(34,211,238,.2);color:#a5f3fc;font-size:11px;font-weight:700">'+d.total_duration_ms+'ms total</span>';
|
||
html += '<span style="padding:4px 10px;border-radius:12px;background:rgba(16,185,129,.2);color:#6ee7b7;font-size:11px;font-weight:700">grounding '+d.grounding_pct+'%</span>';
|
||
html += '<button onclick="this.closest(\'div[style*=inset]\').remove()" style="margin-left:auto;padding:6px 14px;border-radius:8px;background:rgba(239,68,68,.25);color:#fca5a5;border:1px solid rgba(239,68,68,.5);cursor:pointer;font-weight:700">✕ Fermer</button></div>';
|
||
|
||
// Parallel agents grid
|
||
html += '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:6px;margin-bottom:14px">';
|
||
var plan = d.phases.plan || {};
|
||
(plan.agents_to_call || []).forEach(function(a, idx){
|
||
html += '<div style="padding:8px;background:linear-gradient(135deg,rgba(34,211,238,.15),rgba(168,85,247,.1));border-left:3px solid #22d3ee;border-radius:6px;font-size:11px;color:#e0e7ff"><b>#'+(idx+1)+'</b> 🤖 '+a+'</div>';
|
||
});
|
||
html += '</div>';
|
||
|
||
// 7 Phases timeline
|
||
html += '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:4px;margin-bottom:14px">';
|
||
var phases = [
|
||
{k:"thinking", label:"1. THINK", icon:"🧠", color:"#a855f7"},
|
||
{k:"plan", label:"2. PLAN", icon:"📋", color:"#fbbf24"},
|
||
{k:"dispatch", label:"3. DISPATCH", icon:"⚡", color:"#22d3ee"},
|
||
{k:"ground", label:"4. GROUND", icon:"🔗", color:"#10b981"},
|
||
{k:"synthesize", label:"5. SYNTH", icon:"✨", color:"#ec4899"},
|
||
{k:"tests", label:"6. TESTS", icon:"🔬", color:"#60a5fa"}
|
||
];
|
||
phases.forEach(function(p){
|
||
var ph = d.phases[p.k] || {};
|
||
var dur = ph.duration_ms || 0;
|
||
html += '<div style="padding:8px;background:rgba(0,0,0,.3);border-left:3px solid '+p.color+';border-radius:4px"><div style="font-size:9px;color:'+p.color+';font-weight:700">'+p.icon+' '+p.label+'</div><div style="font-size:11px;color:#e0e7ff">'+dur+'ms</div></div>';
|
||
});
|
||
html += '</div>';
|
||
|
||
// Dispatch success
|
||
var disp = d.phases.dispatch || {};
|
||
html += '<div style="padding:10px;background:rgba(16,185,129,.1);border-left:3px solid #10b981;border-radius:6px;margin-bottom:10px;font-size:12px">';
|
||
html += '<b style="color:#6ee7b7">⚡ Dispatch PARALLEL:</b> '+disp.succeeded+'/'+disp.total+' agents succeeded · '+disp.duration_ms+'ms';
|
||
html += '</div>';
|
||
|
||
// Response
|
||
html += '<div style="padding:16px;background:linear-gradient(135deg,rgba(236,72,153,.08),rgba(168,85,247,.05));border:1px solid rgba(236,72,153,.3);border-radius:10px">';
|
||
html += '<div style="font-size:10px;color:#fbcfe8;font-weight:800;margin-bottom:8px;text-transform:uppercase">✨ Synthesized by '+(d.provider||"?")+' · natural language · 0 hallucination</div>';
|
||
html += '<div style="font-size:12.5px;color:#e0e7ff;line-height:1.75;white-space:pre-wrap">'+(d.response||"").replace(/</g,"<")+'</div>';
|
||
html += '</div>';
|
||
|
||
modal.innerHTML = html;
|
||
overlay.appendChild(modal);
|
||
document.body.appendChild(overlay);
|
||
|
||
if (badge) badge.style.background = 'linear-gradient(90deg,rgba(16,185,129,.2),rgba(34,211,238,.2),rgba(168,85,247,.15))';
|
||
__wevalToast && __wevalToast('✓ '+d.agents_parallel+' agents PARALLEL · '+d.grade+' · grounding '+d.grounding_pct+'%', d.grade==="A"?"#10b981":"#fbbf24");
|
||
})
|
||
.catch(function(e){ __wevalToast && __wevalToast('Err: '+e.message, '#ef4444'); });
|
||
};
|
||
|
||
// WAVE 254: Test Multi-Agent Orchestrator · pattern CLAUDE 7 phases
|
||
window.testMultiAgent = function() {
|
||
var badge = document.getElementById('wevia-multiagent-badge');
|
||
if (badge) badge.style.background = 'linear-gradient(90deg,rgba(251,191,36,.3),rgba(34,211,238,.2))';
|
||
__wevalToast && __wevalToast('🧠 Dispatching to multi-agents in parallel...', '#22d3ee');
|
||
|
||
var t0 = Date.now();
|
||
fetch('/api/multiagent-orchestrator.php', {
|
||
method:'POST',
|
||
headers:{'Content-Type':'application/json'},
|
||
body: JSON.stringify({
|
||
message: "Quelle solution prioriser cette semaine? Quel lead pharma relancer? Quelle concurrence surveiller?",
|
||
session: "mao-test-"+Date.now()
|
||
})
|
||
})
|
||
.then(function(r){return r.json();})
|
||
.then(function(d){
|
||
var dur = Date.now() - t0;
|
||
|
||
var overlay = document.createElement('div');
|
||
overlay.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,.85);z-index:99999;display:flex;align-items:center;justify-content:center;padding:20px';
|
||
overlay.onclick = function(e){ if(e.target===overlay) overlay.remove(); };
|
||
|
||
var modal = document.createElement('div');
|
||
modal.style.cssText = 'max-width:900px;background:#0e1424;border:2px solid #22d3ee;border-radius:14px;padding:20px;color:#e0e7ff;max-height:85vh;overflow:auto';
|
||
|
||
var html = '<div style="display:flex;align-items:center;gap:10px;margin-bottom:12px;border-bottom:1px solid rgba(34,211,238,.3);padding-bottom:10px">';
|
||
html += '<h3 style="margin:0;color:#67e8f9;font-size:16px">🧠 Multi-Agent Orchestrator · Pattern CLAUDE</h3>';
|
||
html += '<span style="padding:3px 10px;border-radius:10px;background:'+(d.grade==="A"?"#10b981":"#fbbf24")+';color:#0a0f1a;font-size:11px;font-weight:800">grade '+d.grade+'</span>';
|
||
html += '<span style="padding:3px 10px;border-radius:10px;background:rgba(34,211,238,.2);color:#a5f3fc;font-size:10px;font-weight:700">'+d.total_duration_ms+'ms</span>';
|
||
html += '<button onclick="this.closest(\'div[style*=inset]\').remove()" style="margin-left:auto;padding:6px 12px;border-radius:6px;background:rgba(239,68,68,.2);color:#fca5a5;border:1px solid rgba(239,68,68,.4);cursor:pointer">✕</button>';
|
||
html += '</div>';
|
||
|
||
// 7 phases timeline
|
||
html += '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(110px,1fr));gap:4px;margin-bottom:14px">';
|
||
var phases = [
|
||
{k:"thinking", label:"1. THINKING", icon:"🧠", color:"#a855f7"},
|
||
{k:"plan", label:"2. PLAN", icon:"📋", color:"#fbbf24"},
|
||
{k:"dispatch", label:"3. DISPATCH", icon:"⚡", color:"#22d3ee"},
|
||
{k:"ground", label:"4. GROUND", icon:"🔗", color:"#10b981"},
|
||
{k:"synthesize", label:"5. SYNTH", icon:"✨", color:"#ec4899"},
|
||
{k:"tests", label:"6. TESTS", icon:"🔬", color:"#60a5fa"},
|
||
{k:"response", label:"7. RESP", icon:"📤", color:"#f0abfc"}
|
||
];
|
||
phases.forEach(function(p){
|
||
var ph = d.phases[p.k];
|
||
var dur = ph ? (ph.duration_ms || 0) : 0;
|
||
html += '<div style="padding:8px;background:rgba(0,0,0,.3);border-left:3px solid '+p.color+';border-radius:4px">';
|
||
html += '<div style="font-size:9px;color:'+p.color+';font-weight:700">'+p.icon+' '+p.label+'</div>';
|
||
html += '<div style="font-size:11px;color:#e0e7ff">'+dur+'ms</div>';
|
||
html += '</div>';
|
||
});
|
||
html += '</div>';
|
||
|
||
// Agents mobilized
|
||
html += '<div style="padding:10px;background:rgba(34,211,238,.1);border-left:3px solid #22d3ee;border-radius:6px;margin-bottom:10px">';
|
||
html += '<div style="font-size:11px;color:#a5f3fc;font-weight:700;margin-bottom:4px">⚡ '+d.agents_parallel+' Agents Mobilisés en PARALLÈLE (succeeded: '+d.agents_succeeded+')</div>';
|
||
html += '<div style="font-size:11px;color:#e0e7ff">'+(d.agents_used||[]).map(function(a){return "<span style=\"padding:2px 8px;margin:2px;border-radius:12px;background:rgba(34,211,238,.2);color:#67e8f9;font-size:10px;font-weight:700;display:inline-block\">🤖 "+a+"</span>";}).join(" ")+'</div>';
|
||
html += '</div>';
|
||
|
||
// Grounding score
|
||
html += '<div style="padding:10px;background:rgba(16,185,129,.1);border-left:3px solid #10b981;border-radius:6px;margin-bottom:10px">';
|
||
html += '<div style="font-size:11px;color:#6ee7b7;font-weight:700">🔗 Grounding: '+d.grounding_score+'% · No hallucination: '+(d.phases.tests.tests.no_hallucination?"✓ YES":"✗ NO")+'</div>';
|
||
html += '</div>';
|
||
|
||
// Response
|
||
html += '<div style="padding:14px;background:rgba(0,0,0,.35);border:1px solid rgba(236,72,153,.3);border-radius:8px">';
|
||
html += '<div style="font-size:10px;color:#fbcfe8;font-weight:700;margin-bottom:6px;text-transform:uppercase">✨ Response (synthesized by '+(d.provider||"?")+')</div>';
|
||
html += '<div style="font-size:12.5px;color:#e0e7ff;line-height:1.7;white-space:pre-wrap">'+(d.response||"").replace(/</g,"<")+'</div>';
|
||
html += '</div>';
|
||
|
||
modal.innerHTML = html;
|
||
overlay.appendChild(modal);
|
||
document.body.appendChild(overlay);
|
||
|
||
if (badge) badge.style.background = d.grade==="A" ? 'linear-gradient(90deg,rgba(16,185,129,.2),rgba(34,211,238,.2),rgba(168,85,247,.15))' : 'linear-gradient(90deg,rgba(251,191,36,.2),rgba(34,211,238,.15))';
|
||
__wevalToast && __wevalToast('✓ '+d.agents_parallel+' agents · '+d.grade+' · '+dur+'ms', d.grade==="A"?"#10b981":"#fbbf24");
|
||
})
|
||
.catch(function(e){ __wevalToast && __wevalToast('Err: '+e.message, '#ef4444'); });
|
||
};
|
||
|
||
// WAVE 253: Test WEVIA Master grounding (anti-hallucination)
|
||
window.testWeviaGrounded = function() {
|
||
var badge = document.getElementById('wevia-grounded-badge');
|
||
if (badge) badge.style.background = 'linear-gradient(90deg,rgba(251,191,36,.2),rgba(34,211,238,.1))';
|
||
__wevalToast && __wevalToast('🧪 Testing WEVIA Master grounding...', '#22d3ee');
|
||
|
||
fetch('/api/saas-chat.php', {
|
||
method:'POST',
|
||
headers:{'Content-Type':'application/json'},
|
||
body: JSON.stringify({
|
||
message: "Combien de leads dans Paperclip, top 3 industries, et nom de la solution #1 selon le scanner?",
|
||
session: "test-ground-"+Date.now()
|
||
})
|
||
})
|
||
.then(function(r){return r.json();})
|
||
.then(function(d){
|
||
var resp = (d.response || '').toLowerCase();
|
||
var hasLeads = resp.includes('48');
|
||
var hasPharma = resp.includes('pharma');
|
||
var hasEthica = resp.includes('ethica');
|
||
var score = (hasLeads?1:0) + (hasPharma?1:0) + (hasEthica?1:0);
|
||
|
||
var overlay = document.createElement('div');
|
||
overlay.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,.85);z-index:99999;display:flex;align-items:center;justify-content:center;padding:20px';
|
||
overlay.onclick = function(e){ if(e.target===overlay) overlay.remove(); };
|
||
|
||
var grade = score===3?'A+':(score===2?'B':(score===1?'C':'F'));
|
||
var gradeCol = score===3?'#10b981':(score>=1?'#fbbf24':'#ef4444');
|
||
|
||
var modal = document.createElement('div');
|
||
modal.style.cssText = 'max-width:700px;background:#0e1424;border:2px solid '+gradeCol+';border-radius:14px;padding:20px;color:#e0e7ff;max-height:85vh;overflow:auto';
|
||
var html = '<div style="display:flex;align-items:center;gap:12px;margin-bottom:14px">';
|
||
html += '<div style="width:60px;height:60px;border-radius:50%;background:'+gradeCol+';color:#0a0f1a;display:flex;align-items:center;justify-content:center;font-size:28px;font-weight:800">'+grade+'</div>';
|
||
html += '<div><h3 style="margin:0;color:'+gradeCol+';font-size:18px">Test Grounding · score '+score+'/3</h3>';
|
||
html += '<div style="font-size:11px;color:#94a3b8">Provider: '+(d.provider||'?')+' · leads_count grounding: '+(d.grounding&&d.grounding.leads_count)+' · wave '+((d.grounding||{}).wave)+'</div></div>';
|
||
html += '<button onclick="this.closest(\'div[style*=inset]\').remove()" style="margin-left:auto;padding:6px 12px;border-radius:8px;background:rgba(239,68,68,.2);color:#fca5a5;border:1px solid rgba(239,68,68,.4);cursor:pointer">Fermer</button></div>';
|
||
html += '<div style="font-size:11px;color:#94a3b8;margin-bottom:10px">Tests: <span style="color:'+(hasLeads?'#10b981':'#ef4444')+'">'+(hasLeads?'✓':'✗')+' mentionne 48 leads</span> · <span style="color:'+(hasPharma?'#10b981':'#ef4444')+'">'+(hasPharma?'✓':'✗')+' Pharma</span> · <span style="color:'+(hasEthica?'#10b981':'#ef4444')+'">'+(hasEthica?'✓':'✗')+' Ethica</span></div>';
|
||
html += '<div style="padding:12px;background:rgba(0,0,0,.4);border-radius:6px;border-left:3px solid '+gradeCol+';font-size:12.5px;line-height:1.6;white-space:pre-wrap">'+(d.response||'').replace(/</g,'<')+'</div>';
|
||
modal.innerHTML = html;
|
||
overlay.appendChild(modal);
|
||
document.body.appendChild(overlay);
|
||
if (badge) badge.style.background = score===3 ? 'linear-gradient(90deg,rgba(16,185,129,.2),rgba(34,211,238,.12))' : 'linear-gradient(90deg,rgba(239,68,68,.15),rgba(251,191,36,.1))';
|
||
__wevalToast && __wevalToast('✓ Grounding '+grade+' · '+score+'/3', gradeCol);
|
||
})
|
||
.catch(function(e){ __wevalToast && __wevalToast('Err: '+e.message, '#ef4444'); });
|
||
};
|
||
|
||
// WAVE 252: Predictive Solution Scanner with WePredict-style market scoring
|
||
window.loadSolutionScanner = function() {
|
||
var box = document.getElementById('advisor-solution-scanner');
|
||
if (!box) return;
|
||
box.innerHTML = '<div style="color:#67e8f9;font-size:12px;padding:10px">🧠 WePredict analyzing market signals + capabilities gaps...</div>';
|
||
fetch('/api/solution-scanner.php?action=full_analysis&cb='+Date.now())
|
||
.then(function(r){return r.json();})
|
||
.then(function(d){
|
||
if (!d.ok) { box.innerHTML = '<div style="color:#ef4444">Error: '+(d.error||'?')+'</div>'; return; }
|
||
|
||
var s = d.summary;
|
||
var sols = d.solutions;
|
||
var gaps = d.top_gaps;
|
||
|
||
// SUMMARY KPI bar
|
||
var html = '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:8px;margin-bottom:14px">';
|
||
html += '<div style="padding:10px;background:rgba(16,185,129,.12);border-left:3px solid #10b981;border-radius:6px"><div style="font-size:9px;color:#6ee7b7;text-transform:uppercase;font-weight:700">🚀 SHIP IT</div><div style="font-size:24px;font-weight:800;color:#10b981">'+s.ship_it+'</div><div style="font-size:9px;color:#6ee7b7">ready launch multi-user</div></div>';
|
||
html += '<div style="padding:10px;background:rgba(251,191,36,.12);border-left:3px solid #fbbf24;border-radius:6px"><div style="font-size:9px;color:#fde68a;text-transform:uppercase;font-weight:700">⚡ ACCELERATE</div><div style="font-size:24px;font-weight:800;color:#fbbf24">'+s.accelerate+'</div><div style="font-size:9px;color:#fde68a">push urgently</div></div>';
|
||
html += '<div style="padding:10px;background:rgba(34,211,238,.12);border-left:3px solid #22d3ee;border-radius:6px"><div style="font-size:9px;color:#a5f3fc;text-transform:uppercase;font-weight:700">🛠 DEV SPRINT</div><div style="font-size:24px;font-weight:800;color:#22d3ee">'+s.dev_sprint+'</div><div style="font-size:9px;color:#a5f3fc">needs capabilities</div></div>';
|
||
html += '<div style="padding:10px;background:rgba(168,85,247,.12);border-left:3px solid #a855f7;border-radius:6px"><div style="font-size:9px;color:#c4b5fd;text-transform:uppercase;font-weight:700">🌱 NURTURE</div><div style="font-size:24px;font-weight:800;color:#a855f7">'+s.nurture+'</div><div style="font-size:9px;color:#c4b5fd">low market fit</div></div>';
|
||
html += '<div style="padding:10px;background:rgba(239,68,68,.12);border-left:3px solid #ef4444;border-radius:6px"><div style="font-size:9px;color:#fca5a5;text-transform:uppercase;font-weight:700">⛔ PIVOT</div><div style="font-size:24px;font-weight:800;color:#ef4444">'+s.pivot+'</div><div style="font-size:9px;color:#fca5a5">kill or reposition</div></div>';
|
||
html += '</div>';
|
||
|
||
// Overall cost/time
|
||
html += '<div style="padding:12px;background:rgba(0,0,0,.35);border-radius:8px;margin-bottom:14px">';
|
||
html += '<div style="font-size:11px;color:#67e8f9;font-weight:700;margin-bottom:6px">💰 GLOBAL EFFORT to bring ALL 10 to production multi-user</div>';
|
||
html += '<div style="display:flex;gap:14px;flex-wrap:wrap;font-size:12px;color:#e0e7ff">';
|
||
html += '<span>📅 <b style="color:#fbbf24">'+s.total_dev_days+'</b> dev-days</span>';
|
||
html += '<span>💸 <b style="color:#fbbf24">'+Math.round(s.total_dev_cost_mad/1000)+'K MAD</b> dev cost</span>';
|
||
html += '<span>💰 <b style="color:#10b981">'+Math.round(s.total_mad_pipeline/1000)+'K MAD</b> pipeline</span>';
|
||
var roi = ((s.total_mad_pipeline - s.total_dev_cost_mad) / s.total_dev_cost_mad * 100).toFixed(0);
|
||
html += '<span>🚀 ROI net: <b style="color:#10b981">'+roi+'%</b></span>';
|
||
html += '</div></div>';
|
||
|
||
// RANKED SOLUTIONS
|
||
html += '<div style="margin-bottom:8px;font-size:12px;color:#67e8f9;font-weight:700;text-transform:uppercase">🏆 Classement par winning_score (prediction + ICE + maturité + dev_effort)</div>';
|
||
html += '<div style="display:flex;flex-direction:column;gap:8px">';
|
||
|
||
sols.forEach(function(sol){
|
||
var decColors = {SHIP_IT:'#10b981', ACCELERATE:'#fbbf24', DEV_SPRINT:'#22d3ee', NURTURE:'#a855f7', PIVOT_OR_PARK:'#ef4444'};
|
||
var decIcons = {SHIP_IT:'🚀', ACCELERATE:'⚡', DEV_SPRINT:'🛠', NURTURE:'🌱', PIVOT_OR_PARK:'⛔'};
|
||
var dc = decColors[sol.decision] || '#94a3b8';
|
||
var dIcon = decIcons[sol.decision] || '?';
|
||
var pred = sol.market_prediction;
|
||
var dev = sol.dev_effort;
|
||
|
||
html += '<div style="padding:12px 14px;background:rgba(0,0,0,.35);border-left:4px solid '+dc+';border-radius:8px">';
|
||
// Header
|
||
html += '<div style="display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:8px">';
|
||
html += '<div style="width:40px;height:40px;border-radius:50%;background:'+dc+';color:#0a0f1a;display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:800">'+sol.winning_score+'</div>';
|
||
html += '<div><div style="font-size:13.5px;color:#e0e7ff;font-weight:700">'+sol.name+'</div>';
|
||
html += '<div style="font-size:10px;color:#94a3b8">'+sol.category+' · '+sol.target_segment+' · status '+sol.status+'</div></div>';
|
||
html += '<span style="padding:4px 12px;border-radius:20px;background:'+dc+';color:#0a0f1a;font-size:11px;font-weight:800;margin-left:8px">'+dIcon+' '+sol.decision.replace(/_/g,' ')+'</span>';
|
||
html += '<span style="margin-left:auto;font-size:16px;color:#fbbf24;font-weight:800">'+Math.round(sol.mad_est/1000)+'K MAD</span>';
|
||
html += '</div>';
|
||
|
||
// Metrics grid
|
||
html += '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:8px;margin-bottom:8px">';
|
||
html += '<div style="padding:6px 8px;background:rgba(16,185,129,.1);border-radius:4px"><div style="font-size:9px;color:#6ee7b7">📊 Predict</div><div style="font-size:14px;color:#10b981;font-weight:700">'+pred.score+'/100</div><div style="font-size:9px;color:#94a3b8">'+pred.recommendation+'</div></div>';
|
||
html += '<div style="padding:6px 8px;background:rgba(251,191,36,.1);border-radius:4px"><div style="font-size:9px;color:#fde68a">🎯 ICE</div><div style="font-size:14px;color:#fbbf24;font-weight:700">'+sol.ice_score+'</div></div>';
|
||
html += '<div style="padding:6px 8px;background:rgba(34,211,238,.1);border-radius:4px"><div style="font-size:9px;color:#a5f3fc">⚙ Maturité</div><div style="font-size:14px;color:#22d3ee;font-weight:700">'+sol.maturity+'%</div></div>';
|
||
html += '<div style="padding:6px 8px;background:rgba(168,85,247,.1);border-radius:4px"><div style="font-size:9px;color:#c4b5fd">✅ Capabilities</div><div style="font-size:14px;color:#a855f7;font-weight:700">'+dev.completion_pct+'%</div></div>';
|
||
html += '<div style="padding:6px 8px;background:rgba(236,72,153,.1);border-radius:4px"><div style="font-size:9px;color:#fbcfe8">🛠 Dev calendar</div><div style="font-size:14px;color:#ec4899;font-weight:700">'+dev.calendar_days_est+'j</div><div style="font-size:9px;color:#94a3b8">'+dev.total_dev_days+'d total</div></div>';
|
||
html += '<div style="padding:6px 8px;background:rgba(99,102,241,.1);border-radius:4px"><div style="font-size:9px;color:#a5b4fc">💸 Dev cost</div><div style="font-size:14px;color:#818cf8;font-weight:700">'+Math.round(dev.dev_cost_mad/1000)+'K</div></div>';
|
||
html += '</div>';
|
||
|
||
// Market signals
|
||
html += '<div style="padding:8px 10px;background:rgba(16,185,129,.08);border-left:2px solid #10b981;border-radius:4px;margin-bottom:6px;font-size:10.5px">';
|
||
html += '<b style="color:#6ee7b7">📡 Market signals:</b> <span style="color:#cbd5e1">'+(sol.signals||[]).join(' · ')+'</span>';
|
||
html += '</div>';
|
||
|
||
// WePredict breakdown
|
||
html += '<div style="padding:8px 10px;background:rgba(34,211,238,.08);border-left:2px solid #22d3ee;border-radius:4px;margin-bottom:6px;font-size:10.5px">';
|
||
html += '<b style="color:#a5f3fc">🧠 WePredict breakdown:</b> ';
|
||
html += '<span style="color:#cbd5e1">lead_density '+pred.breakdown.lead_density+'% · avg_MQL '+pred.breakdown.avg_mql+' · SQL '+pred.breakdown.sql_pct+'% · leads in target '+pred.breakdown.leads_in_target+' (SQL '+pred.breakdown.sql_qualified_in_target+')</span>';
|
||
html += '</div>';
|
||
|
||
// Capabilities TODO (critical path)
|
||
if ((sol.capabilities_todo||[]).length) {
|
||
html += '<div style="padding:8px 10px;background:rgba(239,68,68,.08);border-left:2px solid #ef4444;border-radius:4px;font-size:10.5px">';
|
||
html += '<b style="color:#fca5a5">⚠ To ship multi-user production (MISSING):</b> <span style="color:#cbd5e1">';
|
||
html += sol.capabilities_todo.map(function(cap){
|
||
var cl = d.mup_checklist[cap];
|
||
return '<span style="display:inline-block;padding:1px 6px;border-radius:4px;background:'+(cl && cl.critical ? 'rgba(239,68,68,.2)' : 'rgba(148,163,184,.15)')+';margin:1px;font-size:10px;color:'+(cl && cl.critical?'#fca5a5':'#cbd5e1')+'">'+(cl ? cl.name : cap)+' ·'+(cl?cl.dev_days:0)+'d</span>';
|
||
}).join(' ');
|
||
html += '</span></div>';
|
||
}
|
||
|
||
html += '</div>'; // card end
|
||
});
|
||
html += '</div>'; // solutions end
|
||
|
||
// TOP GAPS section
|
||
html += '<div style="margin-top:14px;padding:14px;background:rgba(239,68,68,.08);border:1px dashed rgba(239,68,68,.4);border-radius:10px">';
|
||
html += '<div style="font-size:12px;color:#fca5a5;font-weight:700;text-transform:uppercase;margin-bottom:10px">🔴 TOP 15 Gaps à combler (si 1 fix → impact N solutions)</div>';
|
||
html += '<div style="display:flex;flex-direction:column;gap:4px">';
|
||
gaps.forEach(function(g){
|
||
var barW = Math.round(g.missing_in_solutions/10*100);
|
||
var col = g.critical ? '#ef4444' : '#94a3b8';
|
||
html += '<div style="display:flex;align-items:center;gap:8px;font-size:11px">';
|
||
html += '<span style="width:220px;color:#cbd5e1">'+(g.critical?'🔴':'⚪')+' '+g.name+'</span>';
|
||
html += '<div style="flex:1;height:12px;background:rgba(255,255,255,.05);border-radius:2px;position:relative;overflow:hidden"><div style="position:absolute;left:0;top:0;bottom:0;width:'+barW+'%;background:'+col+'"></div></div>';
|
||
html += '<span style="width:90px;color:'+col+';font-weight:700;text-align:right">'+g.missing_in_solutions+'/10 · '+g.dev_days+'d</span>';
|
||
html += '</div>';
|
||
});
|
||
html += '</div>';
|
||
html += '<div style="margin-top:8px;font-size:10px;color:#94a3b8;font-style:italic">💡 Tip: Implémenter les gaps critiques communs (ex: billing Stripe) débloque simultanément plusieurs produits multi-user</div>';
|
||
html += '</div>';
|
||
|
||
box.innerHTML = html;
|
||
})
|
||
.catch(function(e){ box.innerHTML = '<div style="color:#ef4444">Err: '+e.message+'</div>'; });
|
||
};
|
||
|
||
// Auto-load when advisor tab rendered
|
||
setTimeout(function(){
|
||
if (document.getElementById('advisor-solution-scanner')) loadSolutionScanner();
|
||
}, 500);
|
||
|
||
// WAVE 251: Decisional Matrix with real-world competitor benchmarks
|
||
window.decisionalMatrix = function() {
|
||
// Real benchmark data: WEVAL solutions vs market competitors with maturity score
|
||
var solutions = [
|
||
{
|
||
rank: 1, name: "Ethica HCP Database MENA", category: "Pharma",
|
||
effort: 2, reward: 9, mad_est: 600000, days: 28,
|
||
maturity: 95, status: "PROD", ice: 270,
|
||
competitors: [{name:"IQVIA", price_idx:10, strength:"Global", weakness:"No MENA focus"}, {name:"Veeva OpenData", price_idx:9, strength:"Pharma-native", weakness:"Expensive"}, {name:"Doctolib Pro", price_idx:5, strength:"EU brand", weakness:"No pharma depth"}],
|
||
weval_edge: "157K HCPs · 87% email · consent-first · 0€ infra sovereign",
|
||
market_tam: "12M€ MENA HCP data market",
|
||
quadrant: "STAR"
|
||
},
|
||
{
|
||
rank: 2, name: "WEVAL SaaS Freemium", category: "AI Platform",
|
||
effort: 6, reward: 9, mad_est: 800000, days: 45,
|
||
maturity: 70, status: "BETA", ice: 120,
|
||
competitors: [{name:"Make.com", price_idx:7, strength:"Visual builder", weakness:"Cloud lock-in"}, {name:"Zapier", price_idx:8, strength:"Ecosystem", weakness:"Pricing scales bad"}, {name:"n8n cloud", price_idx:6, strength:"Self-host option", weakness:"Steep learning"}],
|
||
weval_edge: "WEVIA Master 269 tools · 17 providers cascade · 0€ inference Cerebras/Groq",
|
||
market_tam: "8M€ MA+MENA AI automation",
|
||
quadrant: "BIG_BET"
|
||
},
|
||
{
|
||
rank: 3, name: "WEVADS Brain Outreach", category: "Email Engine",
|
||
effort: 3, reward: 8, mad_est: 450000, days: 21,
|
||
maturity: 92, status: "PROD", ice: 120,
|
||
competitors: [{name:"Mailgun", price_idx:7, strength:"Reputation", weakness:"GDPR MENA fuzzy"}, {name:"SendGrid", price_idx:8, strength:"Scale", weakness:"Shared IPs"}, {name:"Mailjet", price_idx:6, strength:"FR root", weakness:"Limited APIs"}],
|
||
weval_edge: "PMTA+Kumo+Postfix triple MTA · 9 winners · 95%+ delivery · own IPs",
|
||
market_tam: "4M€ MA+MENA cold outreach",
|
||
quadrant: "QUICK_WIN"
|
||
},
|
||
{
|
||
rank: 4, name: "DocuSeal E-signature MENA", category: "Legal Tech",
|
||
effort: 2, reward: 7, mad_est: 250000, days: 14,
|
||
maturity: 85, status: "PROD", ice: 87.5,
|
||
competitors: [{name:"DocuSign", price_idx:10, strength:"Global brand", weakness:"Expensive per seat"}, {name:"Yousign", price_idx:7, strength:"EU/FR", weakness:"No MENA office"}, {name:"HelloSign", price_idx:6, strength:"Dropbox backed", weakness:"Limited MENA"}],
|
||
weval_edge: "Self-hosted 0€ · data sovereignty MENA · unlimited users",
|
||
market_tam: "3.5M€ MA+MENA e-signature",
|
||
quadrant: "QUICK_WIN"
|
||
},
|
||
{
|
||
rank: 5, name: "Dark Scout Intel", category: "Competitive Intel",
|
||
effort: 4, reward: 7, mad_est: 300000, days: 30,
|
||
maturity: 75, status: "PROD", ice: 52.5,
|
||
competitors: [{name:"Recorded Future", price_idx:10, strength:"OSINT leader", weakness:"Not MENA specific"}, {name:"Crayon", price_idx:8, strength:"Battlecards", weakness:"B2B SaaS only"}, {name:"Klue", price_idx:7, strength:"Enterprise", weakness:"No dark web"}],
|
||
weval_edge: "34 scans · multi-engine · dark web + clearnet · 3 presets",
|
||
market_tam: "2M€ MENA intelligence",
|
||
quadrant: "BIG_BET"
|
||
},
|
||
{
|
||
rank: 6, name: "WEVIA Master Orchestrator", category: "AI Orchestration",
|
||
effort: 5, reward: 9, mad_est: 700000, days: 60,
|
||
maturity: 65, status: "BETA", ice: 126,
|
||
competitors: [{name:"Claude Desktop", price_idx:8, strength:"Anthropic brand", weakness:"No sovereignty"}, {name:"ChatGPT Enterprise", price_idx:10, strength:"OpenAI", weakness:"Data leaves org"}, {name:"LangGraph", price_idx:5, strength:"Framework", weakness:"Dev-only"}],
|
||
weval_edge: "269 tools · multi-agents · 0€ inference · self-host · French/MENA fluent",
|
||
market_tam: "15M€ MENA enterprise AI",
|
||
quadrant: "BIG_BET"
|
||
},
|
||
{
|
||
rank: 7, name: "Blade AI Web Agent", category: "Automation",
|
||
effort: 3, reward: 6, mad_est: 200000, days: 21,
|
||
maturity: 80, status: "PROD", ice: 40,
|
||
competitors: [{name:"Browse AI", price_idx:7, strength:"No-code", weakness:"Cloud only"}, {name:"Multion", price_idx:6, strength:"Consumer agent", weakness:"No enterprise"}, {name:"Anthropic Computer Use", price_idx:9, strength:"Research-grade", weakness:"API only"}],
|
||
weval_edge: "Selenium+Chrome · 232 tasks automated · heartbeat monitoring",
|
||
market_tam: "1.5M€ MENA automation",
|
||
quadrant: "QUICK_WIN"
|
||
},
|
||
{
|
||
rank: 8, name: "WePredict AI Cockpits", category: "Predictive Analytics",
|
||
effort: 4, reward: 7, mad_est: 350000, days: 35,
|
||
maturity: 72, status: "BETA", ice: 61.25,
|
||
competitors: [{name:"Salesforce Einstein", price_idx:10, strength:"CRM native", weakness:"Expensive"}, {name:"HubSpot AI", price_idx:7, strength:"PMF", weakness:"SMB focus"}, {name:"Pipedrive AI", price_idx:6, strength:"Simple", weakness:"Basic models"}],
|
||
weval_edge: "16 cockpits · 64 predictions · load monitoring · deal close probability",
|
||
market_tam: "3M€ MENA sales intelligence",
|
||
quadrant: "BIG_BET"
|
||
},
|
||
{
|
||
rank: 9, name: "WEVAL Arena Command Center", category: "Multi-LLM",
|
||
effort: 3, reward: 6, mad_est: 180000, days: 14,
|
||
maturity: 88, status: "PROD", ice: 36,
|
||
competitors: [{name:"OpenRouter", price_idx:6, strength:"Model routing", weakness:"Pay-per-token"}, {name:"LiteLLM", price_idx:4, strength:"Open-source", weakness:"DIY"}, {name:"Portkey", price_idx:7, strength:"Enterprise", weakness:"Expensive"}],
|
||
weval_edge: "409 options · 715 agents · best LLM per use case · 17 providers",
|
||
market_tam: "1M€ MENA LLM orchestration",
|
||
quadrant: "QUICK_WIN"
|
||
},
|
||
{
|
||
rank: 10, name: "Paperclip PM + CRM", category: "Project Mgmt",
|
||
effort: 6, reward: 5, mad_est: 150000, days: 45,
|
||
maturity: 60, status: "BETA", ice: 12.5,
|
||
competitors: [{name:"Asana", price_idx:8, strength:"Market leader", weakness:"Expensive"}, {name:"Monday", price_idx:9, strength:"UX polish", weakness:"Pricing"}, {name:"Notion", price_idx:7, strength:"Flexibility", weakness:"Not PM native"}],
|
||
weval_edge: "48 leads tracked · self-host · integrated WEVIA + WEVADS",
|
||
market_tam: "800K€ MA PM tools",
|
||
quadrant: "FILL_IN"
|
||
}
|
||
];
|
||
|
||
var box = document.getElementById('advisor-decisional-matrix');
|
||
if (!box) return;
|
||
|
||
// Top KPIs bar
|
||
var totalMad = solutions.reduce(function(s,x){return s+x.mad_est;},0);
|
||
var avgMaturity = Math.round(solutions.reduce(function(s,x){return s+x.maturity;},0)/solutions.length);
|
||
var prodCount = solutions.filter(function(x){return x.status==='PROD';}).length;
|
||
|
||
var html = '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:10px;margin-bottom:14px">';
|
||
html += '<div style="padding:10px;background:rgba(0,0,0,.3);border-left:3px solid #f0abfc;border-radius:6px"><div style="font-size:9px;color:#fbcfe8;text-transform:uppercase;font-weight:700">💰 Pipeline total</div><div style="font-size:22px;font-weight:800;color:#f0abfc">'+Math.round(totalMad/1000)+'K<span style="font-size:12px"> MAD</span></div></div>';
|
||
html += '<div style="padding:10px;background:rgba(0,0,0,.3);border-left:3px solid #10b981;border-radius:6px"><div style="font-size:9px;color:#6ee7b7;text-transform:uppercase;font-weight:700">✅ PROD ready</div><div style="font-size:22px;font-weight:800;color:#10b981">'+prodCount+'<span style="font-size:12px">/10</span></div></div>';
|
||
html += '<div style="padding:10px;background:rgba(0,0,0,.3);border-left:3px solid #22d3ee;border-radius:6px"><div style="font-size:9px;color:#a5f3fc;text-transform:uppercase;font-weight:700">📈 Maturité moy</div><div style="font-size:22px;font-weight:800;color:#22d3ee">'+avgMaturity+'<span style="font-size:12px">%</span></div></div>';
|
||
html += '<div style="padding:10px;background:rgba(0,0,0,.3);border-left:3px solid #fbbf24;border-radius:6px"><div style="font-size:9px;color:#fde68a;text-transform:uppercase;font-weight:700">🎯 Solutions</div><div style="font-size:22px;font-weight:800;color:#fbbf24">'+solutions.length+'</div></div>';
|
||
html += '</div>';
|
||
|
||
// Effort vs Reward SCATTER PLOT (inline SVG)
|
||
html += '<div style="padding:14px;background:rgba(0,0,0,.35);border-radius:10px;margin-bottom:14px">';
|
||
html += '<div style="font-size:11px;color:#f0abfc;font-weight:700;margin-bottom:10px;text-transform:uppercase">📈 Matrice Effort × Rendement (BCG quadrants)</div>';
|
||
html += '<svg viewBox="0 0 700 400" style="width:100%;max-width:700px;height:auto;display:block;margin:auto">';
|
||
// Grid + quadrants
|
||
html += '<rect x="40" y="20" width="640" height="340" fill="rgba(0,0,0,.2)" stroke="rgba(255,255,255,.08)" stroke-width="1"/>';
|
||
// Quadrant backgrounds
|
||
html += '<rect x="40" y="20" width="320" height="170" fill="rgba(16,185,129,.08)" />'; // QUICK_WIN top-left
|
||
html += '<rect x="360" y="20" width="320" height="170" fill="rgba(59,130,246,.08)" />'; // BIG_BET top-right
|
||
html += '<rect x="40" y="190" width="320" height="170" fill="rgba(251,191,36,.05)" />'; // FILL_IN bottom-left
|
||
html += '<rect x="360" y="190" width="320" height="170" fill="rgba(239,68,68,.05)" />'; // THANKLESS bottom-right
|
||
// Axes
|
||
html += '<line x1="40" y1="190" x2="680" y2="190" stroke="rgba(255,255,255,.2)" stroke-width="1" stroke-dasharray="4,4"/>';
|
||
html += '<line x1="360" y1="20" x2="360" y2="360" stroke="rgba(255,255,255,.2)" stroke-width="1" stroke-dasharray="4,4"/>';
|
||
// Axis labels
|
||
html += '<text x="360" y="385" text-anchor="middle" fill="#94a3b8" font-size="12" font-weight="700">Effort →</text>';
|
||
html += '<text x="20" y="190" text-anchor="middle" fill="#94a3b8" font-size="12" font-weight="700" transform="rotate(-90, 20, 190)">← Rendement</text>';
|
||
// Quadrant labels
|
||
html += '<text x="200" y="38" text-anchor="middle" fill="#10b981" font-size="10" font-weight="800">🎯 QUICK WIN</text>';
|
||
html += '<text x="520" y="38" text-anchor="middle" fill="#3b82f6" font-size="10" font-weight="800">💎 BIG BET</text>';
|
||
html += '<text x="200" y="355" text-anchor="middle" fill="#fbbf24" font-size="10" font-weight="800">⚙ FILL-IN</text>';
|
||
html += '<text x="520" y="355" text-anchor="middle" fill="#ef4444" font-size="10" font-weight="800">⛔ THANKLESS</text>';
|
||
|
||
// Plot points
|
||
solutions.forEach(function(s){
|
||
// effort 0-10 → x 40-680 (range 640)
|
||
var x = 40 + (s.effort / 10) * 640;
|
||
var y = 360 - (s.reward / 10) * 340;
|
||
// Size by MAD (50k=6r, 800k=22r)
|
||
var r = 6 + Math.min(16, s.mad_est / 50000);
|
||
var colors = {STAR:'#f0abfc', PROD:'#10b981', BETA:'#fbbf24'};
|
||
var col = colors[s.status] || '#94a3b8';
|
||
html += '<circle cx="'+x+'" cy="'+y+'" r="'+r+'" fill="'+col+'" fill-opacity="0.7" stroke="'+col+'" stroke-width="2"/>';
|
||
html += '<text x="'+x+'" y="'+(y+3)+'" text-anchor="middle" fill="#0a0f1a" font-size="10" font-weight="800">'+s.rank+'</text>';
|
||
});
|
||
html += '</svg>';
|
||
html += '<div style="display:flex;gap:14px;margin-top:8px;justify-content:center;font-size:10px;color:#94a3b8">';
|
||
html += '<span><span style="display:inline-block;width:8px;height:8px;border-radius:50%;background:#f0abfc;margin-right:3px"></span> STAR</span>';
|
||
html += '<span><span style="display:inline-block;width:8px;height:8px;border-radius:50%;background:#10b981;margin-right:3px"></span> PROD</span>';
|
||
html += '<span><span style="display:inline-block;width:8px;height:8px;border-radius:50%;background:#fbbf24;margin-right:3px"></span> BETA</span>';
|
||
html += '<span>⭕ Taille = pipeline MAD</span>';
|
||
html += '</div>';
|
||
html += '</div>';
|
||
|
||
// Ranked solutions list with benchmarks
|
||
html += '<div style="display:flex;flex-direction:column;gap:8px">';
|
||
solutions.forEach(function(s){
|
||
var qCol = {QUICK_WIN:'#10b981', BIG_BET:'#3b82f6', FILL_IN:'#fbbf24', STAR:'#f0abfc', THANKLESS:'#ef4444'}[s.quadrant] || '#94a3b8';
|
||
var statusCol = {PROD:'#10b981', BETA:'#fbbf24', ALPHA:'#ef4444'}[s.status] || '#94a3b8';
|
||
|
||
html += '<div style="padding:12px 14px;background:rgba(0,0,0,.3);border-left:4px solid '+qCol+';border-radius:8px;transition:all .2s" onmouseover="this.style.background=\'rgba(0,0,0,.45)\'" onmouseout="this.style.background=\'rgba(0,0,0,.3)\'">';
|
||
// Header
|
||
html += '<div style="display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:8px">';
|
||
html += '<div style="width:32px;height:32px;border-radius:50%;background:'+qCol+';color:#0a0f1a;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:800">'+s.rank+'</div>';
|
||
html += '<div style="font-size:13.5px;color:#e0e7ff;font-weight:700">'+s.name+'</div>';
|
||
html += '<span style="padding:2px 8px;border-radius:10px;background:'+qCol+'33;color:'+qCol+';font-size:9px;font-weight:700">'+s.quadrant+'</span>';
|
||
html += '<span style="padding:2px 8px;border-radius:10px;background:'+statusCol+'33;color:'+statusCol+';font-size:9px;font-weight:700">'+s.status+'</span>';
|
||
html += '<span style="padding:2px 8px;border-radius:10px;background:rgba(148,163,184,.15);color:#94a3b8;font-size:9px;font-weight:700">'+s.category+'</span>';
|
||
html += '<span style="margin-left:auto;font-size:15px;color:#fbbf24;font-weight:800">'+Math.round(s.mad_est/1000)+'K MAD</span>';
|
||
html += '</div>';
|
||
|
||
// Stats row
|
||
html += '<div style="display:flex;gap:14px;flex-wrap:wrap;margin-bottom:8px;font-size:11px">';
|
||
html += '<span style="color:#94a3b8">⚡ Effort <b style="color:#fbbf24">'+s.effort+'/10</b></span>';
|
||
html += '<span style="color:#94a3b8">🚀 Rendement <b style="color:#10b981">'+s.reward+'/10</b></span>';
|
||
html += '<span style="color:#94a3b8">🎯 ICE <b style="color:#f0abfc">'+s.ice+'</b></span>';
|
||
html += '<span style="color:#94a3b8">⏱ Durée <b style="color:#22d3ee">'+s.days+'j</b></span>';
|
||
html += '<span style="color:#94a3b8">📊 Maturité <b style="color:'+(s.maturity>=85?'#10b981':(s.maturity>=65?'#fbbf24':'#ef4444'))+'">'+s.maturity+'%</b></span>';
|
||
html += '<span style="color:#94a3b8">💰 TAM <b style="color:#6ee7b7">'+s.market_tam+'</b></span>';
|
||
html += '</div>';
|
||
|
||
// WEVAL edge
|
||
html += '<div style="padding:8px 10px;background:rgba(16,185,129,.1);border-left:2px solid #10b981;border-radius:4px;margin-bottom:8px;font-size:11px;color:#6ee7b7"><b>💪 Edge WEVAL:</b> '+s.weval_edge+'</div>';
|
||
|
||
// Benchmark competitors
|
||
html += '<div style="padding:8px 10px;background:rgba(239,68,68,.08);border-left:2px solid #ef4444;border-radius:4px;font-size:10.5px">';
|
||
html += '<div style="color:#fca5a5;font-weight:700;margin-bottom:4px">🥊 Benchmark concurrence:</div>';
|
||
s.competitors.forEach(function(c){
|
||
var bars = '█'.repeat(c.price_idx) + '░'.repeat(10-c.price_idx);
|
||
html += '<div style="display:flex;gap:8px;margin-bottom:2px;color:#cbd5e1"><span style="width:120px;font-weight:600">'+c.name+'</span><span style="color:#fbbf24;font-family:monospace;font-size:9px">'+bars+'</span><span style="color:#94a3b8;font-size:10px">✅ '+c.strength+' · ⚠ '+c.weakness+'</span></div>';
|
||
});
|
||
html += '</div>';
|
||
|
||
html += '</div>'; // card end
|
||
});
|
||
html += '</div>'; // list end
|
||
|
||
box.innerHTML = html;
|
||
};
|
||
|
||
// Auto-load on advisor render
|
||
setTimeout(function(){
|
||
if (document.getElementById('advisor-decisional-matrix')) decisionalMatrix();
|
||
}, 800);
|
||
|
||
// WAVE 246: KPI Dashboard with inline SVG charts
|
||
window.loadKpiDashboard = function() {
|
||
var box = document.getElementById('advisor-kpi-box');
|
||
if (!box) return;
|
||
box.innerHTML = '<div style="color:#10b981;font-size:11px">🔍 Loading KPIs + rendering charts...</div>';
|
||
fetch('/api/social-signals-hub.php?action=kpi_dashboard&cb='+Date.now())
|
||
.then(function(r){return r.json();})
|
||
.then(function(d){
|
||
var html = '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:10px">';
|
||
// Top KPI cards
|
||
var leads = d.leads || {};
|
||
var tasks = d.tasks || {};
|
||
html += '<div style="padding:12px;background:rgba(0,0,0,.3);border-left:3px solid #10b981;border-radius:6px"><div style="font-size:10px;color:#6ee7b7;text-transform:uppercase;font-weight:700">Leads · MQL avg</div><div style="font-size:22px;font-weight:800;color:#10b981">'+(leads.n||0)+' · <span style="font-size:14px">M'+(leads.avg_mql||0)+'</span></div><div style="font-size:10px;color:#6ee7b7">'+(leads.sql_q||0)+' SQL qualified</div></div>';
|
||
html += '<div style="padding:12px;background:rgba(0,0,0,.3);border-left:3px solid #fbbf24;border-radius:6px"><div style="font-size:10px;color:#fde68a;text-transform:uppercase;font-weight:700">Tasks · Pipeline MAD</div><div style="font-size:22px;font-weight:800;color:#fbbf24">'+(tasks.n||0)+' · <span style="font-size:14px">'+Math.round((tasks.total_mad||0)/1000)+'K</span></div><div style="font-size:10px;color:#fde68a">'+Object.keys(d.tasks_by_status||{}).length+' statuses</div></div>';
|
||
html += '<div style="padding:12px;background:rgba(0,0,0,.3);border-left:3px solid #22d3ee;border-radius:6px"><div style="font-size:10px;color:#a5f3fc;text-transform:uppercase;font-weight:700">Countries</div><div style="font-size:22px;font-weight:800;color:#22d3ee">'+Object.keys(d.leads_by_country||{}).length+'</div><div style="font-size:10px;color:#a5f3fc">'+Object.keys(d.leads_by_country||{}).slice(0,3).join(' · ')+'</div></div>';
|
||
html += '<div style="padding:12px;background:rgba(0,0,0,.3);border-left:3px solid #a855f7;border-radius:6px"><div style="font-size:10px;color:#c4b5fd;text-transform:uppercase;font-weight:700">Industries</div><div style="font-size:22px;font-weight:800;color:#a855f7">'+Object.keys(d.industries||{}).length+'</div><div style="font-size:10px;color:#c4b5fd">'+Object.keys(d.industries||{}).slice(0,3).join(' · ')+'</div></div>';
|
||
html += '</div>';
|
||
|
||
// Inline SVG bar chart: leads_by_country
|
||
html += '<div style="margin-top:14px;padding:12px;background:rgba(0,0,0,.25);border-radius:6px"><div style="font-size:11px;color:#6ee7b7;font-weight:700;margin-bottom:8px">🗺 Leads par pays</div>';
|
||
var countries = Object.entries(d.leads_by_country||{}).sort(function(a,b){return b[1]-a[1];}).slice(0,8);
|
||
var maxC = Math.max.apply(null, countries.map(function(c){return c[1];}).concat([1]));
|
||
countries.forEach(function(c){
|
||
var pct = Math.round(c[1]/maxC*100);
|
||
html += '<div style="display:flex;align-items:center;gap:8px;margin-bottom:3px;font-size:11px"><span style="width:40px;color:#94a3b8">'+c[0]+'</span><div style="flex:1;background:rgba(255,255,255,.04);height:16px;border-radius:3px;position:relative;overflow:hidden"><div style="position:absolute;left:0;top:0;bottom:0;width:'+pct+'%;background:linear-gradient(90deg,#10b981,#6ee7b7)"></div><span style="position:relative;padding-left:6px;color:#e0e7ff;font-weight:700;line-height:16px">'+c[1]+'</span></div></div>';
|
||
});
|
||
html += '</div>';
|
||
|
||
// Industries bar chart
|
||
html += '<div style="margin-top:10px;padding:12px;background:rgba(0,0,0,.25);border-radius:6px"><div style="font-size:11px;color:#c4b5fd;font-weight:700;margin-bottom:8px">🏭 Industries</div>';
|
||
var inds = Object.entries(d.industries||{}).sort(function(a,b){return b[1]-a[1];});
|
||
var maxI = Math.max.apply(null, inds.map(function(x){return x[1];}).concat([1]));
|
||
inds.forEach(function(it){
|
||
var pct = Math.round(it[1]/maxI*100);
|
||
html += '<div style="display:flex;align-items:center;gap:8px;margin-bottom:3px;font-size:11px"><span style="width:80px;color:#94a3b8">'+it[0]+'</span><div style="flex:1;background:rgba(255,255,255,.04);height:16px;border-radius:3px;position:relative;overflow:hidden"><div style="position:absolute;left:0;top:0;bottom:0;width:'+pct+'%;background:linear-gradient(90deg,#a855f7,#c4b5fd)"></div><span style="position:relative;padding-left:6px;color:#e0e7ff;font-weight:700;line-height:16px">'+it[1]+'</span></div></div>';
|
||
});
|
||
html += '</div>';
|
||
|
||
// Tasks by status
|
||
html += '<div style="margin-top:10px;padding:12px;background:rgba(0,0,0,.25);border-radius:6px"><div style="font-size:11px;color:#fde68a;font-weight:700;margin-bottom:8px">📋 Tasks par status + MAD</div>';
|
||
Object.entries(d.tasks_by_status||{}).forEach(function(t){
|
||
var s = t[0]; var v = t[1];
|
||
var cs = {proposed:'#fbbf24',in_progress:'#22d3ee',done:'#10b981',cancelled:'#94a3b8',blocked:'#ef4444'}[s]||'#94a3b8';
|
||
html += '<div style="display:flex;align-items:center;gap:8px;margin-bottom:3px;font-size:11px"><span style="width:100px;color:'+cs+';font-weight:700">'+s+'</span><span style="color:#e0e7ff">'+v.count+' tasks · '+Math.round((v.mad||0)/1000)+'K MAD</span></div>';
|
||
});
|
||
html += '</div>';
|
||
|
||
box.innerHTML = html;
|
||
})
|
||
.catch(function(e){ box.innerHTML = '<div style="color:#ef4444">Err: '+e.message+'</div>'; });
|
||
};
|
||
|
||
// WAVE 247: Kanban board
|
||
window.loadKanban = function() {
|
||
var box = document.getElementById('advisor-kanban-box');
|
||
if (!box) return;
|
||
box.innerHTML = '<div style="color:#a855f7">Loading kanban…</div>';
|
||
fetch('/api/social-signals-hub.php?action=kanban&cb='+Date.now())
|
||
.then(function(r){return r.json();})
|
||
.then(function(d){
|
||
var html = '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:8px">';
|
||
var statuses = ['proposed','in_progress','done','cancelled','blocked'];
|
||
var cols = {proposed:'#fbbf24',in_progress:'#22d3ee',done:'#10b981',cancelled:'#94a3b8',blocked:'#ef4444'};
|
||
statuses.forEach(function(s){
|
||
var cards = (d.columns||{})[s] || [];
|
||
var mad = (d.mad_by_status||{})[s] || 0;
|
||
html += '<div style="padding:10px;background:rgba(0,0,0,.3);border-top:3px solid '+cols[s]+';border-radius:6px;min-height:100px">';
|
||
html += '<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:6px;font-size:10px;font-weight:700;color:'+cols[s]+';text-transform:uppercase">'+s+' <span style="opacity:.8">'+cards.length+' · '+Math.round(mad/1000)+'K</span></div>';
|
||
cards.forEach(function(c){
|
||
html += '<div style="padding:6px;margin-bottom:4px;background:rgba(0,0,0,.35);border-left:2px solid '+cols[s]+';border-radius:3px">';
|
||
html += '<div style="font-size:10.5px;color:#e0e7ff;font-weight:600">#'+c.id+' '+(c.title||'?').slice(0,40)+'</div>';
|
||
if (c.lead_company) html += '<div style="font-size:9px;color:#22d3ee;margin-top:2px">📌 '+c.lead_company+' MQL '+(c.lead_mql||'?')+'</div>';
|
||
if (c.estimated_mad) html += '<div style="font-size:9px;color:#fbbf24;margin-top:2px">'+Math.round(c.estimated_mad/1000)+'K MAD</div>';
|
||
html += '</div>';
|
||
});
|
||
if (!cards.length) html += '<div style="color:#64748b;font-size:10px;text-align:center;padding:8px">empty</div>';
|
||
html += '</div>';
|
||
});
|
||
html += '</div>';
|
||
box.innerHTML = html;
|
||
})
|
||
.catch(function(e){ box.innerHTML = '<div style="color:#ef4444">Err: '+e.message+'</div>'; });
|
||
};
|
||
|
||
// WAVE 248: Pipeline stages
|
||
window.loadPipelineStages = function() {
|
||
var box = document.getElementById('advisor-pipeline-box');
|
||
if (!box) return;
|
||
box.innerHTML = '<div style="color:#60a5fa">Loading pipeline…</div>';
|
||
fetch('/api/social-signals-hub.php?action=pipeline_stages&cb='+Date.now())
|
||
.then(function(r){return r.json();})
|
||
.then(function(d){
|
||
var html = '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:6px">';
|
||
var totalMad = Object.values(d.stages||{}).reduce(function(s,x){return s+(x.mad||0);},0);
|
||
Object.entries(d.stages||{}).forEach(function(e){
|
||
var s = e[0], v = e[1];
|
||
var pct = totalMad ? Math.round(v.mad/totalMad*100) : 0;
|
||
html += '<div style="padding:10px;background:rgba(0,0,0,.3);border-bottom:3px solid '+v.color+';border-radius:6px">';
|
||
html += '<div style="font-size:10px;color:'+v.color+';font-weight:700;text-transform:uppercase">'+v.name+'</div>';
|
||
html += '<div style="font-size:18px;color:#e0e7ff;font-weight:800">'+v.count+'</div>';
|
||
html += '<div style="font-size:10px;color:#94a3b8">'+Math.round(v.mad/1000)+'K MAD ('+pct+'%)</div>';
|
||
html += '<div style="height:4px;margin-top:4px;background:rgba(255,255,255,.05);border-radius:2px;overflow:hidden"><div style="height:100%;width:'+pct+'%;background:'+v.color+'"></div></div>';
|
||
html += '</div>';
|
||
});
|
||
html += '</div>';
|
||
box.innerHTML = html;
|
||
})
|
||
.catch(function(e){ box.innerHTML = '<div style="color:#ef4444">Err: '+e.message+'</div>'; });
|
||
};
|
||
|
||
// WAVE 249: Activity timeline
|
||
window.loadActivityTimeline = function() {
|
||
var box = document.getElementById('advisor-timeline-box');
|
||
if (!box) return;
|
||
box.innerHTML = '<div style="color:#fbbf24">Loading timeline…</div>';
|
||
fetch('/api/social-signals-hub.php?action=activity_timeline&cb='+Date.now())
|
||
.then(function(r){return r.json();})
|
||
.then(function(d){
|
||
var html = '<div style="font-size:10px;color:#fde68a;margin-bottom:8px">'+(d.count||0)+' events</div>';
|
||
(d.events||[]).forEach(function(e){
|
||
var icon = e.type === 'task_created' ? '📋' : (e.type === 'lead_created' ? '👤' : '⚡');
|
||
var color = e.type === 'task_created' ? '#22d3ee' : '#10b981';
|
||
html += '<div style="padding:8px 10px;margin-bottom:4px;background:rgba(0,0,0,.25);border-left:3px solid '+color+';border-radius:4px">';
|
||
html += '<div style="display:flex;align-items:center;gap:6px"><span style="font-size:13px">'+icon+'</span><b style="font-size:11px;color:#e0e7ff">'+(e.title||'?').slice(0,60)+'</b><span style="margin-left:auto;font-size:9px;color:#64748b">'+(e.ts||'').slice(5,16)+'</span></div>';
|
||
var meta = e.meta || {};
|
||
var metaStr = Object.entries(meta).map(function(x){return x[0]+':'+x[1];}).join(' · ');
|
||
if (metaStr) html += '<div style="font-size:9px;color:#94a3b8;margin-top:3px">'+metaStr+'</div>';
|
||
html += '</div>';
|
||
});
|
||
box.innerHTML = html;
|
||
})
|
||
.catch(function(e){ box.innerHTML = '<div style="color:#ef4444">Err: '+e.message+'</div>'; });
|
||
};
|
||
|
||
// WAVE 250: Search tasks
|
||
window.runSearch = function() {
|
||
var box = document.getElementById('advisor-search-results');
|
||
if (!box) return;
|
||
var q = document.getElementById('search-q').value;
|
||
var st = document.getElementById('search-status').value;
|
||
var mm = document.getElementById('search-min-mad').value;
|
||
var url = '/api/social-signals-hub.php?action=search_tasks';
|
||
if (q) url += '&q=' + encodeURIComponent(q);
|
||
if (st) url += '&status=' + encodeURIComponent(st);
|
||
if (mm) url += '&min_mad=' + encodeURIComponent(mm);
|
||
url += '&cb=' + Date.now();
|
||
box.innerHTML = '<div style="color:#ec4899">Searching…</div>';
|
||
fetch(url)
|
||
.then(function(r){return r.json();})
|
||
.then(function(d){
|
||
if (!d.ok || !d.tasks.length) { box.innerHTML = '<div style="color:#94a3b8">No results · '+(d.count||0)+'</div>'; return; }
|
||
var html = '<div style="font-size:11px;color:#fbcfe8;margin-bottom:6px">✓ '+d.count+' results for "'+(d.query||'')+'"</div>';
|
||
d.tasks.forEach(function(t){
|
||
var cs = {proposed:'#fbbf24',in_progress:'#22d3ee',done:'#10b981',cancelled:'#94a3b8',blocked:'#ef4444'}[t.status]||'#94a3b8';
|
||
html += '<div style="padding:6px 8px;margin-bottom:3px;background:rgba(0,0,0,.25);border-left:2px solid '+cs+';border-radius:4px">';
|
||
html += '<div style="display:flex;align-items:center;gap:6px"><b style="font-size:11px;color:#e0e7ff">#'+t.id+' '+(t.title||'').slice(0,60)+'</b><span style="padding:1px 5px;border-radius:4px;background:'+cs+'22;color:'+cs+';font-size:9px">'+t.status+'</span>';
|
||
if (t.estimated_mad) html += '<span style="margin-left:auto;color:#fbbf24;font-size:10px;font-weight:700">'+Math.round(t.estimated_mad/1000)+'K</span>';
|
||
html += '</div>';
|
||
if (t.lead_company) html += '<div style="font-size:9px;color:#22d3ee;margin-top:2px">📌 '+t.lead_company+' MQL '+(t.lead_mql||'?')+'</div>';
|
||
html += '</div>';
|
||
});
|
||
box.innerHTML = html;
|
||
})
|
||
.catch(function(e){ box.innerHTML = '<div style="color:#ef4444">Err: '+e.message+'</div>'; });
|
||
};
|
||
|
||
// Auto-load all new sections when advisor tab opens
|
||
var origBuildSocialHub = buildSocialHub;
|
||
// Already wraps in wave 230 - extend further
|
||
setTimeout(function(){
|
||
if (document.getElementById('advisor-kpi-box')) {
|
||
loadKpiDashboard();
|
||
loadKanban();
|
||
loadPipelineStages();
|
||
loadActivityTimeline();
|
||
}
|
||
}, 1500);
|
||
|
||
window.refreshSocialHub = refreshSocialHub;
|
||
|
||
window.renderAdvisorV2 = renderAdvisor;
|
||
})();
|
||
</script>
|
||
|
||
<!-- DOCTRINE-60-UX-JS --><script id="doctrine60-ux-js-direct">
|
||
|
||
// DOCTRINE-60-UX-JS staggered entrance
|
||
(function(){
|
||
if (!('IntersectionObserver' in window)) return;
|
||
const obs = new IntersectionObserver((entries) => {
|
||
entries.forEach((e, i) => {
|
||
if (e.isIntersecting) {
|
||
setTimeout(() => e.target.classList.add('enter-stagger'), i * 80);
|
||
obs.unobserve(e.target);
|
||
}
|
||
});
|
||
});
|
||
document.querySelectorAll('.card, .kpi, .panel').forEach(el => obs.observe(el));
|
||
})();
|
||
|
||
</script>
|
||
</body>
|
||
</html>
|