// Telas 4 e 5 — SSIDs & bridges + Telas do portal. const DSr = window.WiFi_eeb21e; const { Card: CardR, CardContent: CardContentR, CardHeader: CardHeaderR, CardTitle: CardTitleR, Badge: BadgeR, Button: BtnR, Input: InputR, Label: LabelR, Separator: SepR } = DSr; const { GTh: ThR, GTd: TdR, BtnMini: BtnMiniR, TermoDica: TermoR, SelectG: SelR, mkLinha: mkR, slugSsid, Dot: DotR } = window; function TelaSsids({ 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.ssids(k) .then(r => (r.ssids || []).map(c => ({ ...c, __k: k, __rot: meta[k].label }))))) .then(a => a.flat()), [list.join(',')]); const vRows = carga.dados || []; const qcom = s.stack === 'qcom'; const temAcao = multi ? vRows.some(x => meta[x.__k].stack !== 'qcom') : !qcom; const [nome, setNome] = React.useState(''); const [banda, setBanda] = React.useState('2ghz'); const [seg, setSeg] = React.useState('portal'); const criar = () => { const cfg = 'cfg-' + slugSsid(nome); const linhas = qcom ? [mkR(s.alvo, `/interface wifi configuration add name=${cfg} ssid="${nome}"${seg === 'wpa2' ? ' security.authentication-types=wpa2-psk security.passphrase="TROCAR-SENHA"' : ''}`), mkR(s.alvo, `/interface wifi provisioning print`)] : [mkR(s.alvo, `/caps-man configuration add name=${cfg} ssid="${nome}" datapath.bridge=${s.bridge.replace(' (inline)', '')}${banda === '5ghz' ? ' channel.band=5ghz-ac' : ' channel.band=2ghz-g/n'}${seg === 'wpa2' ? ' security.authentication-types=wpa2-psk security.passphrase="TROCAR-SENHA"' : ''}`), mkR(s.alvo, `/caps-man provisioning print detail`)]; openCmd({ titulo: 'Criar SSID', alvo: s.alvo, slug: alvo, acao: 'ssid-add', onSucesso: () => carga.recarrega(), nome, banda, seg, cfg, stack: s.stack, bridge: s.bridge, linhas, nota: qcom ? 'Ponto wifi-qcom: depois de criar a configuration, vincule na provisioning (segunda linha lista as regras). SSID aberto cai no portal do hotspot da bridge.' : 'Molde do playbook: a config nasce apontando para a bridge do hotspot — nada de bridge nova. Vincule na regra de provisioning existente (segunda linha lista).' }); }; const trocarBridge = c => { const sc = meta[c.__k]; const destino = c.__k === 'habibi' ? 'Bridge_Hotspot' : 'dp-bridge-hotspot'; openCmd({ titulo: 'Trocar bridge do SSID', alvo: sc.alvo, slug: c.__k, acao: 'ssid-bridge', cfg: c.cfg, bridge: destino, onSucesso: () => carga.recarrega(), linhas: [mkR(sc.alvo, c.__k === 'habibi' ? `/caps-man configuration set ${c.cfg} datapath.bridge=Bridge_Hotspot` : `/caps-man configuration set ${c.cfg} datapath=dp-bridge-hotspot`)], nota: 'É o comando do swap validado em produção — o servidor confere se a bridge destino tem DHCP ativo antes de aplicar. Rollback: trocar o valor de volta.' }); }; return