354 lines
14 KiB
HTML
354 lines
14 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Home{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="row g-4">
|
|
<div class="col-12">
|
|
<div class="welcome-header">
|
|
<h2 class="mb-2">Olá, {{ nome_usuario }}!</h2>
|
|
<h4 class="text-muted">
|
|
{{ data_atual }}
|
|
</h4>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Cards de Estatísticas -->
|
|
<div class="col-md-6 col-lg-3">
|
|
<div class="stats-card blue">
|
|
<div class="title">Total de Militantes</div>
|
|
<div class="value">{{ total_militantes }}</div>
|
|
<a href="{{ url_for('listar_militantes') }}" class="link">
|
|
Ver detalhes <i class="fas fa-arrow-right"></i>
|
|
</a>
|
|
<div class="icon">
|
|
<i class="fas fa-users"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-6 col-lg-3">
|
|
<div class="stats-card green">
|
|
<div class="title">Total de Cotas</div>
|
|
<div class="value">R$ {{ total_cotas }}</div>
|
|
<a href="{{ url_for('listar_cotas') }}" class="link">
|
|
Ver detalhes <i class="fas fa-arrow-right"></i>
|
|
</a>
|
|
<div class="icon">
|
|
<i class="fas fa-dollar-sign"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-6 col-lg-3">
|
|
<div class="stats-card cyan">
|
|
<div class="title">Materiais Vendidos</div>
|
|
<div class="value">{{ total_materiais }}</div>
|
|
<a href="{{ url_for('listar_materiais') }}" class="link">
|
|
Ver detalhes <i class="fas fa-arrow-right"></i>
|
|
</a>
|
|
<div class="icon">
|
|
<i class="fas fa-book"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-6 col-lg-3">
|
|
<div class="stats-card yellow">
|
|
<div class="title">Assinaturas Ativas</div>
|
|
<div class="value">{{ total_assinaturas }}</div>
|
|
<a href="{{ url_for('listar_assinaturas') }}" class="link">
|
|
Ver detalhes <i class="fas fa-arrow-right"></i>
|
|
</a>
|
|
<div class="icon">
|
|
<i class="fas fa-newspaper"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mt-4">
|
|
<!-- Últimos Militantes -->
|
|
<div class="col-md-6 mb-4">
|
|
<div class="card h-100">
|
|
<div class="card-header">
|
|
<h5 class="card-title">
|
|
<i class="fas fa-user-plus"></i>Últimos Militantes Cadastrados
|
|
</h5>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
{% if ultimos_militantes %}
|
|
<div class="list-group list-group-flush">
|
|
{% for militante in ultimos_militantes %}
|
|
<div class="list-group-item" onclick="window.location='{{ url_for('editar_militante', id=militante.id) }}'">
|
|
<div class="militante-info">
|
|
<h6 class="mb-1">{{ militante.nome }}</h6>
|
|
<small>{{ militante.email }}</small>
|
|
</div>
|
|
<i class="fas fa-chevron-right text-muted"></i>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% else %}
|
|
<p class="text-muted m-3">Nenhum militante cadastrado recentemente.</p>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Últimos Pagamentos -->
|
|
<div class="col-md-6 mb-4">
|
|
<div class="card h-100">
|
|
<div class="card-header">
|
|
<h5 class="card-title">
|
|
<i class="fas fa-money-bill-wave"></i>Últimos Pagamentos
|
|
</h5>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
{% if ultimos_pagamentos %}
|
|
<div class="list-group list-group-flush">
|
|
{% for pagamento in ultimos_pagamentos %}
|
|
<div class="list-group-item" onclick="window.location='{{ url_for('editar_pagamento', id=pagamento.id) }}'">
|
|
<div class="militante-info">
|
|
<h6 class="mb-1">{{ pagamento.militante.nome }}</h6>
|
|
<small>{{ pagamento.data_pagamento.strftime('%d/%m/%Y') }}</small>
|
|
</div>
|
|
<span class="badge bg-success">R$ {{ "%.2f"|format(pagamento.valor) }}</span>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% else %}
|
|
<p class="text-muted m-3">Nenhum pagamento registrado recentemente.</p>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal de Detalhes do Militante -->
|
|
<div class="modal fade" id="militanteModal" tabindex="-1">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">
|
|
<i class="fas fa-user me-2"></i>Detalhes do Militante
|
|
</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fechar"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="mb-3">
|
|
<label class="fw-bold">Nome:</label>
|
|
<p id="militanteNome" class="mb-2"></p>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="fw-bold">CPF:</label>
|
|
<p id="militanteCPF" class="mb-2"></p>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="fw-bold">Email:</label>
|
|
<p id="militanteEmail" class="mb-2"></p>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="fw-bold">Telefone:</label>
|
|
<p id="militanteTelefone" class="mb-2"></p>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="fw-bold">Endereço:</label>
|
|
<p id="militanteEndereco" class="mb-2"></p>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="fw-bold">Status:</label>
|
|
<p id="militanteFiliado" class="mb-2"></p>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modalEditarMilitante">
|
|
<i class="fas fa-edit me-2"></i>Editar
|
|
</button>
|
|
<button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#deleteModal">
|
|
<i class="fas fa-trash me-2"></i>Excluir
|
|
</button>
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancelar</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal de Edição -->
|
|
<div class="modal fade" id="modalEditarMilitante" tabindex="-1">
|
|
<div class="modal-dialog modal-lg modal-dialog-centered">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">
|
|
<i class="fas fa-user-edit me-2"></i>Editar Militante
|
|
</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form id="formEditarMilitante" method="post">
|
|
<div class="row">
|
|
<div class="col-md-6 mb-3">
|
|
<label for="editNome" class="form-label">Nome:</label>
|
|
<input type="text" class="form-control" id="editNome" name="nome" required>
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label for="editCpf" class="form-label">CPF:</label>
|
|
<input type="text" class="form-control" id="editCpf" name="cpf" required>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-6 mb-3">
|
|
<label for="editEmail" class="form-label">Email:</label>
|
|
<input type="email" class="form-control" id="editEmail" name="email" required>
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label for="editTelefone" class="form-label">Telefone:</label>
|
|
<input type="text" class="form-control" id="editTelefone" name="telefone">
|
|
</div>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="editEndereco" class="form-label">Endereço:</label>
|
|
<input type="text" class="form-control" id="editEndereco" name="endereco">
|
|
</div>
|
|
<div class="mb-3 form-check">
|
|
<input type="checkbox" class="form-check-input" id="editFiliado" name="filiado">
|
|
<label class="form-check-label" for="editFiliado">Filiado</label>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancelar</button>
|
|
<button type="submit" form="formEditarMilitante" class="btn btn-success">
|
|
<i class="fas fa-save me-2"></i>Salvar
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal de Exclusão -->
|
|
<div class="modal fade" id="deleteModal" tabindex="-1">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Confirmar Exclusão</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p>Tem certeza que deseja excluir este militante?</p>
|
|
<p class="text-danger">Esta ação não pode ser desfeita.</p>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancelar</button>
|
|
<button type="button" class="btn btn-danger" id="confirmDelete">
|
|
<i class="fas fa-trash me-2"></i>Excluir
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
<script>
|
|
// Função para formatar CPF
|
|
function formatCPF(cpf) {
|
|
return cpf.replace(/(\d{3})(\d{3})(\d{3})(\d{2})/, "$1.$2.$3-$4");
|
|
}
|
|
|
|
// Função para formatar telefone
|
|
function formatPhone(phone) {
|
|
return phone.replace(/(\d{2})(\d{5})(\d{4})/, "($1) $2-$3");
|
|
}
|
|
|
|
// Função para carregar detalhes do militante
|
|
function loadMilitanteDetails(id) {
|
|
fetch(`/api/militante/${id}`)
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
document.getElementById('militanteNome').textContent = data.nome;
|
|
document.getElementById('militanteCPF').textContent = formatCPF(data.cpf);
|
|
document.getElementById('militanteEmail').textContent = data.email;
|
|
document.getElementById('militanteTelefone').textContent = formatPhone(data.telefone);
|
|
document.getElementById('militanteEndereco').textContent = data.endereco;
|
|
document.getElementById('militanteFiliado').textContent = data.filiado ? 'Filiado' : 'Não Filiado';
|
|
|
|
// Preencher formulário de edição
|
|
document.getElementById('editNome').value = data.nome;
|
|
document.getElementById('editCpf').value = data.cpf;
|
|
document.getElementById('editEmail').value = data.email;
|
|
document.getElementById('editTelefone').value = data.telefone;
|
|
document.getElementById('editEndereco').value = data.endereco;
|
|
document.getElementById('editFiliado').checked = data.filiado;
|
|
});
|
|
}
|
|
|
|
// Função para excluir militante
|
|
function deleteMilitante(id) {
|
|
fetch(`/api/militante/${id}`, {
|
|
method: 'DELETE',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
}
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
window.location.reload();
|
|
} else {
|
|
alert('Erro ao excluir militante: ' + data.message);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Event listeners
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Máscara para CPF
|
|
const cpfInput = document.getElementById('editCpf');
|
|
cpfInput.addEventListener('input', function(e) {
|
|
let value = e.target.value.replace(/\D/g, '');
|
|
if (value.length > 11) value = value.slice(0, 11);
|
|
e.target.value = formatCPF(value);
|
|
});
|
|
|
|
// Máscara para telefone
|
|
const phoneInput = document.getElementById('editTelefone');
|
|
phoneInput.addEventListener('input', function(e) {
|
|
let value = e.target.value.replace(/\D/g, '');
|
|
if (value.length > 11) value = value.slice(0, 11);
|
|
e.target.value = formatPhone(value);
|
|
});
|
|
|
|
// Submit do formulário de edição
|
|
const formEditar = document.getElementById('formEditarMilitante');
|
|
formEditar.addEventListener('submit', function(e) {
|
|
e.preventDefault();
|
|
const formData = new FormData(formEditar);
|
|
const data = Object.fromEntries(formData.entries());
|
|
|
|
fetch('/api/militante/' + data.id, {
|
|
method: 'PUT',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify(data)
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
window.location.reload();
|
|
} else {
|
|
alert('Erro ao editar militante: ' + data.message);
|
|
}
|
|
});
|
|
});
|
|
|
|
// Confirmação de exclusão
|
|
const confirmDelete = document.getElementById('confirmDelete');
|
|
confirmDelete.addEventListener('click', function() {
|
|
const id = this.dataset.militanteId;
|
|
deleteMilitante(id);
|
|
});
|
|
});
|
|
</script>
|
|
{% endblock %} |