// ═══════════════════════════════════════════════════════
// BAUKO CRM — Dashboard Screen  (v4 · 2026-05-22)
// Dois modos: Gerência (visão estratégica) · Vendedor (visão operacional)
// Detecção automática via localStorage bauko_user_email → CRM_DATA.usuarios
// ═══════════════════════════════════════════════════════
/* global React, CRM_DATA, KPICard, Panel, Badge, fR, fN, fDate, fDateTime, AtivIcon */
const { useState: useDashState, useEffect: useDashEffect, useRef: useDashRef } = React;

// ── Etapas do pipeline ───────────────────────────────────────────────────────
var _DASH_ETAPAS = [
  { id: 'lead',         label: 'Lead',        bg: '#e3f0fb', color: '#0077cc' },
  { id: 'qualificacao', label: 'Qualificação', bg: '#fff8e1', color: '#8a6200' },
  { id: 'proposta',     label: 'Proposta',     bg: '#eef0fe', color: '#3461d1' },
  { id: 'negociacao',   label: 'Negociação',   bg: '#f5f0ff', color: '#7c3aed' },
];
var _ETAPA_COMPAT_DASH = { lead:'lead', qualificacao:'qualificacao', proposta:'proposta', negociacao:'negociacao' };

// ── Helpers de data ──────────────────────────────────────────────────────────
function _dhoje()       { var d = new Date(); d.setHours(0,0,0,0); return d; }
function _diasMes(d)    { var h = new Date(); return d.getUTCMonth()===h.getUTCMonth() && d.getUTCFullYear()===h.getUTCFullYear(); }
function _eHoje(d)      { var h = _dhoje(); var t = new Date(h); t.setDate(t.getDate()+1); return d>=h && d<t; }
function _prox7(d)      { var h = _dhoje(); var t = new Date(h); t.setDate(t.getDate()+7); return d>=h && d<t; }
function _diasDiff(a,b) { return Math.floor((a-b)/86400000); }
function _ini90()       { var d = new Date(); d.setDate(d.getDate()-90); d.setHours(0,0,0,0); return d; }
function _iniSemana()   { var d = _dhoje(); d.setDate(d.getDate()-((d.getDay()+6)%7)); return d; }
function _iniMes()      { var d = new Date(); d.setDate(1); d.setHours(0,0,0,0); return d; }

// ── Índices de última atividade ──────────────────────────────────────────────
function _idxUltimaAtivCliente(atividades) {
  var idx = {};
  atividades.forEach(function(at) {
    if (!at.cliente_id || !at.data) return;
    var d = new Date(at.data);
    if (!idx[at.cliente_id] || d > idx[at.cliente_id]) idx[at.cliente_id] = d;
  });
  return idx;
}
function _idxUltimaAtivOp(atividades) {
  var idx = {};
  atividades.forEach(function(at) {
    if (!at.op_id || !at.data) return;
    var d = new Date(at.data);
    if (!idx[at.op_id] || d > idx[at.op_id]) idx[at.op_id] = d;
  });
  return idx;
}
// Retorna o melhor valor disponível para uma oportunidade:
// op.valor quando > 0; caso contrário, o maior valor dentre suas propostas.
function _valorEfetivo(o) {
  if (o.valor > 0) return o.valor;
  var _props = (window.CRM_DATA && CRM_DATA.propostas) || [];
  return _props.filter(function(p){ return p.op_id === o.id; })
               .reduce(function(mx, p){ return Math.max(mx, p.valor || 0); }, 0);
}

// ════════════════════════════════════════════════════════════════════════════
// MAPA DE VISITAS (heatmap com circle markers)
// ════════════════════════════════════════════════════════════════════════════
var MUNICIPIOS_CACHE_KEY = 'bauko_municipios_v1';

