2026-03-09 18:46:01 +00:00
{% extends "base.html" %}
{% block title %}Gerenciar Permissões - SGMP{% endblock %}
{% block css %}
< style >
feat(sgmp): API REST, app Next.js, ConfiguracaoSGMP e ajustes de permissões/serviços
- API JSON (auth, dashboard, colaboradores, solicitações) e app Next em frontend/
- Modelo ConfiguracaoSGMP, migrações e permissões (acesso, decorators, context)
- Serviços/views/templates e integrações Winthor/SQL Server
- Docs: MIGRACAO, ARQUITETURA_APROVACAO, README_PERMISSOES; Dockerfile/requirements
- Testes: fluxo de desligamento alinhado a pareceres GG/Ctrl + Diretoria; criar_solicitacao_desligamento com tipo/aviso
Made-with: Cursor
2026-04-15 01:44:49 +00:00
.perfil-ADMIN { background: #f3e8ff; color: #6b21a8; }
2026-03-09 18:46:01 +00:00
.perfil-GESTOR { background: #dbeafe; color: #1e40af; }
.perfil-HEAD { background: #e0e7ff; color: #3730a3; }
.perfil-GG { background: #d1fae5; color: #065f46; }
.perfil-CONTROLADORIA { background: #fef3c7; color: #92400e; }
.perfil-DIRETORIA { background: #fce7f3; color: #9f1239; }
.ativo-badge.ativo { background: #d1fae5; color: #065f46; }
.ativo-badge.inativo { background: #fee2e2; color: #991b1b; }
< / style >
{% endblock %}
{% block content %}
< div class = "mb-8" >
< h1 class = "text-2xl font-bold text-slate-800 mb-2" > Gerenciar Permissões< / h1 >
< p class = "text-slate-500 text-sm" > Gerencie os perfis e permissões dos usuários do sistema< / p >
< / div >
{% if messages %}
< div class = "mb-5" >
< ul class = "list-none p-0 m-0" >
{% for message in messages %}
< li class = "py-3 px-4 mb-2 rounded-lg border {% if message.tags == 'error' %}bg-red-50 text-red-800 border-red-200{% else %}bg-emerald-50 text-emerald-800 border-emerald-200{% endif %}" > {{ message }}< / li >
{% endfor %}
< / ul >
< / div >
{% endif %}
< div class = "bg-blue-50 border border-blue-200 rounded-lg p-4 mb-5 text-blue-800" >
< strong class = "block mb-1" > Seu Perfil Atual:< / strong >
< span class = "perfil-badge inline-block py-1 px-3 rounded-xl text-xs font-semibold perfil-{{ usuario_sistema.perfil }}" > {{ usuario_sistema.get_perfil_display }}< / span >
< p class = "mt-2 text-sm" > Você pode alterar seu próprio perfil e o de outros usuários abaixo.< / p >
< / div >
< div class = "bg-white p-5 rounded-lg shadow border border-slate-200 mb-5" >
< form method = "get" class = "flex flex-wrap gap-3" >
< input type = "text" name = "q" value = "{{ busca }}" placeholder = "Buscar por nome ou matrícula..." class = "flex-1 min-w-[200px] py-2.5 px-3 border border-slate-200 rounded-md text-base focus:outline-none focus:border-primary focus:ring-2 focus:ring-primary/20" >
< button type = "submit" class = "py-2.5 px-5 bg-primary text-white border-0 rounded-md font-semibold cursor-pointer hover:bg-primary-hover transition-colors" > Buscar< / button >
{% if busca %}< a href = "{% url 'solicitacoes:gerenciar_permissoes' %}" class = "py-2.5 px-5 bg-slate-500 text-white no-underline rounded-md inline-block hover:bg-slate-600 transition-colors" > Limpar< / a > {% endif %}
< / form >
< / div >
< div class = "bg-white rounded-lg shadow border border-slate-200 overflow-hidden" >
< table class = "w-full border-collapse" >
< thead >
< tr >
< th class = "p-3 text-left border-b border-slate-200 bg-slate-50 font-semibold text-slate-600" > Matrícula< / th >
< th class = "p-3 text-left border-b border-slate-200 bg-slate-50 font-semibold text-slate-600" > Nome< / th >
< th class = "p-3 text-left border-b border-slate-200 bg-slate-50 font-semibold text-slate-600" > Perfil Atual< / th >
< th class = "p-3 text-left border-b border-slate-200 bg-slate-50 font-semibold text-slate-600" > Status< / th >
< th class = "p-3 text-left border-b border-slate-200 bg-slate-50 font-semibold text-slate-600" > Alterar Perfil< / th >
< th class = "p-3 text-left border-b border-slate-200 bg-slate-50 font-semibold text-slate-600" > Head em relação a (gestores)< / th >
< / tr >
< / thead >
< tbody >
{% for item in usuarios_com_gestores %}
{% with usuario=item.usuario gestores_com_selecao=item.gestores_com_selecao %}
< tr class = "hover:bg-slate-50 border-b border-slate-200 last:border-b-0" >
< td class = "p-3 text-slate-800" > {{ usuario.matricula }}< / td >
< td class = "p-3 text-slate-800" >
{{ usuario.nome }}
{% if usuario.id == usuario_sistema.id %}< strong class = "text-primary" > (Você)< / strong > {% endif %}
< / td >
< td class = "p-3" >
< span class = "perfil-badge inline-block py-1 px-3 rounded-xl text-xs font-semibold perfil-{{ usuario.perfil }}" > {{ usuario.get_perfil_display }}< / span >
< / td >
< td class = "p-3" >
< span class = "ativo-badge inline-block py-1 px-2 rounded-lg text-[11px] font-semibold {% if usuario.ativo %}ativo{% else %}inativo{% endif %}" > {% if usuario.ativo %}Ativo{% else %}Inativo{% endif %}< / span >
< / td >
< td class = "p-3" >
< form method = "post" class = "flex flex-col gap-2" >
{% csrf_token %}
< input type = "hidden" name = "usuario_id" value = "{{ usuario.id }}" >
< div class = "flex flex-wrap gap-2 items-center" >
< select name = "perfil" required class = "py-1.5 px-2.5 border border-slate-200 rounded-md text-sm focus:outline-none focus:border-primary" >
{% for valor, label in perfis %}
< option value = "{{ valor }}" { % if usuario . perfil = = valor % } selected { % endif % } > {{ label }}< / option >
{% endfor %}
< / select >
< button type = "submit" class = "py-1.5 px-3 bg-primary text-white border-0 rounded-md text-sm font-semibold cursor-pointer hover:bg-primary-hover" > Atualizar< / button >
< / div >
< div class = "flex flex-wrap gap-2 text-xs text-slate-600" >
< span class = "font-semibold mr-1" > Perfis adicionais:< / span >
{% for valor, label in perfis %}
{% if valor != usuario.perfil %}
< label class = "inline-flex items-center gap-1" >
< input type = "checkbox"
name="perfis_extras"
value="{{ valor }}"
class="w-3.5 h-3.5 accent-primary"
{% if valor in item.perfis_extras %}checked{% endif %}>
< span > {{ label }}< / span >
< / label >
{% endif %}
{% endfor %}
< / div >
< / form >
< / td >
< td class = "p-3" >
{% if usuario.perfil == 'HEAD' %}
< div class = "mt-2 p-3 bg-slate-50 rounded-md border border-slate-200" >
< form method = "post" >
{% csrf_token %}
< input type = "hidden" name = "gestores_head_id" value = "{{ usuario.id }}" >
< label for = "gestores-{{ usuario.id }}" class = "block text-sm text-slate-500 mb-1.5" > Este Head aprova solicitações dos gestores:< / label >
< select id = "gestores-{{ usuario.id }}" name = "gestores_ids" multiple class = "min-w-[200px] min-h-[80px] py-1.5 px-2 border border-slate-200 rounded-md text-sm focus:outline-none focus:border-primary" >
{% for g, selected in gestores_com_selecao %}
< option value = "{{ g.id }}" { % if selected % } selected { % endif % } > {{ g.nome }} ({{ g.matricula }})< / option >
{% endfor %}
< / select >
< button type = "submit" class = "mt-2 py-1.5 px-3 bg-indigo-600 text-white border-0 rounded-md text-sm font-semibold cursor-pointer hover:bg-indigo-700" > Salvar gestores< / button >
< / form >
< / div >
{% else %}—{% endif %}
< / td >
< / tr >
{% endwith %}
{% empty %}
< tr >
< td colspan = "6" class = "text-center py-10 text-slate-500" > Nenhum usuário encontrado.< / td >
< / tr >
{% endfor %}
< / tbody >
< / table >
< / div >
{% if usuarios.has_other_pages %}
< div class = "mt-5 flex items-center justify-center gap-2 flex-wrap" >
{% if usuarios.has_previous %}
< a href = "?page=1{% if busca %}&q={{ busca }}{% endif %}" class = "py-2 px-3 no-underline border border-slate-200 rounded-md text-slate-600 bg-white hover:bg-slate-50 hover:border-primary transition-colors" > « Primeira< / a >
< a href = "?page={{ usuarios.previous_page_number }}{% if busca %}&q={{ busca }}{% endif %}" class = "py-2 px-3 no-underline border border-slate-200 rounded-md text-slate-600 bg-white hover:bg-slate-50 hover:border-primary transition-colors" > ‹ Anterior< / a >
{% endif %}
< span class = "py-2 px-3 bg-primary text-white rounded-md" > Página {{ usuarios.number }} de {{ usuarios.paginator.num_pages }}< / span >
{% if usuarios.has_next %}
< a href = "?page={{ usuarios.next_page_number }}{% if busca %}&q={{ busca }}{% endif %}" class = "py-2 px-3 no-underline border border-slate-200 rounded-md text-slate-600 bg-white hover:bg-slate-50 hover:border-primary transition-colors" > Próxima › < / a >
< a href = "?page={{ usuarios.paginator.num_pages }}{% if busca %}&q={{ busca }}{% endif %}" class = "py-2 px-3 no-underline border border-slate-200 rounded-md text-slate-600 bg-white hover:bg-slate-50 hover:border-primary transition-colors" > Última »< / a >
{% endif %}
< / div >
{% endif %}
< div class = "mt-8 p-4 bg-slate-50 rounded-lg border-l-4 border-primary" >
< strong > 💡 Dica:< / strong > Você também pode gerenciar permissões pelo < a href = "/admin/solicitacoes/usuariosistema/" class = "text-primary font-semibold hover:underline" > painel administrativo< / a > .
< / div >
{% endblock %}