wagtail-enap-designsystem 1.2.1.201__py3-none-any.whl → 1.2.1.203__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of wagtail-enap-designsystem might be problematic. Click here for more details.

@@ -2,21 +2,21 @@
2
2
  {% load static %}
3
3
  {% load wagtailcore_tags wagtailimages_tags %}
4
4
 
5
-
6
5
  {% block metadata %}
7
- {% comment %} <meta name="viewport" content="width=device-width, initial-scale=1.0"> {% endcomment %}
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <!-- Adicionar CSS estilo baseado na captura de tela -->
8
+ <link rel="stylesheet" href="{% static 'enap_designsystem/css/capsulas-design-v2.css' %}">
8
9
  {% endblock %}
9
10
 
10
-
11
11
  {% block title %}
12
- <title>{{ page.title }}</title>
12
+ <title>{{ page.title }}</title>
13
13
  {% endblock %}
14
14
 
15
15
  {%block govnavbar %}
16
16
  <div style="background-color: #071E41;">
17
17
  <div class="menu">
18
18
  <div class="logo">
19
- <img style="width: 51px; height: 18px;" src="{% static 'enap_designsystem/icons/logo-white.png' %}" alt="Passar pro lado esquerdo" alt="Logo GovBR" height="40">
19
+ <img style="width: 51px; height: 18px;" src="{% static 'enap_designsystem/icons/logo-white.png' %}" alt="Logo GovBR">
20
20
  </div>
21
21
  <a href="https://www.gov.br/secom/pt-br/acesso-a-informacao/comunicabr">Comunica BR</a>
22
22
  <div class="separator"></div>
@@ -31,7 +31,6 @@
31
31
  </div>
32
32
  {% endblock %}
33
33
 
34
-
35
34
  {% block navbar %}
36
35
  {% if page.navbar %}
37
36
  {% include "enap_designsystem/blocks/navbar/navbar_block.html" with navbar=page.navbar %}
@@ -40,245 +39,280 @@
40
39
  {% endif %}
41
40
  {% endblock %}
42
41
 
43
-
44
42
  {% block content %}
45
43
  <div class="acessibilidade-container-page">
46
- <div class="acessibilidade-container-white">
47
- <div class="hearder-search">
48
- <!-- Na sua página -->
49
- {% include "enap_designsystem/blocks/auto_breadcrumb_block.html" with value=breadcrumb_config %}
50
- <div class="">
51
- <div class="space-header">
52
- <div>
53
- <h1 class="title-large-green">
54
- {% if query %}
55
- "{{ query }}"
56
- {% else %}
57
- Todos os resultados disponíveis
58
- {% endif %}
59
- </h1>
60
-
61
- </div>
62
-
63
- </div>
64
- </div>
65
- </div>
44
+ <!-- Cabeçalho da página -->
45
+ <div class="page-title-container">
46
+ <h1 class="page-title-capsulas">Buscar Cápsulas de Acessibilidade</h1>
47
+ <p>Encontre o conteúdo específico que você precisa usando nossos filtros inteligentes</p>
66
48
  </div>
49
+ <div class="page-containera-cessibilidade">
67
50
  <div class="acessibilidade-conteudo-container">
