Aplicação web construída com React + TypeScript que consome a GitHub REST API para buscar perfis de usuários e explorar seus repositórios públicos.
MVP / Demo: https://githubhunter.vercel.app
- Busca de usuários por nome de usuário do GitHub
- Histórico de buscas
- Salva os últimos 5 usuários pesquisados no
localStorage - Permite reexecutar uma busca com 1 clique
- Salva os últimos 5 usuários pesquisados no
- Perfil completo
- Avatar, nome, bio
- E-mail, localização, empresa, website e Twitter (quando disponível)
- Seguidores/seguindo e total de repositórios públicos
- Featured Repositories (Home)
- Lista de repositórios populares do ecossistema moderno
- Ao clicar, navega para
/user/:usernamecomo um atalho para a busca
- Listagem de repositórios com ordenação por:
- Estrelas (maior/menor)
- Nome (A→Z / Z→A)
- Data de atualização (mais recente/mais antiga)
- Paginação incremental na listagem de repositórios
- Carrega uma primeira página (30 itens)
- Carregamento automático ao rolar (infinite scroll)
- Itens com efeito de fade-in conforme entram na viewport
- Página de detalhes de cada repositório
- Linguagem principal (com cor por linguagem)
- Estrelas, forks, watchers, issues
- Licença, branch padrão, datas e tópicos
- Link direto para o repositório e (quando existir) homepage/demo
- Estados de loading, erro e vazio tratados
- Skeleton loading para perfil e lista de repositórios
- Responsivo (mobile-first)
- Acessibilidade
aria-labelem controles relevantes- Navegação por teclado em cards clicáveis
O layout foi pensado para funcionar bem em telas pequenas e grandes.
A aplicação suporta dark mode (padrão) e light mode com um botão de alternância no header.
- Persistência: a preferência do tema é salva em
localStorage.
| Categoria | Tecnologia |
|---|---|
| Framework | React 18 + TypeScript |
| Build | Vite 5 |
| Roteamento | React Router DOM v6 |
| Estado global | Zustand (com devtools) |
| HTTP | Axios |
| UI Components | shadcn/ui (com Radix UI) |
| Estilização | Tailwind CSS v3 + tailwindcss-animate |
| Fontes | Syne + JetBrains Mono |
| Ícones | Lucide (lucide-react) |
| Testes | Vitest + Testing Library (jsdom) |
| Package manager | pnpm |
- Node.js >= 18
- pnpm >= 9
# Clone o repositório
git clone https://github.com/<seu-usuario>/github-hunter.git
cd github-hunter
# Instale as dependências
pnpm install
# Inicie o servidor de desenvolvimento
pnpm devA aplicação estará disponível em http://localhost:5173.
# Build para produção
pnpm build
# Preview do build de produção
pnpm preview
# Rodar testes (watch)
pnpm test
# Testes com UI interativa
pnpm test:ui
# Relatório de cobertura
pnpm test:coverage
# Lint
pnpm lint
# Formatador (Prettier)
pnpm format
# Verificar formatação (CI)
pnpm format:checkO projeto utiliza Prettier para padronizar a formatação do código (escopo principal: src/).
- Config:
.prettierrc - Ignorados:
.prettierignore
| Rota | Página |
|---|---|
/ |
Tela inicial com busca |
/user/:username |
Perfil do usuário + lista de repositórios |
/user/:username/repo/:repoName |
Detalhes do repositório |
* |
Página 404 |
-
Busca
- O componente
SearchBarnavega para/user/:username. - A
UserPagereage ao parâmetro da rota e chamasearchUser(username)no Zustand.
- O componente
-
Store global (Zustand)
- Arquivo:
src/store/searchStore.ts - Responsabilidades:
- Guardar
query,user,repositories, flags de loading e erros - Buscar usuário e repositórios em paralelo via
Promise.allSettled - Armazenar a opção de ordenação e expor
getSortedRepositories()
- Guardar
- Arquivo:
-
Camada de serviços (API)
- Arquivo:
src/services/github.ts - Usa uma instância do Axios (
baseURL: https://api.github.com). - Tratamento de erros com mensagens amigáveis (ex: 404, 403 rate limit, problemas de rede).
- Repositórios são buscados por página (ex: 30 itens por vez) para melhorar performance e evitar carregar tudo de uma vez.
- Também existe um fetch "completo" com paginação e safety cap para evitar loop infinito.
- Arquivo:
-
Detalhe do repositório
- Página:
src/pages/RepositoryDetailPage.tsx - Primeiro tenta encontrar o repositório no estado global.
- Se não encontrar, faz um fetch fallback buscando todos os repositórios do usuário.
- Página:
src/
├── components/
│ ├── home/ # HomeHero, HomeSearchSection, FeaturesGrid, FeatureCard
│ ├── layout/ # Header
│ ├── search/ # SearchBar
│ ├── theme/ # ThemeProvider, ThemeToggleButton
│ ├── user/ # UserCard e subcomponentes (UserHeader, UserMeta, UserStats, etc.)
│ ├── repository/ # RepositoryCard, RepositoryList e subpastas
│ │ ├── detail/ # Seções da página de detalhe do repositório
│ │ └── list/ # Header/estados da listagem de repositórios
│ └── ui/ # Componentes shadcn (Button, Card, Badge, etc.)
├── pages/
│ ├── HomePage.tsx
│ ├── UserPage.tsx
│ ├── RepositoryDetailPage.tsx
│ └── NotFoundPage.tsx
├── store/
│ └── searchStore.ts # Zustand store global
├── services/
│ └── github.ts # Camada de API (Axios)
├── types/
│ └── github.ts # Interfaces TypeScript
├── utils/
│ ├── cn.ts # clsx + tailwind-merge
│ ├── format.ts # Formatação de números e datas
│ ├── sort.ts # Ordenação de repositórios
│ └── languageColors.ts # Cores por linguagem
├── test/
│ ├── setup.ts # Configuração global do Testing Library
│ ├── mocks.ts # Dados mockados reutilizáveis
│ ├── sort.test.ts
│ ├── format.test.ts
│ ├── SearchBar.test.tsx
│ ├── UserCard.test.tsx
│ ├── RepositoryCard.test.tsx
│ └── github.service.test.ts
├── App.tsx # Rotas
├── main.tsx # Entry point
└── index.css # Estilos globais + tokens CSS
O projeto usa Vitest com ambiente jsdom e @testing-library/jest-dom.
- Utilitários
sortRepositoriesformatNumber,formatDate,formatRelativeDate,truncate
- Componentes
SearchBar,UserCard,RepositoryCard
- Serviços
github.ts(tratamento de erros)
- Links externos usam
rel="noopener noreferrer" - Input de busca tem:
maxLength={39}(limite real de username do GitHub)patternpara restringir formato válido
- Sem armazenamento de tokens/dados sensíveis
- URLs de blog são normalizadas para
https://quando necessário
O histórico de commits segue o padrão Conventional Commits.
MIT



