284 lines
9.1 KiB
HTML
284 lines
9.1 KiB
HTML
{% extends 'base.html' %}
|
|
|
|
{% block title %}Assinaturas{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container">
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<h2><i class="fas fa-newspaper me-2"></i>Assinaturas</h2>
|
|
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modalNovaAssinatura">
|
|
<i class="fas fa-plus me-2"></i>Nova Assinatura
|
|
</button>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-body p-0">
|
|
{% if assinaturas %}
|
|
<div class="table-responsive">
|
|
<table class="table table-hover">
|
|
<thead>
|
|
<tr>
|
|
<th>Militante</th>
|
|
<th>Data Início</th>
|
|
<th>Data Fim</th>
|
|
<th>Status</th>
|
|
<th>Valor</th>
|
|
<th>Ações</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for assinatura in assinaturas %}
|
|
<tr>
|
|
<td>{{ assinatura.militante.nome }}</td>
|
|
<td>{{ assinatura.data_inicio.strftime('%d/%m/%Y') }}</td>
|
|
<td>{{ assinatura.data_fim.strftime('%d/%m/%Y') }}</td>
|
|
<td>
|
|
{% if assinatura.ativa %}
|
|
<span class="badge bg-success">Ativa</span>
|
|
{% else %}
|
|
<span class="badge bg-danger">Inativa</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>R$ {{ "%.2f"|format(assinatura.valor) }}</td>
|
|
<td>
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-sm btn-outline-primary"
|
|
onclick="editarAssinatura({{ assinatura.id }})">
|
|
<i class="fas fa-edit"></i>
|
|
</button>
|
|
<button type="button" class="btn btn-sm btn-outline-danger"
|
|
onclick="confirmarExclusao({{ assinatura.id }})">
|
|
<i class="fas fa-trash"></i>
|
|
</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% else %}
|
|
<div class="text-center py-4">
|
|
<p class="text-muted mb-0">Nenhuma assinatura encontrada.</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal Nova Assinatura -->
|
|
<div class="modal fade" id="modalNovaAssinatura" tabindex="-1">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Nova Assinatura</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form id="formNovaAssinatura">
|
|
<div class="mb-3">
|
|
<label for="militante" class="form-label">Militante</label>
|
|
<select class="form-select" id="militante" name="militante_id" required>
|
|
<option value="">Selecione um militante</option>
|
|
{% for militante in militantes %}
|
|
<option value="{{ militante.id }}">{{ militante.nome }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="dataInicio" class="form-label">Data de Início</label>
|
|
<input type="date" class="form-control" id="dataInicio" name="data_inicio" required>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="dataFim" class="form-label">Data de Fim</label>
|
|
<input type="date" class="form-control" id="dataFim" name="data_fim" required>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="valor" class="form-label">Valor</label>
|
|
<div class="input-group">
|
|
<span class="input-group-text">R$</span>
|
|
<input type="number" step="0.01" class="form-control" id="valor" name="valor" required>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancelar</button>
|
|
<button type="submit" form="formNovaAssinatura" class="btn btn-primary">Salvar</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal de Confirmação de Exclusão -->
|
|
<div class="modal fade" id="modalConfirmarExclusao" tabindex="-1">
|
|
<div class="modal-dialog">
|
|
<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 esta assinatura?</p>
|
|
<p class="text-danger mb-0"><small>Esta ação não pode ser desfeita.</small></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" onclick="excluirAssinatura()">Excluir</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
let assinaturaIdParaExcluir = null;
|
|
|
|
function editarAssinatura(id) {
|
|
// Implementar edição
|
|
}
|
|
|
|
function confirmarExclusao(id) {
|
|
assinaturaIdParaExcluir = id;
|
|
new bootstrap.Modal(document.getElementById('modalConfirmarExclusao')).show();
|
|
}
|
|
|
|
function excluirAssinatura() {
|
|
if (!assinaturaIdParaExcluir) return;
|
|
|
|
fetch(`/assinaturas/excluir/${assinaturaIdParaExcluir}`, {
|
|
method: 'POST'
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
location.reload();
|
|
} else {
|
|
alert('Erro ao excluir assinatura: ' + data.message);
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Erro:', error);
|
|
alert('Erro ao excluir assinatura');
|
|
});
|
|
}
|
|
|
|
document.getElementById('formNovaAssinatura').addEventListener('submit', function(e) {
|
|
e.preventDefault();
|
|
|
|
const formData = new FormData(this);
|
|
|
|
fetch('/assinaturas/novo', {
|
|
method: 'POST',
|
|
body: formData
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
location.reload();
|
|
} else {
|
|
alert('Erro ao criar assinatura: ' + data.message);
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Erro:', error);
|
|
alert('Erro ao criar assinatura');
|
|
});
|
|
});
|
|
</script>
|
|
{% endblock %}
|
|
|
|
{% block extra_css %}
|
|
<style>
|
|
/* Estilo para colunas ordenáveis */
|
|
th[data-sort] {
|
|
cursor: pointer;
|
|
user-select: none;
|
|
}
|
|
|
|
th[data-sort] i {
|
|
margin-left: 5px;
|
|
color: #ccc;
|
|
}
|
|
|
|
th[data-sort].sort-asc i,
|
|
th[data-sort].sort-desc i {
|
|
color: var(--primary-color);
|
|
}
|
|
|
|
/* Animação para linhas da tabela */
|
|
#assinaturasTable tbody tr {
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
#assinaturasTable tbody tr:hover {
|
|
background-color: rgba(0,0,0,0.02);
|
|
transform: translateX(5px);
|
|
}
|
|
|
|
/* Estilo para botões de ação */
|
|
.btn-group .btn {
|
|
padding: 0.25rem 0.5rem;
|
|
}
|
|
|
|
.btn-group .btn i {
|
|
width: 16px;
|
|
text-align: center;
|
|
}
|
|
|
|
/* Responsividade */
|
|
@media (max-width: 768px) {
|
|
.btn-group {
|
|
display: flex;
|
|
margin-top: 1rem;
|
|
}
|
|
|
|
.btn-group .btn {
|
|
flex: 1;
|
|
}
|
|
}
|
|
|
|
/* Estilo para o backdrop com blur em todos os modais */
|
|
.modal-backdrop.show {
|
|
backdrop-filter: blur(8px);
|
|
background-color: rgba(0, 0, 0, 0.7);
|
|
}
|
|
|
|
/* Estilo para o botão de fechar dos modais */
|
|
.btn-close {
|
|
background-color: transparent;
|
|
padding: 0.5rem;
|
|
opacity: 0.8;
|
|
transition: opacity 0.2s;
|
|
filter: invert(1) grayscale(100%) brightness(200%);
|
|
}
|
|
|
|
.btn-close:hover {
|
|
opacity: 1;
|
|
background-color: transparent;
|
|
}
|
|
|
|
/* Estilo para modais */
|
|
.modal-content {
|
|
border: none;
|
|
border-radius: 12px;
|
|
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.modal-header {
|
|
background: linear-gradient(to right, var(--bs-gray-dark), var(--bs-gray));
|
|
color: white;
|
|
border-radius: 12px 12px 0 0;
|
|
border-bottom: none;
|
|
padding: 1rem;
|
|
}
|
|
|
|
.modal-body {
|
|
padding: 1.5rem;
|
|
}
|
|
|
|
.modal-footer {
|
|
border-top: 1px solid #eee;
|
|
padding: 1rem;
|
|
}
|
|
</style>
|
|
{% endblock %} |