Uma loja de tecnologia com filtros por categoria e busca em tempo real — projeto construído ao vivo durante um bootcamp de 7 dias.
A TechStore foi desenvolvida durante o Bootcamp Programador de IA em 7 dias, ministrado por Rodolfo Mori. O projeto foi construído ao vivo, acompanhando cada etapa do zero — estrutura HTML, estilização CSS e lógica JavaScript.
Mais do que replicar o que estava sendo ensinado, o objetivo pessoal foi entender cada decisão tomada durante a live e ser capaz de reproduzir a mesma lógica em projetos futuros de forma independente.
O resultado é uma loja de tecnologia com catálogo dinâmico, filtros por categoria e busca em tempo real — tudo em JavaScript puro, sem frameworks.
| Desktop | Mobile |
|---|---|
![]() |
![]() |
- Catálogo de 8 produtos renderizado dinamicamente via JavaScript — nenhum card está no HTML
- Filtro por categoria — Smartphones, Notebooks, Fones, Acessórios e SmartWatches
- Busca em tempo real — filtra pelo nome do produto a cada caractere digitado
- Filtros combinados — busca e categoria funcionam juntos simultaneamente
- Hero banner com gradiente laranja → azul para campanha de Black Friday
- Hover nos cards com elevação via
translateYe troca de sombra - Totalmente responsivo — layout em grid adaptado para mobile com coluna única
| Tecnologia | Uso |
|---|---|
| HTML5 semântico | Estrutura da página com header, nav, main e footer |
| CSS3 com custom properties | Design system com variáveis de cor e grid responsivo |
| JavaScript vanilla | Renderização dos cards, filtros e busca em tempo real |
| Font Awesome 6 | Ícones das categorias e da busca |
Nenhuma dependência de frontend além do Font Awesome via CDN. Zero
npm install.
techstore/
├── index.html # Estrutura da página (sem cards — renderizados via JS)
├── scripts.js # Dados dos produtos, filtros e renderização
└── style.css # Design system, grid e responsividade
A filtragem aplica categoria e texto de busca como predicados separados dentro de um único .filter(). Isso significa que os dois filtros se combinam naturalmente sem lógica extra:
let produtosFiltrados = produtos.filter(prd => {
let passouCategoria = (categoriaAtual === "all" || prd.categoria === categoriaAtual);
let passouPesquisa = prd.nome.toLowerCase().includes(textoPesquisa);
return passouPesquisa && passouCategoria;
});Trocar a categoria não reseta a busca, e digitar na busca não reseta a categoria — os dois estados coexistem.
A função trocarCategoria() é responsável por duas coisas ao mesmo tempo: atualizar o estado interno categoriaAtual e refletir o botão ativo visualmente. Dessa forma, a UI nunca fica dessincronizada com o que está sendo filtrado:
function trocarCategoria(categoria) {
categoriaAtual = categoria;
todosBotoes.forEach(botao => {
botao.classList.remove("active");
if (botao.getAttribute("data-category") === categoria) {
botao.classList.add("active");
}
});
mostrarProdutos();
}Os cards são gerados como HTML string e inseridos de uma vez via innerHTML, evitando múltiplas operações no DOM:
produtosFiltrados.forEach((prd) => {
htmlProdutos += `<div class="product-card">
<img src="${prd.imagem}" alt="${prd.nome}">
...
</div>`;
});
containerProdutos.innerHTML = htmlProdutos;| Etapa | O que foi feito |
|---|---|
| 01 | Estrutura HTML com header, barra de categorias, hero e main |
| 02 | Design system em CSS com variáveis de cor e estilização do header |
| 03 | Array de produtos e função mostrarProdutos() com renderização via JS |
| 04 | Filtro por categoria com atualização do botão ativo |
| 05 | Busca em tempo real com input event listener |
| 06 | Combinação dos dois filtros em um único .filter() |
| 07 | Responsividade para mobile com grid de coluna única |
- Teria separado os dados dos produtos em um arquivo
data.jsdesde o início, para manter oscripts.jsfocado apenas na lógica - Teria adicionado um estado de "nenhum resultado encontrado" quando a combinação de filtros retorna zero produtos
- Teria usado
textContentao invés de interpolar diretamente no template string para evitar possíveis problemas com nomes de produtos que contenham caracteres especiais
TULIO VITOR
Feito com muito ☕ e muito ⚡

