feat(master): substituir botoes de acao por icones de editar ver e excluir
This commit is contained in:
@@ -40,7 +40,7 @@
|
||||
<th>Nome</th>
|
||||
<th>Status</th>
|
||||
<th>Plano</th>
|
||||
<th>Editar</th>
|
||||
<th style="text-align: right;">Ações</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="rows"></tbody>
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
const empresaForm=document.querySelector('#empresa-form'),rows=document.querySelector('#rows'),busca=document.querySelector('#busca'),planoSelect=document.querySelector('#plano-select'),cadastroModal=document.querySelector('#cadastro-modal');let empresas=[],planos=[],modo=null,selecionado=null;
|
||||
|
||||
const Icons = {
|
||||
edit: '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path></svg>',
|
||||
eye: '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle></svg>',
|
||||
trash: '<svg viewBox="0 0 24 24" aria-hidden="true"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path><line x1="10" y1="11" x2="10" y2="17"></line><line x1="14" y1="11" x2="14" y2="17"></line></svg>'
|
||||
};
|
||||
|
||||
function esc(v){return String(v??'').replace(/[&<>'"]/g,c=>({'&':'&','<':'<','>':'>',"'":''','"':'"'}[c]))}
|
||||
function planoLabel(p){return `${p.nome} - ${Util.money(p.valor_mensal_centavos)}`}
|
||||
function planoOptions(valor){return '<option value="">Sem plano</option>'+planos.map(p=>`<option value="${p.id}" ${String(valor||'')===String(p.id)?'selected':''}>${planoLabel(p)}</option>`).join('')}
|
||||
@@ -6,7 +13,25 @@ function renderPlanos(){planoSelect.innerHTML=planoOptions('')}
|
||||
function match(e,q){if(!q)return true;return [e.slug,e.nome,e.cnpj,e.status,e.plano,e.api_key].join(' ').toLowerCase().includes(q.toLowerCase())}
|
||||
function statusAction(e){const acao=e.status==='ativa'?'Bloquear':'Ativar';return `<button class="status-action" onclick="alterarStatus(${e.id},'${e.status==='ativa'?'bloqueada':'ativa'}')">${Util.badge(e.status)}<span>${acao}</span></button>`}
|
||||
function detalheRow(e){if(selecionado!==e.id||!modo)return'';if(modo==='ver')return `<tr><td colspan="5"><div class="inline-panel"><h2>${esc(e.nome)}</h2><p><strong>Slug:</strong> ${esc(e.slug)}</p><p><strong>CNPJ:</strong> ${esc(e.cnpj||'-')}</p><p><strong>Status:</strong> ${esc(e.status)}</p><p><strong>Plano:</strong> ${e.plano?`${esc(e.plano)} ${e.plano_valor_centavos?'- '+Util.money(e.plano_valor_centavos):''}`:'-'}</p><div class="field"><label>API Key de integração</label><input readonly value="${esc(e.api_key||'')}" onclick="this.select()"></div><div class="row compact"><button class="btn secondary" type="button" onclick="copiarApiKey(${e.id})">Copiar API Key</button><button class="btn secondary" type="button" onclick="solicitarAlteracaoApiKey(${e.id})">Solicitar alteração</button></div><p><strong>Conta principal:</strong> abra Editar para alterar dados da empresa; funcionarios ficam no acesso da empresa.</p><button class="btn secondary" onclick="fecharDetalhe()">Fechar</button></div></td></tr>`;return `<tr><td colspan="5"><form class="inline-panel grid cols" onsubmit="salvarEdicao(event,${e.id})"><div class="field"><label>Nome</label><input name="nome" value="${esc(e.nome||'')}" required></div><div class="field"><label>CNPJ</label><input name="cnpj" value="${esc(e.cnpj||'')}"></div><div class="field"><label>Plano</label><select name="plano_id">${planoOptions(e.plano_id)}</select></div><div class="row"><button class="btn">Salvar</button><button type="button" class="btn secondary" onclick="fecharDetalhe()">Cancelar</button></div></form></td></tr>`}
|
||||
function render(){const q=busca.value.trim();const lista=empresas.filter(e=>match(e,q));rows.innerHTML=lista.length?lista.map(e=>`<tr><td>${e.slug}</td><td>${e.nome}</td><td>${statusAction(e)}</td><td>${e.plano?`${e.plano} ${e.plano_valor_centavos?'- '+Util.money(e.plano_valor_centavos):''}`:'-'}</td><td><button class="btn secondary" onclick="editar(${e.id})">Editar</button> <button class="btn secondary" onclick="ver(${e.id})">Ver</button> <button class="btn danger" onclick="excluir(${e.id})">Excluir</button></td></tr>${detalheRow(e)}`).join(''):'<tr><td colspan="5">Nenhum cliente encontrado.</td></tr>'}
|
||||
|
||||
function render(){
|
||||
const q=busca.value.trim();
|
||||
const lista=empresas.filter(e=>match(e,q));
|
||||
rows.innerHTML=lista.length?lista.map(e=>`<tr>
|
||||
<td>${e.slug}</td>
|
||||
<td>${e.nome}</td>
|
||||
<td>${statusAction(e)}</td>
|
||||
<td>${e.plano?`${e.plano} ${e.plano_valor_centavos?'- '+Util.money(e.plano_valor_centavos):''}`:'-'}</td>
|
||||
<td style="text-align: right;">
|
||||
<div class="table-actions">
|
||||
<button class="table-icon-btn" type="button" onclick="editar(${e.id})" title="Editar cliente" aria-label="Editar cliente">${Icons.edit}</button>
|
||||
<button class="table-icon-btn" type="button" onclick="ver(${e.id})" title="Ver detalhes" aria-label="Ver detalhes">${Icons.eye}</button>
|
||||
<button class="table-icon-btn danger" type="button" onclick="excluir(${e.id})" title="Excluir cliente" aria-label="Excluir cliente">${Icons.trash}</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>${detalheRow(e)}`).join(''):'<tr><td colspan="5">Nenhum cliente encontrado.</td></tr>';
|
||||
}
|
||||
|
||||
async function load(){try{const [pe,de]=await Promise.all([Api.get('/api/master/planos'),Api.get('/api/master/empresas')]);planos=pe.planos||[];empresas=de.empresas||[];renderPlanos();render()}catch(e){Util.toast(e.message,true)}}
|
||||
|
||||
window.alternarBusca=()=>{
|
||||
|
||||
Reference in New Issue
Block a user