Skip to content

[TESTE] Renato Marinho - Desenvolvedor Frontend#5

Open
renatomarinhofr wants to merge 26 commits intosizebay:mainfrom
renatomarinhofr:feature/renato-marinho
Open

[TESTE] Renato Marinho - Desenvolvedor Frontend#5
renatomarinhofr wants to merge 26 commits intosizebay:mainfrom
renatomarinhofr:feature/renato-marinho

Conversation

@renatomarinhofr
Copy link

@renatomarinhofr renatomarinhofr commented Aug 13, 2025

GitHub Explorer

Desktop.2025.08.13.-.10.10.52.02.mp4

📋 Índice

  1. Visão Geral
  2. Tecnologias Utilizadas
  3. Configuração do Ambiente
  4. Variáveis de Ambiente
  5. Instalação e Execução
  6. Arquitetura do Projeto
  7. Estrutura de Pastas
  8. Componentes
  9. Hooks Customizados
  10. Serviços
  11. Tipos TypeScript
  12. Testes
  13. Scripts Disponíveis

🎯 Visão Geral

O GitHub Explorer é uma aplicação web desenvolvida em Next.js que permite explorar repositórios e perfis do GitHub de forma intuitiva. A aplicação oferece autenticação via GitHub OAuth, busca de usuários, visualização de repositórios e detalhes completos de cada projeto.

Funcionalidades Principais

  • 🔍 Busca de Usuários: Pesquise qualquer usuário do GitHub
  • 📊 Visualização de Repositórios: Liste todos os repositórios públicos de um usuário
  • 📋 Detalhes do Repositório: Visualize informações detalhadas de cada repositório
  • 🔐 Autenticação GitHub: Login opcional para aumentar rate limits da API
  • 📱 Design Responsivo: Interface adaptável para desktop e mobile
  • Performance Otimizada: Cache inteligente com SWR
  • 🧪 Testes Abrangentes: Cobertura completa de testes unitários e de integração

🛠 Tecnologias Utilizadas

Frontend

  • Next.js 15.4.6 - Framework React com App Router
  • TypeScript 5 - Tipagem estática
  • Tailwind CSS 4 - Framework CSS utilitário
  • Heroicons - Biblioteca de ícones

Autenticação

  • NextAuth.js 4.24.11 - Autenticação OAuth
  • GitHub OAuth - Provedor de autenticação

Estado e Cache

  • SWR 2.3.6 - Cache e sincronização de dados

Testes

  • Jest 30.0.5 - Framework de testes
  • Testing Library - Utilitários para testes de componentes
  • Jest Environment JSDOM - Ambiente de testes para DOM

Desenvolvimento

  • ESLint - Linter para JavaScript/TypeScript
  • Turbopack - Bundler rápido para desenvolvimento

⚙️ Configuração do Ambiente

Pré-requisitos

  • Node.js 18.0.0 ou superior
  • npm, yarn, pnpm ou bun

🔐 Variáveis de Ambiente

Crie um arquivo .env.local na raiz do projeto com as seguintes variáveis:

# GitHub OAuth (Obrigatório para autenticação)
GITHUB_CLIENT_ID=Ov23liEFqd35ZBgzX5kX
GITHUB_CLIENT_SECRET=c50749310a426ff05ece931b4f838d70e8d146dc

# NextAuth (Obrigatório)
NEXTAUTH_SECRET=D9yGZ7M74azRzHvst4s0BV7bYTD/OW59PlfM5C7Q/zQ=
NEXTAUTH_URL=http://localhost:3000

### Descrição das Variáveis

- **GITHUB_CLIENT_ID**: ID da aplicação OAuth do GitHub
- **GITHUB_CLIENT_SECRET**: Secret da aplicação OAuth do GitHub
- **NEXTAUTH_SECRET**: Chave secreta para criptografia de sessões (gerado com `openssl rand -base64 32`)
- **NEXTAUTH_URL**: URL base da aplicação

## 🚀 Instalação e Execução

