5858 border : 1px solid rgba (212 , 175 , 55 , 0.3 );
5959 min-height : 400px ;
6060 }
61- .eleicoes -grid {
61+ .candidatos -grid {
6262 display : grid;
6363 grid-template-columns : repeat (auto-fill, minmax (300px , 1fr ));
6464 gap : 20px ;
6565 margin-bottom : 30px ;
6666 }
67- .eleicao -card {
67+ .candidato -card {
6868 background : # 1a1a1a ;
6969 border : 1px solid rgba (212 , 175 , 55 , 0.2 );
7070 border-radius : 10px ;
7171 padding : 20px ;
7272 text-align : center;
7373 }
74- .eleicao -card h3 {
74+ .candidato -card h3 {
7575 color : # d4af37 ;
7676 margin-bottom : 10px ;
7777 }
78- .eleicao -card p {
78+ .candidato -card p {
7979 margin : 5px 0 ;
8080 color : # ccc ;
8181 }
82+ .candidato-foto {
83+ width : 80px ;
84+ height : 80px ;
85+ border-radius : 50% ;
86+ object-fit : cover;
87+ margin : 0 auto 15px ;
88+ border : 2px solid # d4af37 ;
89+ }
8290 .status-badge {
8391 display : inline-block;
8492 padding : 4px 12px ;
189197 .auditor-btn : hover {
190198 background : rgba (86 , 171 , 47 , 0.4 );
191199 }
192- .eleicao -btn {
200+ .candidato -btn {
193201 background : rgba (148 , 0 , 211 , 0.2 );
194202 border : 1px solid # 9400d3 ;
195203 color : # 9400d3 ;
200208 margin-top : 20px ;
201209 transition : .3s ;
202210 }
203- .eleicao -btn: hover {
211+ .candidato -btn: hover {
204212 background : rgba (148 , 0 , 211 , 0.4 );
205213 }
214+ .eleicao-btn {
215+ background : rgba (30 , 144 , 255 , 0.2 );
216+ border : 1px solid # 1e90ff ;
217+ color : # 1e90ff ;
218+ padding : 12px 25px ;
219+ border-radius : 20px ;
220+ cursor : pointer;
221+ font-size : 1.1rem ;
222+ margin-top : 20px ;
223+ transition : .3s ;
224+ }
225+ .eleicao-btn : hover {
226+ background : rgba (30 , 144 , 255 , 0.4 );
227+ }
206228 .header-buttons {
207229 display : flex;
208230 justify-content : center;
209231 gap : 15px ;
210232 margin-top : 15px ;
211233 flex-wrap : wrap;
212234 }
235+ .voltar-btn {
236+ background : rgba (128 , 128 , 128 , 0.2 );
237+ border : 1px solid # 808080 ;
238+ color : # 808080 ;
239+ padding : 10px 20px ;
240+ border-radius : 20px ;
241+ cursor : pointer;
242+ margin : 10px ;
243+ text-decoration : none;
244+ display : inline-block;
245+ }
246+ .voltar-btn : hover {
247+ background : rgba (128 , 128 , 128 , 0.4 );
248+ }
213249
214250 /* NOVOS ESTILOS PARA MESÁRIOS E API */
215251 .mesarios-grid {
288324< div class ="container ">
289325 < header >
290326 < h1 > 🌍 Painel de Autoridade — Terra Dourada</ h1 >
291- < p > Gerencie eleições, votos e créditos</ p >
327+ < p > Gerencie eleições, candidatos e créditos</ p >
292328
293329 < div class ="header-buttons ">
294- < button class ="eleicao -btn " onclick ="window.location.href='cad_eleicao .html' ">
295- 🗳️ Cadastrar Nova Eleição
330+ < button class ="candidato -btn " onclick ="window.location.href='cad_candidato .html' ">
331+ 👤 Cadastrar Candidato
296332 </ button >
297333 < button class ="auditor-btn " onclick ="window.location.href='auditor.html' ">
298334 👁️ Painel do Auditor
@@ -302,21 +338,21 @@ <h1>🌍 Painel de Autoridade — Terra Dourada</h1>
302338
303339 <!-- BOTÕES DAS ABAS -->
304340 < div class ="tabs ">
305- < button class ="tab active " onclick ="showTab('eleicoes ') "> 🗳️ Eleições </ button >
341+ < button class ="tab active " onclick ="showTab('candidatos ') "> 👥 Candidatos </ button >
306342 < button class ="tab " onclick ="showTab('mesarios') "> 👥 Mesários</ button >
307343 < button class ="tab " onclick ="showTab('api-cliente') "> 🔌 API Cliente</ button >
308- < button class ="tab " onclick ="showTab('autorizacao') "> 🔐 Autorizar Votos</ button >
344+ < button class ="tab " onclick ="window.location.href='eleitor_point.html' "> 🔐 Autorizar Votos</ button >
309345 < button class ="tab " onclick ="showTab('monitor') "> 👁️ Monitorar Votos</ button >
310346 < button class ="tab " onclick ="showTab('pagamento') "> 💰 Comprar Créditos</ button >
311347 </ div >
312348
313349 <!-- CONTEÚDO -->
314350 < div class ="content ">
315351
316- <!-- ABA ELEIÇÕES -->
317- < div id ="tab-eleicoes ">
318- < h2 > Lista de Eleições Cadastradas </ h2 >
319- < div id ="eleicoes -list " class ="eleicoes -grid "> </ div >
352+ <!-- ABA CANDIDATOS -->
353+ < div id ="tab-candidatos ">
354+ < h2 > Lista de Candidatos Cadastrados </ h2 >
355+ < div id ="candidatos -list " class ="candidatos -grid "> </ div >
320356 </ div >
321357
322358 <!-- ABA MESÁRIOS -->
@@ -395,7 +431,7 @@ <h2>Votos Autorizados e Realizados</h2>
395431 <!-- ABA PAGAMENTO -->
396432 < div id ="tab-pagamento " style ="display: none; ">
397433 < h2 > 💰 Comprar Créditos de Votação</ h2 >
398- <!-- Conteúdo existente mantido -->
434+
399435 < label > Quantidade de votos:</ label > < br >
400436 < input id ="quantidade " type ="number " min ="10 " placeholder ="Ex: 500 "
401437 style ="padding:10px; width:220px; border-radius:8px; margin-top:10px; "> < br > < br >
@@ -428,6 +464,7 @@ <h2>💰 Comprar Créditos de Votação</h2>
428464const dbEleicoes = new PouchDB ( 'terra_dourada_eleicoes' ) ;
429465const dbVotes = new PouchDB ( 'terra_dourada_votos_local' ) ;
430466const dbMesarios = new PouchDB ( 'terra_dourada_mesarios' ) ;
467+ const dbCandidatos = new PouchDB ( 'terra_dourada_candidatos' ) ;
431468
432469// --- CONFIGURAÇÃO DA API ---
433470let API_CONFIG = {
@@ -448,56 +485,62 @@ <h2>💰 Comprar Créditos de Votação</h2>
448485 document . querySelector ( `button[onclick="showTab('${ tab } ')"]` ) . classList . add ( 'active' ) ;
449486 document . getElementById ( `tab-${ tab } ` ) . style . display = 'block' ;
450487
451- if ( tab === "eleicoes " ) carregarEleicoes ( ) ;
488+ if ( tab === "candidatos " ) carregarCandidatos ( ) ;
452489 if ( tab === "mesarios" ) carregarMesarios ( ) ;
453490 if ( tab === "api-cliente" ) carregarConfigAPI ( ) ;
454491 if ( tab === "monitor" ) carregarVotosAutorizados ( ) ;
455492}
456493
457- // --- CARREGAR ELEIÇÕES ---
458- async function carregarEleicoes ( ) {
459- const res = await dbEleicoes . allDocs ( { include_docs : true } ) ;
460- const cont = document . getElementById ( 'eleicoes-list' ) ;
494+ // --- CARREGAR CANDIDATOS ---
495+ async function carregarCandidatos ( ) {
496+ try {
497+ const res = await dbCandidatos . allDocs ( { include_docs : true } ) ;
498+ const cont = document . getElementById ( 'candidatos-list' ) ;
461499
462- if ( res . rows . length === 0 ) {
463- cont . innerHTML = `
464- <div class="empty-state">
465- <h3>Nenhuma eleição cadastrada </h3>
466- <p>Clique em "Cadastrar Nova Eleição " para começar</p>
467- </div>
468- ` ;
469- return ;
470- }
500+ if ( res . rows . length === 0 ) {
501+ cont . innerHTML = `
502+ <div class="empty-state">
503+ <h3>Nenhum candidato cadastrado </h3>
504+ <p>Clique em "Cadastrar Candidato " para começar</p>
505+ </div>
506+ ` ;
507+ return ;
508+ }
471509
472- cont . innerHTML = res . rows . map ( r => {
473- const eleicao = r . doc ;
474- const status = eleicao . ativa ? 'status-ativa' : 'status-inativa' ;
475- const statusText = eleicao . ativa ? 'Ativa' : 'Inativa' ;
476-
477- return `
478- <div class="eleicao-card">
479- <h3>${ eleicao . titulo } </h3>
480- <p><strong>Cargo:</strong> ${ eleicao . cargo } </p>
481- <p><strong>Data:</strong> ${ new Date ( eleicao . data ) . toLocaleDateString ( ) } </p>
482- <span class="status-badge ${ status } ">${ statusText } </span>
483-
484- <div style="margin-top: 15px;">
485- <button class="action-btn" onclick="gerarLinkVotacao('${ eleicao . _id } ')">
486- 🔗 Link de Votação
487- </button>
488- <button class="action-btn" onclick="editarEleicao('${ eleicao . _id } ')">
489- ✏️ Editar
490- </button>
491- <button class="action-btn" onclick="gerenciarCandidatos('${ eleicao . _id } ')">
492- 👥 Candidatos
493- </button>
494- <button class="delete-btn" onclick="excluirEleicao('${ eleicao . _id } ')">
495- 🗑️ Excluir
496- </button>
510+ cont . innerHTML = res . rows . map ( r => {
511+ const candidato = r . doc ;
512+ const status = candidato . ativo ? 'status-ativa' : 'status-inativa' ;
513+ const statusText = candidato . ativo ? 'Ativo' : 'Inativo' ;
514+
515+ return `
516+ <div class="candidato-card">
517+ ${ candidato . foto ? `<img src="${ candidato . foto } " class="candidato-foto" alt="${ candidato . nome } ">` : '<div class="candidato-foto" style="background:#333; display:flex; align-items:center; justify-content:center;">👤</div>' }
518+ <h3>${ candidato . nome } </h3>
519+ <p><strong>Partido:</strong> ${ candidato . partido || 'N/A' } </p>
520+ <p><strong>Cargo:</strong> ${ candidato . cargo || 'N/A' } </p>
521+ <p><strong>Número:</strong> ${ candidato . numero || 'N/A' } </p>
522+ <span class="status-badge ${ status } ">${ statusText } </span>
523+
524+ <div style="margin-top: 15px;">
525+ <button class="action-btn" onclick="editarCandidato('${ candidato . _id } ')">
526+ ✏️ Editar
527+ </button>
528+ <button class="delete-btn" onclick="excluirCandidato('${ candidato . _id } ')">
529+ 🗑️ Excluir
530+ </button>
531+ </div>
497532 </div>
533+ ` ;
534+ } ) . join ( '' ) ;
535+ } catch ( error ) {
536+ console . error ( 'Erro ao carregar candidatos:' , error ) ;
537+ document . getElementById ( 'candidatos-list' ) . innerHTML = `
538+ <div class="empty-state">
539+ <h3>Erro ao carregar candidatos</h3>
540+ <p>Recarregue a página e tente novamente</p>
498541 </div>
499542 ` ;
500- } ) . join ( '' ) ;
543+ }
501544}
502545
503546// --- SISTEMA DE MESÁRIOS ---
@@ -642,6 +685,24 @@ <h4>${mesario.nome}</h4>
642685 }
643686}
644687
688+ // --- FUNÇÕES PARA CANDIDATOS ---
689+ async function editarCandidato ( candidatoId ) {
690+ alert ( 'Funcionalidade de edição será implementada em breve!' ) ;
691+ }
692+
693+ async function excluirCandidato ( candidatoId ) {
694+ if ( confirm ( 'Tem certeza que deseja excluir este candidato?' ) ) {
695+ try {
696+ const candidato = await dbCandidatos . get ( candidatoId ) ;
697+ await dbCandidatos . remove ( candidato ) ;
698+ carregarCandidatos ( ) ;
699+ } catch ( error ) {
700+ console . error ( 'Erro ao excluir candidato:' , error ) ;
701+ alert ( 'Erro ao excluir candidato!' ) ;
702+ }
703+ }
704+ }
705+
645706// --- API DO CLIENTE ---
646707function carregarConfigAPI ( ) {
647708 const configSalva = localStorage . getItem ( 'api_config_cliente' ) ;
@@ -779,36 +840,6 @@ <h4>🔗 Link para Mesário - ${eleicao.titulo}</h4>
779840}
780841
781842// --- FUNÇÕES EXISTENTES MANTIDAS ---
782- async function gerenciarCandidatos ( eleicaoId ) {
783- window . location . href = `gerenciar_candidatos.html?eleicao=${ eleicaoId } ` ;
784- }
785-
786- async function gerarLinkVotacao ( eleicaoId ) {
787- const token = crypto . randomUUID ( ) ;
788- const expiresAt = new Date ( Date . now ( ) + 3600000 ) ;
789-
790- await dbAuth . put ( {
791- _id : token ,
792- token,
793- eleicao_id : eleicaoId ,
794- created_at : new Date ( ) . toISOString ( ) ,
795- expires_at : expiresAt . toISOString ( ) ,
796- used : false
797- } ) ;
798-
799- const voteURL = `${ window . location . origin } /voto.html?auth=${ token } &eleicao=${ eleicaoId } ` ;
800-
801- alert ( `Link de votação gerado:\n${ voteURL } \n\nExpira em: ${ expiresAt . toLocaleString ( ) } ` ) ;
802- }
803-
804- async function excluirEleicao ( id ) {
805- if ( confirm ( 'Tem certeza que deseja excluir esta eleição?' ) ) {
806- const doc = await dbEleicoes . get ( id ) ;
807- await dbEleicoes . remove ( doc ) ;
808- carregarEleicoes ( ) ;
809- }
810- }
811-
812843async function carregarVotosAutorizados ( ) {
813844 const auths = await dbAuth . allDocs ( { include_docs : true } ) ;
814845 const votes = await dbVotes . allDocs ( { include_docs : true } ) ;
@@ -828,17 +859,13 @@ <h4>🔗 Link para Mesário - ${eleicao.titulo}</h4>
828859}
829860
830861// ======================
831- // PAGAMENTO
862+ // PAGAMENTO - PREÇOS ATUALIZADOS
832863// ======================
833864function calcularPrecoBRL ( q ) {
834- if ( q < 100 ) return q * 0.05 ;
835- if ( q < 1000 ) return q * 0.04 ;
836- if ( q < 10000 ) return q * 0.03 ;
837- if ( q < 100000 ) return q * 0.02 ;
838- if ( q < 1000000 ) return q * 0.01 ;
839- if ( q < 10000000 ) return q * 0.009 ;
840- if ( q < 100000000 ) return q * 0.008 ;
841- return q * 0.007 ;
865+ if ( q < 1000 ) return q * 0.10 ; // 10 centavos por voto
866+ if ( q < 100000 ) return q * 0.05 ; // 5 centavos por voto
867+ if ( q < 1000000 ) return q * 0.03 ; // 3 centavos por voto
868+ return q * 0.01 ; // 1 centavo por voto (acima de 1M)
842869}
843870
844871function simularPagamento ( ) {
@@ -853,15 +880,15 @@ <h4>🔗 Link para Mesário - ${eleicao.titulo}</h4>
853880 const precoBRL = calcularPrecoBRL ( q ) ;
854881
855882 document . getElementById ( "precoEstimado" ) . textContent =
856- `Preço-base BRL : R$ ${ precoBRL . toFixed ( 2 ) } ` ;
883+ `Preço total : R$ ${ precoBRL . toFixed ( 2 ) } ( ${ ( precoBRL / q ) . toFixed ( 3 ) } por voto) ` ;
857884
858885 document . getElementById ( "resultadoPagamento" ) . textContent =
859- `Pagamento SIMULADO em ${ moeda } aprovado! Créditos liberados: ${ q } ` ;
886+ `Pagamento SIMULADO em ${ moeda } aprovado! Créditos liberados: ${ q } votos ` ;
860887}
861888
862889// INICIALIZAÇÃO
863890document . addEventListener ( "DOMContentLoaded" , ( ) => {
864- carregarEleicoes ( ) ;
891+ carregarCandidatos ( ) ;
865892 carregarConfigAPI ( ) ;
866893} ) ;
867894</ script >
0 commit comments