feat: implementa sistema de responsabilidades e instâncias - Adiciona responsabilidades de Finanças e Imprensa para todas as instâncias - Cria templates genéricos para gerenciamento de instâncias - Implementa sistema de permissões baseado em RBAC - Adiciona status de Aspirante com avaliação obrigatória - Atualiza documentação com novas regras e responsabilidades - Cria testes para validação das permissões - Adiciona migração para novos campos no banco de dados

This commit is contained in:
LS
2025-04-03 15:58:07 -03:00
parent 8dac8dc234
commit cbaf227e58
37 changed files with 4305 additions and 953 deletions

View File

@@ -22,6 +22,12 @@
<input type="text" class="form-control" id="nome" name="nome" required>
</div>
<div class="mb-3">
<label for="email" class="form-label">Email:</label>
<input type="email" class="form-control" id="email" name="email" required>
<small class="form-text text-muted">Este email será usado para login e comunicação do sistema</small>
</div>
<div class="mb-3">
<label for="cpf" class="form-label">CPF:</label>
<input type="text" class="form-control" id="cpf" name="cpf" required>
@@ -115,25 +121,67 @@
</div>
<div class="mb-3">
<label for="setor_id" class="form-label">Setor:</label>
<select class="form-select" id="setor_id" name="setor_id" required>
<option value="">Selecione o setor</option>
{% for setor in setores %}
<option value="{{ setor.id }}">{{ setor.nome }}</option>
<label for="cr_id" class="form-label">Comitê Regional:</label>
<select class="form-select" id="cr_id" name="cr_id" required>
<option value="">Selecione o CR</option>
{% for cr in crs %}
<option value="{{ cr.id }}">{{ cr.nome }}</option>
{% endfor %}
</select>
</div>
<div class="mb-3">
<label for="celula_id" class="form-label">Célula:</label>
<select class="form-select" id="celula_id" name="celula_id" required>
<option value="">Selecione a célula</option>
{% for celula in celulas %}
<option value="{{ celula.id }}">{{ celula.nome }}</option>
<label for="setor_id" class="form-label">Setor:</label>
<select class="form-select" id="setor_id" name="setor_id" required>
<option value="">Selecione o setor</option>
{% for setor in setores %}
<option value="{{ setor.id }}" data-cr="{{ setor.cr_id }}">{{ setor.nome }}</option>
{% endfor %}
</select>
</div>
<div class="mb-3">
<label class="form-label">Célula:</label>
{% if pode_criar_celula %}
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="radio" name="celula_opcao" id="celula_existente" value="existente" checked>
<label class="form-check-label" for="celula_existente">
Usar célula existente
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="celula_opcao" id="celula_nova" value="nova">
<label class="form-check-label" for="celula_nova">
Criar nova célula
</label>
</div>
</div>
{% endif %}
<div id="celula_existente_container">
<select class="form-select" id="celula_id" name="celula_id" required>
<option value="">Selecione a célula</option>
{% for celula in celulas %}
<option value="{{ celula.id }}" data-setor="{{ celula.setor_id }}">{{ celula.nome }}</option>
{% endfor %}
</select>
</div>
{% if pode_criar_celula %}
<div id="celula_nova_container" style="display: none;">
<div class="mb-3">
<label for="nova_celula_nome" class="form-label">Nome da Nova Célula:</label>
<input type="text" class="form-control" id="nova_celula_nome" name="nova_celula_nome">
</div>
<div class="mb-3">
<label for="nova_celula_quadro_orientador" class="form-label">Quadro Orientador:</label>
<input type="text" class="form-control" id="nova_celula_quadro_orientador" name="nova_celula_quadro_orientador">
</div>
</div>
{% endif %}
</div>
<div class="d-flex gap-2">
<button type="submit" class="btn btn-primary">Registrar</button>
<a href="{{ url_for('listar_militantes') }}" class="btn btn-secondary">Voltar</a>
@@ -143,5 +191,66 @@
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Função para atualizar as células baseado no setor selecionado
function atualizarCelulas() {
const setorId = document.getElementById('setor_id').value;
const celulaSelect = document.getElementById('celula_id');
// Limpar opções existentes
celulaSelect.innerHTML = '<option value="">Selecione a célula</option>';
// Adicionar apenas células do setor selecionado
document.querySelectorAll('#celula_id option').forEach(option => {
if (option.dataset.setor === setorId) {
celulaSelect.appendChild(option.cloneNode(true));
}
});
}
// Função para atualizar os setores baseado no CR selecionado
function atualizarSetores() {
const crId = document.getElementById('cr_id').value;
const setorSelect = document.getElementById('setor_id');
// Limpar opções existentes
setorSelect.innerHTML = '<option value="">Selecione o setor</option>';
// Adicionar apenas setores do CR selecionado
document.querySelectorAll('#setor_id option').forEach(option => {
if (option.dataset.cr === crId) {
setorSelect.appendChild(option.cloneNode(true));
}
});
// Atualizar células após mudar o setor
atualizarCelulas();
}
// Event listeners
document.getElementById('cr_id').addEventListener('change', atualizarSetores);
document.getElementById('setor_id').addEventListener('change', atualizarCelulas);
// Toggle entre célula existente e nova
const celulaExistente = document.getElementById('celula_existente');
const celulaNova = document.getElementById('celula_nova');
const celulaExistenteContainer = document.getElementById('celula_existente_container');
const celulaNovaContainer = document.getElementById('celula_nova_container');
if (celulaExistente && celulaNova) {
celulaExistente.addEventListener('change', function() {
celulaExistenteContainer.style.display = 'block';
celulaNovaContainer.style.display = 'none';
});
celulaNova.addEventListener('change', function() {
celulaExistenteContainer.style.display = 'none';
celulaNovaContainer.style.display = 'block';
});
}
});
</script>
{% endblock %}