Veredito do inventário por tráfego: quem emite sonda de portal tem navegador; nuvem de fabricante indica IoT; OUI de equipamento de rede com tráfego de celular indica repetidor com NAT.
;
}
function macValido(m) { return /^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$/.test(m); }
function TelaListaBranca({ site, sitesSel, openCmd }) {
const meta = window.GESTAO_META;
const list = sitesSel && sitesSel.length ? sitesSel : [site];
const multi = list.length > 1;
const [alvo, setAlvo] = React.useState(list[0]);
React.useEffect(() => setAlvo(a => list.includes(a) ? a : list[0]), [list.join(',')]);
const s = meta[alvo];
const carga = window.useCarrega(() => Promise.all(list.map(k => window.GestaoAPI.bindings(k)
.then(r => (r.bindings || []).map(b => ({ ...b, __k: k, __rot: meta[k].label })))))
.then(a => a.flat()), [list.join(',')]);
const vRows = carga.dados || [];
const cgCount = vRows.filter(b => b.__k === 'campogas').length;
const [mac, setMac] = React.useState('');
const [com, setCom] = React.useState('');
const pronto = macValido(mac) && com.trim().length >= 3;
const hoje = new Date().toISOString().slice(0, 10);
const incluir = () => openCmd({
titulo: 'Incluir MAC na lista branca', alvo: s.alvo, slug: alvo, acao: 'binding-add', onSucesso: () => carga.recarrega(),
mac: mac.toUpperCase(), comment: `CHARLES ${com.trim().toUpperCase()} ${hoje}`,
linhas: [mkD(s.alvo, `/ip hotspot ip-binding add mac-address=${mac.toUpperCase()} type=bypassed server=${s.server} comment="CHARLES ${com.trim().toUpperCase()} ${hoje}"`), mkD(s.alvo, `/ip hotspot ip-binding print where mac-address=${mac.toUpperCase()}`)],
nota: 'bypassed = nunca passa pelo portal. A segunda linha confere o vínculo criado.'
});
const remover = b => { const sb = meta[b.__k]; openCmd({
titulo: 'Remover vínculo da lista branca', alvo: sb.alvo, slug: b.__k, acao: 'binding-del', mac: b.mac, onSucesso: () => carga.recarrega(),
linhas: [mkD(sb.alvo, `/ip hotspot ip-binding remove [find where mac-address=${b.mac}]`)],
nota: `Vínculo atual: "${b.comment || '(sem comentário)'}". O aparelho volta a cair no portal na próxima conexão.`
}); };
return
{list.includes('campogas') ? Rede crítica da empresa — Campo Gás{`${cgCount || 'Os'} vínculos sustentam DVR, relógio de ponto, alarme, impressoras e PCs — 100% do tráfego real. Nunca recriar, renomear ou remover o hotspot server: os vínculos estão amarrados a server=${meta.campogas.server}.`} : null}
{multi ? 'Vínculos bypassed — pontos selecionados' : `Vínculos bypassed — ${s.label}`}