- Laravel 11 backend with API REST - React 18 + TypeScript + Vite frontend - Multi-parser architecture for accounting systems (CONTPAQi, Aspel, SAP) - 27+ financial metrics calculation - PDF report generation with Browsershot - Complete documentation (10 documents) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
272 lines
5.8 KiB
Markdown
272 lines
5.8 KiB
Markdown
# 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 <Navigate to="/login" />;
|
|
|
|
return <div>Hola {user.nombre}</div>;
|
|
}
|
|
```
|
|
|
|
### 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
|
|
<KPICard
|
|
title="Ingresos"
|
|
value="$1,500,000"
|
|
subtitle="12% vs mes anterior"
|
|
tendencia="positivo"
|
|
/>
|
|
```
|
|
|
|
### MetricTable
|
|
```tsx
|
|
<MetricTable
|
|
title="Márgenes"
|
|
metricas={[
|
|
{ nombre: 'Margen Bruto', valor: 0.45, tendencia: 'positivo' },
|
|
{ nombre: 'Margen Neto', valor: 0.12, tendencia: 'neutral' },
|
|
]}
|
|
/>
|
|
```
|
|
|
|
### BarChart
|
|
```tsx
|
|
<BarChartComponent
|
|
data={[
|
|
{ name: 'Ingresos', valor: 1500000 },
|
|
{ name: 'Gastos', valor: -800000 },
|
|
]}
|
|
horizontal={false}
|
|
/>
|
|
```
|
|
|
|
### LineChart
|
|
```tsx
|
|
<LineChartComponent
|
|
data={periodos.map(p => ({
|
|
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
|
|
```
|