Use esta especificação como base para criar o projeto.
- Framework: React 14+
- Build Tool: Vite
- Estilização: Tailwind CSS
- Roteamento: React Router DOM
- Gerenciamento de Estado: Context API + useReducer (ou Zustand para projetos maiores)
- Formulários: React Hook Form + Zod
- Infraestrutura: Docker + Nginx
project-root/
├── src/
│ ├── assets/
│ │ ├── images/
│ │ ├── fonts/
│ │ └── icons/
│ │
│ ├── components/
│ │ ├── ui/ # Componentes base reutilizáveis
│ │ │ ├── Button.jsx
│ │ │ ├── Input.jsx
│ │ │ ├── Modal.jsx
│ │ │ ├── Table.jsx
│ │ │ ├── Loading.jsx
│ │ │ └── index.js
│ │ │
│ │ ├── layout/ # Componentes de estrutura
│ │ │ ├── Header.jsx
│ │ │ ├── Sidebar.jsx
│ │ │ ├── Footer.jsx
│ │ │ └── index.js
│ │ │
│ │ └── shared/ # Componentes compartilhados específicos
│ │ ├── UserAvatar.jsx
│ │ ├── Pagination.jsx
│ │ └── index.js
│ │
│ ├── contexts/
│ │ ├── AuthContext.jsx
│ │ ├── ThemeContext.jsx
│ │ └── index.js
│ │
│ ├── hooks/
│ │ ├── useAuth.js
│ │ ├── useApi.js
│ │ ├── useLocalStorage.js
│ │ ├── useDebounce.js
│ │ └── index.js
│ │
│ ├── pages/
│ │ ├── auth/
│ │ │ ├── Login.jsx
│ │ │ └── ForgotPassword.jsx
│ │ │
│ │ ├── dashboard/
│ │ │ └── Dashboard.jsx
│ │ │
│ │ ├── users/
│ │ │ ├── UserList.jsx
│ │ │ ├── UserForm.jsx
│ │ │ └── UserDetail.jsx
│ │ │
│ │ └── errors/
│ │ ├── NotFound.jsx
│ │ └── Unauthorized.jsx
│ │
│ ├── routes/
│ │ ├── AppRoutes.jsx # Definição de todas as rotas
│ │ ├── PrivateRoute.jsx # Wrapper para rotas autenticadas
│ │ └── index.js
│ │
│ ├── services/
│ │ ├── api.js # Instância Axios configurada
│ │ ├── authService.js
│ │ ├── userService.js
│ │ └── index.js
│ │
│ ├── utils/
│ │ ├── formatters.js # Formatação de datas, moedas, etc.
│ │ ├── validators.js # Validações comuns
│ │ ├── constants.js # Constantes da aplicação
│ │ ├── helpers.js # Funções auxiliares
│ │ └── index.js
│ │
│ ├── styles/
│ │ └── global.css # Imports Tailwind + estilos globais
│ │
│ ├── App.jsx
│ └── main.jsx
│
├── public/
│ └── favicon.ico
│
├── .env.example
├── .gitignore
├── index.html
├── package.json
├── postcss.config.js
├── tailwind.config.js
├── vite.config.js
├── Dockerfile
├── docker-compose.yml
├── nginx.conf
└── README.md
| Tipo | Padrão | Exemplo |
|---|---|---|
| Componentes | PascalCase | UserCard.jsx |
| Hooks | camelCase com prefixo "use" | useAuth.js |
| Contexts | PascalCase com sufixo "Context" | AuthContext.jsx |
| Services | camelCase com sufixo "Service" | authService.js |
| Utils/Helpers | camelCase | formatters.js |
| Constantes | UPPER_SNAKE_CASE | API_BASE_URL |
| Props/Variáveis | camelCase | isLoading, userName |
// Ordem dos imports
1. React e hooks do React
2. Bibliotecas externas
3. Contexts
4. Hooks customizados
5. Services
6. Componentes
7. Utils
8. Assets/Styles
// Ordem dentro do componente
1. Hooks (useState, useEffect, custom hooks)
2. Variáveis derivadas/computadas
3. Handlers/Funções
4. useEffect
5. Renderização condicional/early returns
6. Return JSX// Componente funcional com PropTypes ou TypeScript
// Usar arrow function para componentes
// Exportar como default no final
const ComponentName = ({ prop1, prop2 }) => {
// lógica
return (
// JSX
);
};
export default ComponentName;- Componentes em
ui/devem ser genéricos e reutilizáveis - Não devem conter lógica de negócio
- Devem aceitar props para customização (variant, size, disabled, etc.)
- Usar
classNamepara permitir extensão de estilos via Tailwind
- Cada página representa uma rota
- Podem importar e compor componentes
- Contêm a lógica de negócio específica daquela tela
- Organizar em subpastas por domínio (users/, products/, etc.)
- Cada service encapsula chamadas à API de um domínio
- Usar instância configurada do Axios com interceptors
- Retornar apenas os dados (response.data), não o response completo
- Tratar erros de forma padronizada
- Extrair lógica reutilizável em hooks
- Hooks de API devem retornar: { data, loading, error, refetch }
- Nomear sempre com prefixo "use"
- Token JWT armazenado no localStorage
- Interceptor do Axios adiciona token no header Authorization
- Context de autenticação provê: user, login, logout, isAuthenticated
- PrivateRoute redireciona para login se não autenticado
- Usar Context API para estados simples (auth, theme)
- Para projetos maiores, considerar Zustand
- Evitar prop drilling excessivo
// Configurar:
// - content: apontar para arquivos com classes Tailwind
// - theme.extend: cores customizadas, fontes, breakpoints
// - plugins: forms, typography se necessário- Preferir classes utilitárias do Tailwind
- Usar
@applycom moderação (apenas para componentes muito repetidos) - Criar variantes de componentes via props, não duplicar estilos
- Mobile-first: usar breakpoints sm:, md:, lg:, xl:
- Base URL via variável de ambiente
- Interceptor de request: adiciona token JWT
- Interceptor de response: trata erros 401 (logout automático)
- Timeout configurado
// Cada service exporta funções que retornam promises
// Exemplo: userService.js
// - getAll(params)
// - getById(id)
// - create(data)
// - update(id, data)
// - remove(id)- Capturar erros nos componentes/pages
- Exibir mensagens amigáveis ao usuário
- Logar erros no console em desenvolvimento
- Usar toast/notification para feedback
- Rotas públicas: login, forgot-password, etc.
- Rotas privadas: envolvidas por PrivateRoute
- Lazy loading para páginas (React.lazy + Suspense)
- Rota 404 como fallback
- Verifica se usuário está autenticado
- Redireciona para /login se não autenticado
- Pode verificar permissões/roles se necessário
VITE_API_URL=http://localhost:3000/api
VITE_APP_NAME=MyApp
VITE_APP_ENV=development
Nota: Variáveis devem ter prefixo VITE_ para serem expostas ao cliente.
{
"dependencies": {
"react": "^18.x",
"react-dom": "^18.x",
"react-router-dom": "^6.x",
"axios": "^1.x",
"react-hook-form": "^7.x",
"zod": "^3.x",
"@hookform/resolvers": "^3.x",
"react-hot-toast": "^2.x",
"lucide-react": "^0.x",
"clsx": "^2.x"
},
"devDependencies": {
"@vitejs/plugin-react": "^4.x",
"vite": "^5.x",
"tailwindcss": "^3.x",
"postcss": "^8.x",
"autoprefixer": "^10.x"
}
}{
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"lint": "eslint src --ext js,jsx"
}# Stage 1: Build
# - Base node:24-alpine
# - Instalar dependências
# - Rodar build
# Stage 2: Production
# - Base nginx:alpine
# - Copiar build do stage anterior
# - Copiar nginx.conf customizado
# - Expor porta 80- Servir arquivos estáticos do build
- Configurar fallback para index.html (SPA)
- Gzip habilitado
- Cache headers para assets
- Serviço web: build do Dockerfile, porta 80
- Variáveis de ambiente para build-time (ARG) se necessário
- Usar React Hook Form para gerenciamento
- Validação com Zod schemas
- Exibir erros inline nos campos
- Desabilitar submit durante loading
- Implementar paginação
- Loading state durante fetch
- Empty state quando sem dados
- Tratamento de erro com retry
- Controlar abertura via estado
- Fechar ao clicar fora ou ESC
- Animações de entrada/saída
- Prevenir scroll do body quando aberto
- Skeleton loaders para conteúdo
- Spinner para ações pontuais
- Disabled em botões durante submit
- Feedback visual em todas as ações assíncronas