diff --git a/app.py b/app.py index 1021cdf..de22e58 100644 --- a/app.py +++ b/app.py @@ -50,6 +50,7 @@ import random import string from sqlalchemy.sql import func from flask_wtf.csrf import CSRFProtect +import json load_dotenv() @@ -425,7 +426,7 @@ def criar_militante(): def listar_militantes(): db = get_db_connection() try: - militantes = db.query(Militante).all() + militantes = db.query(Militante).order_by(Militante.nome).all() celulas = db.query(Celula).order_by(Celula.nome).all() return render_template('listar_militantes.html', militantes=militantes, Militante=Militante, celulas=celulas) finally: @@ -1051,13 +1052,22 @@ def editar_militante(militante_id): militante.celula_id = None # Tratar responsabilidades corretamente - responsabilidades = request.form.getlist('responsabilidades') - if responsabilidades: - try: - militante.responsabilidades = sum(int(r) for r in responsabilidades) - except (ValueError, TypeError): + try: + responsabilidades_json = request.form.get('responsabilidades') + if responsabilidades_json: + responsabilidades_lista = json.loads(responsabilidades_json) + valor_responsabilidades = 0 + if 'Finanças' in responsabilidades_lista: + valor_responsabilidades |= Militante.RESPONSAVEL_FINANCAS + if 'Imprensa' in responsabilidades_lista: + valor_responsabilidades |= Militante.RESPONSAVEL_IMPRENSA + if 'Quadro-Orientador' in responsabilidades_lista: + valor_responsabilidades |= Militante.QUADRO_ORIENTADOR + militante.responsabilidades = valor_responsabilidades + else: militante.responsabilidades = 0 - else: + except (ValueError, TypeError, json.JSONDecodeError) as e: + print(f"Erro ao processar responsabilidades: {str(e)}") militante.responsabilidades = 0 print("Dados organizacionais atualizados") @@ -1555,54 +1565,43 @@ def excluir_assinatura(id): finally: db.close() -@app.route("/militantes//dados") +@app.route("/militantes/dados/") @require_login @require_permission('gerenciar_militantes') -def get_militante_dados(militante_id): - """Retorna os dados completos de um militante""" - print(f"Buscando dados do militante {militante_id}") +def buscar_dados_militante(militante_id): + """Retorna os dados de um militante""" db = get_db_connection() try: militante = db.query(Militante).options( joinedload(Militante.endereco), - joinedload(Militante.emails), - joinedload(Militante.celula) + joinedload(Militante.emails) ).get(militante_id) if not militante: - print(f"Militante {militante_id} não encontrado") return jsonify({ 'status': 'error', 'message': 'Militante não encontrado' }), 404 - print(f"Militante {militante_id} encontrado: {militante.nome}") + # Converter responsabilidades para lista de strings + responsabilidades = [] + if militante.responsabilidades & Militante.RESPONSAVEL_FINANCAS: + responsabilidades.append('Finanças') + if militante.responsabilidades & Militante.RESPONSAVEL_IMPRENSA: + responsabilidades.append('Imprensa') + if militante.responsabilidades & Militante.QUADRO_ORIENTADOR: + responsabilidades.append('Quadro-Orientador') - # Formatar datas para o formato YYYY-MM-DD - data_nascimento = militante.data_nascimento.strftime('%Y-%m-%d') if militante.data_nascimento else None - data_entrada = militante.data_entrada_oci.strftime('%Y-%m-%d') if militante.data_entrada_oci else None - data_efetivacao = militante.data_efetivacao_oci.strftime('%Y-%m-%d') if militante.data_efetivacao_oci else None - - # Buscar o primeiro email do militante - email_principal = None - if militante.emails and len(militante.emails) > 0: - email_principal = militante.emails[0].endereco_email - - dados = { - 'id': militante.id, + return jsonify({ 'nome': militante.nome, 'cpf': militante.cpf, 'titulo_eleitoral': militante.titulo_eleitoral, - 'data_nascimento': data_nascimento, - 'data_entrada_oci': data_entrada, - 'data_efetivacao_oci': data_efetivacao, - - # Contato + 'data_nascimento': militante.data_nascimento.strftime('%Y-%m-%d') if militante.data_nascimento else None, + 'data_entrada_oci': militante.data_entrada_oci.strftime('%Y-%m-%d') if militante.data_entrada_oci else None, + 'data_efetivacao_oci': militante.data_efetivacao_oci.strftime('%Y-%m-%d') if militante.data_efetivacao_oci else None, 'telefone1': militante.telefone1, 'telefone2': militante.telefone2, - 'email': email_principal, - - # Endereço + 'email': militante.emails[0].endereco_email if militante.emails else None, 'endereco': { 'cep': militante.endereco.cep if militante.endereco else None, 'estado': militante.endereco.estado if militante.endereco else None, @@ -1612,34 +1611,22 @@ def get_militante_dados(militante_id): 'numero': militante.endereco.numero if militante.endereco else None, 'complemento': militante.endereco.complemento if militante.endereco else None } if militante.endereco else None, - - # Profissional 'profissao': militante.profissao, 'regime_trabalho': militante.regime_trabalho, 'empresa': militante.empresa, 'contratante': militante.contratante, - - # Acadêmico 'instituicao_ensino': militante.instituicao_ensino, 'tipo_instituicao': militante.tipo_instituicao, - - # Sindical 'sindicato': militante.sindicato, 'cargo_sindical': militante.cargo_sindical, 'central_sindical': militante.central_sindical, 'dirigente_sindical': militante.dirigente_sindical, - - # Organização - 'estado': militante.estado.value if militante.estado else 'ATIVO', + 'estado': militante.estado.name if militante.estado else None, 'celula_id': militante.celula_id, - 'responsabilidades': militante.responsabilidades - } - - print(f"Dados formatados: {dados}") - return jsonify(dados) - + 'responsabilidades': responsabilidades + }) except Exception as e: - print(f"Erro ao buscar dados do militante {militante_id}: {str(e)}") + print(f"Erro ao buscar dados do militante: {str(e)}") return jsonify({ 'status': 'error', 'message': f'Erro ao buscar dados do militante: {str(e)}' diff --git a/static/css/components.css b/static/css/components.css index 8e57e30..739d3cf 100644 --- a/static/css/components.css +++ b/static/css/components.css @@ -45,7 +45,12 @@ } .table-hover tbody tr:hover { - background-color: var(--table-hover-bg); + background-color: var(--table-hover-bg) !important; + cursor: pointer; +} + +.table-hover tbody tr { + transition: all 0.3s ease; } /* Botões de ação */ @@ -125,8 +130,8 @@ /* Badges */ .badge { - padding: 0.5em 0.75em; font-weight: 500; + padding: 0.5em 0.8em; } .badge.bg-success { @@ -415,4 +420,25 @@ input[type="date"]:focus { border-color: var(--primary-color); box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25); +} + +/* 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 */ +#militantesTable tbody tr { + transition: all 0.3s ease; } \ No newline at end of file diff --git a/templates/modals/militante_editar.html b/templates/modals/militante_editar.html index 162acee..f5672ec 100644 --- a/templates/modals/militante_editar.html +++ b/templates/modals/militante_editar.html @@ -117,8 +117,8 @@
- - + +
@@ -212,10 +212,10 @@
@@ -228,24 +228,25 @@
+
- +
- +
- +