Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
c66f352
Initial commit
allbertuu Feb 11, 2026
7d32c7d
Merge branch 'master' of https://github.com/allbertuu/pokedex
allbertuu Feb 11, 2026
e9f67ab
chore: delete `logo.png`
allbertuu Feb 11, 2026
4dd853f
feat: Pokémon listing feature (ML2)
allbertuu Feb 11, 2026
3709815
chore: delete `package-lock.json`
allbertuu Feb 11, 2026
7812c14
test: Pokémon listing feature (ML2)
allbertuu Feb 11, 2026
341e49f
Merge branch 'master' of https://github.com/allbertuu/pokedex
allbertuu Feb 11, 2026
16adafa
test(PokémonList): refactor tests to use mock data
allbertuu Feb 11, 2026
cbc74cf
refactor: move `Pokemon` type definition to a separate file
allbertuu Feb 11, 2026
bd86fce
feat(PokemonsList): add loading icon indicator
allbertuu Feb 11, 2026
d03baa2
feat(PokemonsList): add `tabIndex` for keyboard navigation accessibility
allbertuu Feb 12, 2026
476ff57
fix(styles): change bg color to css style
allbertuu Feb 12, 2026
868fb0b
test(PokemonsList): enhance tests for `Pokémon` information display a…
allbertuu Feb 12, 2026
1db024a
fix(pokedex): use `getPokemonByName` from `pokenode-ts`
allbertuu Feb 12, 2026
ea0a025
feat(home): add search and filtering functionality for `PokémonsList`
allbertuu Feb 12, 2026
9f6c8ec
feat(home): add search and filtering functionality for `PokémonsList`…
allbertuu Feb 12, 2026
8ea6be4
Merge branch 'master' of https://github.com/allbertuu/pokedex
allbertuu Feb 12, 2026
5dbe074
docs(readme): add README for onboarding and project overview
allbertuu Feb 13, 2026
19052ef
docs(readme): update README with images
allbertuu Feb 13, 2026
90de7d2
Atualizar o README.md
allbertuu Jul 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .cta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"projectName": "pokedex",
"mode": "file-router",
"typescript": true,
"packageManager": "npm",
"tailwind": true,
"addOnOptions": {},
"git": true,
"version": 1,
"framework": "react-cra",
"chosenAddOns": [
"biome"
]
}
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
node_modules
.DS_Store
dist
dist-ssr
*.local
count.txt
.env
.nitro
.tanstack
.wrangler
*-lock.json
35 changes: 35 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"files.watcherExclude": {
"**/routeTree.gen.ts": true
},
"search.exclude": {
"**/routeTree.gen.ts": true
},
"files.readonlyInclude": {
"**/routeTree.gen.ts": true
},
"[javascript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[javascriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[json]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[jsonc]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[css]": {
"editor.defaultFormatter": "biomejs.biome"
},
"editor.codeActionsOnSave": {
"source.organizeImports.biome": "explicit"
}
}
189 changes: 137 additions & 52 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,52 +1,137 @@
### Would you like to work with us? Apply [here](https://looqbox.gupy.io/)!

