Skip to content

Commit a189e80

Browse files
add filtro departamento e status
1 parent 08e7c1b commit a189e80

File tree

2 files changed

+185
-75
lines changed

2 files changed

+185
-75
lines changed

src/components/IniciativasProjetosDePesquisaSection.astro

Lines changed: 164 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ const { textos, iniciativas, projetos = [] } = Astro.props;
44
const projetosData = iniciativas?.projetosLista || projetos || [];
55
66
console.log("Total de projetos:", projetosData.length);
7-
console.log("Estrutura do primeiro projeto:", Object.keys(projetosData[0] || {}));
7+
console.log(
8+
"Estrutura do primeiro projeto:",
9+
Object.keys(projetosData[0] || {}),
10+
);
811
912
const url = new URL(Astro.request.url);
1013
const ordemValida = ["titulo", "docente", "periodo"];
@@ -21,18 +24,31 @@ const agenciaInicial = agenciaParam || "";
2124
{iniciativas?.projetosDePesquisa ?? "Projetos de Pesquisa"}
2225
</h1>
2326
<p class="text-lg text-base-content max-w-3xl mx-auto">
24-
{iniciativas?.descricaoProjetosDePesquisa ?? "Projetos desenvolvidos por docentes e associados ao CPPS."}
27+
{
28+
iniciativas?.descricaoProjetosDePesquisa ??
29+
"Projetos desenvolvidos por docentes e associados ao CPPS."
30+
}
2531
</p>
2632
</div>
2733

28-
<div class="flex flex-wrap gap-4 items-center justify-start mb-4 p-4 bg-base-200 rounded-lg">
34+
<div
35+
class="flex flex-wrap gap-4 items-center justify-start mb-4 p-4 bg-base-200 rounded-lg"
36+
>
2937
<span class="font-semibold text-base-content">
3038
{iniciativas?.ordenarPor ?? "Ordenar por"}:
3139
</span>
3240
<div class="btn-group" id="ordenacao-botoes">
33-
<button class="btn btn-sm btn-outline" onclick="ordenarProjetos('titulo')">Título</button>
34-
<button class="btn btn-sm btn-outline" onclick="ordenarProjetos('docente')">Docente</button>
35-
<button class="btn btn-sm btn-outline" onclick="ordenarProjetos('periodo')">Período</button>
41+
<button class="btn btn-sm btn-outline" onclick="ordenarProjetos('titulo')"
42+
>Título</button
43+
>
44+
<button
45+
class="btn btn-sm btn-outline"
46+
onclick="ordenarProjetos('docente')">Docente</button
47+
>
48+
<button
49+
class="btn btn-sm btn-outline"
50+
onclick="ordenarProjetos('periodo')">Período</button
51+
>
3652
</div>
3753
</div>
3854

@@ -59,18 +75,35 @@ const agenciaInicial = agenciaParam || "";
5975
<div class="md:flex md:gap-4">
6076
<label class="form-control md:w-1/2">
6177
<span class="label-text">Departamento</span>
62-
<select id="filtro-departamento" class="select select-bordered select-sm">
63-
<option value="">Todos</option>
64-
</select>
78+
<select
79+
id="filtro-departamento"
80+
class="select select-bordered select-sm"></select>
81+
</label>
82+
<label class="form-control md:w-1/2">
83+
<span class="label-text">Status</span>
84+
<select id="filtro-status" class="select select-bordered select-sm"
85+
></select>
6586
</label>
6687
<div class="flex gap-4">
6788
<label class="form-control w-32">
6889
<span class="label-text">Ano Início</span>
69-
<input type="number" id="filtro-inicio" class="input input-bordered input-sm" min="1900" max="2100" />
90+
<input
91+
type="number"
92+
id="filtro-inicio"
93+
class="input input-bordered input-sm"
94+
min="1900"
95+
max="2100"
96+
/>
7097
</label>
7198
<label class="form-control w-32">
7299
<span class="label-text">Ano Fim</span>
73-
<input type="number" id="filtro-fim" class="input input-bordered input-sm" min="1900" max="2100" />
100+
<input
101+
type="number"
102+
id="filtro-fim"
103+
class="input input-bordered input-sm"
104+
min="1900"
105+
max="2100"
106+
/>
74107
</label>
75108
</div>
76109
</div>
@@ -91,168 +124,224 @@ const agenciaInicial = agenciaParam || "";
91124

