/* global React */ const { useState, useMemo, useEffect, useRef } = React; // =============== Icons (small inline SVGs) =============== const Icon = ({name, size=16, stroke=1.7}) => { const p = {width:size, height:size, viewBox:"0 0 24 24", fill:"none", stroke:"currentColor", strokeWidth:stroke, strokeLinecap:"round", strokeLinejoin:"round"}; const g = { grid: , map: , users: , user:, rocket: , network: , trophy: , calendar: , bell:, search:, settings:, arrowRight:, arrowUp:, plus:, spark:, chip: , layers: , building: , briefcase:, book:, target:, flame:, star:, check:, eye:, msg:, filter:, }; return {g[name] || g.grid}; }; window.Icon = Icon; // =============== Avatar =============== function Avatar({name, initials, color, size='md'}) { const cls = size==='sm' ? 'avatar-sm' : size==='lg' ? 'avatar-lg' : size==='xl' ? 'avatar-xl' : ''; const colors = ['#0B5FBE','#0E3F84','#7C3AED','#DB2777','#0891B2','#059669','#F59E0B','#DC2626','#0EA5E9','#6366F1']; const seed = (name||'?').charCodeAt(0) + (name||'?').charCodeAt(1 || 0) || 0; const bg = color || colors[Math.abs(seed) % colors.length]; return
{initials}
; } function shade(hex, p) { const n = hex.replace('#',''); const r = parseInt(n.slice(0,2),16), g = parseInt(n.slice(2,4),16), b = parseInt(n.slice(4,6),16); const f = (c) => Math.max(0, Math.min(255, Math.round(c + 255*p))); return '#'+[f(r),f(g),f(b)].map(c=>c.toString(16).padStart(2,'0')).join(''); } window.Avatar = Avatar; window.shade = shade; // =============== Badge / Selo =============== function Selo({id, small=false}) { const s = window.SELOS[id]; if (!s) return null; return {s.icon} {small ? null : s.nome} ; } window.Selo = Selo; function ClassifPill({id, withDot=true}) { const c = window.CLASSIFICACOES.find(x=>x.id===id); if (!c) return null; return {withDot && } {c.nome} ; } window.ClassifPill = ClassifPill; // =============== Sparkline =============== function Sparkline({data, w=80, h=22, color='#0B5FBE', fill=true}) { const max = Math.max(...data), min = Math.min(...data); const range = max - min || 1; const dx = w / (data.length - 1); let path = ''; data.forEach((v, i) => { const x = i * dx, y = h - ((v - min) / range) * (h - 2) - 1; path += (i===0?'M':'L') + x.toFixed(1) + ' ' + y.toFixed(1) + ' '; }); const fillPath = path + `L ${w} ${h} L 0 ${h} Z`; return {fill && } ; } window.Sparkline = Sparkline; // =============== Radar Chart =============== function Radar({dim, size=200, color='#0B5FBE'}) { const cx = size/2, cy = size/2, R = size/2 - 22; const labels = [ {key:'engajamento', name:'Engajamento'}, {key:'execucao', name:'Execução'}, {key:'colaboracao', name:'Colaboração'}, {key:'reconhecimento', name:'Reconhecimento'}, {key:'maturidade', name:'Maturidade'}, ]; const N = labels.length; const point = (val, i) => { const a = -Math.PI/2 + i * 2*Math.PI/N; const r = (val/100) * R; return [cx + r*Math.cos(a), cy + r*Math.sin(a)]; }; const grid = [0.25, 0.5, 0.75, 1].map(f => labels.map((_, i) => point(100*f, i)).map(p=>p.join(',')).join(' ') ); const dataPoly = labels.map((l, i) => point(dim[l.key], i)).map(p=>p.join(',')).join(' '); return (
{grid.map((pts, i) => ( ))} {labels.map((l, i) => { const [x, y] = point(100, i); return ; })} {labels.map((l, i) => { const [x, y] = point(dim[l.key], i); return ; })} {labels.map((l, i) => { const [x, y] = point(118, i); return {l.name}; })}
{labels.map(l => (
{l.name} {dim[l.key]}
))}
); } window.Radar = Radar; // =============== Trail (gamified progression) =============== function Trail({points}) { const steps = window.CLASSIFICACOES; const currentIdx = steps.findIndex(s => points >= s.faixa[0] && points < s.faixa[1]); return (
{steps.map((s, i) => { const done = i < currentIdx; const current = i === currentIdx; const cls = done ? 'done' : current ? 'current' : ''; return (
{done ? '✓' : i+1}
{s.nome}
{s.faixa[0]}–{s.faixa[1]>=999?'∞':s.faixa[1]} pts
); })}
); } window.Trail = Trail; // =============== Bar list =============== function BarRow({name, value, max, color='#0B5FBE'}) { const pct = (value/max)*100; return
{name}
{value}
; } window.BarRow = BarRow; Object.assign(window, {Icon, Avatar, shade, Selo, ClassifPill, Sparkline, Radar, Trail, BarRow});