68
-
69
51
  {# ============================================ #}
70
52
  {# SIDEBAR DE BUSCA E FILTROS #}
71
53
  {# ============================================ #}
72
54
  <aside class="filtros-lateral" role="complementary" aria-label="Busca e filtros">
73
-
74
- {# Campo de busca #}
75
-
76
-
77
55
  {# Filtros avançados #}
78
- <div class="opcoes-filtragem">
79
-
80
- <div id="filtragem-conteudo" class="filtragem-conteudo">
81
- <form method="get" id="filtros-form">
82
-
83
- {# TIPO DE DEFICIÊNCIA - DROPDOWN #}
56
+ <div class="filtros-avancados-container">
57
+ <div class="filtros-header">
58
+ <div class="filtros-titulo">
59
+ <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
60
+ <polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"></polygon>
61
+ </svg>
62
+ Filtros Avançados
63
+ </div>
64
+ <button type="button" aria-expanded="true" id="toggle-filtros">
65
+ <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
66
+ <path d="M18 15l-6-6-6 6"></path>
67
+ </svg>
68
+ </button>
69
+ </div>
70
+
71
+ <div id="filtros-container">
72
+ <form id="filtros-form">
73
+ {# TIPO DE DEFICIÊNCIA #}
84
74
  <fieldset class="categoria-filtro">
85
- <div class="categoria-dropdown" id="dropdown-deficiencia">
86
- <button type="button"
87
- class="categoria-cabecalho"
88
- aria-expanded="false"
89
- onclick="toggleDropdown('deficiencia')">
90
- <span class="categoria-titulo">
91
- Tipo de Deficiência
92
- <span class="contador-badge" id="count-deficiencia">0</span>
93
- </span>
94
- <svg class="seta-dropdown" fill="none" stroke="currentColor" viewBox="0 0 24 24">
95
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
96
- </svg>
97
- </button>
98
- <div class="categoria-opcoes" id="opcoes-deficiencia">
99
- {% for value, label in opcoes_filtros.tipos_deficiencia %}
100
- <label class="selecao-checkbox">
101
- <input type="checkbox"
102
- name="tipo_deficiencia"
103
- value="{{ value }}"
104
- {% if value in filtros_ativos.tipo_deficiencia %}checked{% endif %}
105
- onchange="updateCount('deficiencia'); this.form.submit()">
106
- <span class="texto-checkbox">{{ label }}</span>
107
- </label>
108
- {% endfor %}
109
- </div>
75
+ <h3 class="categoria-titulo">Tipo de Deficiência</h3>
76
+ <div class="opcoes-filtro">
77
+ {% for value, label in opcoes_filtros.tipos_deficiencia %}
78
+ <div class="checkbox-item">
79
+ <input type="checkbox"
80
+ name="tipo_deficiencia"
81
+ id="tipo_{{ value }}"
82
+ value="{{ value }}"
83
+ class="filtro-checkbox"
84
+ data-filtro-tipo="tipo_deficiencia"
85
+ {% if value in filtros_ativos.tipo_deficiencia %}checked{% endif %}>
86
+ <label for="tipo_{{ value }}" class="checkbox-label">{{ label }}</label>
87
+ </div>
88
+ {% endfor %}
110
89
  </div>
111
90
  </fieldset>
112
91
 
113
- {# FORMATO DE AÇÃO - DROPDOWN #}
92
+ {# FORMATO DE AÇÃO #}
114
93
  <fieldset class="categoria-filtro">
115
- <div class="categoria-dropdown" id="dropdown-formato">
116
- <button type="button"
117
- class="categoria-cabecalho"
118
- aria-expanded="false"
119
- onclick="toggleDropdown('formato')">
120
- <span class="categoria-titulo">
121
- Formato de Ação
122
- <span class="contador-badge" id="count-formato">0</span>
123
- </span>
124
- <svg class="seta-dropdown" fill="none" stroke="currentColor" viewBox="0 0 24 24">
125
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
126
- </svg>
127
- </button>
128
- <div class="categoria-opcoes" id="opcoes-formato">
129
- {% for value, label in opcoes_filtros.formatos_acao %}
130
- <label class="selecao-checkbox">
131
- <input type="checkbox"
132
- name="formato_acao"
133
- value="{{ value }}"
134
- {% if value in filtros_ativos.formato_acao %}checked{% endif %}
135
- onchange="updateCount('formato'); this.form.submit()">
136
- <span class="texto-checkbox">{{ label }}</span>
137
- </label>
138
- {% endfor %}
139
- </div>
94
+ <h3 class="categoria-titulo">Formato de Ação de Desenvolvimento</h3>
95
+ <div class="opcoes-filtro">
96
+ {% for value, label in opcoes_filtros.formatos_acao %}
97
+ <div class="checkbox-item">
98
+ <input type="checkbox"
99
+ name="formato_acao"
100
+ id="formato_{{ value }}"
101
+ value="{{ value }}"
102
+ class="filtro-checkbox"
103
+ data-filtro-tipo="formato_acao"
104
+ {% if value in filtros_ativos.formato_acao %}checked{% endif %}>
105
+ <label for="formato_{{ value }}" class="checkbox-label">{{ label }}</label>
106
+ </div>
107
+ {% endfor %}
140
108
  </div>
141
109
  </fieldset>
142
110
 
143
- {# TIPO DE RECURSO - DROPDOWN #}
111
+ {# TIPO DE RECURSO #}
144
112
  <fieldset class="categoria-filtro">
145
- <div class="categoria-dropdown" id="dropdown-recurso">
146
- <button type="button"
147
- class="categoria-cabecalho"
148
- aria-expanded="false"
149
- onclick="toggleDropdown('recurso')">
150
- <span class="categoria-titulo">
151
- Tipo de Recurso
152
- <span class="contador-badge" id="count-recurso">0</span>
153
- </span>
154
- <svg class="seta-dropdown" fill="none" stroke="currentColor" viewBox="0 0 24 24">
155
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
156
- </svg>
157
- </button>
158
- <div class="categoria-opcoes" id="opcoes-recurso">
159
- {% for value, label in opcoes_filtros.tipos_recurso %}
160
- <label class="selecao-checkbox">
161
- <input type="checkbox"
162
- name="tipo_recurso"
163
- value="{{ value }}"
164
- {% if value in filtros_ativos.tipo_recurso %}checked{% endif %}
165
- onchange="updateCount('recurso'); this.form.submit()">
166
- <span class="texto-checkbox">{{ label }}</span>
167
- </label>
168
- {% endfor %}
169
- </div>
113
+ <h3 class="categoria-titulo">Tipo de Recurso</h3>
114
+ <div class="opcoes-filtro">
115
+ {% for value, label in opcoes_filtros.tipos_recurso %}
116
+ <div class="checkbox-item">
117
+ <input type="checkbox"
118
+ name="tipo_recurso"
119
+ id="recurso_{{ value }}"
120
+ value="{{ value }}"
121
+ class="filtro-checkbox"
122
+ data-filtro-tipo="tipo_recurso"
123
+ {% if value in filtros_ativos.tipo_recurso %}checked{% endif %}>
124
+ <label for="recurso_{{ value }}" class="checkbox-label">{{ label }}</label>
125
+ </div>
126
+ {% endfor %}
170
127
  </div>
171
128
  </fieldset>
172
129
 
130
+ {# PERFIL PROFISSIONAL #}
131
+ <fieldset class="categoria-filtro">
132
+ <h3 class="categoria-titulo">Perfil Profissional</h3>
133
+ <div class="opcoes-filtro">
134
+ {% for value, label in opcoes_filtros.perfis_profissionais %}
135
+ <div class="checkbox-item">
136
+ <input type="checkbox"
137
+ name="perfil_profissional"
138
+ id="perfil_{{ value }}"
139
+ value="{{ value }}"
140
+ class="filtro-checkbox"
141
+ data-filtro-tipo="perfil_profissional"
142
+ {% if value in filtros_ativos.perfil_profissional %}checked{% endif %}>
143
+ <label for="perfil_{{ value }}" class="checkbox-label">{{ label }}</label>
144
+ </div>
145
+ {% endfor %}
146
+ </div>
147
+ </fieldset>
173
148
  </form>
174
149
  </div>
175
150
  </div>
176
-
177
151
  </aside>
178
152
 
179
153
  {# ============================================ #}
180
- {# ÁREA DE RESULTADOS #}
154
+ {# ÁREA DOS RESULTADOS #}
181
155
  {# ============================================ #}
182
- <main class="conteudo-principal" role="main">
156
+ <main class="resultados-container" role="main">
157
+ <!-- Filtros ativos e opções de ordenação -->
158
+ <div class="filtros-ativos-wrapper">
159
+ <div class="filtros-ativos-container" id="filtros-ativos-container">
160
+ <!-- Aqui entram as tags de filtros ativos via JavaScript -->
161
+ </div>
162
+
163
+ <button type="button" class="limpar-todos" id="limpar-todos-btn" style="display: none;">
164
+ Limpar todos
165
+ </button>
166
+ </div>
183
167
 
184
- <div class="conteudo-cabecalho">
185
-
168
+ <div class="resultados-header">
169
+ <div class="contagem-resultados" id="contagem-resultados">
170
+ {{ total_resultados }} cápsulas encontradas
171
+ </div>
186
172
 
187
- <div class="conteudo-ordenacao">
188
- <label for="sort-select" class="ordenacao-texto">Ordenar por:</label>
189
- <select id="sort-select" class="ordenacao-select">
190
- <option value="relevancia">Relevância</option>
191
- <option value="recente">Mais recentes</option>
192
- <option value="titulo">A-Z</option>
193
- </select>
173
+ <div class="ordenacao-dropdown">
174
+ <button type="button" class="ordenacao-button">
175
+ Relevância
176
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
177
+ <path d="M6 9l6 6 6-6"></path>
178
+ </svg>
179
+ </button>
194
180
  </div>
195
181
  </div>
196
182
 
197
- {% if capsulas %}
198
- <div class="recursos-grid">
199
- {% for capsula in capsulas %}
200
- <article class="recurso-card">
201
- <!-- Link principal que envolve todo o card -->
202
- <a href="{% pageurl capsula %}" class="recurso-card-link" aria-labelledby="card-titulo-{{ forloop.counter }}">
203
- <span class="sr-only">Acessar cápsula: {{ capsula.title }}</span>
204
-
205
-
206
- <div class="recurso-card-icone">
207
- <svg fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
208
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"></path>
209
- </svg>
183
+ <div class="grade-resultados" id="grade-resultados">
184
+ {% for capsula in capsulas %}
185
+ <div class="capsula-card"
186
+ data-tipo-deficiencia="{{ capsula.tipos_deficiencia|join:' ' }}"
187
+ data-formato-acao="{{ capsula.formatos_acao|join:' ' }}"
188
+ data-tipo-recurso="{{ capsula.tipos_recurso|join:' ' }}"
189
+ data-perfil-profissional="{{ capsula.perfis_profissionais|join:' ' }}"
190
+ data-prioridade="{{ capsula.prioridade }}">
191
+ <div class="capsula-conteudo">
192
+ <div class="capsula-icone">
193
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
194
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"></path>
195
+ </svg>
196
+ </div>
197
+
198
+ <h2 class="capsula-titulo">
199
+ {{ capsula.title }}
200
+ </h2>
201
+
202
+ <p class="capsula-descricao">
203
+ {{ capsula.resumo_card|default:"Aprenda sobre este importante aspecto da acessibilidade digital." }}
204
+ </p>
205
+
206
+ {# Tipos de deficiência #}
207
+ {% if capsula.tipos_deficiencia %}
208
+ <div class="capsula-tipos" aria-label="Tipos de deficiência abordados">
209
+ <i class="fa-solid fa-tags"></i>
210
+ {% for tipo_value, tipo_label in opcoes_filtros.tipos_deficiencia %}
211
+ {% if tipo_value in capsula.tipos_deficiencia %}
212
+ <div class="capsula-tipo {{ tipo_value }}">
213
+ <div class="tipo-dot"></div>
214
+ <div class="tipo-text">{{ tipo_label }}</div>
215
+ </div>
216
+ {% endif %}
217
+ {% endfor %}
210
218
  </div>
211
-
212
- <h2 class="recurso-card-titulo" id="card-titulo-{{ forloop.counter }}">
213
- {{ capsula.title }}
214
- </h2>
215
-
216
- <p class="recurso-card-descricao">
217
- {{ capsula.resumo_card|default:"Aprenda sobre este importante aspecto da acessibilidade digital." }}
218
- </p>
219
-
220
- {# Tags de deficiência #}
221
- {% if capsula.tipos_deficiencia %}
222
- <div class="recurso-tags-categoria" aria-label="Tipos de deficiência abordados">
223
- {% for tipo in capsula.get_tipos_deficiencia_display|slice:":2" %}
224
- <span class="tag-categoria">
225
- <svg class="tag-categoria-icone" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
226
- <circle cx="10" cy="10" r="4"></circle>
227
- </svg>
228
- {{ tipo }}
229
- </span>
230
- {% endfor %}
231
- </div>
232
- {% endif %}
233
-
234
- {# Badge de prioridade #}
235
- {% if capsula.prioridade %}
236
- <div class="recurso-badge recurso-badge-{{ capsula.prioridade }}" aria-label="Nível de prioridade">
237
- <svg class="badge-icone" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
238
- <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path>
239
- </svg>
240
- {{ capsula.get_prioridade_display }}
241
- </div>
242
- {% endif %}
243
-
244
- {# Tags de recurso #}
245
- {% if capsula.tipos_recurso %}
246
- <div class="recurso-tags-tipo" aria-label="Tipos de recurso">
247
- {% for recurso in capsula.get_tipos_recurso_display|slice:":3" %}
248
- <span class="tag-tipo">
249
- <svg class="tag-tipo-icone" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
250
- <path fill-rule="evenodd" d="M4 3a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V5a2 2 0 00-2-2H4zm12 12H4l4-8 3 6 2-4 3 6z" clip-rule="evenodd"></path>
251
- </svg>
252
- {{ recurso }}
253
- </span>
254
- {% endfor %}
255
- </div>
256
- {% endif %}
257
-
258
- <div class="recurso-card-botao-wrapper">
259
- <span class="recurso-card-botao">
260
- Acessar Cápsula
261
- </span>
219
+ {% endif %}
220
+
221
+
222
+
223
+ {# Tags de recurso #}
224
+ {% if capsula.tipos_recurso %}
225
+ <div class="capsula-recursos" aria-label="Tipos de recurso">
226
+ {% for recurso_value, recurso_label in opcoes_filtros.tipos_recurso %}
227
+ {% if recurso_value in capsula.tipos_recurso %}
228
+ <div class="recurso-tag">
229
+ {% if recurso_value == 'imagem' %}
230
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
231
+ <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
232
+ <circle cx="8.5" cy="8.5" r="1.5"></circle>
233
+ <polyline points="21 15 16 10 5 21"></polyline>
234
+ </svg>
235
+ {% elif recurso_value == 'video' %}
236
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
237
+ <polygon points="23 7 16 12 23 17 23 7"></polygon>
238
+ <rect x="1" y="5" width="15" height="14" rx="2" ry="2"></rect>
239
+ </svg>
240
+ {% elif recurso_value == 'grafico' %}
241
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
242
+ <line x1="18" y1="20" x2="18" y2="10"></line>
243
+ <line x1="12" y1="20" x2="12" y2="4"></line>
244
+ <line x1="6" y1="20" x2="6" y2="14"></line>
245
+ </svg>
246
+ {% elif recurso_value == 'tabela' %}
247
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
248
+ <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
249
+ <line x1="3" y1="9" x2="21" y2="9"></line>
250
+ <line x1="3" y1="15" x2="21" y2="15"></line>
251
+ <line x1="9" y1="3" x2="9" y2="21"></line>
252
+ <line x1="15" y1="3" x2="15" y2="21"></line>
253
+ </svg>
254
+ {% else %}
255
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
256
+ <polyline points="22 12 16 12 14 15 10 15 8 12 2 12"></polyline>
257
+ <path d="M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"></path>
258
+ </svg>
259
+ {% endif %}
260
+ {{ recurso_label }}
261
+ </div>
262
+ {% endif %}
263
+ {% endfor %}
262
264
  </div>
265
+ {% endif %}
266
+
267
+ <a href="{% pageurl capsula %}" class="btn large primary">
268
+ Acessar Cápsula
263
269
  </a>
264
- </article>
265
- {% endfor %}
266
- </div>
267
-
268
- {% else %}
269
- <div class="conteudo-vazio">
270
- <svg class="conteudo-vazio-icone" fill="none" stroke="currentColor" viewBox="0 0 24 24">
271
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.172 16.172a4 4 0 015.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
272
- </svg>
273
- <h2>Nenhuma cápsula encontrada</h2>
274
- <p>Tente ajustar os filtros ou <a href="{{ page.url }}">limpe os filtros</a> para ver todas as cápsulas.</p>
275
- </div>
276
- {% endif %}
270
+ </div>
271
+ </div>
272
+ {% endfor %}
273
+ </div>
277
274
 
275
+ <!-- Mensagem para nenhum resultado -->
276
+ <div id="mensagem-vazia" class="conteudo-vazio" style="display: none;">
277
+ <svg class="conteudo-vazio-icone" fill="none" stroke="currentColor" viewBox="0 0 24 24">
278
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.172 16.172a4 4 0 015.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
279
+ </svg>
280
+ <h2>Nenhuma cápsula encontrada</h2>
281
+ <p>Tente ajustar os filtros ou <a href="javascript:void(0)" onclick="limparTodosFiltros()">limpe os filtros</a> para ver todas as cápsulas.</p>
282
+ </div>
278
283
  </main>
279
-
284
+ </div>
280
285
  </div>
281
286
  </div>
287
+
288
+ <style>
289
+ /* Estilo do esqueleto para efeito de loading */
290
+ .skeleton-card {
291
+ background: #e0e0e0;
292
+ animation: skeleton-loading 1.5s infinite ease-in-out;
293
+ min-width: 268px;
294
+ min-height: 450px;
295
+ border-radius: 20px;
296
+ box-shadow: inset 0 0 0 1px #DEE3ED;
297
+ margin-top: 20px;
298
+ }
299
+
300
+ .skeleton-card:nth-child(odd) {
301
+ animation-delay: 0.5s;
302
+ }
303
+
304
+ @keyframes skeleton-loading {
305
+ 0% {
306
+ background-color: #e0e0e0;
307
+ }
308
+ 50% {
309
+ background-color: #f0f0f0;
310
+ }
311
+ 100% {
312
+ background-color: #e0e0e0;
313
+ }
314
+ }
315
+ </style>
282
316
  {% endblock %}
283
317
 
284
318
  {% block footer %}
@@ -287,65 +321,244 @@
287
321
 
288
322
  {% block scriptinline %}
289
323
  <script>
290
- // Toggle dos dropdowns individuais
291
- function toggleDropdown(tipo) {
292
- const header = document.querySelector(`#dropdown-${tipo} .categoria-cabecalho`);
293
- const opcoes = document.getElementById(`opcoes-${tipo}`);
294
- const dropdown = document.getElementById(`dropdown-${tipo}`);
295
- const expanded = header.getAttribute('aria-expanded') === 'true';
324
+ document.addEventListener('DOMContentLoaded', function() {
325
+ // Cache dos elementos DOM
326
+ const checkboxes = document.querySelectorAll('.filtro-checkbox');
327
+ const capsulaCards = document.querySelectorAll('.capsula-card');
328
+ const contagemResultados = document.getElementById('contagem-resultados');
329
+ const mensagemVazia = document.getElementById('mensagem-vazia');
330
+ const filtrosAtivosContainer = document.getElementById('filtros-ativos-container');
331
+ const limparTodosBtn = document.getElementById('limpar-todos-btn');
296
332
 
297
- // Fecha outros dropdowns
298
- document.querySelectorAll('.categoria-dropdown').forEach(dd => {
299
- if (dd.id !== `dropdown-${tipo}`) {
300
- dd.classList.remove('active');
301
- const h = dd.querySelector('.categoria-cabecalho');
302
- const o = dd.querySelector('.categoria-opcoes');
303
- h.setAttribute('aria-expanded', 'false');
304
- o.classList.remove('open');
305
- }
333
+ // Mapeamento de rótulos para cada opção de filtro
334
+ const filtroLabels = {
335
+ {% for tipo, opcoes in opcoes_filtros.items %}
336
+ '{{ tipo }}': {
337
+ {% for value, label in opcoes %}
338
+ '{{ value }}': '{{ label }}',
339
+ {% endfor %}
340
+ },
341
+ {% endfor %}
342
+ };
343
+
344
+ // Inicializar: aplicar filtros já marcados na URL
345
+ aplicarFiltros();
346
+ atualizarFiltrosAtivos();
347
+
348
+ // Adicionar eventos de mudança para todos os checkboxes
349
+ checkboxes.forEach(checkbox => {
350
+ checkbox.addEventListener('change', function() {
351
+ aplicarFiltros();
352
+ atualizarFiltrosAtivos();
353
+ atualizarURL();
354
+ });
306
355
  });
307
356
 
308
- // Toggle do dropdown atual
309
- header.setAttribute('aria-expanded', !expanded);
310
- opcoes.classList.toggle('open');
311
- dropdown.classList.toggle('active');
312
- }
313
-
314
- // Atualiza o contador de filtros selecionados
315
- function updateCount(tipo) {
316
- const checkboxes = document.querySelectorAll(`#opcoes-${tipo} input[type="checkbox"]:checked`);
317
- const badge = document.getElementById(`count-${tipo}`);
318
- const count = checkboxes.length;
357
+ // Evento para o botão "Limpar todos"
358
+ if (limparTodosBtn) {
359
+ limparTodosBtn.addEventListener('click', function(e) {
360
+ e.preventDefault();
361
+ limparTodosFiltros();
362
+ });
363
+ }
319
364
 
320
- badge.textContent = count;
321
- badge.style.display = count > 0 ? 'inline-flex' : 'none';
322
- }
323
-
324
- // Inicializa os contadores ao carregar a página
325
- document.addEventListener('DOMContentLoaded', function() {
326
- updateCount('deficiencia');
327
- updateCount('formato');
328
- updateCount('recurso');
365
+ // Toggle dos filtros avançados
366
+ const toggleBtn = document.getElementById('toggle-filtros');
367
+ if (toggleBtn) {
368
+ toggleBtn.addEventListener('click', function() {
369
+ const container = document.getElementById('filtros-container');
370
+ const button = this;
371
+
372
+ if (button.getAttribute('aria-expanded') === 'true') {
373
+ button.setAttribute('aria-expanded', 'false');
374
+ button.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"></path></svg>';
375
+ container.style.display = 'none';
376
+ } else {
377
+ button.setAttribute('aria-expanded', 'true');
378
+ button.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 15l-6-6-6 6"></path></svg>';
379
+ container.style.display = 'block';
380
+ }
381
+ });
382
+ }
383
+
384
+ // Função para aplicar filtros
385
+ function aplicarFiltros() {
386
+ // Coletar filtros ativos
387
+ const filtrosAtivos = {
388
+ tipo_deficiencia: [],
389
+ formato_acao: [],
390
+ tipo_recurso: [],
391
+ perfil_profissional: [],
392
+ prioridade: null
393
+ };
394
+
395
+ // Preencher arrays de filtros ativos baseado nos checkboxes marcados
396
+ checkboxes.forEach(checkbox => {
397
+ if (checkbox.checked) {
398
+ const tipoFiltro = checkbox.getAttribute('data-filtro-tipo');
399
+ if (filtrosAtivos[tipoFiltro] !== undefined) {
400
+ filtrosAtivos[tipoFiltro].push(checkbox.value);
401
+ }
402
+ }
403
+ });
404
+
405
+ // Contar cápsulas visíveis para atualizar o contador
406
+ let capsulasFiltradas = 0;
407
+
408
+ // Aplicar filtros em cada card
409
+ capsulaCards.forEach(card => {
410
+ let mostrar = true;
411
+
412
+ // Verificar cada tipo de filtro
413
+ if (filtrosAtivos.tipo_deficiencia.length > 0) {
414
+ const tiposDeficiencia = (card.getAttribute('data-tipo-deficiencia') || '').split(' ').filter(t => t);
415
+ if (!filtrosAtivos.tipo_deficiencia.some(tipo => tiposDeficiencia.includes(tipo))) {
416
+ mostrar = false;
417
+ }
418
+ }
419
+
420
+ if (mostrar && filtrosAtivos.formato_acao.length > 0) {
421
+ const formatosAcao = (card.getAttribute('data-formato-acao') || '').split(' ').filter(t => t);
422
+ if (!filtrosAtivos.formato_acao.some(formato => formatosAcao.includes(formato))) {
423
+ mostrar = false;
424
+ }
425
+ }
426
+
427
+ if (mostrar && filtrosAtivos.tipo_recurso.length > 0) {
428
+ const tiposRecurso = (card.getAttribute('data-tipo-recurso') || '').split(' ').filter(t => t);
429
+ if (!filtrosAtivos.tipo_recurso.some(recurso => tiposRecurso.includes(recurso))) {
430
+ mostrar = false;
431
+ }
432
+ }
433
+
434
+ if (mostrar && filtrosAtivos.perfil_profissional.length > 0) {
435
+ const perfis = (card.getAttribute('data-perfil-profissional') || '').split(' ').filter(t => t);
436
+ if (!filtrosAtivos.perfil_profissional.some(perfil => perfis.includes(perfil))) {
437
+ mostrar = false;
438
+ }
439
+ }
440
+
441
+ if (mostrar && filtrosAtivos.prioridade) {
442
+ const prioridade = card.getAttribute('data-prioridade');
443
+ if (prioridade !== filtrosAtivos.prioridade) {
444
+ mostrar = false;
445
+ }
446
+ }
447
+
448
+ // Aplicar resultado
449
+ if (mostrar) {
450
+ card.style.display = 'block';
451
+ capsulasFiltradas++;
452
+ } else {
453
+ card.style.display = 'none';
454
+ }
455
+ });
456
+
457
+ // Atualizar contador de resultados
458
+ if (contagemResultados) {
459
+ contagemResultados.textContent = capsulasFiltradas + ' cápsulas encontradas';
460
+ }
461
+
462
+ // Mostrar mensagem de "nenhum resultado" se necessário
463
+ if (mensagemVazia) {
464
+ mensagemVazia.style.display = capsulasFiltradas === 0 ? 'block' : 'none';
465
+ }
466
+ }
329
467
 
330
- // Esconde badges com contador 0
331
- document.querySelectorAll('.contador-badge').forEach(badge => {
332
- if (badge.textContent === '0') {
333
- badge.style.display = 'none';
468
+ // Função para atualizar a exibição de filtros ativos
469
+ function atualizarFiltrosAtivos() {
470
+ // Limpar container completamente
471
+ filtrosAtivosContainer.innerHTML = '';
472
+
473
+ let temFiltrosAtivos = false;
474
+
475
+ // Para cada tipo de filtro, adicionar tags para os valores ativos
476
+ ['tipo_deficiencia', 'formato_acao', 'tipo_recurso', 'perfil_profissional'].forEach(tipoFiltro => {
477
+ const checkboxesTipo = document.querySelectorAll(`.filtro-checkbox[data-filtro-tipo="${tipoFiltro}"]:checked`);
478
+
479
+ checkboxesTipo.forEach(checkbox => {
480
+ temFiltrosAtivos = true;
481
+
482
+ // Verificar se o label existe
483
+ const labelTexto = filtroLabels[tipoFiltro] && filtroLabels[tipoFiltro][checkbox.value]
484
+ ? filtroLabels[tipoFiltro][checkbox.value]
485
+ : checkbox.value;
486
+
487
+ // Criar tag de filtro
488
+ const tagFiltro = document.createElement('div');
489
+ tagFiltro.className = 'tag-filtro';
490
+ tagFiltro.innerHTML = `
491
+ ${labelTexto}
492
+ <button type="button" class="remover-filtro-btn" data-tipo="${tipoFiltro}" data-valor="${checkbox.value}">
493
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
494
+ <line x1="18" y1="6" x2="6" y2="18"></line>
495
+ <line x1="6" y1="6" x2="18" y2="18"></line>
496
+ </svg>
497
+ </button>
498
+ `;
499
+
500
+ // Adicionar ao container
501
+ filtrosAtivosContainer.appendChild(tagFiltro);
502
+ });
503
+ });
504
+
505
+ // Adicionar eventos aos botões de remover filtro
506
+ document.querySelectorAll('.remover-filtro-btn').forEach(btn => {
507
+ btn.addEventListener('click', function(e) {
508
+ e.preventDefault();
509
+ const tipo = this.getAttribute('data-tipo');
510
+ const valor = this.getAttribute('data-valor');
511
+ removerFiltro(tipo, valor);
512
+ });
513
+ });
514
+
515
+ // Mostrar ou ocultar botão "Limpar todos"
516
+ if (limparTodosBtn) {
517
+ limparTodosBtn.style.display = temFiltrosAtivos ? 'inline-block' : 'none';
334
518
  }
335
- });
336
- });
337
-
338
- // Fecha dropdowns ao clicar fora
339
- document.addEventListener('click', function(event) {
340
- if (!event.target.closest('.categoria-dropdown')) {
341
- document.querySelectorAll('.categoria-dropdown').forEach(dropdown => {
342
- dropdown.classList.remove('active');
343
- const header = dropdown.querySelector('.categoria-cabecalho');
344
- const opcoes = dropdown.querySelector('.categoria-opcoes');
345
- header.setAttribute('aria-expanded', 'false');
346
- opcoes.classList.remove('open');
519
+ }
520
+
521
+ // Função para atualizar a URL com os filtros selecionados
522
+ function atualizarURL() {
523
+ const urlParams = new URLSearchParams();
524
+
525
+ // Coletar todos os filtros ativos
526
+ checkboxes.forEach(checkbox => {
527
+ if (checkbox.checked) {
528
+ urlParams.append(checkbox.getAttribute('data-filtro-tipo'), checkbox.value);
529
+ }
347
530
  });
531
+
532
+ // Atualizar URL sem recarregar a página
533
+ const newUrl = window.location.pathname + (urlParams.toString() ? '?' + urlParams.toString() : '');
534
+ history.pushState(null, '', newUrl);
348
535
  }
536
+
537
+ // Função para remover um filtro específico
538
+ function removerFiltro(tipo, valor) {
539
+ const checkbox = document.querySelector(`input[data-filtro-tipo="${tipo}"][value="${valor}"]`);
540
+ if (checkbox) {
541
+ checkbox.checked = false;
542
+ aplicarFiltros();
543
+ atualizarFiltrosAtivos();
544
+ atualizarURL();
545
+ }
546
+ }
547
+
548
+ // Função para limpar todos os filtros
549
+ function limparTodosFiltros() {
550
+ checkboxes.forEach(checkbox => {
551
+ checkbox.checked = false;
552
+ });
553
+
554
+ aplicarFiltros();
555
+ atualizarFiltrosAtivos();
556
+ atualizarURL();
557
+ }
558
+
559
+ // Tornar funções acessíveis globalmente (fallback)
560
+ window.removerFiltro = removerFiltro;
561
+ window.limparTodosFiltros = limparTodosFiltros;
349
562
  });
350
- </script>
563
+ </script>
351
564
  {% endblock %}