Oculta cadastros no detalhe do condominio

This commit is contained in:
Tiago
2026-10-06 15:39:08 -03:00
parent 4fa63c54a4
commit 8fd7c57c18
+29 -6
View File
@@ -1,4 +1,13 @@
const id=new URLSearchParams(location.search).get('id');const sections=['contatos','espacos','assembleias','documentos','avisos'];document.querySelectorAll('.nav-tabs button').forEach(b=>b.onclick=()=>{document.querySelectorAll('.nav-tabs button').forEach(x=>x.classList.remove('active'));b.classList.add('active');sections.forEach(s=>document.querySelector('#'+s).classList.toggle('hidden',s!==b.dataset.tab))});let contatos=[],docs=[],avisos=[],funcionariosVinculados=[],extras=[],assembleiasCalendario=[],calMonth=new Date();function recLabel(v){return {1:'Mensal',3:'Trimestral',12:'Anual'}[Number(v)]||'Sem recorrencia'}
const id=new URLSearchParams(location.search).get('id');const sections=['contatos','espacos','assembleias','documentos','avisos'];document.querySelectorAll('.nav-tabs button').forEach(b=>b.onclick=()=>{document.querySelectorAll('.nav-tabs button').forEach(x=>x.classList.remove('active'));b.classList.add('active');sections.forEach(s=>document.querySelector('#'+s).classList.toggle('hidden',s!==b.dataset.tab))});let contatos=[],docs=[],avisos=[],funcionariosVinculados=[],extras=[],assembleiasCalendario=[],calMonth=new Date(),espacos=[],assembleias=[];function recLabel(v){return {1:'Mensal',3:'Trimestral',12:'Anual'}[Number(v)]||'Sem recorrencia'}
function esc(v){return String(v??'').replace(/[&<>'"]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;',"'":'&#39;','"':'&quot;'}[c]))}
function lupaBtn(fn,label){return `<button class="search-icon-btn" type="button" onclick="${fn}" aria-label="${label}" title="Buscar"><svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="11" cy="11" r="7"></circle><path d="m16.5 16.5 4 4"></path></svg></button>`}
function headerCadastro(titulo,tipo,novoFn,extra=''){const q=esc(termoDetalhe(tipo)),open=document.querySelector(`#${tipo}-search`)&&!document.querySelector(`#${tipo}-search`)?.classList.contains('hidden');return `<div class="section-head"><h2>${titulo}</h2><div class="section-actions">${extra}${lupaBtn(`alternarBuscaDetalhe('${tipo}')`,'Buscar '+titulo)}<button class="btn" type="button" onclick="${novoFn}">Novo</button></div></div><div id="${tipo}-search" class="search-strip ${open?'':'hidden'}"><input id="${tipo}-search-input" placeholder="Buscar" value="${q}"></div>`}
function termoDetalhe(tipo){return document.querySelector(`#${tipo}-search-input`)?.value.trim().toLowerCase()||''}
function contemDetalhe(q,...vals){return !q||vals.some(v=>String(v??'').toLowerCase().includes(q))}
window.alternarBuscaDetalhe=tipo=>{const strip=document.querySelector(`#${tipo}-search`),input=document.querySelector(`#${tipo}-search-input`);if(!strip||!input)return;strip.classList.toggle('hidden');if(!strip.classList.contains('hidden'))input.focus()};
function ensureDetailModal(){let m=document.querySelector('#detail-form-modal');if(m)return m;document.body.insertAdjacentHTML('beforeend','<div id="detail-form-modal" class="modal hidden"><div class="modal-backdrop" onclick="fecharDetailModal()"></div><section class="modal-panel"><div class="modal-head"><h2 id="detail-form-title"></h2><button class="btn secondary" type="button" onclick="fecharDetailModal()">Fechar</button></div><div id="detail-form-body"></div></section></div>');return document.querySelector('#detail-form-modal')}
function abrirDetailModal(titulo,html){const m=ensureDetailModal();document.querySelector('#detail-form-title').textContent=titulo;document.querySelector('#detail-form-body').innerHTML=html;m.classList.remove('hidden')}
window.fecharDetailModal=()=>{const m=document.querySelector('#detail-form-modal');if(m)m.classList.add('hidden');const body=document.querySelector('#detail-form-body');if(body)body.innerHTML=''};
function dateKey(v){const d=new Date(v);if(Number.isNaN(d.getTime()))return'';const pad=n=>String(n).padStart(2,'0');return d.getFullYear()+'-'+pad(d.getMonth()+1)+'-'+pad(d.getDate())}
function monthLabel(d){return d.toLocaleDateString('pt-BR',{month:'long',year:'numeric'})}
@@ -18,13 +27,27 @@ window.fecharAvisoNotificacao=()=>document.querySelector('#aviso-notif-modal')?.
window.salvarAvisoNotificacao=()=>{const ids=new Set([...document.querySelectorAll('#aviso-notif-body input:checked')].map(x=>x.value));avisoDestInputs().forEach(x=>x.checked=ids.has(x.value));updateAvisoNotifSummary();fecharAvisoNotificacao()};
async function safeLoad(section,fn){try{await fn()}catch(e){document.querySelector('#'+section).innerHTML=`<p>${e.message}</p>`;Util.toast(e.message,true)}}
async function load(){try{const d=await Api.get(`/api/condominios/${id}`);document.querySelector('#header').innerHTML=`<h2>${d.condominio.nome}</h2><p>${d.condominio.endereco||''}</p><div class="cards"><div class="stat">Sindico<strong>${d.sindico_atual?.contato_nome||'-'}</strong></div><div class="stat">Assembleias futuras<strong>${d.assembleias_futuras||0}</strong></div><div class="stat">Avisos ativos<strong>${d.avisos_ativos||0}</strong></div></div>`;await safeLoad('contatos',loadContatos);await safeLoad('avisos',loadFuncionariosVinculados);await safeLoad('avisos',loadExtras);await safeLoad('espacos',loadEspacos);await safeLoad('assembleias',loadAssembleias);await safeLoad('documentos',loadDocs);await safeLoad('avisos',loadAvisos)}catch(e){Util.toast(e.message,true)}}
async function loadContatos(){const d=await Api.get(`/api/condominios/${id}/contatos`);contatos=d.contatos||[];document.querySelector('#contatos').innerHTML=`<h2>Contatos</h2><form id="contato-form" class="grid cols"><div class="field"><label>Nome</label><input name="nome" required></div><div class="field"><label>Telefone</label><input name="telefone"></div><div class="field"><label>E-mail</label><input name="email"></div><div class="field"><label>Tipo</label><select name="tipo"><option value="sindico">Sindico</option><option value="subsindico">Subsindico</option><option value="conselheiro">Conselheiro</option></select></div><button class="btn">Cadastrar</button></form><div class="table-wrap"><table><thead><tr><th>Nome</th><th>Tipo</th><th>Telefone</th><th>Email</th></tr></thead><tbody>${contatos.map(c=>`<tr><td>${c.contato_nome}</td><td>${c.tipo}</td><td>${c.contato_telefone||''}</td><td>${c.contato_email||''}</td></tr>`).join('')}</tbody></table></div>`;document.querySelector('#contato-form').onsubmit=async e=>{e.preventDefault();try{await Api.post(`/api/condominios/${id}/contatos/vincular`,Util.formData(e.target));Util.toast('Contato salvo');loadContatos()}catch(err){Util.toast(err.message,true)}}}
async function loadEspacos(){const d=await Api.get(`/api/condominios/${id}/espacos-comuns`);document.querySelector('#espacos').innerHTML=`<h2>Espacos comuns</h2><form id="espaco-form" class="grid cols"><div class="field"><label>Nome</label><input name="nome" required></div><div class="field"><label>Valor centavos</label><input name="valor_utilizacao_centavos" type="number"></div><div class="field"><label>Indice</label><input name="indice_correcao"></div><div class="field"><label>Descricao</label><input name="descricao"></div><button class="btn">Cadastrar</button></form><div class="table-wrap"><table><thead><tr><th>Nome</th><th>Valor</th><th>Indice</th><th>Descricao</th></tr></thead><tbody>${(d.espacos||[]).map(x=>`<tr><td>${x.nome}</td><td>${Util.money(x.valor_utilizacao_centavos)}</td><td>${x.indice_correcao||''}</td><td>${x.descricao||''}</td></tr>`).join('')}</tbody></table></div>`;document.querySelector('#espaco-form').onsubmit=async e=>{e.preventDefault();try{await Api.post(`/api/condominios/${id}/espacos-comuns`,Util.formData(e.target));Util.toast('Espaco salvo');loadEspacos()}catch(err){Util.toast(err.message,true)}}}
async function loadAssembleias(){const d=await Api.get(`/api/condominios/${id}/assembleias`);document.querySelector('#assembleias').innerHTML=`<div class="section-head"><h2>Assembleias</h2><button class="icon-btn calendar-open" type="button" onclick="abrirCalendarioAssembleias()" title="Calendário de assembleias" aria-label="Calendário de assembleias"></button></div><form id="ass-form" class="grid cols"><div class="field"><label>Tipo</label><input name="tipo" required></div><div class="field"><label>Data e hora</label><input name="data_hora" type="datetime-local" required></div><div class="field"><label>Local</label><input name="local"></div><div class="field"><label>Pauta</label><input name="pauta"></div><button class="btn">Cadastrar</button></form><div class="table-wrap"><table><thead><tr><th>Tipo</th><th>Data</th><th>Local</th><th>Status</th></tr></thead><tbody>${(d.assembleias||[]).map(a=>`<tr><td>${a.tipo}</td><td>${Util.date(a.data_hora)}</td><td>${a.local||''}</td><td>${Util.badge(a.status)}</td></tr>`).join('')}</tbody></table></div>`;document.querySelector('#ass-form').onsubmit=async e=>{e.preventDefault();try{await Api.post(`/api/condominios/${id}/assembleias`,Util.formData(e.target));Util.toast('Assembleia salva');loadAssembleias();load()}catch(err){Util.toast(err.message,true)}}}
async function loadContatos(){const d=await Api.get(`/api/condominios/${id}/contatos`);contatos=d.contatos||[];renderContatos()}
function renderContatos(){const q=termoDetalhe('contatos');const lista=contatos.filter(c=>contemDetalhe(q,c.contato_nome,c.tipo,c.contato_telefone,c.contato_email));document.querySelector('#contatos').innerHTML=headerCadastro('Contatos','contatos','abrirNovoContato()')+`<div class="table-wrap"><table><thead><tr><th>Nome</th><th>Tipo</th><th>Telefone</th><th>Email</th></tr></thead><tbody>${lista.map(c=>`<tr><td>${esc(c.contato_nome)}</td><td>${esc(c.tipo)}</td><td>${esc(c.contato_telefone||'')}</td><td>${esc(c.contato_email||'')}</td></tr>`).join('')||'<tr><td colspan="4">Nenhum contato encontrado.</td></tr>'}</tbody></table></div>`;document.querySelector('#contatos-search-input')?.addEventListener('input',renderContatos)}
window.abrirNovoContato=()=>{abrirDetailModal('Novo contato','<form id="contato-form" class="grid cols"><div class="field"><label>Nome</label><input name="nome" required></div><div class="field"><label>Telefone</label><input name="telefone"></div><div class="field"><label>E-mail</label><input name="email"></div><div class="field"><label>Tipo</label><select name="tipo"><option value="sindico">Sindico</option><option value="subsindico">Subsindico</option><option value="conselheiro">Conselheiro</option></select></div><div class="row"><button class="btn">Cadastrar</button><button class="btn secondary" type="button" onclick="fecharDetailModal()">Cancelar</button></div></form>');document.querySelector('#contato-form').onsubmit=async e=>{e.preventDefault();try{await Api.post(`/api/condominios/${id}/contatos/vincular`,Util.formData(e.target));Util.toast('Contato salvo');fecharDetailModal();loadContatos();load()}catch(err){Util.toast(err.message,true)}}};
async function loadEspacos(){const d=await Api.get(`/api/condominios/${id}/espacos-comuns`);espacos=d.espacos||[];renderEspacos()}
function renderEspacos(){const q=termoDetalhe('espacos');const lista=espacos.filter(x=>contemDetalhe(q,x.nome,x.valor_utilizacao_centavos,x.indice_correcao,x.descricao));document.querySelector('#espacos').innerHTML=headerCadastro('Espacos comuns','espacos','abrirNovoEspaco()')+`<div class="table-wrap"><table><thead><tr><th>Nome</th><th>Valor</th><th>Indice</th><th>Descricao</th></tr></thead><tbody>${lista.map(x=>`<tr><td>${esc(x.nome)}</td><td>${Util.money(x.valor_utilizacao_centavos)}</td><td>${esc(x.indice_correcao||'')}</td><td>${esc(x.descricao||'')}</td></tr>`).join('')||'<tr><td colspan="4">Nenhum espaco encontrado.</td></tr>'}</tbody></table></div>`;document.querySelector('#espacos-search-input')?.addEventListener('input',renderEspacos)}
window.abrirNovoEspaco=()=>{abrirDetailModal('Novo espaco comum','<form id="espaco-form" class="grid cols"><div class="field"><label>Nome</label><input name="nome" required></div><div class="field"><label>Valor centavos</label><input name="valor_utilizacao_centavos" type="number"></div><div class="field"><label>Indice</label><input name="indice_correcao"></div><div class="field"><label>Descricao</label><input name="descricao"></div><div class="row"><button class="btn">Cadastrar</button><button class="btn secondary" type="button" onclick="fecharDetailModal()">Cancelar</button></div></form>');document.querySelector('#espaco-form').onsubmit=async e=>{e.preventDefault();try{await Api.post(`/api/condominios/${id}/espacos-comuns`,Util.formData(e.target));Util.toast('Espaco salvo');fecharDetailModal();loadEspacos()}catch(err){Util.toast(err.message,true)}}};
async function loadAssembleias(){const d=await Api.get(`/api/condominios/${id}/assembleias`);assembleias=d.assembleias||[];renderAssembleias()}
function renderAssembleias(){const q=termoDetalhe('assembleias');const lista=assembleias.filter(a=>contemDetalhe(q,a.tipo,a.data_hora,a.local,a.status));const calendar='<button class="icon-btn calendar-open" type="button" onclick="abrirCalendarioAssembleias()" title="Calendário de assembleias" aria-label="Calendário de assembleias"></button>';document.querySelector('#assembleias').innerHTML=headerCadastro('Assembleias','assembleias','abrirNovaAssembleia()',calendar)+`<div class="table-wrap"><table><thead><tr><th>Tipo</th><th>Data</th><th>Local</th><th>Status</th></tr></thead><tbody>${lista.map(a=>`<tr><td>${esc(a.tipo)}</td><td>${Util.date(a.data_hora)}</td><td>${esc(a.local||'')}</td><td>${Util.badge(a.status)}</td></tr>`).join('')||'<tr><td colspan="4">Nenhuma assembleia encontrada.</td></tr>'}</tbody></table></div>`;document.querySelector('#assembleias-search-input')?.addEventListener('input',renderAssembleias)}
window.abrirNovaAssembleia=()=>{abrirDetailModal('Nova assembleia','<form id="ass-form" class="grid cols"><div class="field"><label>Tipo</label><input name="tipo" required></div><div class="field"><label>Data e hora</label><input name="data_hora" type="datetime-local" required></div><div class="field"><label>Local</label><input name="local"></div><div class="field"><label>Pauta</label><input name="pauta"></div><div class="row"><button class="btn">Cadastrar</button><button class="btn secondary" type="button" onclick="fecharDetailModal()">Cancelar</button></div></form>');document.querySelector('#ass-form').onsubmit=async e=>{e.preventDefault();try{await Api.post(`/api/condominios/${id}/assembleias`,Util.formData(e.target));Util.toast('Assembleia salva');fecharDetailModal();loadAssembleias();load()}catch(err){Util.toast(err.message,true)}}};
async function loadFuncionariosVinculados(){const d=await Api.get(`/api/condominios/${id}/funcionarios-vinculados`);funcionariosVinculados=d.funcionarios||[]}
async function loadExtras(){const d=await Api.get(`/api/extras`);extras=(d.extras||[]).filter(x=>x.status==='ativo')}
async function loadDocs(){const d=await Api.get(`/api/condominios/${id}/documentos`);docs=d.documentos||[];document.querySelector('#documentos').innerHTML=`<h2>Documentos</h2><form id="doc-form" class="row"><div class="field"><label>Tipo</label><input name="tipo"></div><div class="field"><label>Arquivo</label><input name="arquivo" type="file" required></div><button class="btn">Enviar</button></form><div class="table-wrap"><table><thead><tr><th>ID</th><th>Arquivo</th><th>Tipo</th><th>Download</th></tr></thead><tbody>${docs.map(d=>`<tr><td>${d.id}</td><td>${d.nome_arquivo}</td><td>${d.tipo||''}</td><td><a href="/api/documentos/${d.id}/download">Baixar</a></td></tr>`).join('')}</tbody></table></div>`;document.querySelector('#doc-form').onsubmit=async e=>{e.preventDefault();const fd=new FormData(e.target);try{await Api.post(`/api/condominios/${id}/documentos`,fd);Util.toast('Documento enviado');loadDocs()}catch(err){Util.toast(err.message,true)}}}
async function loadAvisos(){const d=await Api.get(`/api/condominios/${id}/avisos`);avisos=d.avisos||[];const destContatos=contatos.map(c=>`<label><input type="checkbox" name="dest" value="contato:${c.contato_id}"> ${c.contato_nome} (${c.tipo})</label>`).join('');const destFuncionarios=funcionariosVinculados.map(f=>`<label><input type="checkbox" name="dest" value="funcionario:${f.funcionario_id||f.id}"> ${f.nome} (funcionario)</label>`).join('');const destExtras=extras.map(x=>`<label><input type="checkbox" name="dest" value="extra:${x.id}"> ${x.nome} (extra)</label>`).join('');const dest=[destContatos,destFuncionarios,destExtras].filter(Boolean).join('');const docChecks=docs.map(d=>`<label><input type="checkbox" name="doc" value="${d.id}"> ${d.nome_arquivo}</label>`).join('');document.querySelector('#avisos').innerHTML=`<h2>Avisos</h2><form id="aviso-form" class="grid cols"><div class="field"><label>Titulo</label><input name="titulo" required></div><div class="field"><label>Tipo</label><input name="tipo" value="aviso"></div><div class="field"><label>Prioridade</label><select name="prioridade"><option>normal</option><option>alta</option><option>urgente</option></select></div><div class="field"><label>Mensagem</label><textarea name="mensagem" required></textarea></div><div class="field"><label>Data/hora de envio</label><input name="data_evento" type="datetime-local"></div><div class="field"><label>Recorrencia</label><select name="recorrencia_meses"><option value="0">Sem recorrencia</option><option value="1">1 vez por mes</option><option value="3">A cada 3 meses</option><option value="12">1 vez por ano</option></select></div><div class="field"><label>Destinatarios</label><button class="btn secondary" type="button" onclick="abrirAvisoNotificacao()">Notificação</button> <span id="aviso-notif-summary" class="muted">Nenhuma pessoa selecionada</span><div id="aviso-dests-hidden" class="hidden">${dest}</div></div><div class="field"><label>Documentos</label>${docChecks||'<p>Nenhum documento.</p>'}</div><label><input type="checkbox" name="enviar_whatsapp" value="true"> Enviar por WhatsApp</label><label><input type="checkbox" name="enviar_email" value="true"> Enviar por e-mail</label><button class="btn">Criar aviso</button></form><div class="table-wrap"><table><thead><tr><th>Titulo</th><th>Status</th><th>Envio</th><th>Publicado em</th><th>Recorrencia</th><th>Acoes</th></tr></thead><tbody>${avisos.map(a=>`<tr><td>${a.titulo}</td><td>${Util.badge(a.status_envio)}</td><td>${Util.date(a.data_evento)}</td><td>${Util.date(a.data_publicacao)}</td><td>${recLabel(a.recorrencia_meses)}</td><td><button class="btn secondary" onclick="reenviarAviso(${a.id})">Reenviar</button> <button class="btn danger" onclick="excluirAviso(${a.id})">Excluir</button></td></tr>`).join('')}</tbody></table></div>`;updateAvisoNotifSummary();document.querySelector('#aviso-form').onsubmit=async e=>{e.preventDefault();const f=e.target,b=Util.formData(f);b.enviar_whatsapp=!!f.enviar_whatsapp.checked;b.enviar_email=!!f.enviar_email.checked;b.destinatarios=[...f.querySelectorAll('input[name=dest]:checked')].map(x=>{const [tipo,did]=x.value.split(':');return{tipo_destinatario:tipo,id:Number(did)}});b.documentos=[...f.querySelectorAll('input[name=doc]:checked')].map(x=>Number(x.value));try{await Api.post(`/api/condominios/${id}/avisos`,b);Util.toast('Aviso criado');loadAvisos();load()}catch(err){Util.toast(err.message,true)}}}
async function loadDocs(){const d=await Api.get(`/api/condominios/${id}/documentos`);docs=d.documentos||[];renderDocs()}
function renderDocs(){const q=termoDetalhe('documentos');const lista=docs.filter(d=>contemDetalhe(q,d.id,d.nome_arquivo,d.tipo));document.querySelector('#documentos').innerHTML=headerCadastro('Documentos','documentos','abrirNovoDocumento()')+`<div class="table-wrap"><table><thead><tr><th>ID</th><th>Arquivo</th><th>Tipo</th><th>Download</th></tr></thead><tbody>${lista.map(d=>`<tr><td>${d.id}</td><td>${esc(d.nome_arquivo)}</td><td>${esc(d.tipo||'')}</td><td><a href="/api/documentos/${d.id}/download">Baixar</a></td></tr>`).join('')||'<tr><td colspan="4">Nenhum documento encontrado.</td></tr>'}</tbody></table></div>`;document.querySelector('#documentos-search-input')?.addEventListener('input',renderDocs)}
window.abrirNovoDocumento=()=>{abrirDetailModal('Novo documento','<form id="doc-form" class="row"><div class="field"><label>Tipo</label><input name="tipo"></div><div class="field"><label>Arquivo</label><input name="arquivo" type="file" required></div><div class="row"><button class="btn">Enviar</button><button class="btn secondary" type="button" onclick="fecharDetailModal()">Cancelar</button></div></form>');document.querySelector('#doc-form').onsubmit=async e=>{e.preventDefault();const fd=new FormData(e.target);try{await Api.post(`/api/condominios/${id}/documentos`,fd);Util.toast('Documento enviado');fecharDetailModal();loadDocs();loadAvisos()}catch(err){Util.toast(err.message,true)}}};
function avisoFormHtml(){const destContatos=contatos.map(c=>`<label><input type="checkbox" name="dest" value="contato:${c.contato_id}"> ${esc(c.contato_nome)} (${esc(c.tipo)})</label>`).join('');const destFuncionarios=funcionariosVinculados.map(f=>`<label><input type="checkbox" name="dest" value="funcionario:${f.funcionario_id||f.id}"> ${esc(f.nome)} (funcionario)</label>`).join('');const destExtras=extras.map(x=>`<label><input type="checkbox" name="dest" value="extra:${x.id}"> ${esc(x.nome)} (extra)</label>`).join('');const dest=[destContatos,destFuncionarios,destExtras].filter(Boolean).join('');const docChecks=docs.map(d=>`<label><input type="checkbox" name="doc" value="${d.id}"> ${esc(d.nome_arquivo)}</label>`).join('');return `<form id="aviso-form" class="grid cols"><div class="field"><label>Titulo</label><input name="titulo" required></div><div class="field"><label>Tipo</label><input name="tipo" value="aviso"></div><div class="field"><label>Prioridade</label><select name="prioridade"><option>normal</option><option>alta</option><option>urgente</option></select></div><div class="field"><label>Mensagem</label><textarea name="mensagem" required></textarea></div><div class="field"><label>Data/hora de envio</label><input name="data_evento" type="datetime-local"></div><div class="field"><label>Recorrencia</label><select name="recorrencia_meses"><option value="0">Sem recorrencia</option><option value="1">1 vez por mes</option><option value="3">A cada 3 meses</option><option value="12">1 vez por ano</option></select></div><div class="field"><label>Destinatarios</label><button class="btn secondary" type="button" onclick="abrirAvisoNotificacao()">Notificação</button> <span id="aviso-notif-summary" class="muted">Nenhuma pessoa selecionada</span><div id="aviso-dests-hidden" class="hidden">${dest}</div></div><div class="field"><label>Documentos</label>${docChecks||'<p>Nenhum documento.</p>'}</div><label><input type="checkbox" name="enviar_whatsapp" value="true"> Enviar por WhatsApp</label><label><input type="checkbox" name="enviar_email" value="true"> Enviar por e-mail</label><div class="row"><button class="btn">Criar aviso</button><button class="btn secondary" type="button" onclick="fecharDetailModal()">Cancelar</button></div></form>`}
async function loadAvisos(){const d=await Api.get(`/api/condominios/${id}/avisos`);avisos=d.avisos||[];renderAvisos()}
function renderAvisos(){const q=termoDetalhe('avisos');const lista=avisos.filter(a=>contemDetalhe(q,a.titulo,a.status_envio,a.data_evento,a.data_publicacao,recLabel(a.recorrencia_meses)));document.querySelector('#avisos').innerHTML=headerCadastro('Avisos','avisos','abrirNovoAviso()')+`<div class="table-wrap"><table><thead><tr><th>Titulo</th><th>Status</th><th>Envio</th><th>Publicado em</th><th>Recorrencia</th><th>Acoes</th></tr></thead><tbody>${lista.map(a=>`<tr><td>${esc(a.titulo)}</td><td>${Util.badge(a.status_envio)}</td><td>${Util.date(a.data_evento)}</td><td>${Util.date(a.data_publicacao)}</td><td>${recLabel(a.recorrencia_meses)}</td><td><button class="btn secondary" onclick="reenviarAviso(${a.id})">Reenviar</button> <button class="btn danger" onclick="excluirAviso(${a.id})">Excluir</button></td></tr>`).join('')||'<tr><td colspan="6">Nenhum aviso encontrado.</td></tr>'}</tbody></table></div>`;document.querySelector('#avisos-search-input')?.addEventListener('input',renderAvisos)}
window.abrirNovoAviso=()=>{abrirDetailModal('Novo aviso',avisoFormHtml());updateAvisoNotifSummary();document.querySelector('#aviso-form').onsubmit=async e=>{e.preventDefault();const f=e.target,b=Util.formData(f);b.enviar_whatsapp=!!f.enviar_whatsapp.checked;b.enviar_email=!!f.enviar_email.checked;b.destinatarios=[...f.querySelectorAll('input[name=dest]:checked')].map(x=>{const [tipo,did]=x.value.split(':');return{tipo_destinatario:tipo,id:Number(did)}});b.documentos=[...f.querySelectorAll('input[name=doc]:checked')].map(x=>Number(x.value));try{await Api.post(`/api/condominios/${id}/avisos`,b);Util.toast('Aviso criado');fecharDetailModal();loadAvisos();load()}catch(err){Util.toast(err.message,true)}}};
window.reenviarAviso=async avisoId=>{try{await Api.post(`/api/condominios/${id}/avisos/${avisoId}/reenviar`,{});Util.toast('Aviso reenviado');loadAvisos()}catch(err){Util.toast(err.message,true)}};
window.excluirAviso=async avisoId=>{try{await Api.request(`/api/condominios/${id}/avisos/${avisoId}`,{method:'DELETE'});Util.toast('Aviso excluido');loadAvisos();load()}catch(err){Util.toast(err.message,true)}};
load();