/* ============================================================ FLOWSHIELD — Dashboard ============================================================ */ function TeamLaunch({ theme, icon, kicker, title, desc, stat, statLabel, onClick }) { const ref = useRefL(null); const onMove = (e) => { const el = ref.current; if (!el) return; const b = el.getBoundingClientRect(); el.style.setProperty('--mx', ((e.clientX-b.left)/b.width)*100+'%'); el.style.setProperty('--my', ((e.clientY-b.top)/b.height)*100+'%'); }; return (
{kicker}
{title}
{desc}
{stat} {statLabel}
); } function Dashboard({ onNav }) { const [ov, setOv] = useStateL(null); const [demo, setDemo] = useStateL(false); const load = () => { window.fsApi('/api/results/overview', { method:'GET' }) .then(d => { setOv(d); setDemo(!d || !d.scans || d.scans.total === 0); }) .catch(() => { setDemo(true); }); }; useEffectL(() => { load(); }, []); const F = ov && ov.findings; const sevData = F ? F.sev : { crit:2, high:4, med:3, low:2 }; const openN = F ? F.status.open : 9; const recentScans = (ov && ov.scans && ov.scans.recent && ov.scans.recent.length) ? ov.scans.recent.slice(0,4) : window.SEED_SCANS.slice(0,4); const btScore = ov && ov.blueteam_score != null ? ov.blueteam_score : null; const surf = (ov && ov.surface) || null; const compN = ov && ov.compliance_scans != null ? ov.compliance_scans : null; const maxSev = Math.max(1, sevData.crit||0, sevData.high||0, sevData.med||0, sevData.low||0); return (
ActualizaronNav('redteam')} className="theme-fs">Nuevo escaneo} /> {demo && } {/* three teams */}
Operaciones
onNav('redteam')} /> onNav('blueteam')} /> onNav('normativa')} />
{/* posture row */}
Resumen de vulnerabilidades
últimos 14 días
{[['crit','Críticos'],['high','Altos'],['med','Medios'],['low','Bajos']].map(([k,l])=>{ const n = sevData[k]||0; return (
{l}
{n}
);})}
Postura defensiva
s.team==='blue').length || '—') : '—'} />
{/* scan activity */}
Actividad de escaneo
{/* recent scans */}
Escaneos recientes
{recentScans.map(s => ( onNav('scans')}> ))}
IDHerramientaObjetivoEstadoHallazgosFecha
{s.code||s.id} {s.tool} {s.target} {s.status==='running' ? {s.progress}% : ( (s.found && (s.found.crit||s.found.high||s.found.med||s.found.low)) ?
{['crit','high','med','low'].map(k => s.found[k] ? {s.found[k]} : null)}
: )}
{window.rptDate?window.rptDate(s.date):s.date}
); } function Row({ k, v, c }) { return (
{k} {v}
); } Object.assign(window, { Dashboard });