function VisitasHeatmap({ atividades, clientes }) {
  var containerRef = useDashRef(null);
  var mapRef       = useDashRef(null);
  var layerRef     = useDashRef(null);
  var [status,     setStatus]     = useDashState('loading');  // loading | ready | error | nodata
  var [periodo,    setPeriodo]    = useDashState('90d');
  var [municipios, setMunicipios] = useDashState(null);

  // Carregar municipios.json (com cache localStorage)
  useDashEffect(function() {
    try {
      var raw = localStorage.getItem(MUNICIPIOS_CACHE_KEY);
      if (raw) { setMunicipios(JSON.parse(raw)); return; }
    } catch(e) {}
    fetch('municipios.json')
      .then(function(r) { return r.json(); })
      .then(function(d) {
        try { localStorage.setItem(MUNICIPIOS_CACHE_KEY, JSON.stringify(d)); } catch(e) {}
        setMunicipios(d);
      })
      .catch(function(e) { console.warn('[Heatmap] municipios.json:', e.message); setStatus('error'); });
  }, []);

  // Inicializar mapa Leaflet
  useDashEffect(function() {
    if (!municipios || !containerRef.current || typeof window.L === 'undefined') return;
    if (!mapRef.current) {
      try {
        var L = window.L;
        var m = L.map(containerRef.current, { center:[-15.78,-52.92], zoom:4, zoomControl:true,
          scrollWheelZoom:false, attributionControl:false });
        L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', {
          subdomains:'abcd', maxZoom:19 }).addTo(m);
        mapRef.current = m;
      } catch(e) { setStatus('error'); return; }
    }
    setStatus('ready');
  }, [municipios]);

  // Atualizar marcadores quando dados ou período mudam
  useDashEffect(function() {
    if (status !== 'ready' || !mapRef.current || !municipios) return;
    var L = window.L;
    if (layerRef.current) { try { mapRef.current.removeLayer(layerRef.current); } catch(e) {} }

    var corte = periodo === '90d' ? _ini90() : new Date(0);
    var visitas = atividades.filter(function(at) {
      return at.tipo === 'visita' && at.data && new Date(at.data) >= corte;
    });

    // Agrupar por cidade
    var contagem = {};
    visitas.forEach(function(at) {
      var cli = CRM_DATA.getCliente(at.cliente_id);
      if (!cli || !cli.cidade || !cli.uf) return;
      var key = cli.cidade.trim() + '|' + (cli.uf||'').toUpperCase().slice(0,2);
      contagem[key] = (contagem[key] || 0) + 1;
    });

    var cidades = Object.keys(contagem);
    if (cidades.length === 0) { setStatus('nodata'); return; }
    setStatus('ready');

    var maxCount = Math.max.apply(null, cidades.map(function(k) { return contagem[k]; }));
    var group = L.layerGroup();

    cidades.forEach(function(key) {
      var coords = municipios[key];
      if (!coords) {
        // fallback sem acento
        var sem = key.normalize('NFD').replace(/[̀-ͯ]/g,'');
        coords = municipios[sem];
      }
      if (!coords) return;
      var n   = contagem[key];
      var pct = n / maxCount;
      var r   = 6 + Math.round(pct * 20); // 6px → 26px
      var cor = pct < 0.33 ? '#007c44' : pct < 0.66 ? '#f4a300' : '#c04000';
      var nome = key.split('|')[0];
      var circle = L.circleMarker(coords, {
        radius: r, color: cor, fillColor: cor, fillOpacity: 0.65, weight: 1.5
      });
      circle.bindTooltip(
        '<div style="font:600 12px/1.4 sans-serif">' + nome + '</div>' +
        '<div style="font:400 11px/1 sans-serif;color:#555">' + n + ' visita' + (n>1?'s':'') + '</div>',
        { direction:'top', offset:[0,-4] }
      );
      group.addLayer(circle);
    });

    group.addTo(mapRef.current);
    layerRef.current = group;

    // Ajusta zoom/centro para os pontos reais — evita ficar na América do Sul toda
    var pontosValidos = cidades
      .map(function(key) {
        var c = municipios[key] || municipios[key.normalize('NFD').replace(/[̀-ͯ]/g,'')];
        return c || null;
      })
      .filter(Boolean);
    if (pontosValidos.length === 1) {
      mapRef.current.setView(pontosValidos[0], 9);
    } else if (pontosValidos.length > 1) {
      mapRef.current.fitBounds(L.latLngBounds(pontosValidos), { padding: [40, 40], maxZoom: 10 });
    }
  }, [status, periodo, municipios, atividades]);

  return (
    <div>
      <div style={{ display:'flex', justifyContent:'flex-end', marginBottom:8 }}>
        <div className="tabs" style={{ marginBottom:0 }}>
          <button className={periodo==='90d'?'is-on':''} onClick={function(){ setPeriodo('90d'); }}>Últimos 90 dias</button>
          <button className={periodo==='all'?'is-on':''} onClick={function(){ setPeriodo('all'); }}>Todo período</button>
        </div>
      </div>
      <div ref={containerRef} style={{ height:340, borderRadius:'var(--r-md)', overflow:'hidden',
        border:'1px solid var(--border)', background:'var(--surface-2)' }} />
      {status === 'loading' && (
        <div style={{ marginTop:8, textAlign:'center', font:'400 12px/1 var(--ff-body)', color:'var(--tx-3)' }}>
          Carregando mapa...
        </div>
      )}
      {status === 'nodata' && (
        <div style={{ marginTop:8, textAlign:'center', font:'400 12px/1 var(--ff-body)', color:'var(--tx-3)' }}>
          Nenhuma visita registrada no período.
        </div>
      )}
      {status === 'error' && (
        <div style={{ marginTop:8, textAlign:'center', font:'400 12px/1 var(--ff-body)', color:'var(--tx-3)' }}>
          Erro ao carregar o mapa. Recarregue a página.
        </div>
      )}
      <div style={{ marginTop:8, display:'flex', gap:16, justifyContent:'center',
        font:'400 11px/1 var(--ff-mono)', color:'var(--tx-3)' }}>
        <span><span style={{ display:'inline-block', width:10, height:10, borderRadius:'50%',
          background:'#007c44', marginRight:4, verticalAlign:'middle' }}></span>1–33%</span>
        <span><span style={{ display:'inline-block', width:10, height:10, borderRadius:'50%',
          background:'#f4a300', marginRight:4, verticalAlign:'middle' }}></span>34–66%</span>
        <span><span style={{ display:'inline-block', width:10, height:10, borderRadius:'50%',
          background:'#c04000', marginRight:4, verticalAlign:'middle' }}></span>67–100%</span>
        <span style={{ marginLeft:8 }}>· Tamanho = frequência relativa</span>
      </div>
    </div>
  );
}

