GRUPO PLANO
Menu
Home
Quem Somos
Soluções
Contabilidade
Assessoria Financeira
Certificação Digital
Assessoria Jurídica
Soluções Bancárias
Endereço Fiscal
Consultas
Contato
Trabalhe Conosco
Área do cliente
Área do colaborador
Financeiro
Histórico, 2ª via de boletos, pague via Pix/cartão, notas fiscais.
Acessar
Onvio
Envie documentos, acompanhe serviços e notificações.
Acessar
plugins premium WordPress
'; return; } voteBtn.style.display = ''; qVote.textContent = poll.question; const alreadyVoted = (state.my_vote !== null && state.my_vote !== undefined); const votedIdx = alreadyVoted ? parseInt(state.my_vote, 10) : null; voteBtn.disabled = !!alreadyVoted; chosen = alreadyVoted ? votedIdx : null; poll.options.forEach((opt, idx) => { const row = document.createElement('label'); row.className = 'cp-option'; const rb = document.createElement('input'); rb.type = 'radio'; rb.name = 'cp_choice'; rb.value = String(idx); if (alreadyVoted) { rb.disabled = true; rb.checked = (idx === votedIdx); } else { rb.disabled = false; rb.addEventListener('change', () => { chosen = idx; }); } const span = document.createElement('span'); span.textContent = opt; row.appendChild(rb); row.appendChild(span); voteArea.appendChild(row); }); } function renderResults(){ resMsg.textContent = ''; barsBox.innerHTML = ''; const poll = state?.poll; const results = state?.results; if(!poll || !poll.question || !poll.options?.length){ qRes.textContent = 'Resultados'; barsBox.innerHTML = '
Nenhuma enquete disponível no momento.
'; return; } qRes.textContent = poll.question; const total = results?.total || 0; if(total === 0) resMsg.textContent = 'Ainda não há votos.'; const counts = poll.options.map((_, idx) => { return results?.by_option?.[String(idx)]?.count || 0; }); poll.options.forEach((opt, idx) => { const count = counts[idx] || 0; const widthPct = total ? (count / total) * 100 : 0; const row = document.createElement('div'); row.className = 'cp-bar-row'; const label = document.createElement('div'); label.className = 'cp-bar-label'; label.textContent = `${opt} — ${count} voto(s)`; const track = document.createElement('div'); track.className = 'cp-bar-track'; const fill = document.createElement('div'); fill.className = 'cp-bar-fill'; fill.style.width = widthPct + '%'; track.appendChild(fill); row.appendChild(label); row.appendChild(track); barsBox.appendChild(row); }); } function addOptionRow(value=''){ const row = document.createElement('div'); row.className = 'cp-opt-row'; const inp = document.createElement('input'); inp.className = 'cp-input'; inp.placeholder = 'Opção...'; inp.value = value; const del = document.createElement('button'); del.className = 'cp-icon-btn'; del.type = 'button'; del.textContent = '✕'; del.addEventListener('click', () => { row.remove(); ensureMinOptions(); }); row.appendChild(inp); row.appendChild(del); optionsBox.appendChild(row); } function getOptionsValues(){ const vals = []; optionsBox.querySelectorAll('input.cp-input').forEach(inp => { const v = (inp.value || '').trim(); if (v) vals.push(v); }); return vals; } function ensureMinOptions(){ const count = optionsBox.querySelectorAll('.cp-opt-row').length; if (count < 2) for(let i=count;i<2;i++) addOptionRow(''); } addOptBtn.addEventListener('click', () => addOptionRow('')); voteBtn.addEventListener('click', async () => { if(chosen === null || chosen === undefined) return; voteBtn.disabled = true; const res = await api('/poll/vote', 'POST', {choice: chosen}); if(!res.ok){ voteBtn.disabled = false; return; } await load(); setTab('results'); }); saveBtn.addEventListener('click', async () => { manageMsg.textContent = 'Publicando...'; const q = (newQuestion.value || '').trim(); const opts = getOptionsValues(); if (!q || opts.length < 2){ manageMsg.textContent = 'Informe a pergunta e pelo menos 2 opções.'; return; } const res = await api('/poll/update', 'POST', {question: q, options: opts}); if(!res.ok){ manageMsg.textContent = res.json?.message || 'Erro ao publicar.'; return; } manageMsg.textContent = 'Enquete publicada ✅'; await load(); setTab('vote'); }); clearBtn.addEventListener('click', async () => { if(!confirm('Tem certeza que deseja LIMPAR a enquete? Isso remove a enquete atual e todos os votos.')) return; manageMsg.textContent = 'Limpando enquete...'; const res = await api('/poll/clear', 'POST', {}); if(!res.ok){ manageMsg.textContent = res.json?.message || 'Erro ao limpar.'; return; } manageMsg.textContent = 'Enquete limpa ✅'; await load(); setTab('vote'); }); async function load(){ const res = await api('/poll', 'GET'); state = res.ok ? res.json : { poll:{id:0,question:'',options:[]}, my_vote:null, can_manage:false, results:{total:0,by_option:{}} }; manageTab.style.display = state.can_manage ? '' : 'none'; renderVote(); renderResults(); optionsBox.innerHTML = ''; ensureMinOptions(); } // quando volta a ficar visível document.addEventListener('visibilitychange', () => { if (!document.hidden) load(); }); load(); } function initAll(forceReset=false){ document.querySelectorAll('.collab-poll').forEach(root => { if (forceReset) delete root.dataset.cpInited; // ✅ permite reinit initOne(root); }); } // inicialização normal if (document.readyState === 'loading'){ document.addEventListener('DOMContentLoaded', () => initAll(false)); } else { initAll(false); } // ✅ FIX PRINCIPAL: ao voltar de outra página (bfcache), reinicializa window.addEventListener('pageshow', (e) => { // se voltou do cache, pode estar "travado" com cpInited=1 sem listeners if (e.persisted) { initAll(true); } else { // mesmo sem persisted, garante init caso builder re-renderize initAll(false); } }); // ✅ se Elementor/tema recriar o HTML, reinicializa const mo = new MutationObserver(() => initAll(false)); mo.observe(document.documentElement, {childList:true, subtree:true}); })(); //# sourceURL=collab-poll-inline-js-after