# Looqbox FrontEnd Challenge
![Looqbox](https://github.com/looqbox/looqbox-frontend-challenge/blob/master/logo.png)

## Challenge
In this challenge you will need to build a **S**ingle **P**age **A**pplication using ReactJS and a provided api

We will not use anything from your project other than evaluate your skills and you are free to use it in your portfolio

## Stack
We use:
- ReactJS
- Redux
- TypeScript
- AntDesign

## Submitting
- Make a fork of this repository
- Create your branch
- ⚠️ Do a initial Commit when you start
- ⚠️ Do a final commit when you finish
- When you're done send us a pull request

# Guidelines
You need to create a Single Page Application (SPA) that displays a list of Pokémon and allows users to search for them, using the [Pokeapi](https://pokeapi.co/docs/v2). Your app must be dynamic, meaning you **must not** reload the page to show new content.

The PokeAPI was chosen for its simplicity in making requests. Since it is an open API, please **be mindful of how many requests** you make.

## Requirements:

- On the main page, include a search bar and a preloaded list of Pokémon.
- Clicking on any Pokémon should display a card, modal, or page with that Pokémon’s information.
- Typing in the search bar and pressing Enter should display the search result instead of the list.
- Your app must include at least two different routes (e.g., /home, /details — be creative!).
- Add a README file to document your project.

You may use any libraries or dependencies you like (e.g., Axios, Bootstrap, Material UI...).

## Bonus points!
- Pagination
- Error handling
- Documentation
- Linting
- Charts
- Unit Testing
- Ant Design

## Useful links
- [React docs](https://react.dev/)
- [PokeApi docs](https://pokeapi.co/docs/v2)
- [Redux](https://redux.js.org/)
# Guia de bolso para projetos de software (Pokédex)

Bem-vindo(a)!
Pokédex, lista de Pokémons... De novo? Bom, sim e não. É óbvio que este projeto não é sobre código complexo (nem deveria), grandes arquiteturas e novos padrões de desenvolvimento. Até porquê se fosse eu não teria feito uma Pokédex. Mas você já se perguntou quais elementos formam um bom projeto de software?

Vou te perguntar de outra forma. Porquê quando você acessa esse tipo de projeto, tão simples, você ainda pode encontrar, com bastante frequência, um código nada intuitivo e fácil de manter?

Eu posso chutar uma razão: porquê para que um projetos simples ou complexo, tanto faz, possa ser fácil de mudar e satisfatório para o(s) usuário(s), esse projeto **depende da preparação e simplicidade do idealizador e abordagem pragmática e simplicidade do desenvolvedor.** Nessa matemática, simplicidade conta em dobro.

Este projeto tenta provar esse argumento e oferecer um guia de bolso para caso você se esqueça, absorto no código e reuniões diárias, do que realmente importa para projetos de software fluírem bem, junto com você.

## Sumário

* [Funcionalidades](#funcionalidades)
* [Decisões Técnicas](#decisões-técnicas---e-porquê)
* [Tecnologias usadas](#tecnologias-usadas)
* [Próximos Passos (Roadmap)](#próximos-passos-roadmap)
* [Como rodar e revisar o projeto](#como-rodar-e-revisar-o-projeto)

---

## Funcionalidades

Aqui está o resumo das funcionalidades implementadas.

* **🔍 Busca:** Barra de busca funcional na página principal. Ao pressionar **Enter**, a lista é filtrada dinamicamente, priorizando a intenção do usuário.
* **📜 Listagem:** Lista de Pokémons pré-carregada para evitar telas vazias no primeiro acesso.
* **📑 Detalhes (incompleto):** Página dedicada para cada Pokémon, exibindo informações, estatísticas e gráficos.
* **🛣️ Roteamento Avançado:** Navegação multipáginas utilizando um sistema de rotas baseado em arquivos (`/home` e `/details/$pokemonName`).
* **♿ Acessibilidade (A11y):** Navegação completa via teclado. Use `Tab` para percorrer e `Enter` para selecionar.
* **🖼️ Fallback de Imagem:** Tratativa para Pokémons sem foto oficial com a clássica imagem do *"Quem é esse Pokémon?"*.
<img width="263" height="324" alt="image" src="https://github.com/user-attachments/assets/09ff6571-5fcc-4d5b-9c82-078c0ad1475c" />

### Bonus!

Os seguintes itens extras que garantem a robustez do projeto:

* [x] **Error Handling:** Sistema de captura de erros com feedback visual e contato direto com o dev.
* [x] **Documentation:** Este guia completo de onboarding.
* [x] **Linting:** Configuração rigorosa com Biome para código limpo.
* [ ] **Charts (incompleto):** Visualização de stats com Recharts.
* [x] **Unit Testing:** Lógica central testada com Vitest.

## Decisões técnicas – e porquê

Minha maior decisão técnica foi separar as responsabilidades da `PokemonsList`. Segui uma arquitetura **inspirada no MVC (Model-View-Controller)** adaptada ao ecossistema React.

<img width="614" height="127" alt="image" src="https://github.com/user-attachments/assets/960d177f-fa00-46f6-bc90-00e6e18e1f8e" />

### 1. A Camada de Serviço (Service Layer)
Isolei toda a comunicação externa e as regras de negócio em `src/services/pokedex.ts`.

* **Por que?** Desacoplamento total. Se a PokéAPI mudar seus tipos, métodos etc ou se precisarmos trocar a biblioteca de fetch, a interface do usuário permanece intacta.

### 2. Separação entre tratamento dos dados e renderização

Deleguei o controle do fluxo de dados (loading, erro, filtragem e fetching) para um **hook personalizado integrado ao Context**.

* **Por que?** A `PokemonsList` foca 100% na "View". Ela não sabe como os dados chegam; ela apenas os renderiza da melhor forma visual. Isso torna o código altamente testável e fácil de manter.

### 3. UX na busca por Pokémon

* **Tratativa de 404:** Em vez de exibir um erro sistêmico, trato o "Not Found" como um estado da interface, informando amigavelmente que nenhum Pokémon foi encontrado.
* **Feedback Proativo:** Implementei uma forma de contato direto comigo que envia o erro automaticamente.
<img width="519" alt="image" src="https://github.com/user-attachments/assets/596c1d1c-a4dd-4aa3-8390-b2c1a9ef4e6a" />


## Tecnologias usadas

> **Atenção:** Toda decisão técnica serve apenas para este snapshot do projeto. Não me preocupo em mudar de ideia, caso os requisitos e contexto mudem. A melhor decisão é a que resolve o problema do negócio com a ferramenta que traz menos colaterais indesejáveis.

| Tecnologia | Por que usei? |
| --- | --- |
| **Vite** | Aplicação simples, poucas rotas e sem necessidade de SEO pesado. Custo de deploy menor (Static) sem precisar de servidor Node.js para SSR. |
| **TanStack Router** | Roteamento robusto com **Type Safety** absoluto e excelente suporte para *search params* (rota `/details`). |
| **TailwindCSS** | Optei por não usar libs de componentes (como AntDesign) para manter o bundle leve e ter controle total do design (algo que valorizo muito) sem "sobrescrever" estilos pesados. Cuidei para que a interface tivessse boa acessibilidade, ainda que dessa forma mais "crua". |
| **Biome** | Toolchain *all-in-one* para lint e format. Mais rápido que Prettier e com quase zero configuração. |
| **Vitest** | Rapidez e ótima DX para garantir que o "coração" da lógica esteja seguro, com bons testes automatizados. |
| **pokenode-ts** | Recomendação oficial da PokéAPI. Tipagem *built-in* que facilita a integração e paginação, além de função de cache configurado com Axios. |

#### Detalhe para os tipos - arquivos `.d.ts`

Utilizei arquivos de definição de tipos específicos para não "sujar" o código de produção com tipos que não geram código executável.

## Próximos Passos (Roadmap)

Se eu tivesse mais tempo (ou para uma V2), meu foco seria:

* **GraphQL:** Implementar para evitar *over-fetching* na home, buscando e organizando apenas os dados estritamente necessários para a listagem inicial.
* **Paginação:** Dessa forma a página inicial pode mostrar mais Pokémons e o usuário navegar na vasta coleção que existe. O módulo `pokenode-ts` facilita esse processo ainda mais.
* **Busca por termo incompleto (fuzzy search):** Eu percebi que a PokéAPI não permite pesquisar dessa forma nativamente, como um _fuzzy search_. A aplicação hoje busca por termos exatos, mas seria muito legal implementar isso de alguma forma no futuro. As soluções que pensei eram desnecessariamente complexas...

## Como rodar e revisar o projeto:

1. Clone o repositório:

```bash
git clone https://github.com/allbertuu/pokedex.git
```

2. Acesse o diretório do projeto:

```bash
cd pokedex
```

3. Instale as dependências:

```bash
npm install
```

4. Inicie o servidor de desenvolvimento:

```bash
npm run dev
```

5. Abra o navegador e acesse:

```bash
http://localhost:3000
```

## Testes

Para executar os testes, utilize o comando:

```bash
npm test
```

**Recomendação de Revisão:** Comece pelo arquivo `src/services/pokedex.ts` (a base), passe pelo `src/contexts/PokemonContext.tsx` (a orquestração) e termine nos componentes da pasta `pages/`.

---

O código limpo, simples e bem planejado é, acima de tudo, um gesto de respeito aos colegas de equipe e usuários do sistema.
35 changes: 35 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"$schema": "https://biomejs.dev/schemas/2.2.4/schema.json",
"vcs": {
"enabled": false,
"clientKind": "git",
"useIgnoreFile": false
},
"files": {
"ignoreUnknown": false,
"includes": [
"**/src/**/*",
"**/.vscode/**/*",
"**/index.html",
"**/vite.config.ts",
"!**/src/routeTree.gen.ts",
"!**/src/styles.css"
]
},
"formatter": {
"enabled": true,
"indentStyle": "tab"
},
"assist": { "actions": { "source": { "organizeImports": "on" } } },
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"javascript": {
"formatter": {
"quoteStyle": "double"
}
}
}
21 changes: 21 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="/favicon.ico" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Pokédex, mas com a premissa de que clareza é uma funcionalidade."
/>
<link rel="apple-touch-icon" href="/logo192.png" />
<link rel="manifest" href="/manifest.json" />
<title>Pokédex</title>
</head>

<body>
<div id="app"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Binary file removed logo.png
Binary file not shown.
50 changes: 50 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"name": "pokedex",
"private": true,
"type": "module",
"scripts": {
"dev": "vite --port 3000",
"build": "vite build && tsc",
"preview": "vite preview",
"test": "vitest run",
"test:watch": "vitest run --watch",
"test:ui": "vitest --ui",
"format": "biome format",
"lint": "biome lint",
"check": "biome check",
"check:write": "biome check --write"
},
"dependencies": {
"@tailwindcss/vite": "^4.0.6",
"@tanstack/react-devtools": "^0.7.0",
"@tanstack/react-router": "^1.132.0",
"@tanstack/react-router-devtools": "^1.132.0",
"@tanstack/router-plugin": "^1.132.0",
"axios": "^1.13.5",
"axios-cache-interceptor": "^1.11.4",
"lucide-react": "^0.545.0",
"motion": "^12.34.0",
"pokenode-ts": "^1.20.0",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"recharts": "^3.7.0",
"tailwindcss": "^4.0.6"
},
"devDependencies": {
"@biomejs/biome": "2.2.4",
"@tanstack/devtools-vite": "^0.3.11",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "^14.6.1",
"@types/node": "^22.10.2",
"@types/react": "^19.2.0",
"@types/react-dom": "^19.2.0",
"@vitejs/plugin-react": "^5.0.4",
"jsdom": "^27.4.0",
"typescript": "^5.7.2",
"vite": "^7.1.7",
"vitest": "^3.2.4",
"web-vitals": "^5.1.0"
}
}
Binary file added public/favicon.ico
Binary file not shown.
Binary file added public/logo192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/logo512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions public/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"short_name": "TanStack App",
"name": "Create TanStack App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
3 changes: 3 additions & 0 deletions public/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
Binary file added public/tanstack-circle-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading