Melhorias na lógica de ativação de badges e atualização de responsabilidades
This commit is contained in:
@@ -8,6 +8,54 @@ let currentPage = 1;
|
||||
let rowsPerPage = 20;
|
||||
let totalRows = 0;
|
||||
|
||||
// Mapa de responsabilidades para valores numéricos
|
||||
const RESPONSABILIDADES_MAP = {
|
||||
'Secretario': 1,
|
||||
'Tesoureiro': 2,
|
||||
'Imprensa': 4,
|
||||
'MNS': 8,
|
||||
'MPS': 16,
|
||||
'Juventude': 32,
|
||||
'Quadro-Orientador': 64,
|
||||
'Aspirante': 128,
|
||||
'Responsavel de Financas': 256,
|
||||
'Responsavel de Imprensa': 512
|
||||
};
|
||||
|
||||
// Mapa reverso para converter valores em nomes
|
||||
const RESPONSABILIDADES_REVERSE_MAP = {
|
||||
1: 'Secretario',
|
||||
2: 'Tesoureiro',
|
||||
4: 'Imprensa',
|
||||
8: 'MNS',
|
||||
16: 'MPS',
|
||||
32: 'Juventude',
|
||||
64: 'Quadro-Orientador',
|
||||
128: 'Aspirante',
|
||||
256: 'Responsavel de Financas',
|
||||
512: 'Responsavel de Imprensa'
|
||||
};
|
||||
|
||||
// Função para validar data no formato DD/MM/YYYY
|
||||
function validarData(data) {
|
||||
if (!data) return true; // Campo vazio é válido
|
||||
|
||||
// Verifica o formato
|
||||
if (!/^\d{2}\/\d{2}\/\d{4}$/.test(data)) return false;
|
||||
|
||||
// Extrai dia, mês e ano
|
||||
const [dia, mes, ano] = data.split('/').map(Number);
|
||||
|
||||
// Cria um objeto Date
|
||||
const dataObj = new Date(ano, mes - 1, dia);
|
||||
|
||||
// Verifica se a data é válida
|
||||
return dataObj.getDate() === dia &&
|
||||
dataObj.getMonth() === mes - 1 &&
|
||||
dataObj.getFullYear() === ano &&
|
||||
ano >= 1900 && ano <= 2100;
|
||||
}
|
||||
|
||||
// Função para formatar data do formato ISO (YYYY-MM-DD) para DD/MM/YYYY
|
||||
function formatarData(data) {
|
||||
if (!data) return '';
|
||||
@@ -18,7 +66,7 @@ function formatarData(data) {
|
||||
// Função para converter data de DD/MM/YYYY para YYYY-MM-DD
|
||||
function converterDataParaISO(data) {
|
||||
if (!data) return '';
|
||||
if (data.includes('-')) return data; // Já está no formato ISO
|
||||
if (data.includes('-')) return data;
|
||||
const [dia, mes, ano] = data.split('/');
|
||||
return `${ano}-${mes}-${dia}`;
|
||||
}
|
||||
@@ -138,8 +186,21 @@ function filtrarMilitantes() {
|
||||
// Filtro de responsabilidades
|
||||
if (filtroResponsabilidade) {
|
||||
const badges = row.querySelectorAll('.badge');
|
||||
const responsabilidadeMap = {
|
||||
'responsavel-financas': 'RFI',
|
||||
'responsavel-imprensa': 'RIM',
|
||||
'quadro-orientador': 'QOR',
|
||||
'secretario': 'SEC',
|
||||
'tesoureiro': 'TES',
|
||||
'imprensa': 'IMP',
|
||||
'mns': 'MNS',
|
||||
'mps': 'MPS',
|
||||
'juventude': 'JUV',
|
||||
'aspirante': 'ASP'
|
||||
};
|
||||
const responsabilidadeTexto = responsabilidadeMap[filtroResponsabilidade];
|
||||
const hasResponsabilidade = Array.from(badges).some(badge =>
|
||||
badge.textContent.toLowerCase() === filtroResponsabilidade.toLowerCase()
|
||||
badge.textContent.trim() === responsabilidadeTexto
|
||||
);
|
||||
if (!hasResponsabilidade) {
|
||||
shouldShow = false;
|
||||
@@ -157,6 +218,7 @@ function filtrarMilitantes() {
|
||||
// Marcar linha como filtrada ou não
|
||||
if (shouldShow) {
|
||||
row.removeAttribute('data-filtered-out');
|
||||
row.style.display = '';
|
||||
} else {
|
||||
row.setAttribute('data-filtered-out', '');
|
||||
row.style.display = 'none';
|
||||
@@ -173,35 +235,208 @@ function filtrarMilitantes() {
|
||||
function configurarCampoData(campo) {
|
||||
if (!campo) return;
|
||||
|
||||
// Criar um campo de texto para exibição
|
||||
const campoTexto = document.createElement('input');
|
||||
campoTexto.type = 'text';
|
||||
campoTexto.className = campo.className;
|
||||
campoTexto.placeholder = 'dd/mm/aaaa';
|
||||
campoTexto.readOnly = true; // Evita edição manual
|
||||
|
||||
// Esconder o campo original mas manter ao lado
|
||||
// Remover campo de texto anterior se existir
|
||||
const campoTextoExistente = campo.previousElementSibling;
|
||||
if (campoTextoExistente && campoTextoExistente.classList.contains('campo-data-texto')) {
|
||||
campoTextoExistente.remove();
|
||||
}
|
||||
|
||||
// Configurar o campo de data
|
||||
campo.type = 'date';
|
||||
campo.style.position = 'absolute';
|
||||
campo.style.left = '-9999px';
|
||||
|
||||
// Inserir o campo de texto antes do campo de data
|
||||
campo.parentNode.insertBefore(campoTexto, campo);
|
||||
|
||||
// Se já tiver valor, formatar
|
||||
// Se já tiver valor, garantir que está no formato ISO
|
||||
if (campo.value) {
|
||||
campoTexto.value = formatarData(campo.value);
|
||||
campo.value = converterDataParaISO(campo.value);
|
||||
}
|
||||
|
||||
// Quando o campo original mudar, atualizar o texto
|
||||
// Quando o valor mudar, garantir formato ISO
|
||||
campo.addEventListener('change', function() {
|
||||
campoTexto.value = this.value ? formatarData(this.value) : '';
|
||||
if (this.value) {
|
||||
this.value = converterDataParaISO(this.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Função para carregar os dados do militante no modal de edição
|
||||
function carregarDadosMilitante(id) {
|
||||
console.log('Carregando dados do militante:', id);
|
||||
|
||||
// Quando clicar no campo de texto, abrir o calendário
|
||||
campoTexto.addEventListener('click', function() {
|
||||
campo.showPicker();
|
||||
});
|
||||
fetch(`/militantes/dados/${id}`)
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
return response.text().then(text => {
|
||||
try {
|
||||
return JSON.parse(text);
|
||||
} catch (e) {
|
||||
console.error('Erro ao fazer parse do JSON:', e);
|
||||
console.log('Texto recebido:', text);
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
})
|
||||
.then(data => {
|
||||
console.log('Dados recebidos:', data);
|
||||
|
||||
// Mapear campos básicos
|
||||
const camposTexto = {
|
||||
'edit_militante_id': data.id,
|
||||
'edit_nome': data.nome || '',
|
||||
'edit_cpf': data.cpf || '',
|
||||
'edit_titulo_eleitoral': data.titulo_eleitoral || '',
|
||||
'edit_email': data.email || '',
|
||||
'edit_telefone1': data.telefone1 || '',
|
||||
'edit_telefone2': data.telefone2 || '',
|
||||
'edit_sindicato': data.sindicato || '',
|
||||
'edit_cargo_sindical': data.cargo_sindical || '',
|
||||
'edit_central_sindical': data.central_sindical || ''
|
||||
};
|
||||
|
||||
// Preencher campos de texto simples
|
||||
Object.entries(camposTexto).forEach(([id, valor]) => {
|
||||
const campo = document.getElementById(id);
|
||||
if (campo) {
|
||||
campo.value = valor;
|
||||
} else {
|
||||
console.warn(`Campo não encontrado: ${id}`);
|
||||
}
|
||||
});
|
||||
|
||||
// Tratar campos de seleção
|
||||
const selects = {
|
||||
'edit_estado_militante': data.estado || 'ATIVO',
|
||||
'edit_celula': data.celula_id || ''
|
||||
};
|
||||
|
||||
Object.entries(selects).forEach(([id, valor]) => {
|
||||
const campo = document.getElementById(id);
|
||||
if (campo) {
|
||||
campo.value = valor;
|
||||
} else {
|
||||
console.warn(`Campo select não encontrado: ${id}`);
|
||||
}
|
||||
});
|
||||
|
||||
// Tratar campos de checkbox
|
||||
const checkboxes = {
|
||||
'edit_dirigente_sindical': data.dirigente_sindical || false
|
||||
};
|
||||
|
||||
Object.entries(checkboxes).forEach(([id, valor]) => {
|
||||
const campo = document.getElementById(id);
|
||||
if (campo) {
|
||||
campo.checked = !!valor;
|
||||
} else {
|
||||
console.warn(`Campo checkbox não encontrado: ${id}`);
|
||||
}
|
||||
});
|
||||
|
||||
// Tratar campos de data
|
||||
const camposData = {
|
||||
'edit_data_nascimento': data.data_nascimento,
|
||||
'edit_data_entrada': data.data_entrada_oci,
|
||||
'edit_data_efetivacao': data.data_efetivacao_oci
|
||||
};
|
||||
|
||||
Object.entries(camposData).forEach(([id, valor]) => {
|
||||
const campo = document.getElementById(id);
|
||||
if (campo) {
|
||||
// Se o valor existe e está em formato ISO, converter para DD/MM/AAAA
|
||||
if (valor && typeof valor === 'string' && valor.includes('-')) {
|
||||
campo.value = formatarData(valor);
|
||||
} else {
|
||||
campo.value = valor || '';
|
||||
}
|
||||
} else {
|
||||
console.warn(`Campo data não encontrado: ${id}`);
|
||||
}
|
||||
});
|
||||
|
||||
// Converter responsabilidades
|
||||
const responsabilidadesBits = data.responsabilidades_bits || data.responsabilidades || 0;
|
||||
console.log('Responsabilidades bits:', responsabilidadesBits);
|
||||
|
||||
// Resetar todas as badges para o estado inicial
|
||||
const badges = document.querySelectorAll('#modalEditarMilitante .badge-clickable');
|
||||
badges.forEach(badge => {
|
||||
// Remover todas as classes exceto 'badge' e 'badge-clickable'
|
||||
const classesToKeep = ['badge', 'badge-clickable'];
|
||||
badge.classList.forEach(cls => {
|
||||
if (!classesToKeep.includes(cls)) {
|
||||
badge.classList.remove(cls);
|
||||
}
|
||||
});
|
||||
|
||||
// Adicionar a classe bg-light como estado inicial
|
||||
badge.classList.add('bg-light');
|
||||
badge.classList.remove('active');
|
||||
});
|
||||
|
||||
// Ativar as badges correspondentes às responsabilidades
|
||||
badges.forEach(badge => {
|
||||
const value = parseInt(badge.getAttribute('data-value'));
|
||||
if ((responsabilidadesBits & value) === value) {
|
||||
badge.classList.remove('bg-light');
|
||||
badge.classList.add('active');
|
||||
|
||||
// Adicionar a classe original
|
||||
const originalClass = badge.getAttribute('data-original-class');
|
||||
if (originalClass) {
|
||||
originalClass.split(' ').forEach(cls => {
|
||||
badge.classList.add(cls);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Atualizar o valor total das responsabilidades
|
||||
const responsabilidadesInput = document.getElementById('responsabilidades_values');
|
||||
if (responsabilidadesInput) {
|
||||
responsabilidadesInput.value = responsabilidadesBits;
|
||||
}
|
||||
|
||||
// Reinicializar os badges clicáveis
|
||||
initBadgeClickable();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Erro ao carregar dados do militante:', error);
|
||||
// Mostrar alerta de erro
|
||||
mostrarAlerta('Erro ao carregar dados do militante: ' + error.message, 'danger');
|
||||
});
|
||||
}
|
||||
|
||||
// Função para mostrar alertas
|
||||
function mostrarAlerta(mensagem, tipo = 'success') {
|
||||
console.log('Mostrando alerta:', mensagem, tipo);
|
||||
|
||||
// Criar div de alerta se não existir
|
||||
let alertPlaceholder = document.getElementById('alertPlaceholder');
|
||||
if (!alertPlaceholder) {
|
||||
alertPlaceholder = document.createElement('div');
|
||||
alertPlaceholder.id = 'alertPlaceholder';
|
||||
alertPlaceholder.style.position = 'fixed';
|
||||
alertPlaceholder.style.top = '20px';
|
||||
alertPlaceholder.style.right = '20px';
|
||||
alertPlaceholder.style.zIndex = '9999';
|
||||
document.body.appendChild(alertPlaceholder);
|
||||
}
|
||||
|
||||
// Criar wrapper para o alerta
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.innerHTML = `
|
||||
<div class="alert alert-${tipo} alert-dismissible fade show" role="alert">
|
||||
${mensagem}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
`;
|
||||
alertPlaceholder.appendChild(wrapper);
|
||||
|
||||
// Remover o alerta após 5 segundos
|
||||
setTimeout(() => {
|
||||
wrapper.firstElementChild.classList.remove('show');
|
||||
setTimeout(() => wrapper.remove(), 150);
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
// Configurar eventos quando o DOM estiver carregado
|
||||
@@ -242,10 +477,10 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
filtroAtual = 'todos';
|
||||
filtroResponsabilidade = null;
|
||||
filtroCelula = null;
|
||||
} else if (['financas', 'imprensa', 'quadro-orientador'].includes(filter)) {
|
||||
} else if (['responsavel-financas', 'responsavel-imprensa', 'quadro-orientador'].includes(filter)) {
|
||||
filtroAtual = 'todos';
|
||||
filtroResponsabilidade = filter === 'financas' ? 'Finanças' :
|
||||
filter === 'imprensa' ? 'Imprensa' :
|
||||
filtroResponsabilidade = filter === 'responsavel-financas' ? 'Responsável de Finanças' :
|
||||
filter === 'responsavel-imprensa' ? 'Responsável de Imprensa' :
|
||||
'Quadro-Orientador';
|
||||
filtroCelula = null;
|
||||
} else if (filter === 'celula') {
|
||||
@@ -265,44 +500,32 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
console.log('Configurando modal de edição...');
|
||||
|
||||
// Configurar máscara para campos de data
|
||||
$('.date-mask').mask('00/00/0000', {
|
||||
placeholder: 'DD/MM/AAAA',
|
||||
clearIfNotMatch: true
|
||||
});
|
||||
|
||||
// Validar campos de data quando perderem o foco
|
||||
$('.date-mask').on('blur', function() {
|
||||
const valor = $(this).val();
|
||||
if (valor && !validarData(valor)) {
|
||||
$(this).addClass('is-invalid');
|
||||
if (!$(this).next('.invalid-feedback').length) {
|
||||
$(this).after('<div class="invalid-feedback">Data inválida</div>');
|
||||
}
|
||||
} else {
|
||||
$(this).removeClass('is-invalid');
|
||||
$(this).next('.invalid-feedback').remove();
|
||||
}
|
||||
});
|
||||
|
||||
// Configurar campos de data em todos os modais
|
||||
const modalNovoMilitante = document.getElementById('modalNovoMilitante');
|
||||
const modalEditarMilitante = document.getElementById('modalEditarMilitante');
|
||||
|
||||
// Configurar campos quando o modal novo for aberto
|
||||
if (modalNovoMilitante) {
|
||||
modalNovoMilitante.addEventListener('show.bs.modal', function() {
|
||||
// Configurar campos de data do modal novo
|
||||
const camposData = this.querySelectorAll('input[type="date"]');
|
||||
camposData.forEach(configurarCampoData);
|
||||
});
|
||||
|
||||
// Limpar formulário e alertas quando o modal for fechado
|
||||
modalNovoMilitante.addEventListener('hidden.bs.modal', function () {
|
||||
formNovoMilitante.reset();
|
||||
const alerts = this.querySelectorAll('.alert');
|
||||
alerts.forEach(alert => alert.remove());
|
||||
});
|
||||
}
|
||||
|
||||
// Configurar campos quando o modal editar for aberto
|
||||
if (modalEditarMilitante) {
|
||||
modalEditarMilitante.addEventListener('show.bs.modal', function() {
|
||||
// Configurar campos de data do modal editar
|
||||
const camposData = this.querySelectorAll('input[type="date"]');
|
||||
camposData.forEach(configurarCampoData);
|
||||
});
|
||||
}
|
||||
|
||||
// Configurar modal de edição
|
||||
if (modalEditarMilitante) {
|
||||
console.log('Modal encontrado, configurando eventos...');
|
||||
|
||||
// Criar instância do modal Bootstrap
|
||||
const modalInstance = new bootstrap.Modal(modalEditarMilitante);
|
||||
console.log('Instância do modal criada:', modalInstance);
|
||||
|
||||
// Configurar eventos quando o modal é mostrado
|
||||
modalEditarMilitante.addEventListener('show.bs.modal', function(event) {
|
||||
console.log('Modal sendo aberto...');
|
||||
|
||||
@@ -327,201 +550,126 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
}
|
||||
|
||||
// Buscar dados do militante
|
||||
fetch(`/militantes/dados/${militanteId}`, {
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
return response.json().then(data => {
|
||||
throw new Error(data.message || `HTTP error! status: ${response.status}`);
|
||||
});
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(dados => {
|
||||
console.log('Dados do militante recebidos:', dados);
|
||||
|
||||
if (!dados) {
|
||||
throw new Error('Dados do militante não encontrados');
|
||||
}
|
||||
|
||||
try {
|
||||
// Preencher os campos do formulário
|
||||
const campos = {
|
||||
'edit_nome': dados.nome,
|
||||
'edit_cpf': dados.cpf,
|
||||
'edit_titulo_eleitoral': dados.titulo_eleitoral,
|
||||
'edit_data_nascimento': dados.data_nascimento,
|
||||
'edit_data_entrada': dados.data_entrada_oci,
|
||||
'edit_data_efetivacao': dados.data_efetivacao_oci,
|
||||
'edit_telefone1': dados.telefone1,
|
||||
'edit_telefone2': dados.telefone2,
|
||||
'edit_email': dados.email,
|
||||
'edit_cep': dados.endereco?.cep,
|
||||
'edit_estado': dados.endereco?.estado,
|
||||
'edit_cidade': dados.endereco?.cidade,
|
||||
'edit_bairro': dados.endereco?.bairro,
|
||||
'edit_rua': dados.endereco?.rua,
|
||||
'edit_numero': dados.endereco?.numero,
|
||||
'edit_complemento': dados.endereco?.complemento,
|
||||
'edit_profissao': dados.profissao,
|
||||
'edit_regime_trabalho': dados.regime_trabalho,
|
||||
'edit_empresa': dados.empresa,
|
||||
'edit_contratante': dados.contratante,
|
||||
'edit_instituicao_ensino': dados.instituicao_ensino,
|
||||
'edit_tipo_instituicao': dados.tipo_instituicao,
|
||||
'edit_sindicato': dados.sindicato,
|
||||
'edit_cargo_sindical': dados.cargo_sindical,
|
||||
'edit_central_sindical': dados.central_sindical,
|
||||
'edit_estado_militante': dados.estado,
|
||||
'edit_celula': dados.celula_id
|
||||
};
|
||||
|
||||
// Preencher cada campo se ele existir
|
||||
Object.entries(campos).forEach(([id, valor]) => {
|
||||
const campo = document.getElementById(id);
|
||||
if (campo) {
|
||||
if (campo.type === 'date') {
|
||||
// Para campos de data, atualizar também o campo de texto
|
||||
campo.value = valor || '';
|
||||
const campoTexto = campo.previousElementSibling;
|
||||
if (campoTexto && campoTexto.type === 'text') {
|
||||
campoTexto.value = valor ? formatarData(valor) : '';
|
||||
}
|
||||
} else {
|
||||
campo.value = valor || '';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Checkbox de dirigente sindical
|
||||
const checkDirigente = document.getElementById('edit_dirigente_sindical');
|
||||
if (checkDirigente) {
|
||||
checkDirigente.checked = dados.dirigente_sindical;
|
||||
}
|
||||
|
||||
// Checkboxes de responsabilidades
|
||||
const responsabilidadesMap = {
|
||||
'Finanças': 'edit_resp_1',
|
||||
'Imprensa': 'edit_resp_2',
|
||||
'Quadro-Orientador': 'edit_resp_4'
|
||||
};
|
||||
|
||||
console.log('Responsabilidades recebidas:', dados.responsabilidades);
|
||||
|
||||
// Resetar todos os checkboxes primeiro
|
||||
Object.values(responsabilidadesMap).forEach(id => {
|
||||
const checkbox = document.getElementById(id);
|
||||
if (checkbox) {
|
||||
checkbox.checked = false;
|
||||
}
|
||||
});
|
||||
|
||||
// Marcar os checkboxes baseado nas responsabilidades recebidas
|
||||
if (Array.isArray(dados.responsabilidades)) {
|
||||
dados.responsabilidades.forEach(resp => {
|
||||
const checkboxId = responsabilidadesMap[resp];
|
||||
if (checkboxId) {
|
||||
const checkbox = document.getElementById(checkboxId);
|
||||
if (checkbox) {
|
||||
checkbox.checked = true;
|
||||
console.log(`Marcando checkbox ${checkboxId} para responsabilidade ${resp}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
console.log('Formulário preenchido com sucesso');
|
||||
} catch (error) {
|
||||
console.error('Erro ao preencher formulário:', error);
|
||||
mostrarAlerta('Erro ao carregar dados do militante', 'danger');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Erro ao buscar dados:', error);
|
||||
mostrarAlerta('Erro ao carregar dados do militante', 'danger');
|
||||
});
|
||||
carregarDadosMilitante(militanteId);
|
||||
});
|
||||
|
||||
// Envio do formulário de edição via AJAX
|
||||
// Configurar formulário de edição
|
||||
const formEditarMilitante = document.getElementById('formEditarMilitante');
|
||||
if (formEditarMilitante) {
|
||||
formEditarMilitante.addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
console.log('Enviando formulário de edição...');
|
||||
console.log('Formulário submetido');
|
||||
|
||||
// Os campos de data já estarão no formato ISO, não precisa converter
|
||||
// Validar todas as datas antes do envio
|
||||
const camposData = this.querySelectorAll('.date-mask');
|
||||
let datasValidas = true;
|
||||
|
||||
// Coletar responsabilidades selecionadas
|
||||
const responsabilidades = [];
|
||||
if (document.getElementById('edit_resp_1').checked) responsabilidades.push('Finanças');
|
||||
if (document.getElementById('edit_resp_2').checked) responsabilidades.push('Imprensa');
|
||||
if (document.getElementById('edit_resp_4').checked) responsabilidades.push('Quadro-Orientador');
|
||||
camposData.forEach(campo => {
|
||||
const valor = campo.value;
|
||||
if (valor && !validarData(valor)) {
|
||||
datasValidas = false;
|
||||
$(campo).addClass('is-invalid');
|
||||
if (!$(campo).next('.invalid-feedback').length) {
|
||||
$(campo).after('<div class="invalid-feedback">Data inválida</div>');
|
||||
}
|
||||
} else {
|
||||
$(campo).removeClass('is-invalid');
|
||||
$(campo).next('.invalid-feedback').remove();
|
||||
}
|
||||
});
|
||||
|
||||
if (!datasValidas) {
|
||||
mostrarAlerta('Existem datas inválidas no formulário', 'danger');
|
||||
return;
|
||||
}
|
||||
|
||||
// Converter datas para formato ISO
|
||||
camposData.forEach(campo => {
|
||||
if (campo.value) {
|
||||
campo.value = converterDataParaISO(campo.value);
|
||||
console.log(`Data convertida para ISO: ${campo.name} = ${campo.value}`);
|
||||
}
|
||||
});
|
||||
|
||||
// Criar FormData com todos os campos
|
||||
const formData = new FormData(this);
|
||||
formData.set('responsabilidades', JSON.stringify(responsabilidades));
|
||||
|
||||
console.log('Responsabilidades enviadas:', responsabilidades);
|
||||
|
||||
// Obter o CSRF token
|
||||
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
|
||||
|
||||
// Obter o ID do militante do campo hidden
|
||||
const militanteId = document.getElementById('edit_militante_id').value;
|
||||
|
||||
if (!militanteId) {
|
||||
console.error('ID do militante não encontrado!');
|
||||
mostrarAlerta('Erro: ID do militante não encontrado', 'danger');
|
||||
// Verificar se o input de responsabilidades existe
|
||||
const responsabilidadesInput = document.getElementById('responsabilidades_values');
|
||||
if (!responsabilidadesInput) {
|
||||
mostrarAlerta('Erro: Campo de responsabilidades não encontrado', 'danger');
|
||||
return;
|
||||
}
|
||||
|
||||
// Garantir que o campo de endereço está correto
|
||||
const logradouro = formData.get('logradouro');
|
||||
if (logradouro) {
|
||||
formData.set('rua', logradouro);
|
||||
formData.delete('logradouro');
|
||||
// Converter responsabilidades para array antes de enviar
|
||||
const responsabilidadesBits = parseInt(responsabilidadesInput.value) || 0;
|
||||
const responsabilidades = [];
|
||||
|
||||
// Converter bits para nomes de responsabilidades
|
||||
for (const [valor, nome] of Object.entries(RESPONSABILIDADES_REVERSE_MAP)) {
|
||||
if ((responsabilidadesBits & parseInt(valor)) === parseInt(valor)) {
|
||||
responsabilidades.push(nome);
|
||||
}
|
||||
}
|
||||
|
||||
// Substituir o valor numérico pelo array de responsabilidades
|
||||
formData.set('responsabilidades', JSON.stringify(responsabilidades));
|
||||
|
||||
// Log dos dados sendo enviados
|
||||
console.log('Dados do formulário:');
|
||||
for (let [key, value] of formData.entries()) {
|
||||
console.log(`${key}: ${value}`);
|
||||
}
|
||||
|
||||
// Obter o ID do militante
|
||||
const militanteId = document.getElementById('edit_militante_id').value;
|
||||
if (!militanteId) {
|
||||
mostrarAlerta('Erro: ID do militante não encontrado', 'danger');
|
||||
return;
|
||||
}
|
||||
|
||||
// Enviar dados para o servidor
|
||||
fetch(`/militantes/editar/${militanteId}`, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'X-CSRFToken': csrfToken
|
||||
},
|
||||
credentials: 'same-origin'
|
||||
body: formData
|
||||
})
|
||||
.then(response => {
|
||||
console.log('Resposta recebida:', response);
|
||||
if (!response.ok) {
|
||||
return response.json().then(data => {
|
||||
throw new Error(data.message || `HTTP error! status: ${response.status}`);
|
||||
return response.text().then(text => {
|
||||
try {
|
||||
const jsonResponse = JSON.parse(text);
|
||||
return jsonResponse;
|
||||
} catch (e) {
|
||||
console.error('Erro ao fazer parse do JSON:', e);
|
||||
console.log('Texto recebido:', text);
|
||||
throw new Error('Erro ao processar resposta do servidor');
|
||||
}
|
||||
});
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
console.log('Resposta processada:', data);
|
||||
if (data.status === 'success') {
|
||||
console.log('Resposta do servidor:', data);
|
||||
if (data.success) {
|
||||
mostrarAlerta('Militante atualizado com sucesso!', 'success');
|
||||
|
||||
// Fechar o modal
|
||||
bootstrap.Modal.getInstance(modalEditarMilitante).hide();
|
||||
const modal = bootstrap.Modal.getInstance(document.getElementById('modalEditarMilitante'));
|
||||
if (modal) {
|
||||
modal.hide();
|
||||
} else {
|
||||
console.warn('Modal não encontrado');
|
||||
}
|
||||
|
||||
// Mostrar mensagem de sucesso
|
||||
mostrarAlerta(data.message, 'success');
|
||||
|
||||
// Recarregar a página após um breve delay
|
||||
setTimeout(() => {
|
||||
location.reload();
|
||||
}, 1500);
|
||||
// Recarregar a página após 1 segundo
|
||||
setTimeout(() => window.location.reload(), 1000);
|
||||
} else {
|
||||
throw new Error(data.message || 'Erro ao salvar dados');
|
||||
throw new Error(data.message || 'Erro ao atualizar militante');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Erro ao enviar formulário:', error);
|
||||
mostrarAlerta(`Erro ao salvar dados: ${error.message}`, 'danger');
|
||||
console.error('Erro:', error);
|
||||
mostrarAlerta(error.message || 'Erro ao atualizar militante', 'danger');
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -535,13 +683,37 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
console.error('Modal de edição não encontrado!');
|
||||
}
|
||||
|
||||
// Envio do formulário via AJAX
|
||||
// Ajustar o formulário de novo militante
|
||||
const formNovoMilitante = document.getElementById('formNovoMilitante');
|
||||
if (formNovoMilitante) {
|
||||
formNovoMilitante.addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Os campos de data já estarão no formato ISO, não precisa converter
|
||||
// Validar todas as datas antes do envio
|
||||
const camposData = this.querySelectorAll('.date-mask');
|
||||
let datasValidas = true;
|
||||
|
||||
camposData.forEach(campo => {
|
||||
const valor = campo.value;
|
||||
if (valor && !validarData(valor)) {
|
||||
datasValidas = false;
|
||||
$(campo).addClass('is-invalid');
|
||||
if (!$(campo).next('.invalid-feedback').length) {
|
||||
$(campo).after('<div class="invalid-feedback">Data inválida</div>');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!datasValidas) {
|
||||
return; // Não envia o formulário se houver datas inválidas
|
||||
}
|
||||
|
||||
// Converter datas para formato ISO antes do envio
|
||||
camposData.forEach(campo => {
|
||||
if (campo.value) {
|
||||
campo.value = converterDataParaISO(campo.value);
|
||||
}
|
||||
});
|
||||
|
||||
const formData = new FormData(this);
|
||||
|
||||
@@ -792,30 +964,82 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
});
|
||||
});
|
||||
|
||||
// Inicializar tooltips do Bootstrap
|
||||
const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
|
||||
tooltipTriggerList.map(function (tooltipTriggerEl) {
|
||||
return new bootstrap.Tooltip(tooltipTriggerEl, {
|
||||
placement: 'top',
|
||||
trigger: 'hover'
|
||||
});
|
||||
});
|
||||
|
||||
// Inicializar badges clicáveis
|
||||
initBadgeClickable();
|
||||
|
||||
// Inicializar paginação
|
||||
updateVisibleRows();
|
||||
updatePagination();
|
||||
});
|
||||
|
||||
// Função para mostrar alertas
|
||||
function mostrarAlerta(mensagem, tipo) {
|
||||
// Criar o elemento de alerta
|
||||
const alertDiv = document.createElement('div');
|
||||
alertDiv.className = `alert alert-${tipo} alert-dismissible fade show position-fixed top-0 start-50 translate-middle-x mt-3`;
|
||||
alertDiv.style.zIndex = '9999';
|
||||
alertDiv.innerHTML = `
|
||||
${mensagem}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
`;
|
||||
// Função para inicializar as badges clicáveis
|
||||
function initBadgeClickable() {
|
||||
const badges = document.querySelectorAll('.badge-clickable');
|
||||
const selectedValues = [];
|
||||
|
||||
// Adicionar o alerta ao corpo do documento
|
||||
document.body.appendChild(alertDiv);
|
||||
// Inicializar o array com os valores das badges que já estão ativas
|
||||
badges.forEach(badge => {
|
||||
if (badge.classList.contains('active')) {
|
||||
const value = parseInt(badge.getAttribute('data-value'));
|
||||
if (!selectedValues.includes(value)) {
|
||||
selectedValues.push(value);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Configurar o Bootstrap alert
|
||||
const bsAlert = new bootstrap.Alert(alertDiv);
|
||||
// Atualizar o input hidden com o valor total inicial
|
||||
const totalValue = selectedValues.reduce((a, b) => a + b, 0);
|
||||
document.getElementById('responsabilidades_values').value = totalValue;
|
||||
|
||||
// Remover o alerta após 3 segundos
|
||||
setTimeout(() => {
|
||||
bsAlert.close();
|
||||
}, 3000);
|
||||
}
|
||||
// Adicionar evento de clique para cada badge
|
||||
badges.forEach(badge => {
|
||||
badge.addEventListener('click', function() {
|
||||
const value = parseInt(this.getAttribute('data-value'));
|
||||
const originalClass = this.getAttribute('data-original-class');
|
||||
|
||||
// Toggle do estado ativo
|
||||
if (this.classList.contains('active')) {
|
||||
// Desativar badge
|
||||
this.classList.remove('active');
|
||||
originalClass.split(' ').forEach(cls => {
|
||||
this.classList.remove(cls);
|
||||
});
|
||||
this.classList.add('bg-light');
|
||||
|
||||
// Remover valor do array
|
||||
const index = selectedValues.indexOf(value);
|
||||
if (index > -1) {
|
||||
selectedValues.splice(index, 1);
|
||||
}
|
||||
} else {
|
||||
// Ativar badge
|
||||
this.classList.add('active');
|
||||
this.classList.remove('bg-light');
|
||||
originalClass.split(' ').forEach(cls => {
|
||||
this.classList.add(cls);
|
||||
});
|
||||
|
||||
// Adicionar valor ao array
|
||||
if (!selectedValues.includes(value)) {
|
||||
selectedValues.push(value);
|
||||
}
|
||||
}
|
||||
|
||||
// Atualizar o input hidden com o novo valor total
|
||||
const newTotal = selectedValues.reduce((a, b) => a + b, 0);
|
||||
document.getElementById('responsabilidades_values').value = newTotal;
|
||||
|
||||
console.log('Valores selecionados:', selectedValues);
|
||||
console.log('Valor total:', newTotal);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user