// ════════════════════════════════════════════════════════════════════════════
// DASHBOARD GERÊNCIA — visão estratégica
// ════════════════════════════════════════════════════════════════════════════
function DashboardGerencia({ onNav, onOpenOp }) {
  var ops        = CRM_DATA.oportunidades;
  var atividades = CRM_DATA.atividades;
  var clientes   = CRM_DATA.clientes;
  var propostas  = CRM_DATA.propostas;
  var usuarios   = CRM_DATA.usuarios;
  var agenda     = CRM_DATA.agenda;
  var hoje       = _dhoje();

  var abertas  = ops.filter(function(o) { return !o.cancelada_em && o.etapa!=='fechado_ganho' && o.etapa!=='fechado' && o.etapa!=='fechado_perdido'; });
  var ganhas   = ops.filter(function(o) { return o.etapa==='fechado_ganho' || o.etapa==='fechado'; });
  var perdidas = ops.filter(function(o) { return o.etapa==='fechado_perdido'; });

  // ── KPIs financeiros ────────────────────────────────────────────────────
  var receitaTotal = ganhas.reduce(function(s,o){ return s+_valorEfetivo(o); }, 0);
  var pipelinePond = abertas.reduce(function(s,o){ return s+_valorEfetivo(o)*((o.probabilidade||0)/100); }, 0);
  var forecastMes  = abertas.filter(function(o){ return o.previsao_fechamento && _diasMes(new Date(o.previsao_fechamento)); })
                            .reduce(function(s,o){ return s+_valorEfetivo(o)*((o.probabilidade||0)/100); }, 0);
  var taxaConv     = (ganhas.length+perdidas.length)>0 ? ganhas.length/(ganhas.length+perdidas.length)*100 : 0;
  var ticketMedio  = ganhas.length ? receitaTotal/ganhas.length : 0;

  // ── KPIs visitas ────────────────────────────────────────────────────────
  var visitas      = atividades.filter(function(at){ return at.tipo==='visita'; });
  var visitasSem   = visitas.filter(function(at){ return new Date(at.data||0) >= _iniSemana(); }).length;
  var visitasMes   = visitas.filter(function(at){ return new Date(at.data||0) >= _iniMes(); }).length;
  var visitas90    = visitas.filter(function(at){ return new Date(at.data||0) >= _ini90(); }).length;

  // Visitas por vendedor (últimos 90 dias)
  var vis90 = visitas.filter(function(at){ return new Date(at.data||0) >= _ini90(); });
  var visPorVend = {};
  vis90.forEach(function(at){
    visPorVend[at.vendedor_id] = (visPorVend[at.vendedor_id]||0)+1;
  });
  var rankingVisitas = Object.keys(visPorVend)
    .map(function(vid){ return { u: CRM_DATA.getUsuario(vid), count: visPorVend[vid] }; })
    .filter(function(r){ return r.u; })
    .sort(function(a,b){ return b.count-a.count; })
    .slice(0, 6);

  // ── Funil ───────────────────────────────────────────────────────────────
  var totalValorPipe = abertas.reduce(function(s,o){ return s+(o.valor||0); }, 0) || 1;
  var funil = _DASH_ETAPAS.map(function(et) {
    var etOps = abertas.filter(function(o){ return (_ETAPA_COMPAT_DASH[o.etapa]||o.etapa)===et.id; });
    var valor = etOps.reduce(function(s,o){ return s+(o.valor||0); }, 0);
    return { etapa:et, count:etOps.length, valor:valor, pct:Math.max(4,(valor/totalValorPipe)*100) };
  });

  // ── Ops em risco ────────────────────────────────────────────────────────
  var lastAtivOp = _idxUltimaAtivOp(atividades);
  var limite15   = new Date(hoje); limite15.setDate(limite15.getDate()-15);
  var opsRisco   = abertas.filter(function(o) {
    var vencida = o.previsao_fechamento && new Date(o.previsao_fechamento)<hoje;
    var altaSemAtiv = o.prioridade==='alta' && (!lastAtivOp[o.id]||lastAtivOp[o.id]<limite15);
    return vencida || altaSemAtiv;
  }).sort(function(a,b){
    var av = a.previsao_fechamento && new Date(a.previsao_fechamento)<hoje;
    var bv = b.previsao_fechamento && new Date(b.previsao_fechamento)<hoje;
    if(av&&!bv) return -1; if(!av&&bv) return 1;
    return new Date(a.previsao_fechamento||0)-new Date(b.previsao_fechamento||0);
  }).slice(0,8);

  // ── Alertas ─────────────────────────────────────────────────────────────
  var propExpiradas  = propostas.filter(function(p){ return p.status==='enviada'&&p.validade&&new Date(p.validade)<hoje; }).length;
  var opsVencidasQtd = abertas.filter(function(o){ return o.previsao_fechamento&&new Date(o.previsao_fechamento)<hoje; }).length;

  // ── Ranking financeiro ──────────────────────────────────────────────────
  var lastAtivCli = _idxUltimaAtivCliente(atividades);
  var limite30    = new Date(hoje); limite30.setDate(limite30.getDate()-30);
  var ranking = usuarios.map(function(u) {
    var uGanhas  = ganhas.filter(function(o){ return o.vendedor_id===u.id; });
    var uAbertas = abertas.filter(function(o){ return o.vendedor_id===u.id; });
    var uAtivs   = atividades.filter(function(at){ return at.vendedor_id===u.id; });
    var uClis    = clientes.filter(function(c){ return c.vendedor_id===u.email||c.vendedor_id===u.id; });
    var semCont  = uClis.filter(function(c){ return !lastAtivCli[c.id]||lastAtivCli[c.id]<limite30; }).length;
    var receita  = uGanhas.reduce(function(s,o){ return s+_valorEfetivo(o); }, 0);
    var pipe     = uAbertas.reduce(function(s,o){ return s+_valorEfetivo(o)*((o.probabilidade||0)/100); }, 0);
    return { u:u, receita:receita, pipeline:pipe, atividades:uAtivs.length, semContato:semCont };
  }).filter(function(r){ return r.receita>0||r.pipeline>0||r.atividades>0; })
    .sort(function(a,b){ return b.receita-a.receita; });
  var medals = ['🥇','🥈','🥉'];

  // ── Agenda da equipe — próximos 7 dias ──────────────────────────────────
  var prox7equipe = agenda.filter(function(ag){
    if (!ag.data) return false;
    var d = new Date(ag.data);
    return _prox7(d);
  }).sort(function(a,b){ return new Date(a.data)-new Date(b.data); }).slice(0,10);

  return (
    <div data-screen-label="01 Dashboard">

      {/* ── Alertas ────────────────────────────────────────────────── */}
      {(opsVencidasQtd>0||propExpiradas>0) && (
        <div style={{ background:'#fff8e1', border:'1px solid #f59e0b', borderRadius:'var(--r)',
          padding:'10px 16px', marginBottom:18, display:'flex', alignItems:'center',
          gap:10, flexWrap:'wrap', font:'500 13px/1.4 var(--ff-body)', color:'var(--tx)' }}>
          <span style={{ fontSize:16 }}>⚠️</span>
          {opsVencidasQtd>0 && <span><strong>{opsVencidasQtd}</strong> op{opsVencidasQtd!==1?'s':''} com previsão vencida</span>}
          {opsVencidasQtd>0&&propExpiradas>0 && <span style={{ color:'var(--tx-3)' }}>·</span>}
          {propExpiradas>0 && <span><strong>{propExpiradas}</strong> proposta{propExpiradas!==1?'s':''} expirada{propExpiradas!==1?'s':''} sem resposta</span>}
        </div>
      )}

      {/* ── KPIs financeiros (5 colunas) ─────────────────────────── */}
      <div className="kpi-grid" style={{ gridTemplateColumns:'repeat(5,1fr)', marginBottom:18 }}>
        <KPICard eyebrow="Receita realizada" value={fR(receitaTotal)}
          delta={ganhas.length+' negócio'+(ganhas.length!==1?'s':'')+' fechado'+(ganhas.length!==1?'s':'')}
          deltaTone="pos" accent />
        <KPICard eyebrow="Pipeline ponderado" value={fR(pipelinePond)}
          delta="Probabilidade ponderada" deltaTone="warn" mono />
        <KPICard eyebrow="Forecast do mês" value={fR(forecastMes)}
          delta="Ponderado · fechamento previsto este mês" deltaTone="warn" mono />
        <KPICard eyebrow="Taxa de conversão" value={isNaN(taxaConv)?'—':fN(taxaConv,0)} unit={isNaN(taxaConv)?'':'%'}
          delta="Ganhos / (G + P)" deltaTone={taxaConv>=40?'pos':'warn'} mono />
        <KPICard eyebrow="Ticket médio" value={fR(ticketMedio)}
          delta="Por negócio fechado" deltaTone="neu" mono />
      </div>

      {/* ── KPIs visitas (4 colunas) ─────────────────────────────── */}
      <div className="kpi-grid" style={{ gridTemplateColumns:'repeat(4,1fr)', marginBottom:18 }}>
        <KPICard eyebrow="Visitas esta semana" value={String(visitasSem)}
          delta="Toda a equipe" deltaTone="neu" mono />
        <KPICard eyebrow="Visitas este mês" value={String(visitasMes)}
          delta="Toda a equipe" deltaTone="neu" mono />
        <KPICard eyebrow="Visitas (90 dias)" value={String(visitas90)}
          delta="Histórico recente" deltaTone="neu" mono />
        <KPICard eyebrow="Top visitador (90d)" value={rankingVisitas.length>0?(rankingVisitas[0].u.nome||'').split(' ')[0]:'—'}
          delta={rankingVisitas.length>0?rankingVisitas[0].count+' visitas':'Sem visitas'} deltaTone="pos" mono />
      </div>

      {/* ── Funil + Ranking financeiro ────────────────────────────── */}
      <div className="two-col" style={{ marginBottom:18 }}>

        <Panel title="Funil — snapshot atual" actions={
          <button className="btn btn-ghost" onClick={function(){ onNav('pipeline'); }}>Ver pipeline →</button>
        }>
          {funil.map(function(row) {
            return (
              <div key={row.etapa.id} style={{ marginBottom:16 }}>
                <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:6 }}>
                  <span style={{ padding:'2px 9px', borderRadius:99, fontSize:11, fontWeight:600,
                    background:row.etapa.bg, color:row.etapa.color, fontFamily:'var(--ff-body)' }}>
                    {row.etapa.label}
                  </span>
                  <span style={{ font:'400 11px/1 var(--ff-mono)', color:'var(--tx-3)' }}>
                    {row.count} op{row.count!==1?'s':''} · {fR(row.valor)}
                  </span>
                </div>
                <div style={{ height:7, background:'var(--border)', borderRadius:4, overflow:'hidden' }}>
                  <div style={{ height:'100%', background:row.etapa.color, opacity:0.65,
                    width:row.pct+'%', borderRadius:4, transition:'width 0.4s' }} />
                </div>
              </div>
            );
          })}
          <div style={{ paddingTop:10, borderTop:'1px solid var(--border)', display:'flex',
            justifyContent:'space-between', font:'600 12px/1 var(--ff-mono)', color:'var(--tx-2)' }}>
            <span>Total no pipeline</span>
            <span style={{ color:'var(--grn)' }}>
              {fR(abertas.reduce(function(s,o){ return s+(o.valor||0); }, 0))}
            </span>
          </div>
        </Panel>

        <Panel title="Ranking de vendedores">
          {ranking.length===0
            ? <p style={{ color:'var(--tx-3)', fontSize:13, margin:0 }}>Nenhum dado disponível.</p>
            : (
              <div style={{ overflowX:'auto' }}>
                <table style={{ width:'100%', borderCollapse:'collapse', fontSize:12 }}>
                  <thead>
                    <tr style={{ borderBottom:'1px solid var(--border)' }}>
                      {['Vendedor','Receita','Pipeline','Ativs.','S/ contato'].map(function(h,i) {
                        return (
                          <th key={h} style={{ padding:'4px '+(i===0?'8px 8px 0':'8px')+' 8px',
                            textAlign:i===0?'left':'right', color:'var(--tx-3)', fontWeight:500, whiteSpace:'nowrap' }}>
                            {h}
                          </th>
                        );
                      })}
                    </tr>
                  </thead>
                  <tbody>
                    {ranking.map(function(r,i) {
                      return (
                        <tr key={r.u.id} style={{ borderBottom:'1px solid var(--border)' }}>
                          <td style={{ padding:'9px 8px 9px 0' }}>
                            <div style={{ display:'flex', alignItems:'center', gap:7 }}>
                              <div style={{ width:26, height:26, borderRadius:'50%', background:r.u.avatar_color||'var(--tx-3)',
                                display:'flex', alignItems:'center', justifyContent:'center',
                                font:'600 10px/1 var(--ff-body)', color:'#fff', flexShrink:0 }}>
                                {r.u.iniciais||'?'}
                              </div>
                              <div>
                                <div style={{ font:'500 12px/1 var(--ff-body)', color:'var(--tx)' }}>
                                  {medals[i]||''} {r.u.nome?r.u.nome.split(' ')[0]:r.u.email}
                                </div>
                                <div style={{ font:'400 10px/1 var(--ff-mono)', color:'var(--tx-3)', marginTop:2 }}>
                                  {r.u.cargo||r.u.grupo||''}
                                </div>
                              </div>
                            </div>
                          </td>
                          <td style={{ textAlign:'right', padding:'9px 8px', font:'600 12px/1 var(--ff-mono)', color:'var(--grn)' }}>{fR(r.receita)}</td>
                          <td style={{ textAlign:'right', padding:'9px 8px', font:'400 12px/1 var(--ff-mono)', color:'var(--tx-2)' }}>{fR(r.pipeline)}</td>
                          <td style={{ textAlign:'right', padding:'9px 4px', font:'400 12px/1 var(--ff-mono)', color:'var(--tx-2)' }}>{r.atividades}</td>
                          <td style={{ textAlign:'right', padding:'9px 0', font:'600 12px/1 var(--ff-mono)',
                            color:r.semContato>3?'var(--danger)':r.semContato>0?'var(--warn)':'var(--ok)' }}>
                            {r.semContato}
                          </td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              </div>
            )
          }
        </Panel>
      </div>

      {/* ── Agenda equipe + Ranking de visitas ───────────────────── */}
      <div className="two-col" style={{ marginBottom:18 }}>

        <Panel title="Agenda da equipe — próximos 7 dias"
          meta={prox7equipe.length+' compromisso'+(prox7equipe.length!==1?'s':'')}
          actions={<button className="btn btn-ghost" onClick={function(){ onNav('agenda'); }}>Ver agenda →</button>}>
          {prox7equipe.length===0
            ? <p style={{ color:'var(--tx-3)', fontSize:13, margin:0 }}>Nenhum compromisso agendado para os próximos 7 dias.</p>
            : (
              <div style={{ display:'flex', flexDirection:'column', gap:0 }}>
                {prox7equipe.map(function(ag, i) {
                  var cli  = CRM_DATA.getCliente(ag.cliente_id);
                  var vend = CRM_DATA.getUsuario(ag.vendedor_id);
                  var dataD = new Date(ag.data);
                  var label = dataD.toLocaleDateString('pt-BR',{ weekday:'short', day:'2-digit', month:'2-digit' });
                  var hora  = dataD.toLocaleTimeString('pt-BR',{ hour:'2-digit', minute:'2-digit' });
                  var TIPO_ICON_EMOJI = { visita:'🏭', reuniao:'🤝', ligacao:'📞', followup:'⏰', email:'✉️', whatsapp:'💬' };
                  return (
                    <div key={ag.id||i} style={{ display:'flex', gap:10, alignItems:'flex-start', padding:'8px 0',
                      borderBottom:i<prox7equipe.length-1?'1px solid var(--border)':'none' }}>
                      <span style={{ fontSize:14, flexShrink:0 }}>{TIPO_ICON_EMOJI[ag.tipo]||'📋'}</span>
                      <div style={{ flex:1, minWidth:0 }}>
                        <div style={{ font:'500 12px/1.2 var(--ff-body)', color:'var(--tx)',
                          overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{ag.titulo}</div>
                        <div style={{ font:'400 10px/1 var(--ff-mono)', color:'var(--tx-3)', marginTop:2 }}>
                          {vend?(vend.nome||'').split(' ')[0]:'?'}
                          {cli?' · '+(cli.razao||'').split(' ').slice(0,2).join(' '):''}
                        </div>
                      </div>
                      <div style={{ textAlign:'right', flexShrink:0 }}>
                        <div style={{ font:'500 11px/1 var(--ff-mono)', color:'var(--tx-2)' }}>{label}</div>
                        <div style={{ font:'400 10px/1 var(--ff-mono)', color:'var(--tx-3)', marginTop:2 }}>{hora}</div>
                      </div>
                    </div>
                  );
                })}
              </div>
            )
          }
        </Panel>

        <Panel title="Visitas por vendedor — 90 dias">
          {rankingVisitas.length===0
            ? <p style={{ color:'var(--tx-3)', fontSize:13, margin:0 }}>Nenhuma visita nos últimos 90 dias.</p>
            : (
              <div style={{ display:'flex', flexDirection:'column', gap:0 }}>
                {rankingVisitas.map(function(r, i) {
                  var maxV = rankingVisitas[0].count||1;
                  var pct  = (r.count/maxV)*100;
                  return (
                    <div key={r.u.id} style={{ padding:'8px 0', borderBottom:i<rankingVisitas.length-1?'1px solid var(--border)':'none' }}>
                      <div style={{ display:'flex', justifyContent:'space-between', marginBottom:5 }}>
                        <span style={{ font:'500 12px/1 var(--ff-body)', color:'var(--tx)' }}>
                          {medals[i]||''} {r.u.nome?(r.u.nome.split(' ').slice(0,2).join(' ')):r.u.email}
                        </span>
                        <span style={{ font:'600 12px/1 var(--ff-mono)', color:'var(--grn)' }}>
                          {r.count} visita{r.count!==1?'s':''}
                        </span>
                      </div>
                      <div style={{ height:4, background:'var(--border)', borderRadius:2, overflow:'hidden' }}>
                        <div style={{ height:'100%', background:'var(--grn)', opacity:0.7,
                          width:pct+'%', borderRadius:2, transition:'width 0.4s' }} />
                      </div>
                    </div>
                  );
                })}
              </div>
            )
          }
        </Panel>
      </div>

      {/* ── Mapa de visitas ──────────────────────────────────────── */}
      <Panel title="Mapa de visitas" meta="Concentração geográfica" actions={
        <span style={{ font:'400 11px/1 var(--ff-mono)', color:'var(--tx-3)' }}>
          Baseado na cidade cadastrada do cliente
        </span>
      }>
        <VisitasHeatmap atividades={atividades} clientes={clientes} />
      </Panel>

      {/* ── Ops em risco ─────────────────────────────────────────── */}
      {opsRisco.length>0 && (
        <Panel title="Oportunidades em risco" meta={opsRisco.length+' item'+(opsRisco.length!==1?'s':'')}
               style={{ marginTop:18 }}>
          <div style={{ display:'flex', flexDirection:'column', gap:0 }}>
            {opsRisco.map(function(op,i) {
              var cli      = CRM_DATA.getCliente(op.cliente_id);
              var vend     = CRM_DATA.getUsuario(op.vendedor_id);
              var vencida  = op.previsao_fechamento && new Date(op.previsao_fechamento)<hoje;
              var diasVenc = vencida ? _diasDiff(hoje, new Date(op.previsao_fechamento)) : 0;
              var ultimaOp = lastAtivOp[op.id];
              var diasSemAtiv = ultimaOp ? _diasDiff(hoje, ultimaOp) : null;
              return (
                <div key={op.id} onClick={function(){ onNav('oportunidade', op.id); }}
                  style={{ display:'flex', alignItems:'center', gap:12, padding:'10px 0',
                    borderBottom:i<opsRisco.length-1?'1px solid var(--border)':'none', cursor:'pointer' }}>
                  <span style={{ fontSize:15, flexShrink:0 }}>{vencida?'🔴':'🟡'}</span>
                  <div style={{ flex:1, minWidth:0 }}>
                    <div style={{ font:'500 13px/1.2 var(--ff-body)', color:'var(--tx)',
                      overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{op.titulo}</div>
                    <div style={{ font:'400 11px/1 var(--ff-mono)', color:'var(--tx-3)', marginTop:3 }}>
                      {cli?cli.razao.split(' ').slice(0,3).join(' '):'—'}
                      {vend?' · '+vend.nome.split(' ')[0]:''}
                    </div>
                  </div>
                  <div style={{ textAlign:'right', flexShrink:0 }}>
                    {vencida
                      ? <div style={{ font:'600 11px/1 var(--ff-mono)', color:'var(--danger)' }}>Vencida há {diasVenc}d</div>
                      : <div style={{ font:'600 11px/1 var(--ff-mono)', color:'var(--warn)' }}>
                          {diasSemAtiv!==null?'Sem atv. há '+diasSemAtiv+'d':'Sem atividade'}
                        </div>
                    }
                    <div style={{ font:'400 11px/1 var(--ff-mono)', color:'var(--tx-3)', marginTop:2 }}>{fR(op.valor)}</div>
                  </div>
                </div>
              );
            })}
          </div>
        </Panel>
      )}

    </div>
  );
}

// ════════════════════════════════════════════════════════════════════════════
// DASHBOARD VENDEDOR — visão operacional (minha carteira)
// ════════════════════════════════════════════════════════════════════════════
function DashboardVendedor({ onNav, onOpenOp, user }) {
  var ops        = CRM_DATA.oportunidades;
  var atividades = CRM_DATA.atividades;
  var clientes   = CRM_DATA.clientes;
  var agenda     = CRM_DATA.agenda;
  var propostas  = CRM_DATA.propostas;
  var hoje       = _dhoje();
  var userId     = user ? user.id    : null;
  var userEmail  = user ? user.email : null;

  // ── Filtros pessoais ────────────────────────────────────────────────────
  var minhasOps     = ops.filter(function(o){ return o.vendedor_id===userId && !o.cancelada_em; });
  var minhasAbertas = minhasOps.filter(function(o){ return o.etapa!=='fechado_ganho' && o.etapa!=='fechado' && o.etapa!=='fechado_perdido'; });
  var minhasGanhas  = minhasOps.filter(function(o){ return o.etapa==='fechado_ganho' || o.etapa==='fechado'; });
  var minhasAtivs   = atividades.filter(function(at){ return at.vendedor_id===userId; });
  var meusClientes  = clientes.filter(function(c){ return c.vendedor_id===userEmail || c.vendedor_id===userId; });

  // ── KPIs financeiros ────────────────────────────────────────────────────
  var meuPipeline    = minhasAbertas.reduce(function(s,o){ return s+_valorEfetivo(o); }, 0);
  var meuForecast    = minhasAbertas
    .filter(function(o){ return o.previsao_fechamento && _diasMes(new Date(o.previsao_fechamento)); })
    .reduce(function(s,o){ return s+_valorEfetivo(o)*((o.probabilidade||0)/100); }, 0);
  var receitaFechada = minhasGanhas.reduce(function(s,o){ return s+_valorEfetivo(o); }, 0);

  // ── KPIs visitas ────────────────────────────────────────────────────────
  var minhasVisitas    = minhasAtivs.filter(function(at){ return at.tipo==='visita'; });
  var visitasSemana    = minhasVisitas.filter(function(at){ return new Date(at.data||0) >= _iniSemana(); }).length;
  var visitasMes       = minhasVisitas.filter(function(at){ return new Date(at.data||0) >= _iniMes(); }).length;
  var visitas90d       = minhasVisitas.filter(function(at){ return new Date(at.data||0) >= _ini90(); }).length;

  // Top cliente visitado
  var visitasPorCli = {};
  minhasVisitas.filter(function(at){ return new Date(at.data||0) >= _ini90(); }).forEach(function(at){
    visitasPorCli[at.cliente_id] = (visitasPorCli[at.cliente_id]||0)+1;
  });
  var topCliId  = Object.keys(visitasPorCli).sort(function(a,b){ return visitasPorCli[b]-visitasPorCli[a]; })[0];
  var topCli    = topCliId ? CRM_DATA.getCliente(topCliId) : null;
  var topCliCount = topCliId ? visitasPorCli[topCliId] : 0;

  // ── Agenda de hoje ──────────────────────────────────────────────────────
  var agendaHoje = agenda.filter(function(ag){
    return ag.vendedor_id===userId && ag.data && _eHoje(new Date(ag.data));
  }).sort(function(a,b){ return new Date(a.data)-new Date(b.data); });

  // ── Próximos 7 dias ─────────────────────────────────────────────────────
  var prox7 = agenda.filter(function(ag){
    if (ag.vendedor_id!==userId || !ag.data) return false;
    var d = new Date(ag.data);
    return _prox7(d) && !_eHoje(d);
  }).sort(function(a,b){ return new Date(a.data)-new Date(b.data); }).slice(0,8);

  // ── Ações urgentes ──────────────────────────────────────────────────────
  var lastAtivOp = _idxUltimaAtivOp(minhasAtivs);
  var lim10 = new Date(hoje); lim10.setDate(lim10.getDate()-10);
  var lim7  = new Date(hoje); lim7.setDate(lim7.getDate()-7);

  var opsVencidas     = minhasAbertas.filter(function(o){ return o.previsao_fechamento && new Date(o.previsao_fechamento)<hoje; });
  var propSemResposta = propostas.filter(function(p){
    if (p.status!=='enviada' || !p.data) return false;
    var op = ops.find(function(o){ return o.id===p.op_id; });
    return op && op.vendedor_id===userId && new Date(p.data)<lim7;
  });
  var idsVencidas = new Set(opsVencidas.map(function(o){ return o.id; }));
  var altaSemAtiv = minhasAbertas.filter(function(o){
    return o.prioridade==='alta' && !idsVencidas.has(o.id) && (!lastAtivOp[o.id]||lastAtivOp[o.id]<lim10);
  });
  var totalUrgente = opsVencidas.length+propSemResposta.length+altaSemAtiv.length;

  // ── Clientes sem contato ────────────────────────────────────────────────
  var lastAtivCli = _idxUltimaAtivCliente(minhasAtivs);
  var lim30 = new Date(hoje); lim30.setDate(lim30.getDate()-30);
  var semContato = meusClientes.filter(function(c){
    return c.status!=='inativo' && (!lastAtivCli[c.id]||lastAtivCli[c.id]<lim30);
  }).sort(function(a,b){
    var da = lastAtivCli[a.id] ? lastAtivCli[a.id].getTime() : 0;
    var db = lastAtivCli[b.id] ? lastAtivCli[b.id].getTime() : 0;
    return da-db;
  }).slice(0,8);

  var TIPO_ICON_EMOJI = { visita:'🏭', reuniao:'🤝', ligacao:'📞', followup:'⏰', email:'✉️', whatsapp:'💬' };

  function _linhaUrgente(emoji, titulo, subtitulo, badge, cor, onClickFn, key) {
    return (
      <div key={key} onClick={onClickFn}
        style={{ display:'flex', alignItems:'center', gap:10, padding:'9px 0',
          borderBottom:'1px solid var(--border)', cursor:onClickFn?'pointer':'default' }}>
        <span style={{ fontSize:14, flexShrink:0 }}>{emoji}</span>
        <div style={{ flex:1, minWidth:0 }}>
          <div style={{ font:'500 12px/1.2 var(--ff-body)', color:'var(--tx)',
            overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{titulo}</div>
          {subtitulo && <div style={{ font:'400 11px/1 var(--ff-mono)', color:'var(--tx-3)', marginTop:2 }}>{subtitulo}</div>}
        </div>
        {badge && <span style={{ font:'600 11px/1 var(--ff-mono)', color:cor, flexShrink:0 }}>{badge}</span>}
      </div>
    );
  }

  var urgentesItems = [];
  opsVencidas.slice(0,4).forEach(function(op){
    var cli  = CRM_DATA.getCliente(op.cliente_id);
    var dias = _diasDiff(hoje, new Date(op.previsao_fechamento));
    urgentesItems.push(_linhaUrgente('🔴', op.titulo,
      (cli?cli.razao.split(' ').slice(0,2).join(' '):'—')+' · '+fR(op.valor),
      'Vencida há '+dias+'d', 'var(--danger)', function(){ onNav('oportunidade', op.id); }, op.id+'_v'));
  });
  propSemResposta.slice(0,3).forEach(function(p){
    var op  = ops.find(function(o){ return o.id===p.op_id; });
    var cli = op ? CRM_DATA.getCliente(op.cliente_id) : null;
    var dias = _diasDiff(hoje, new Date(p.data));
    urgentesItems.push(_linhaUrgente('🟡', 'Proposta '+p.id+' sem resposta',
      cli?cli.razao.split(' ').slice(0,2).join(' '):'—',
      'há '+dias+'d', 'var(--warn)', op?function(){ onNav('oportunidade', op.id); }:null, p.id+'_p'));
  });
  altaSemAtiv.slice(0,3).forEach(function(op){
    var cli    = CRM_DATA.getCliente(op.cliente_id);
    var ultima = lastAtivOp[op.id];
    var dias   = ultima ? _diasDiff(hoje, ultima) : null;
    urgentesItems.push(_linhaUrgente('🟠', op.titulo,
      (cli?cli.razao.split(' ').slice(0,2).join(' '):'—')+' · Alta prioridade',
      dias!==null?'Sem atv. '+dias+'d':'Sem atividade', 'var(--warn)',
      function(){ onNav('oportunidade', op.id); }, op.id+'_a'));
  });

  return (
    <div data-screen-label="01 Dashboard">

      {/* ── Agenda hoje ────────────────────────────────────────────── */}
      <Panel title={'Hoje — '+new Date().toLocaleDateString('pt-BR',{ weekday:'long', day:'2-digit', month:'long' })}
             actions={<button className="btn btn-ghost" onClick={function(){ onNav('agenda'); }}>Ver agenda →</button>}>
        {agendaHoje.length===0
          ? <p style={{ color:'var(--tx-3)', fontSize:13, margin:0 }}>
              Nenhuma atividade programada para hoje — que tal agendar um follow-up?
            </p>
          : (
            <div style={{ display:'flex', flexDirection:'column', gap:0 }}>
              {agendaHoje.slice(0,6).map(function(ag,i){
                var cli  = CRM_DATA.getCliente(ag.cliente_id);
                var hora = new Date(ag.data).toLocaleTimeString('pt-BR',{ hour:'2-digit', minute:'2-digit' });
                return (
                  <div key={ag.id||i} style={{ display:'flex', gap:10, alignItems:'flex-start', padding:'8px 0',
                    borderBottom:i<agendaHoje.length-1?'1px solid var(--border)':'none' }}>
                    <span style={{ fontSize:16, flexShrink:0 }}>{TIPO_ICON_EMOJI[ag.tipo]||'📋'}</span>
                    <div style={{ flex:1 }}>
                      <div style={{ font:'500 13px/1.2 var(--ff-body)', color:'var(--tx)' }}>{ag.titulo}</div>
                      <div style={{ font:'400 11px/1 var(--ff-mono)', color:'var(--tx-3)', marginTop:2 }}>
                        {hora}{cli?' · '+cli.razao.split(' ').slice(0,3).join(' '):''}
                      </div>
                    </div>
                  </div>
                );
              })}
            </div>
          )
        }
      </Panel>

      {/* ── KPIs financeiros ─────────────────────────────────────── */}
      <div className="kpi-grid" style={{ marginTop:18 }}>
        <KPICard eyebrow="Meu pipeline ativo" value={fR(meuPipeline)}
          delta={minhasAbertas.length+' oportunidade'+(minhasAbertas.length!==1?'s':'')+' abertas'}
          deltaTone="warn" mono />
        <KPICard eyebrow="Forecast do mês" value={fR(meuForecast)}
          delta="Ponderado por probabilidade" deltaTone="warn" mono />
        <KPICard eyebrow="Receita fechada" value={fR(receitaFechada)}
          delta={minhasGanhas.length+' negócio'+(minhasGanhas.length!==1?'s':'')+' ganho'+(minhasGanhas.length!==1?'s':'')}
          deltaTone="pos" accent />
        <KPICard eyebrow="Clientes na carteira" value={String(meusClientes.length)}
          delta={semContato.length+' sem contato recente'} deltaTone={semContato.length>0?'warn':'pos'} mono />
      </div>

      {/* ── KPIs visitas ─────────────────────────────────────────── */}
      <div className="kpi-grid" style={{ marginTop:18, gridTemplateColumns:'repeat(4,1fr)' }}>
        <KPICard eyebrow="Visitas esta semana" value={String(visitasSemana)}
          delta="Minhas visitas" deltaTone="neu" mono />
        <KPICard eyebrow="Visitas este mês" value={String(visitasMes)}
          delta="Minhas visitas" deltaTone="neu" mono />
        <KPICard eyebrow="Visitas (90 dias)" value={String(visitas90d)}
          delta="Histórico recente" deltaTone="neu" mono />
        <KPICard eyebrow="Cliente mais visitado" value={topCli?(topCli.razao||'').split(' ').slice(0,2).join(' '):'—'}
          delta={topCliCount>0?topCliCount+' visita'+(topCliCount!==1?'s':''):'Sem visitas (90d)'}
          deltaTone="pos" mono />
      </div>

      {/* ── Urgentes + Próximos 7 dias ───────────────────────────── */}
      <div className="two-col" style={{ marginTop:18, marginBottom:18 }}>
        <Panel title="Ações urgentes"
               meta={totalUrgente>0?totalUrgente+' item'+(totalUrgente!==1?'s':''):'Tudo em dia ✓'}>
          {totalUrgente===0
            ? <p style={{ color:'var(--ok)', fontSize:13, margin:0 }}>✅ Nenhuma ação urgente pendente.</p>
            : <div style={{ display:'flex', flexDirection:'column', gap:0 }}>{urgentesItems}</div>
          }
        </Panel>
        <Panel title="Próximos 7 dias"
               actions={<button className="btn btn-ghost" onClick={function(){ onNav('agenda'); }}>Ver agenda →</button>}>
          {prox7.length===0
            ? <p style={{ color:'var(--tx-3)', fontSize:13, margin:0 }}>Nenhuma atividade programada nos próximos dias.</p>
            : (
              <div style={{ display:'flex', flexDirection:'column', gap:0 }}>
                {prox7.map(function(ag,i){
                  var cli   = CRM_DATA.getCliente(ag.cliente_id);
                  var dataD = new Date(ag.data);
                  var label = dataD.toLocaleDateString('pt-BR',{ weekday:'short', day:'2-digit', month:'2-digit' });
                  var hora  = dataD.toLocaleTimeString('pt-BR',{ hour:'2-digit', minute:'2-digit' });
                  return (
                    <div key={ag.id||i} style={{ display:'flex', gap:10, alignItems:'flex-start', padding:'8px 0',
                      borderBottom:i<prox7.length-1?'1px solid var(--border)':'none' }}>
                      <span style={{ fontSize:15, flexShrink:0 }}>{TIPO_ICON_EMOJI[ag.tipo]||'📋'}</span>
                      <div style={{ flex:1 }}>
                        <div style={{ font:'500 12px/1.2 var(--ff-body)', color:'var(--tx)' }}>{ag.titulo}</div>
                        {cli && <div style={{ font:'400 10px/1 var(--ff-mono)', color:'var(--tx-3)', marginTop:2 }}>
                          {cli.razao.split(' ').slice(0,3).join(' ')}
                        </div>}
                      </div>
                      <div style={{ textAlign:'right', flexShrink:0 }}>
                        <div style={{ font:'500 11px/1 var(--ff-mono)', color:'var(--tx-2)' }}>{label}</div>
                        <div style={{ font:'400 10px/1 var(--ff-mono)', color:'var(--tx-3)', marginTop:2 }}>{hora}</div>
                      </div>
                    </div>
                  );
                })}
              </div>
            )
          }
        </Panel>
      </div>

      {/* ── Mapa de visitas ──────────────────────────────────────── */}
      <Panel title="Minhas visitas no mapa" meta="Concentração geográfica" actions={
        <span style={{ font:'400 11px/1 var(--ff-mono)', color:'var(--tx-3)' }}>
          Baseado na cidade cadastrada do cliente
        </span>
      }>
        <VisitasHeatmap atividades={minhasAtivs} clientes={clientes} />
      </Panel>

      {/* ── Clientes sem contato ─────────────────────────────────── */}
      {semContato.length>0 && (
        <Panel title="Clientes sem contato recente" style={{ marginTop:18 }}
               meta={'Mais de 30 dias · '+semContato.length+' cliente'+(semContato.length!==1?'s':'')}>
          <div style={{ display:'flex', flexDirection:'column', gap:0 }}>
            {semContato.map(function(cli,i){
              var ultima    = lastAtivCli[cli.id];
              var diasAtras = ultima ? _diasDiff(hoje, ultima) : null;
              return (
                <div key={cli.id} style={{ display:'flex', alignItems:'center', gap:12, padding:'9px 0',
                  borderBottom:i<semContato.length-1?'1px solid var(--border)':'none' }}>
                  <div style={{ flex:1, minWidth:0 }}>
                    <div style={{ font:'500 13px/1.2 var(--ff-body)', color:'var(--tx)',
                      overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{cli.razao}</div>
                    <div style={{ font:'400 11px/1 var(--ff-mono)', color:'var(--tx-3)', marginTop:2 }}>
                      {cli.cidade?cli.cidade+(cli.uf?'/'+cli.uf:'')+ ' · ':''}
                      {ultima?'Último contato: '+fDate(ultima.toISOString()):'Sem atividade registrada'}
                    </div>
                  </div>
                  <div style={{ display:'flex', gap:8, alignItems:'center', flexShrink:0 }}>
                    {diasAtras!==null && (
                      <span style={{ font:'600 11px/1 var(--ff-mono)',
                        color:diasAtras>60?'var(--danger)':'var(--warn)' }}>{diasAtras}d atrás</span>
                    )}
                    <button className="btn btn-ghost" style={{ padding:'3px 8px', fontSize:11 }}
                      onClick={function(){ onNav('clientes'); }}>Ver →</button>
                  </div>
                </div>
              );
            })}
          </div>
        </Panel>
      )}

    </div>
  );
}

// ════════════════════════════════════════════════════════════════════════════
// DASHBOARD — ROTEADOR
// ════════════════════════════════════════════════════════════════════════════
function Dashboard({ onNav, onOpenOp }) {
  // Lê do CRM_USER (centralizado, reativo a "Visualizar como")
  var emailLogado = (window.CRM_USER && window.CRM_USER.email) || '';
  var userLogado  = CRM_DATA.usuarios.find(function(u){ return (u.email||'').toLowerCase()===emailLogado; }) || null;
  var isGerencia  = !!(window.CRM_USER && window.CRM_USER.isGerente);
  if (isGerencia) return React.createElement(DashboardGerencia, { onNav:onNav, onOpenOp:onOpenOp });
  return React.createElement(DashboardVendedor, { onNav:onNav, onOpenOp:onOpenOp, user:userLogado });
}

window.Dashboard = Dashboard;