### 1. Clone o repositório
```bash
git clone https://github.com/sizebay/test-frontend.git
cd test-frontend

2. Entre na branch feature/renato-marinho

git checkout feature/renato-marinho
cd github-explorer

3. Instale as dependências

npm install
# ou
yarn install
# ou
pnpm install

3. Configure as variáveis de ambiente

crie o arquivo .env.local
# Edite o arquivo .env.local com as credenciais descritas acima

4. Execute o projeto

npm run dev
# ou
yarn dev
# ou
pnpm dev

5. Acesse a aplicação

Abra http://localhost:3000 no seu navegador.

🏗 Arquitetura do Projeto

O projeto segue uma arquitetura baseada em Atomic Design e Clean Architecture:

Camadas da Aplicação

  1. Presentation Layer (Componentes)

    • Atoms: Componentes básicos (Button, Text, Icon)
    • Molecules: Combinações de atoms (SearchForm, UserCard)
    • Organisms: Seções complexas (Header, RepositoryGrid)
    • Templates: Layouts de página (HomeTemplate)
  2. Business Logic Layer (Hooks)

    • Hooks customizados para lógica de negócio
    • Gerenciamento de estado local
    • Integração com APIs
  3. Data Layer (Services)

    • Serviços para comunicação com APIs externas
    • Transformação e validação de dados
  4. Infrastructure Layer

    • Configurações do Next.js
    • Autenticação

Padrões Utilizados

  • Component Composition: Composição de componentes reutilizáveis
  • Custom Hooks: Encapsulamento de lógica de estado
  • Service Layer: Abstração de chamadas de API
  • TypeScript First: Tipagem forte em toda aplicação
  • SWR Pattern: Cache e sincronização de dados

📁 Estrutura de Pastas

src/
├── __tests__/              # Testes
│   ├── components/          # Testes de componentes
│   ├── hooks/              # Testes de hooks
│   └── integration/        # Testes de integração
├── app/                    # App Router (Next.js 13+)
│   ├── [username]/         # Rotas dinâmicas
│   ├── api/               # API Routes
│   ├── globals.css        # Estilos globais
│   ├── layout.tsx         # Layout raiz
│   └── page.tsx           # Página inicial
├── components/            # Componentes React
│   ├── atoms/             # Componentes básicos
│   ├── molecules/         # Componentes compostos
│   ├── organisms/         # Seções complexas
│   └── templates/         # Templates de página
├── hooks/                 # Hooks customizados
├── lib/                   # Utilitários
├── services/              # Serviços de API
├── types/                 # Definições TypeScript
└── utils/                 # Funções utilitárias

🧩 Componentes

Atoms (Componentes Básicos)

Button

interface ButtonProps {
  variant?: 'primary' | 'secondary' | 'ghost'
  size?: 'sm' | 'md' | 'lg'
  isLoading?: boolean
  disabled?: boolean
  onClick?: () => void
  children: React.ReactNode
}

Text

interface TextProps {
  as?: 'p' | 'span' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
  size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'
  weight?: 'normal' | 'medium' | 'semibold' | 'bold'
  color?: 'primary' | 'secondary' | 'muted'
  children: React.ReactNode
}

Avatar

interface AvatarProps {
  src?: string | null
  alt: string
  size?: 'sm' | 'md' | 'lg'
  fallback?: string
}

Molecules (Componentes Compostos)

SearchForm

interface SearchFormProps {
  initialValue?: string
  onSearch: (username: string) => void
  isLoading?: boolean
}

RepositoryCard

interface RepositoryCardProps {
  repository: Repository
  onClick?: () => void
}

UserCard

interface UserCardProps {
  user: GitHubUser
  isLoading?: boolean
}

Organisms (Seções Complexas)

Header

interface HeaderProps {
  showAuthButton?: boolean
  authMessage?: string
}

RepositoryGrid

interface RepositoryGridProps {
  repositories: Repository[]
  isLoading: boolean
  error?: string | null
  onRepositoryClick: (owner: string, repo: string) => void
}

Templates (Layouts de Página)

HomeTemplate

interface HomeTemplateProps {
  searchUsername: string
  onSearch: (username: string) => void
  user: GitHubUser | null
  userLoading: boolean
  userError: string | null
  repositories: Repository[]
  isLoading: boolean
  error: string | null
  isAuthenticated: boolean
  showAuthError?: boolean
  authErrorMessage?: string
}

🎣 Hooks Customizados

useGitHubAuth

Gerencia autenticação com GitHub OAuth.

interface UseGitHubAuthReturn {
  session: ExtendedSession | null
  authToken: string | null
  isAuthenticated: boolean
  isLoading: boolean
  user?: {
    name?: string | null
    email?: string | null
    image?: string | null
  }
}

Funcionalidades:

  • Gerencia sessão do NextAuth
  • Fornece token de autenticação
  • Fallback para token público
  • Estado de carregamento

useGitHubRepositories

Busca repositórios de um usuário.

interface UseGitHubRepositoriesReturn {
  repositories: Repository[]
  isLoading: boolean
  error: string | null
  refetch: () => void
}

Funcionalidades:

  • Cache com SWR
  • Retry automático em caso de erro
  • Deduplicação de requisições
  • Revalidação em foco

useUserDetails

Busca detalhes de um usuário.

interface UseUserDetailsReturn {
  data: GitHubUser | undefined
  error: any
  loading: boolean
}

Funcionalidades:

  • Busca assíncrona de dados do usuário
  • Gerenciamento de estado de carregamento
  • Tratamento de erros

useRepositoryDetails

Busca detalhes de um repositório específico.

interface UseRepositoryDetailsReturn {
  repository: RepositoryDetails | null
  isLoading: boolean
  error: string | null
  refetch: () => void
}

Funcionalidades:

  • Cache com SWR
  • Dados detalhados do repositório
  • Estatísticas completas

🔧 Serviços

GitHubApiService

Serviço principal para comunicação com a API do GitHub.

class GitHubApiService {
  private getHeaders(authToken?: string): HeadersInit
  private async fetchFromGitHub<T>(endpoint: string, authToken?: string): Promise<T>
  
  async getUserDetails(username: string, authToken?: string): Promise<GitHubUser>
  async getUserRepositories(username: string, authToken?: string): Promise<Repository[]>
  async getRepositoryDetails(owner: string, repo: string, authToken?: string): Promise<RepositoryDetails>
}

Funcionalidades:

  • Headers automáticos para API do GitHub
  • Autenticação opcional
  • Tratamento de erros padronizado
  • Rate limiting respeitado

📝 Tipos TypeScript

Principais Interfaces

Repository

interface Repository {
  id: number
  name: string
  full_name: string
  description: string | null
  language: string | null
  stargazers_count: number
  forks_count: number
  updated_at: string
  html_url: string
  owner: {
    login: string
    avatar_url: string
  }
}

GitHubUser

interface GitHubUser {
  login: string
  id: number
  avatar_url: string
  html_url: string
  name: string | null
  company: string | null
  blog: string | null
  location: string | null
  email: string | null
  bio: string | null
  public_repos: number
  public_gists: number
  followers: number
  following: number
  created_at: string
  updated_at: string
}

RepositoryDetails

interface RepositoryDetails extends Repository {
  open_issues_count: number
  watchers_count: number
  size: number
  default_branch: string
  created_at: string
  pushed_at: string
  clone_url: string
  ssh_url: string
  homepage: string | null
  topics: string[]
  private: boolean
  license: {
    key: string
    name: string
    spdx_id: string
    url: string | null
  } | null
}

🧪 Testes

Estrutura de Testes

__tests__/
├── components/
│   ├── atoms/              # Testes de componentes básicos
│   └── molecules/          # Testes de componentes compostos
├── hooks/                  # Testes de hooks customizados
└── integration/            # Testes de integração

Tipos de Testes

1. Testes Unitários

  • Componentes: Renderização, props, interações
  • Hooks: Lógica de estado, efeitos colaterais
  • Serviços: Chamadas de API, transformação de dados

2. Testes de Integração

  • Happy Path: Fluxo completo da aplicação
  • Error Handling: Tratamento de erros
  • User Interactions: Interações do usuário

Configuração de Testes

jest.config.js

const nextJest = require('next/jest')

const createJestConfig = nextJest({
  dir: './',
})

const customJestConfig = {
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
  testEnvironment: 'jest-environment-jsdom',
  moduleNameMapping: {
    '^@/(.*)$': '<rootDir>/src/$1',
  },
  collectCoverageFrom: [
    'src/**/*.{js,jsx,ts,tsx}',
    '!src/**/*.d.ts',
  ],
}

module.exports = createJestConfig(customJestConfig)

Executando Testes

# Executar todos os testes
npm test

# Executar testes em modo watch
npm run test:watch

# Executar testes com cobertura
npm run test:coverage

# Executar testes específicos
npm test -- SearchForm

# Executar testes de integração
npm test -- integration

Cobertura de Testes

O projeto mantém alta cobertura de testes:

  • Componentes: 95%+
  • Hooks: 90%+
  • Serviços: 85%+
  • Integração: Fluxos principais cobertos

📜 Scripts Disponíveis

{
  "scripts": {
    "dev": "next dev --turbopack",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:coverage": "jest --coverage"
  }
}

Descrição dos Scripts

  • dev: Inicia servidor de desenvolvimento com Turbopack
  • build: Gera build de produção
  • start: Inicia servidor de produção
  • lint: Executa ESLint para verificar código
  • test: Executa todos os testes
  • test:watch: Executa testes em modo watch
  • test:coverage: Gera relatório de cobertura

- Add fixed height (h-48) to repository cards for uniform layout
- Implement text truncation with ellipsis for descriptions (2 lines max)
- Add style prop support to Text component for CSS customization
- Remove all console.log statements from authentication flow
- Fix TypeScript errors in NextAuth callbacks and useGitHubAuth hook
- Add fallback GitHub token for unauthenticated requests
- Improve code maintainability and production readiness
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant