Browse Source

Criação da tela de erro mais amigável

pull/3858/head
rangelbruno 11 months ago
parent
commit
37b1db6d7a
  1. 245
      sapl/templates/403.html
  2. 1
      sapl/templates/base.html
  3. 135
      sapl/templates/fluxo_proposicoes.html
  4. 7
      sapl/urls.py

245
sapl/templates/403.html

@ -0,0 +1,245 @@
{% extends "base.html" %}
{% load i18n %}
{% block head_title %}Acesso Negado - {{nome_casa}}{% endblock %}
{% block base_content %}
<style>
.error-container {
text-align: center;
padding: 60px 20px;
min-height: 60vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.error-icon {
font-size: 120px;
color: #e74c3c;
margin-bottom: 30px;
animation: shake 0.5s;
}
@keyframes shake {
0%, 100% { transform: translateX(0); }
25% { transform: translateX(-10px); }
75% { transform: translateX(10px); }
}
.error-code {
font-size: 72px;
font-weight: bold;
color: #34495e;
margin: 0;
line-height: 1;
}
.error-title {
font-size: 32px;
color: #2c3e50;
margin: 20px 0;
font-weight: 600;
}
.error-message {
font-size: 18px;
color: #7f8c8d;
max-width: 600px;
margin: 20px auto;
line-height: 1.6;
}
.error-details {
background: #ecf0f1;
border-left: 4px solid #e74c3c;
padding: 20px;
margin: 30px auto;
max-width: 700px;
border-radius: 5px;
text-align: left;
}
.error-details h4 {
color: #e74c3c;
margin-top: 0;
margin-bottom: 15px;
font-size: 20px;
}
.error-details ul {
margin: 15px 0;
padding-left: 25px;
}
.error-details li {
margin: 8px 0;
color: #2c3e50;
}
.error-actions {
margin-top: 40px;
display: flex;
gap: 15px;
justify-content: center;
flex-wrap: wrap;
}
.btn-error {
padding: 12px 30px;
font-size: 16px;
border-radius: 5px;
text-decoration: none;
transition: all 0.3s;
display: inline-flex;
align-items: center;
gap: 10px;
}
.btn-back {
background: #3498db;
color: white;
border: 2px solid #3498db;
}
.btn-back:hover {
background: #2980b9;
border-color: #2980b9;
color: white;
text-decoration: none;
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
.btn-home {
background: white;
color: #3498db;
border: 2px solid #3498db;
}
.btn-home:hover {
background: #3498db;
color: white;
text-decoration: none;
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
.btn-help {
background: white;
color: #95a5a6;
border: 2px solid #95a5a6;
}
.btn-help:hover {
background: #95a5a6;
color: white;
text-decoration: none;
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
.info-box {
background: #fff3cd;
border: 1px solid #ffc107;
border-radius: 5px;
padding: 15px;
margin: 20px auto;
max-width: 700px;
}
.info-box i {
color: #ffc107;
margin-right: 10px;
}
@media (max-width: 768px) {
.error-code {
font-size: 48px;
}
.error-title {
font-size: 24px;
}
.error-icon {
font-size: 80px;
}
.error-actions {
flex-direction: column;
align-items: center;
}
.btn-error {
width: 100%;
max-width: 300px;
justify-content: center;
}
}
</style>
<div class="error-container">
<div class="error-icon">
<i class="fas fa-ban"></i>
</div>
<h1 class="error-code">403</h1>
<h2 class="error-title">
<i class="fas fa-lock"></i> Acesso Negado
</h2>
<p class="error-message">
Desculpe, você não tem permissão para acessar esta página ou recurso.
</p>
<div class="error-details">
<h4><i class="fas fa-info-circle"></i> Por que estou vendo esta mensagem?</h4>
<p>Esta página requer permissões específicas que seu usuário não possui. Isso pode acontecer por diversos motivos:</p>
<ul>
<li><strong>Você não está logado</strong> - Faça login com suas credenciais</li>
<li><strong>Seu perfil não tem permissão</strong> - Entre em contato com o administrador do sistema</li>
<li><strong>A funcionalidade é restrita</strong> - Apenas alguns tipos de usuário podem acessar</li>
<li><strong>Sessão expirou</strong> - Tente fazer login novamente</li>
</ul>
</div>
{% if user.is_authenticated %}
<div class="info-box">
<i class="fas fa-user"></i>
<strong>Usuário:</strong> {{ user.username }}
{% if user.groups.all %}
| <strong>Grupos:</strong>
{% for group in user.groups.all %}
{{ group.name }}{% if not forloop.last %}, {% endif %}
{% endfor %}
{% endif %}
</div>
{% else %}
<div class="info-box">
<i class="fas fa-exclamation-triangle"></i>
<strong>Dica:</strong> Você não está logado. Faça login para acessar recursos restritos.
</div>
{% endif %}
<div class="error-actions">
<a href="javascript:history.back()" class="btn-error btn-back">
<i class="fas fa-arrow-left"></i> Voltar
</a>
<a href="/" class="btn-error btn-home">
<i class="fas fa-home"></i> Página Inicial
</a>
{% if not user.is_authenticated %}
<a href="/login/" class="btn-error btn-help">
<i class="fas fa-sign-in-alt"></i> Fazer Login
</a>
{% endif %}
</div>
<p style="margin-top: 40px; color: #95a5a6; font-size: 14px;">
Se você acredita que deveria ter acesso a esta página, entre em contato com o administrador do sistema.
</p>
</div>
{% endblock base_content %}

1
sapl/templates/base.html

@ -116,7 +116,6 @@
<img src="{% if logotipo %}{{ MEDIA_URL }}{{ logotipo }}{% else %}{% webpack_static 'img/logo.png' %}{% endif %}"
alt="Logo" class="img-responsive" >
<span class="vcenter">{% if nome %}{{ nome }}{% else %}{% trans 'Câmara/Assembléia não configurada'%}{% endif %}
<br/><small>{{nome_sistema}}</small>
</span>
</a>
</div>

135
sapl/templates/fluxo_proposicoes.html

@ -205,6 +205,10 @@
font-family: 'Courier New', monospace;
margin: 10px 0;
overflow-x: auto;
display: flex;
align-items: center;
justify-content: space-between;
gap: 15px;
}
.url-box code {
@ -212,6 +216,28 @@
background: none;
}
.url-link {
background: #3498db;
color: white;
padding: 5px 12px;
border-radius: 4px;
text-decoration: none;
font-size: 0.85em;
white-space: nowrap;
transition: background 0.3s;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}
.url-link:hover {
background: #2980b9;
color: white;
text-decoration: none;
}
.url-link i {
margin-right: 5px;
}
.comparison-table {
width: 100%;
border-collapse: collapse;
@ -533,7 +559,12 @@
<li>Pode ser excluída</li>
<li>Somente autor vê</li>
</ul>
<div class="url-box">URL: <code>/proposicao/</code></div>
<div class="url-box">
<span>URL: <code>/proposicao/</code></span>
<a href="/proposicao/" class="url-link" title="Ir para Minhas Proposições" target="_blank" rel="noopener noreferrer">
<i class="fas fa-external-link-alt"></i> Acessar
</a>
</div>
</div>
</div>
@ -547,7 +578,12 @@
<li>Autor pode retornar (cancelar)</li>
<li>Operador pode receber ou devolver</li>
</ul>
<div class="url-box">URL: <code>/proposicao/pendente/</code></div>
<div class="url-box">
<span>URL: <code>/proposicao/pendente/</code></span>
<a href="/proposicao/pendente/" class="url-link" title="Ir para Proposições Pendentes" target="_blank" rel="noopener noreferrer">
<i class="fas fa-external-link-alt"></i> Acessar
</a>
</div>
</div>
</div>
@ -560,7 +596,12 @@
<li>Autor pode ver motivo</li>
<li>Pode corrigir e reenviar</li>
</ul>
<div class="url-box">URL: <code>/proposicao/devolvida/</code></div>
<div class="url-box">
<span>URL: <code>/proposicao/devolvida/</code></span>
<a href="/proposicao/devolvida/" class="url-link" title="Ir para Proposições Devolvidas" target="_blank" rel="noopener noreferrer">
<i class="fas fa-external-link-alt"></i> Acessar
</a>
</div>
</div>
</div>
@ -574,7 +615,12 @@
<li>Protocolo gerado (se configurado)</li>
<li>Pode tramitar e ser votada</li>
</ul>
<div class="url-box">URL: <code>/proposicao/recebida/</code></div>
<div class="url-box">
<span>URL: <code>/proposicao/recebida/</code></span>
<a href="/proposicao/recebida/" class="url-link" title="Ir para Proposições Recebidas" target="_blank" rel="noopener noreferrer">
<i class="fas fa-external-link-alt"></i> Acessar
</a>
</div>
</div>
</div>
</div>
@ -589,7 +635,10 @@
<h4><i class="fas fa-user-tie"></i> PARLAMENTAR</h4>
<p>1. Cria Proposição</p>
<div class="url-box" style="background: #8e44ad; color: white; font-size: 0.85em;">
<code style="color: #ecf0f1;">/proposicao/create</code>
<span><code style="color: #ecf0f1;">/proposicao/create</code></span>
<a href="/proposicao/create" class="url-link" style="background: #9b59b6;" title="Ir para Criar Proposição" target="_blank" rel="noopener noreferrer">
<i class="fas fa-external-link-alt"></i> Acessar
</a>
</div>
</div>
@ -623,7 +672,10 @@
<h4><i class="fas fa-inbox"></i> 3. Operador Recebe</h4>
<p>Via código ou lista de pendentes</p>
<div class="url-box" style="background: #c0392b; color: white; font-size: 0.85em;">
<code style="color: #ecf0f1;">/proposicao/receber/</code>
<span><code style="color: #ecf0f1;">/proposicao/receber/</code></span>
<a href="/proposicao/receber/" class="url-link" style="background: #e74c3c;" title="Ir para Receber Proposição" target="_blank" rel="noopener noreferrer">
<i class="fas fa-external-link-alt"></i> Acessar
</a>
</div>
</div>
@ -657,7 +709,10 @@
<h4><i class="fas fa-gavel"></i> MATÉRIA LEGISLATIVA</h4>
<p>PL nº X/2025 criada</p>
<div class="url-box" style="background: #27ae60; color: white; font-size: 0.85em;">
<code style="color: #ecf0f1;">/materia/{id}/</code>
<span><code style="color: #ecf0f1;">/materia/{id}/</code></span>
<a href="/materia/" class="url-link" style="background: #2ecc71;" title="Ir para Matérias Legislativas" target="_blank" rel="noopener noreferrer">
<i class="fas fa-external-link-alt"></i> Ver Lista
</a>
</div>
</div>
@ -712,7 +767,12 @@
<div class="step-by-step">
<div class="step-item">
<h4>Criar o Parlamentar</h4>
<div class="url-box">URL: <code>/parlamentar/create</code></div>
<div class="url-box">
<span>URL: <code>/parlamentar/create</code></span>
<a href="/parlamentar/create" class="url-link" title="Ir para Criar Parlamentar" target="_blank" rel="noopener noreferrer">
<i class="fas fa-external-link-alt"></i> Acessar
</a>
</div>
<p><strong>Dados:</strong></p>
<ul>
<li>Nome Completo: "João da Silva"</li>
@ -727,7 +787,12 @@
<div class="step-item">
<h4>Criar Usuário do Sistema</h4>
<div class="url-box">URL: <code>/sistema/usuario/create</code></div>
<div class="url-box">
<span>URL: <code>/sistema/usuario/create</code></span>
<a href="/sistema/usuario/create" class="url-link" title="Ir para Criar Usuário" target="_blank" rel="noopener noreferrer">
<i class="fas fa-external-link-alt"></i> Acessar
</a>
</div>
<p><strong>Dados:</strong></p>
<ul>
<li>Username: <code>joao.silva</code></li>
@ -739,7 +804,12 @@
<div class="step-item">
<h4>Vincular Usuário ao Autor</h4>
<div class="url-box">URL: <code>/sistema/usuario/{id}/edit</code></div>
<div class="url-box">
<span>URL: <code>/sistema/usuario/{id}/edit</code></span>
<a href="/sistema/usuario/" class="url-link" title="Ir para Lista de Usuários" target="_blank" rel="noopener noreferrer">
<i class="fas fa-external-link-alt"></i> Ver Lista
</a>
</div>
<p>No campo <strong>"Autor"</strong>, selecione: "João da Silva"</p>
<div class="concept-card success">
<strong>Resultado:</strong><br>
@ -763,7 +833,12 @@
<div class="step-item">
<h4>Criar Nova Proposição</h4>
<div class="url-box">URL: <code>/proposicao/create</code></div>
<div class="url-box">
<span>URL: <code>/proposicao/create</code></span>
<a href="/proposicao/create" class="url-link" title="Ir para Criar Proposição" target="_blank" rel="noopener noreferrer">
<i class="fas fa-external-link-alt"></i> Acessar
</a>
</div>
<p><strong>Formulário:</strong></p>
<ul>
<li><strong>Tipo:</strong> Projeto de Lei</li>
@ -810,7 +885,12 @@
<div class="step-item">
<h4>Ver Proposições Pendentes</h4>
<div class="url-box">URL: <code>/proposicao/pendente/</code></div>
<div class="url-box">
<span>URL: <code>/proposicao/pendente/</code></span>
<a href="/proposicao/pendente/" class="url-link" title="Ir para Proposições Pendentes" target="_blank" rel="noopener noreferrer">
<i class="fas fa-external-link-alt"></i> Acessar
</a>
</div>
<p>Lista todas proposições enviadas aguardando recebimento</p>
<p><strong>Informações mostradas:</strong></p>
<ul>
@ -825,7 +905,12 @@
<div class="step-item">
<h4>Receber Proposição</h4>
<p><strong>Opção A:</strong> Via código do recibo</p>
<div class="url-box">URL: <code>/proposicao/receber/</code></div>
<div class="url-box">
<span>URL: <code>/proposicao/receber/</code></span>
<a href="/proposicao/receber/" class="url-link" title="Ir para Receber Proposição" target="_blank" rel="noopener noreferrer">
<i class="fas fa-external-link-alt"></i> Acessar
</a>
</div>
<p>Insira o código e clique em "Receber"</p>
<p style="margin-top: 20px;"><strong>Opção B:</strong> Via lista de pendentes</p>
@ -914,18 +999,22 @@
<tr>
<td>Criar proposição</td>
<td><code>/proposicao/create</code></td>
<td><a href="/proposicao/create" class="btn btn-sm btn-primary" target="_blank" rel="noopener noreferrer"><i class="fas fa-arrow-right"></i></a></td>
</tr>
<tr>
<td>Minhas proposições</td>
<td><code>/proposicao/</code></td>
<td><a href="/proposicao/" class="btn btn-sm btn-primary" target="_blank" rel="noopener noreferrer"><i class="fas fa-arrow-right"></i></a></td>
</tr>
<tr>
<td>Devolvidas</td>
<td><code>/proposicao/devolvida/</code></td>
<td><a href="/proposicao/devolvida/" class="btn btn-sm btn-primary" target="_blank" rel="noopener noreferrer"><i class="fas fa-arrow-right"></i></a></td>
</tr>
<tr>
<td>Recibo</td>
<td><code>/proposicao/recibo/{id}</code></td>
<td><span class="text-muted" style="font-size: 0.85em;">Dinâmica</span></td>
</tr>
</tbody>
</table>
@ -940,18 +1029,22 @@
<tr>
<td>Receber proposição</td>
<td><code>/proposicao/receber/</code></td>
<td><a href="/proposicao/receber/" class="btn btn-sm btn-primary" target="_blank" rel="noopener noreferrer"><i class="fas fa-arrow-right"></i></a></td>
</tr>
<tr>
<td>Pendentes</td>
<td><code>/proposicao/pendente/</code></td>
<td><a href="/proposicao/pendente/" class="btn btn-sm btn-primary" target="_blank" rel="noopener noreferrer"><i class="fas fa-arrow-right"></i></a></td>
</tr>
<tr>
<td>Recebidas</td>
<td><code>/proposicao/recebida/</code></td>
<td><a href="/proposicao/recebida/" class="btn btn-sm btn-primary" target="_blank" rel="noopener noreferrer"><i class="fas fa-arrow-right"></i></a></td>
</tr>
<tr>
<td>Matérias</td>
<td><code>/materia/</code></td>
<td><a href="/materia/" class="btn btn-sm btn-primary" target="_blank" rel="noopener noreferrer"><i class="fas fa-arrow-right"></i></a></td>
</tr>
</tbody>
</table>
@ -965,14 +1058,14 @@
<div class="concept-card info">
<p>Antes de usar o fluxo de proposições, configure:</p>
<ul class="checklist">
<li>Casa Legislativa em <code>/sistema/casa-legislativa/</code></li>
<li>Legislatura em <code>/sistema/parlamentar/legislatura/</code></li>
<li>Tipos de Proposição em <code>/sistema/materia/tipoproposicao/</code></li>
<li>Tipos de Matéria em <code>/sistema/materia/tipo/</code></li>
<li>Regimes de Tramitação em <code>/sistema/materia/regimetramitacao/</code></li>
<li>Parlamentares em <code>/parlamentar/create</code></li>
<li>Usuários em <code>/sistema/usuario/create</code></li>
<li>Vincular Usuários a Autores em <code>/sistema/usuario/{id}/edit</code></li>
<li>Casa Legislativa em <code>/sistema/casa-legislativa/</code> <a href="/sistema/casa-legislativa/" class="btn btn-sm btn-outline-primary" style="margin-left: 10px;" target="_blank" rel="noopener noreferrer"><i class="fas fa-arrow-right"></i></a></li>
<li>Legislatura em <code>/sistema/parlamentar/legislatura/</code> <a href="/sistema/parlamentar/legislatura/" class="btn btn-sm btn-outline-primary" style="margin-left: 10px;" target="_blank" rel="noopener noreferrer"><i class="fas fa-arrow-right"></i></a></li>
<li>Tipos de Proposição em <code>/sistema/materia/tipoproposicao/</code> <a href="/sistema/materia/tipoproposicao/" class="btn btn-sm btn-outline-primary" style="margin-left: 10px;" target="_blank" rel="noopener noreferrer"><i class="fas fa-arrow-right"></i></a></li>
<li>Tipos de Matéria em <code>/sistema/materia/tipo/</code> <a href="/sistema/materia/tipo/" class="btn btn-sm btn-outline-primary" style="margin-left: 10px;" target="_blank" rel="noopener noreferrer"><i class="fas fa-arrow-right"></i></a></li>
<li>Regimes de Tramitação em <code>/sistema/materia/regimetramitacao/</code> <a href="/sistema/materia/regimetramitacao/" class="btn btn-sm btn-outline-primary" style="margin-left: 10px;" target="_blank" rel="noopener noreferrer"><i class="fas fa-arrow-right"></i></a></li>
<li>Parlamentares em <code>/parlamentar/create</code> <a href="/parlamentar/create" class="btn btn-sm btn-outline-primary" style="margin-left: 10px;" target="_blank" rel="noopener noreferrer"><i class="fas fa-arrow-right"></i></a></li>
<li>Usuários em <code>/sistema/usuario/create</code> <a href="/sistema/usuario/create" class="btn btn-sm btn-outline-primary" style="margin-left: 10px;" target="_blank" rel="noopener noreferrer"><i class="fas fa-arrow-right"></i></a></li>
<li>Vincular Usuários a Autores em <code>/sistema/usuario/{id}/edit</code> <a href="/sistema/usuario/" class="btn btn-sm btn-outline-primary" style="margin-left: 10px;" title="Ver lista de usuários" target="_blank" rel="noopener noreferrer"><i class="fas fa-arrow-right"></i></a></li>
</ul>
</div>

7
sapl/urls.py

@ -108,14 +108,17 @@ if settings.DEBUG:
# Make the rate limiter return 429 (Too Many Requests) instead of 403 (Forbidden Access)
def custom_permission_denied_view(request, exception=None):
from django.http import HttpResponse, HttpResponseForbidden
from django.http import HttpResponse
from django.shortcuts import render
from ratelimit.exceptions import Ratelimited
if isinstance(exception, Ratelimited):
resp = HttpResponse('Too many requests', status=429)
resp['Retry-After'] = '60'
return resp
return HttpResponseForbidden('Forbidden')
# Renderiza o template 403.html customizado
return render(request, '403.html', status=403)
handler403 = custom_permission_denied_view

Loading…
Cancel
Save