- 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>
5.8 KiB
5.8 KiB
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
// 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 nullloading- Estado de carga iniciallogin(email, password)- Iniciar sesiónlogout()- Cerrar sesiónisAdmin- Es administradorisAnalista- Es analistaisCliente- Es clienteisEmpleado- Es empleado
Servicio API
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
// 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
<KPICard
title="Ingresos"
value="$1,500,000"
subtitle="12% vs mes anterior"
tendencia="positivo"
/>
MetricTable
<MetricTable
title="Márgenes"
metricas={[
{ nombre: 'Margen Bruto', valor: 0.45, tendencia: 'positivo' },
{ nombre: 'Margen Neto', valor: 0.12, tendencia: 'neutral' },
]}
/>
BarChart
<BarChartComponent
data={[
{ name: 'Ingresos', valor: 1500000 },
{ name: 'Gastos', valor: -800000 },
]}
horizontal={false}
/>
LineChart
<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)
.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)
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
# 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