gohorsejobs/frontend/FRONTEND.md

412 lines
11 KiB
Markdown

# Frontend - GoHorse Jobs
[![Next.js](https://img.shields.io/badge/Next.js-15-black?style=flat-square&logo=next.js)](https://nextjs.org/)
[![Tailwind CSS](https://img.shields.io/badge/Tailwind-4-06B6D4?style=flat-square&logo=tailwindcss)](https://tailwindcss.com/)
[![TypeScript](https://img.shields.io/badge/TypeScript-5-3178C6?style=flat-square&logo=typescript)](https://typescriptlang.org/)
Frontend da plataforma GoHorse Jobs construído com **Next.js 15** e **App Router**.
> **Last Updated:** 2026-01-03
---
## 🚀 Deploy (CI/CD)
### Ambientes
| Ambiente | URL | Branch |
|----------|-----|--------|
| **DEV** | https://dev.gohorsejobs.com | `dev` |
| **PRD** | https://gohorsejobs.com | `main` |
### Pipeline Forgejo
A pipeline está configurada em `.forgejo/workflows/deploy.yaml` e é triggerada automaticamente ao fazer push em `dev` com mudanças em `frontend/`.
**Fluxo:**
1. **Build local:** `podman build -t forgejo-gru.rede5.com.br/rede5/gohorsejobs-frontend:latest .`
2. **Push para registry:** `podman push forgejo-gru.rede5.com.br/rede5/gohorsejobs-frontend:latest`
3. **Commit e push:** `git push origin dev && git push forgejo dev`
4. **Pipeline detecta mudanças** em `frontend/`
5. **Deploy via SSH:** Pull da imagem + restart do serviço
```bash
# Comandos executados pela pipeline no servidor
podman pull forgejo-gru.rede5.com.br/rede5/gohorsejobs-frontend:latest
sudo systemctl restart gohorsejobs-frontend-dev
```
### Verificar Pipeline
```bash
# Via browser
https://forgejo-gru.rede5.com.br/rede5/gohorsejobs/actions
# Testar se está rodando
curl -s https://dev.gohorsejobs.com | head -c 200
```
---
## ✨ Features
- **Server-Side Pagination**: Listagem de vagas otimizada
- **Busca e Filtros**: Tipo, localização, modo de trabalho
- **Internacionalização (i18n)**: PT, EN
- **Dark/Light Mode**: Tema automático
- **Skeleton Loading**: Estados de carregamento
- **Real-time Chat**: Integração Appwrite
- **Push Notifications**: Firebase Cloud Messaging
- **Avatar Upload**: Pre-signed URLs (S3/R2)
- **Email Templates Admin**: CRUD para templates
- **Public Job Posting**: Wizard de registro + vaga
---
## 🏗️ Arquitetura
```
src/
├── app/ # App Router (35 pages)
│ ├── page.tsx # Landing page
│ ├── login/ # Autenticação
│ ├── register/ # Registro (candidate, company)
│ ├── post-job/ # **NEW** Wizard público
│ ├── jobs/ # Listagem e detalhes
│ │ ├── page.tsx # Listagem
│ │ ├── [id]/page.tsx # Detalhes
│ │ └── [id]/apply/ # Candidatura
│ ├── dashboard/ # Área logada (12 subpastas)
│ │ ├── admin/ # Painel Admin
│ │ │ └── email-templates/ # **NEW** CRUD templates
│ │ ├── applications/ # Candidaturas
│ │ ├── candidates/ # Lista candidatos
│ │ ├── companies/ # Lista empresas
│ │ ├── jobs/ # Gestão de vagas
│ │ ├── messages/ # Chat real-time
│ │ ├── profile/ # Perfil do usuário
│ │ ├── settings/ # Configurações
│ │ ├── support/ # Tickets
│ │ └── users/ # Gestão de usuários
│ ├── about/ # Sobre
│ ├── contact/ # Contato
│ ├── faq/ # FAQ
│ └── terms/, privacy/ # Legais
├── components/ # 44 componentes
│ ├── ui/ # 24 shadcn/ui primitives
│ ├── navbar.tsx # Navegação principal
│ ├── footer.tsx # Rodapé
│ ├── sidebar.tsx # Sidebar dashboard
│ ├── job-card.tsx # Card de vaga
│ ├── notification-dropdown.tsx # Notificações
│ ├── profile-picture-upload.tsx # Upload de avatar
│ └── loading-skeletons.tsx # Skeletons
├── contexts/ # React Contexts
│ ├── AuthContext.tsx # Autenticação global
│ └── ThemeContext.tsx # **NEW** Tema configurável
├── hooks/ # Custom Hooks
│ ├── useAuth.ts # Autenticação
│ ├── useProfile.ts # Perfil
│ └── ...
├── lib/ # Utilitários (13 arquivos)
│ ├── api.ts # Cliente HTTP (22KB)
│ ├── auth.ts # Auth helpers
│ ├── appwrite.ts # Appwrite client
│ ├── firebase-client.ts # FCM client
│ ├── storage.ts # Pre-signed URLs
│ ├── i18n.tsx # Internacionalização
│ ├── types.ts # TypeScript types
│ └── mock-data.ts # Dados mock (fallback)
└── i18n/ # Traduções
├── pt.json # Português
└── en.json # English
```
---
## 📱 Páginas
### Públicas
| Rota | Descrição |
|------|-----------|
| `/` | Landing page |
| `/jobs` | Listagem de vagas |
| `/jobs/{id}` | Detalhes da vaga |
| `/jobs/{id}/apply` | Candidatura |
| `/login` | Login |
| `/register/candidate` | Registro candidato |
| `/register/company` | Registro empresa |
| `/post-job` | **NEW** Wizard público (registro + vaga) |
| `/about` | Sobre |
| `/contact` | Contato |
| `/faq` | FAQ |
| `/forgot-password` | Reset senha |
### Dashboard (Autenticadas)
| Rota | Roles | Descrição |
|------|-------|-----------|
| `/dashboard` | All | Dashboard home |
| `/dashboard/profile` | All | Perfil do usuário |
| `/dashboard/settings` | Admin | Configurações (tema, logo) |
| `/dashboard/jobs` | Admin, Recruiter | Gestão de vagas |
| `/dashboard/jobs/new` | Admin, Recruiter | Criar vaga |
| `/dashboard/applications` | Admin, Recruiter | Candidaturas |
| `/dashboard/candidates` | Admin | Lista candidatos |
| `/dashboard/companies` | SuperAdmin | Lista empresas |
| `/dashboard/users` | SuperAdmin, Admin | Gestão usuários |
| `/dashboard/messages` | All | Chat real-time |
| `/dashboard/support` | All | Tickets de suporte |
| `/dashboard/admin/email-templates` | SuperAdmin | **NEW** Templates email |
---
## 🎨 Design System
### Tecnologias
| Tecnologia | Versão | Uso |
|------------|--------|-----|
| **shadcn/ui** | - | Componentes base (Radix UI) |
| **Tailwind CSS** | 4 | Estilização utility-first |
| **Lucide Icons** | 0.454 | Ícones |
| **Framer Motion** | 12 | Animações |
| **Sonner** | 1.7 | Toasts/Notificações |
| **Recharts** | 2.15 | Gráficos |
### Tema
Definido em `src/app/globals.css`:
```css
:root {
--primary: oklch(0.68 0.22 45); /* Laranja */
--background: oklch(1 0 0); /* Branco */
--foreground: oklch(0.145 0 0); /* Preto */
}
.dark {
--background: oklch(0.145 0 0); /* Preto */
--foreground: oklch(0.985 0 0); /* Branco */
}
```
---
## 🔌 API Client
O cliente de API está em `lib/api.ts` (22KB):
### Módulos
| Módulo | Funções |
|--------|---------|
| **jobsApi** | list, getById, create, update, delete |
| **adminApi** | companies, users, candidates, tags |
| **profileApi** | getMe, updateProfile, uploadAvatar |
| **applicationsApi** | create, list, getById, updateStatus |
| **emailTemplatesApi** | **NEW** list, get, create, update, delete |
| **emailSettingsApi** | **NEW** get, update |
| **chatApi** | listConversations, listMessages, sendMessage |
| **supportApi** | tickets, messages |
| **settingsApi** | get, save |
| **fcmApi** | saveToken |
### Exemplo
```typescript
import { jobsApi, profileApi } from "@/lib/api";
// Listar vagas
const jobs = await jobsApi.list({ page: 1, limit: 10 });
// Atualizar perfil
await profileApi.updateProfile({ name: "New Name" });
// Upload avatar (pre-signed URL flow)
await profileApi.uploadAvatar(file);
```
---
## 🔒 Autenticação
### Fluxo
1. **Login**: POST `/api/v1/auth/login`
2. **Token Storage**: `localStorage.auth_token`
3. **Cookie**: JWT HttpOnly (backup)
4. **Headers**: `Authorization: Bearer <token>`
### Auth Context
```typescript
import { useAuth } from "@/hooks/useAuth";
const { user, isLoading, login, logout } = useAuth();
```
---
## 🌍 Internacionalização
### Idiomas Suportados
- 🇧🇷 Português (pt)
- 🇺🇸 English (en)
### Uso
```typescript
import { useTranslation } from "@/lib/i18n";
const { t, locale, setLocale } = useTranslation();
// Usar tradução
<h1>{t("home.hero.title")}</h1>
// Trocar idioma
<button onClick={() => setLocale("en")}>English</button>
```
---
## 🔧 Environment Variables
```env
# API
NEXT_PUBLIC_API_URL=https://api.gohorsejobs.com
# Backoffice
NEXT_PUBLIC_BACKOFFICE_URL=https://backoffice.gohorsejobs.com
# Appwrite (Chat)
NEXT_PUBLIC_APPWRITE_ENDPOINT=https://cloud.appwrite.io/v1
NEXT_PUBLIC_APPWRITE_PROJECT_ID=your-project-id
NEXT_PUBLIC_APPWRITE_DATABASE_ID=your-database-id
# Firebase (Push Notifications)
NEXT_PUBLIC_FIREBASE_API_KEY=your-api-key
NEXT_PUBLIC_FIREBASE_PROJECT_ID=your-project-id
```
---
## 🚀 Desenvolvimento
### Instalar
```bash
npm install
# ou
pnpm install
```
### Executar
```bash
npm run dev
```
### Build
```bash
npm run build
npm run start
```
### Testes
```bash
npm run test
```
### Lint
```bash
npm run lint
```
---
## 🐳 Desenvolvimento com Container (Podman)
```bash
# Build da imagem
podman build -t gohorse-frontend .
# Rodar container
# --net host recomendado para acessar APIs locais (Backend/Backoffice)
podman run --name frontend --net host --env-file .env.local gohorse-frontend
```
> **Nota:** Para orquestração em produção, utilizamos **Quadlet**.
**Nota**: Usa `output: "standalone"` no `next.config.ts`.
---
## 📦 Dependências Principais
| Package | Version | Uso |
|---------|---------|-----|
| next | 15.5 | Framework |
| react | 19.1 | UI Library |
| tailwindcss | 4.1 | CSS |
| framer-motion | 12.23 | Animações |
| sonner | 1.7 | Toasts |
| recharts | 2.15 | Gráficos |
| firebase | 12.7 | FCM |
| appwrite | 17.0 | Chat |
| zod | 3.25 | Validação |
| zustand | 4.5 | State |
---
## 📁 Componentes UI (shadcn)
24 componentes do shadcn/ui:
| Componente | Uso |
|------------|-----|
| `accordion` | FAQ |
| `alert-dialog` | Confirmações |
| `avatar` | Fotos de perfil |
| `badge` | Tags |
| `button` | Ações |
| `card` | Containers |
| `checkbox` | Formulários |
| `dialog` | Modais |
| `dropdown-menu` | Menus |
| `input` | Campos |
| `label` | Labels |
| `popover` | Popovers |
| `progress` | Progresso |
| `radio-group` | Seleção única |
| `scroll-area` | Scroll customizado |
| `select` | Dropdowns |
| `separator` | Divisores |
| `skeleton` | Loading |
| `slider` | Range |
| `switch` | Toggles |
| `tabs` | Navegação |
| `textarea` | Texto longo |
| `toast` | Notificações |
| `tooltip` | Hints |
---
## 🔗 Referências
- [API Documentation](../docs/API.md)
- [Backend](../backend/BACKEND.md)
- [Backoffice](../backoffice/BACKOFFICE.md)
- [Database Schema](../docs/DATABASE.md)
- [Design System](./DESIGN_SYSTEM.md)