@@ -4,7 +4,10 @@ const { textos, iniciativas, projetos = [] } = Astro.props;
44const projetosData = iniciativas ?.projetosLista || projetos || [];
55
66console .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
912const url = new URL (Astro .request .url );
1013const 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