92125
<div id="no-projects-message" class="hidden text-center py-12">
93126
<div class="text-6xl mb-4">📂</div>
94-
<p class="text-xl font-semibold">Nenhum projeto encontrado com os filtros selecionados.</p>
127+
<p class="text-xl font-semibold">
128+
Nenhum projeto encontrado com os filtros selecionados.
129+
</p>
95130
</div>
96131
</section>
97132

98133
<script is:inline define:vars={{ projetosData, ordemInicial, agenciaInicial }}>
99134
let allProjects = projetosData || [];
100-
let currentSort = ordemInicial || 'titulo';
101-
let currentOrder = 'asc';
102-
let currentFilter = agenciaInicial || '';
135+
let currentSort = ordemInicial || "titulo";
136+
let currentOrder = "asc";
137+
let currentFilter = agenciaInicial || "";
103138

104139
function escapeHtml(text) {
105-
if (!text) return '';
106-
const div = document.createElement('div');
140+
if (!text) return "";
141+
const div = document.createElement("div");
107142
div.textContent = text;
108143
return div.innerHTML;
109144
}
110145

146+
function preencherDepartamentosEStatus() {
147+
const selectDep = document.getElementById("filtro-departamento");
148+
const selectStatus = document.getElementById("filtro-status");
149+
if (!selectDep || !selectStatus) return;
150+
151+
const departamentos = [
152+
...new Set(allProjects.map((p) => p.departamento).filter(Boolean)),
153+
].sort();
154+
const statusList = [
155+
...new Set(allProjects.map((p) => p.status).filter(Boolean)),
156+
].sort();
157+
158+
selectDep.innerHTML =
159+
'<option value="">Todos</option>' +
160+
departamentos.map((d) => `<option>${escapeHtml(d)}</option>`).join("");
161+
selectStatus.innerHTML =
162+
'<option value="">Todos</option>' +
163+
statusList.map((s) => `<option>${escapeHtml(s)}</option>`).join("");
164+
}
165+
111166
function getPeriodoAno(periodo) {
112-
const match = (periodo || '').match(/\d{4}/g);
167+
const match = (periodo || "").match(/\d{4}/g);
113168
return match ? match.map(Number) : [];
114169
}
115170

