From 4aeb373d604d1ba44b3122a45b26bed5a709bd57 Mon Sep 17 00:00:00 2001 From: JotaChina Date: Mon, 15 Dec 2025 19:31:58 -0300 Subject: [PATCH] =?UTF-8?q?reforma=20da=20interface=20da=20p=C3=A1gina=20d?= =?UTF-8?q?e=20projetos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/projetos.md | 94 +++++++++++++++++++++++++++++++---------------- 1 file changed, 63 insertions(+), 31 deletions(-) diff --git a/pages/projetos.md b/pages/projetos.md index 9c1cc426..7e67d137 100755 --- a/pages/projetos.md +++ b/pages/projetos.md @@ -416,7 +416,7 @@ document.addEventListener('DOMContentLoaded', () => { const keyFilterSelect = document.getElementById('key-filter'); // CORREÇÃO 1: Pegar referência const projectsContainer = document.getElementById('projects-container'); - let currentGenre = 'all'; + let activeGenres = []; let currentMinStars = 'all'; fetch(JSON_URL) @@ -550,48 +550,74 @@ document.addEventListener('DOMContentLoaded', () => { function createGenreButtons(data) { const genres = new Set(); + + // Coleta todos os gêneros e subgêneros disponíveis data.forEach(i => { - // Macro Gênero if(i.analise_ia?.genero_macro && i.analise_ia.genero_macro !== "Unknown") genres.add(i.analise_ia.genero_macro); - // CORREÇÃO 4: Adicionar Subgêneros aos filtros if(Array.isArray(i.analise_ia?.nuvem_tags)) { i.analise_ia.nuvem_tags.forEach(t => { - // Adiciona se tiver tag e um score razoável (opcional, aqui pegamos tudo) if(t.tag) genres.add(t.tag); }); } }); + // Função auxiliar para resetar tudo para "Todos" + const resetToAll = () => { + activeGenres = []; + document.querySelectorAll('#genre-filters .button').forEach(b => { + b.classList.remove('is-active', 'is-info'); + b.classList.add('is-white'); + }); + const allBtn = document.querySelector('[data-genre="all"]'); + if(allBtn) { + allBtn.classList.remove('is-white'); + allBtn.classList.add('is-active', 'is-info'); + } + applyFilters(); + }; + + // Cria os botões Array.from(genres).sort().forEach(g => { const btn = document.createElement('button'); btn.className = 'button is-small is-rounded is-white'; - btn.textContent = g; // Exibe o nome do gênero + btn.textContent = g; + btn.onclick = () => { - document.querySelectorAll('#genre-filters .button').forEach(b => { - b.classList.remove('is-active', 'is-info'); - b.classList.add('is-white'); - }); - btn.classList.remove('is-white'); - btn.classList.add('is-active', 'is-info'); - currentGenre = g; - applyFilters(); + // 1. Se clicou em um gênero, o botão "Todos" deixa de ser ativo + const allBtn = document.querySelector('[data-genre="all"]'); + if(allBtn) { + allBtn.classList.remove('is-active', 'is-info'); + allBtn.classList.add('is-white'); + } + + // 2. Lógica de Alternar (Toggle) + if (activeGenres.includes(g)) { + // Se já está ativo, remove da lista e tira a cor + activeGenres = activeGenres.filter(item => item !== g); + btn.classList.remove('is-active', 'is-info'); + btn.classList.add('is-white'); + } else { + // Se não está, adiciona na lista e coloca cor + activeGenres.push(g); + btn.classList.remove('is-white'); + btn.classList.add('is-active', 'is-info'); + } + + // 3. Se a lista ficou vazia (desmarcou tudo), volta para "Todos" + if (activeGenres.length === 0) { + resetToAll(); + } else { + applyFilters(); + } }; genreContainer.appendChild(btn); }); + // Configura o botão "Todos" (Reset) const allBtn = genreContainer.querySelector('[data-genre="all"]'); - allBtn.onclick = () => { - document.querySelectorAll('#genre-filters .button').forEach(b => { - b.classList.remove('is-active', 'is-info'); - b.classList.add('is-white'); - }); - allBtn.classList.remove('is-white'); - allBtn.classList.add('is-active', 'is-info'); - currentGenre = 'all'; - applyFilters(); - }; + allBtn.onclick = resetToAll; } function applyFilters() { @@ -599,22 +625,28 @@ document.addEventListener('DOMContentLoaded', () => { const currentKey = document.getElementById('key-filter')?.value || 'all'; const col = c.closest('.project-column'); - const g = c.dataset.genre; // Gênero Macro - const sub = c.dataset.subgenres || ""; // Lista de subgêneros (string) + // Pega todos os dados do projeto (Macro + Subs) em minúsculo para comparar + const gMacro = (c.dataset.genre || "").toLowerCase(); + const gSubs = (c.dataset.subgenres || "").toLowerCase(); + const tagsDoProjeto = gMacro + "," + gSubs; const s = parseInt(c.dataset.stars || 0); const k = c.dataset.key || 'all'; - // CORREÇÃO 5: Lógica de Filtro Aprimorada - // Verifica se o gênero selecionado bate com o Macro OU se está contido nos subgêneros + // --- NOVA LÓGICA DE GÊNERO --- let matchG = false; - if (currentGenre === 'all') { + + // Se a lista estiver vazia, assume "Todos" + if (activeGenres.length === 0) { matchG = true; } else { - // Verifica match exato com Macro OU include na lista de subs - if (g === currentGenre) matchG = true; - if (sub.includes(currentGenre.toLowerCase())) matchG = true; + // Verifica se ALGUM dos gêneros selecionados está presente neste projeto + // Ex: Se selecionei ["Rock", "Piano"], mostra projetos que tenham Rock OU Piano + matchG = activeGenres.some(generoSelecionado => { + return tagsDoProjeto.includes(generoSelecionado.toLowerCase()); + }); } + // ----------------------------- const matchS = (currentMinStars === 'all' || s === parseInt(currentMinStars)); const matchK = (currentKey === 'all' || k === currentKey);