# 5. Guía del Frontend
## Stack Tecnológico
- **React 18** - Biblioteca de UI
- **TypeScript** - Tipado estático
- **Vite** - Build tool y dev server
- **React Router** - Navegación
- **Axios** - Cliente HTTP
- **Recharts** - Gráficas
- **Tailwind CSS** - Estilos
- **react-hot-toast** - Notificaciones
- **react-dropzone** - Upload de archivos
---
## Estructura de Carpetas
```
frontend/src/
├── components/
│ ├── charts/ # Componentes de gráficas
│ │ ├── BarChart.tsx
│ │ └── LineChart.tsx
│ ├── cards/ # Tarjetas y tablas
│ │ ├── KPICard.tsx
│ │ └── MetricTable.tsx
│ ├── forms/ # Formularios
│ │ ├── ClienteForm.tsx
│ │ ├── UploadBalanza.tsx
│ │ └── GenerarReporte.tsx
│ └── layout/ # Estructura de página
│ ├── Layout.tsx
│ ├── Sidebar.tsx
│ └── Header.tsx
├── pages/
│ ├── Login.tsx
│ ├── Clientes/
│ │ ├── ClientesList.tsx
│ │ └── ClienteDetail.tsx
│ ├── Dashboard/
│ │ └── index.tsx
│ ├── PdfView/
│ │ └── index.tsx
│ └── Admin/
│ ├── Usuarios.tsx
│ ├── Giros.tsx
│ ├── Umbrales.tsx
│ └── ReglasMapeeo.tsx
├── context/
│ └── AuthContext.tsx
├── services/
│ └── api.ts
├── types/
│ └── index.ts
└── hooks/
```
---
## Contexto de Autenticación
```tsx
// Uso del contexto
import { useAuth } from '../context/AuthContext';
function MyComponent() {
const { user, login, logout, isAdmin, isAnalista } = useAuth();
if (!user) return ;
return
Hola {user.nombre}
;
}
```
### Propiedades disponibles:
- `user` - Usuario actual o null
- `loading` - Estado de carga inicial
- `login(email, password)` - Iniciar sesión
- `logout()` - Cerrar sesión
- `isAdmin` - Es administrador
- `isAnalista` - Es analista
- `isCliente` - Es cliente
- `isEmpleado` - Es empleado
---
## Servicio API
```tsx
import { clientesApi, balanzasApi, reportesApi } from '../services/api';
// Listar clientes
const clientes = await clientesApi.list();
// Crear cliente
const formData = new FormData();
formData.append('nombre_empresa', 'Mi Empresa');
formData.append('giro_id', '1');
const cliente = await clientesApi.create(formData);
// Subir balanza
const balanza = await balanzasApi.upload(clienteId, formData);
// Generar reporte
const reporte = await reportesApi.create(clienteId, 'Reporte 2024', [1, 2]);
// Descargar PDF
const blob = await reportesApi.downloadPdf(reporteId);
```
---
## Tipos TypeScript
```tsx
// Principales tipos disponibles
interface User {
id: number;
nombre: string;
email: string;
role: 'admin' | 'analista' | 'cliente' | 'empleado';
cliente_id: number | null;
}
interface Cliente {
id: number;
nombre_empresa: string;
logo: string | null;
giro_id: number;
moneda: string;
giro?: Giro;
}
interface Balanza {
id: number;
cliente_id: number;
periodo_inicio: string;
periodo_fin: string;
sistema_origen: string;
status: 'pendiente' | 'procesando' | 'completado' | 'error';
}
interface Reporte {
id: number;
nombre: string;
periodo_tipo: 'mensual' | 'trimestral' | 'anual';
data_calculada: DataCalculada | null;
status: string;
}
type Tendencia = 'muy_positivo' | 'positivo' | 'neutral' | 'negativo' | 'muy_negativo';
```
---
## Componentes Reutilizables
### KPICard
```tsx
```
### MetricTable
```tsx
```
### BarChart
```tsx
```
### LineChart
```tsx
({
periodo: p.periodo,
'Margen Bruto': p.margen_bruto * 100,
'Margen Neto': p.margen_neto * 100,
}))}
lines={['Margen Bruto', 'Margen Neto']}
/>
```
---
## Estilos con Tailwind
### Clases personalizadas (index.css)
```css
.btn { @apply px-4 py-2 rounded-lg font-medium transition-colors; }
.btn-primary { @apply bg-primary-600 text-white hover:bg-primary-700; }
.btn-secondary { @apply bg-gray-200 text-gray-800 hover:bg-gray-300; }
.input { @apply w-full px-3 py-2 border rounded-lg focus:ring-2 focus:ring-primary-500; }
.card { @apply bg-white rounded-xl shadow-sm border border-gray-100 p-6; }
.label { @apply block text-sm font-medium text-gray-700 mb-1; }
```
### Colores de marca (tailwind.config.js)
```js
colors: {
horux: {
dark: '#1a1a2e',
primary: '#16213e',
accent: '#0f3460',
highlight: '#e94560',
},
status: {
'muy-positivo': '#10b981',
'positivo': '#34d399',
'neutral': '#fbbf24',
'negativo': '#f97316',
'muy-negativo': '#ef4444',
},
}
```
---
## Rutas
| Ruta | Componente | Rol requerido |
|------|------------|---------------|
| `/login` | Login | Público |
| `/clientes` | ClientesList | Autenticado |
| `/clientes/:id` | ClienteDetail | Autenticado |
| `/dashboard/:clienteId/:reporteId` | Dashboard | Autenticado |
| `/pdf-view/:id` | PdfView | Token especial |
| `/admin/usuarios` | AdminUsuarios | Admin |
| `/admin/giros` | AdminGiros | Admin |
| `/admin/umbrales` | AdminUmbrales | Admin |
| `/admin/reglas-mapeo` | AdminReglasMapeeo | Admin |
---
## Desarrollo
```bash
# Instalar dependencias
npm install
# Servidor de desarrollo
npm run dev
# Build para producción
npm run build
# Preview del build
npm run preview
# Linting
npm run lint
```