116171
function sortProjects(projects, ordem) {
117172
return [...projects].sort((a, b) => {
118-
const valA = (a[ordem] ?? '').toString();
119-
const valB = (b[ordem] ?? '').toString();
173+
const valA = (a[ordem] ?? "").toString();
174+
const valB = (b[ordem] ?? "").toString();
120175

121-
if (ordem === 'periodo') {
176+
if (ordem === "periodo") {
122177
const anoA = getPeriodoAno(valA)[0] || 0;
123178
const anoB = getPeriodoAno(valB)[0] || 0;
124-
return currentOrder === 'asc' ? anoA - anoB : anoB - anoA;
179+
return currentOrder === "asc" ? anoA - anoB : anoB - anoA;
125180
}
126181

127-
return currentOrder === 'asc'
128-
? valA.localeCompare(valB, 'pt-BR')
129-
: valB.localeCompare(valA, 'pt-BR');
182+
return currentOrder === "asc"
183+
? valA.localeCompare(valB, "pt-BR")
184+
: valB.localeCompare(valA, "pt-BR");
130185
});
131186
}
132187

133188
function filterProjects(projects) {
134-
const agencia = document.getElementById('filtro-agencia')?.value || '';
135-
const docente = document.getElementById('filtro-docente')?.value || '';
136-
const inicio = parseInt(document.getElementById('filtro-inicio')?.value);
137-
const fim = parseInt(document.getElementById('filtro-fim')?.value);
138-
const mensagem = document.getElementById('mensagem-periodo-invalido');
189+
const agencia = document.getElementById("filtro-agencia")?.value || "";
190+
const docente = document.getElementById("filtro-docente")?.value || "";
191+
const inicio = parseInt(document.getElementById("filtro-inicio")?.value);
192+
const fim = parseInt(document.getElementById("filtro-fim")?.value);
193+
const mensagem = document.getElementById("mensagem-periodo-invalido");
194+
const status = document.getElementById("filtro-status")?.value || "";
195+
const departamento =
196+
document.getElementById("filtro-departamento")?.value || "";
139197

140198
if (inicio && fim && inicio > fim) {
141-
mensagem.classList.remove('hidden');
199+
mensagem.classList.remove("hidden");
142200
return [];
143201
} else {
144-
mensagem.classList.add('hidden');
202+
mensagem.classList.add("hidden");
145203
}
146204

147-
return projects.filter(p => {
205+
return projects.filter((p) => {
148206
if (agencia && p.agencia !== agencia) return false;
149207
if (docente && p.docente !== docente) return false;
208+
if (status && p.status !== status) return false;
209+
if (departamento && p.departamento !== departamento) return false;
150210
const anos = getPeriodoAno(p.periodo);
151211
if (inicio && (!anos[0] || anos[0] < inicio)) return false;
152212
if (fim && (!anos[1] || anos[1] > fim)) return false;
153213
return true;
154214
});
155215
}
156216

157-
function renderProject(p, index) {
158-
const id = `extra-info-${index}`;
217+
function renderProject(p, index) {
218+
const id = `extra-info-${index}`;
159219

160-
const temExtras = p.publico_alvo || p.resultados || p.links || p.processo || p.natureza || p.valor || p.associados || p.apoioCentro;
220+
const temExtras =
221+
p.publico_alvo ||
222+
p.resultados ||
223+
p.links ||
224+
p.processo ||
225+
p.natureza ||
226+
p.valor ||
227+
p.associados ||
228+
p.apoioCentro;
161229

162-
return `
230+
return `
163231
<article class="card bg-base-100 shadow border border-base-300 transition-all duration-300">
164232
<div class="card-body">
165233
<h2 class="card-title text-primary">${escapeHtml(p.titulo)}</h2>
166234
<p><strong>Docente responsável:</strong> ${escapeHtml(p.docente)}</p>
167-
<p class="text-sm text-base-content/70">Departamento: ${escapeHtml(p.departamento || '')}</p>
235+
<p class="text-sm text-base-content/70">Departamento: ${escapeHtml(p.departamento || "")}</p>
168236
<p><strong>Agência:</strong> ${escapeHtml(p.agencia)} | <strong>Período:</strong> ${escapeHtml(p.periodo)}</p>
169237

170238
<p class="mt-2 text-base-content/80">
171-
<strong>Resumo:</strong> ${escapeHtml(p.resumo || '')}
239+
<strong>Resumo:</strong> ${escapeHtml(p.resumo || "")}
172240
</p>
173241

174242
<div id="${id}" class="hidden mt-2 space-y-2 text-base-content/80">
175-
${p.publico_alvo ? `<p><strong>Público-alvo:</strong> ${escapeHtml(p.publico_alvo)}</p>` : ''}
176-
${p.resultados ? `<p><strong>Resultados esperados:</strong> ${escapeHtml(p.resultados)}</p>` : ''}
177-
${p.links ? `<p><strong>Links:</strong> <a href="${escapeHtml(p.links)}" target="_blank" class="link link-primary">${escapeHtml(p.links)}</a></p>` : ''}
178-
${p.processo ? `<p><strong>Nº do Processo:</strong> ${escapeHtml(p.processo)}</p>` : ''}
179-
${p.natureza ? `<p><strong>Natureza:</strong> ${escapeHtml(p.natureza)}</p>` : ''}
180-
${p.valor ? `<p><strong>Valor Financiado:</strong> ${escapeHtml(p.valor)}</p>` : ''}
181-
${p.associados ? `<p><strong>Pesquisadores Associados:</strong> ${escapeHtml(p.associados)}</p>` : ''}
182-
${Array.isArray(p.apoioCentro) && p.apoioCentro.length > 0
183-
? `<div><strong>Apoio do CPPS:</strong><ul class="list-disc ml-6">${p.apoioCentro.map(item => `<li>${escapeHtml(item)}</li>`).join('')}</ul></div>`
184-
: ''}
243+
${p.publico_alvo ? `<p><strong>Público-alvo:</strong> ${escapeHtml(p.publico_alvo)}</p>` : ""}
244+
${p.resultados ? `<p><strong>Resultados esperados:</strong> ${escapeHtml(p.resultados)}</p>` : ""}
245+
${p.links ? `<p><strong>Links:</strong> <a href="${escapeHtml(p.links)}" target="_blank" class="link link-primary">${escapeHtml(p.links)}</a></p>` : ""}
246+
${p.processo ? `<p><strong>Nº do Processo:</strong> ${escapeHtml(p.processo)}</p>` : ""}
247+
${p.natureza ? `<p><strong>Natureza:</strong> ${escapeHtml(p.natureza)}</p>` : ""}
248+
${p.valor ? `<p><strong>Valor Financiado:</strong> ${escapeHtml(p.valor)}</p>` : ""}
249+
${p.associados ? `<p><strong>Pesquisadores Associados:</strong> ${escapeHtml(p.associados)}</p>` : ""}
250+
${
251+
Array.isArray(p.apoioCentro) && p.apoioCentro.length > 0
252+
? `<div><strong>Apoio do CPPS:</strong><ul class="list-disc ml-6">${p.apoioCentro.map((item) => `<li>${escapeHtml(item)}</li>`).join("")}</ul></div>`
253+
: ""
254+
}
185255
</div>
186256

187-
${temExtras
188-
? `<button class="btn btn-sm btn-link text-primary-content px-0" onclick="toggleExtra('${id}', this)">Mostrar mais</button>`
189-
: ''}
257+
${
258+
temExtras
259+
? `<button class="btn btn-sm btn-link text-primary-content px-0" onclick="toggleExtra('${id}', this)">Mostrar mais</button>`
260+
: ""
261+
}
190262
</div>
191263
</article>`;
192-
}
264+
}
193265

194266
function renderProjects() {
195-
const list = document.getElementById('lista-projetos');
196-
const noResults = document.getElementById('no-projects-message');
267+
const list = document.getElementById("lista-projetos");
268+
const noResults = document.getElementById("no-projects-message");
197269
const filtered = filterProjects(allProjects);
198270
const sorted = sortProjects(filtered, currentSort);
199271

200-
list.innerHTML = sorted.map((p, i) => renderProject(p, i)).join('');
201-
document.getElementById('project-counter').textContent = sorted.length;
202-
noResults.classList.toggle('hidden', sorted.length > 0);
272+
list.innerHTML = sorted.map((p, i) => renderProject(p, i)).join("");
273+
document.getElementById("project-counter").textContent = sorted.length;
274+
noResults.classList.toggle("hidden", sorted.length > 0);
203275
atualizarBotoes(currentSort, currentOrder);
204276
}
205277

206278
function ordenarProjetos(criterio) {
207279
if (currentSort === criterio) {
208-
currentOrder = currentOrder === 'asc' ? 'desc' : 'asc';
280+
currentOrder = currentOrder === "asc" ? "desc" : "asc";
209281
} else {
210282
currentSort = criterio;
211-
currentOrder = 'asc';
283+
currentOrder = "asc";
212284
}
213285
renderProjects();
214286
}
215287

216288
function atualizarBotoes(criterioAtivo, ordemAtual) {
217289
const icones = {
218290
asc: `<svg xmlns="http://www.w3.org/2000/svg" class="w-4 h-4 ml-1" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 15l7-7 7 7" /></svg>`,
219-
desc: `<svg xmlns="http://www.w3.org/2000/svg" class="w-4 h-4 ml-1" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" /></svg>`
291+
desc: `<svg xmlns="http://www.w3.org/2000/svg" class="w-4 h-4 ml-1" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" /></svg>`,
220292
};
221293

222-
document.querySelectorAll('#ordenacao-botoes button').forEach(btn => {
223-
const criterio = btn.getAttribute('onclick')?.match(/'([^']+)'/)?.[1];
224-
const label = criterio === 'titulo' ? 'Título' : criterio === 'docente' ? 'Docente' : 'Período';
294+
document.querySelectorAll("#ordenacao-botoes button").forEach((btn) => {
295+
const criterio = btn.getAttribute("onclick")?.match(/'([^']+)'/)?.[1];
296+
const label =
297+
criterio === "titulo"
298+
? "Título"
299+
: criterio === "docente"
300+
? "Docente"
301+
: "Período";
225302

226303
if (criterio === criterioAtivo) {
227-
btn.className = 'btn btn-sm btn-primary';
304+
btn.className = "btn btn-sm btn-primary";
228305
btn.innerHTML = `${label}${icones[ordemAtual]}`;
229306
} else {
230-
btn.className = 'btn btn-sm btn-outline';
307+
btn.className = "btn btn-sm btn-outline";
231308
btn.innerHTML = label;
232309
}
233310
});
234311
}
235312

236313
function preencherDocentes() {
237-
const select = document.getElementById('filtro-docente');
314+
const select = document.getElementById("filtro-docente");
238315
if (!select) return;
239-
const docentes = [...new Set(allProjects.map(p => p.docente).filter(Boolean))].sort();
240-
select.innerHTML = '<option value="">Todos</option>' + docentes.map(d => `<option>${escapeHtml(d)}</option>`).join('');
316+
const docentes = [
317+
...new Set(allProjects.map((p) => p.docente).filter(Boolean)),
318+
].sort();
319+
select.innerHTML =
320+
'<option value="">Todos</option>' +
321+
docentes.map((d) => `<option>${escapeHtml(d)}</option>`).join("");
241322
}
242323

243324
function toggleExtra(id, btn) {
244325
const el = document.getElementById(id);
245326
if (!el) return;
246327

247-
const expanded = !el.classList.contains('hidden');
248-
el.classList.toggle('hidden');
249-
btn.textContent = expanded ? 'Mostrar mais' : 'Mostrar menos';
328+
const expanded = !el.classList.contains("hidden");
329+
el.classList.toggle("hidden");
330+
btn.textContent = expanded ? "Mostrar mais" : "Mostrar menos";
250331
}
251332

252-
document.addEventListener('DOMContentLoaded', () => {
333+
document.addEventListener("DOMContentLoaded", () => {
253334
preencherDocentes();
254-
['filtro-agencia', 'filtro-docente', 'filtro-inicio', 'filtro-fim'].forEach(id => {
255-
document.getElementById(id)?.addEventListener('input', renderProjects);
335+
preencherDepartamentosEStatus();
336+
[
337+
"filtro-agencia",
338+
"filtro-docente",
339+
"filtro-inicio",
340+
"filtro-fim",
341+
"filtro-status",,
342+
"filtro-departamento"
343+
].forEach((id) => {
344+
document.getElementById(id)?.addEventListener("input", renderProjects);
256345
});
257346
renderProjects();
258347
});

0 commit comments

Comments
 (0)