Files
horux-strategy-platform/docs/05-frontend.md
Torch2196 4c3dc94ff2 Initial commit: Horux Strategy Platform
- 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>
2026-01-31 22:24:00 -06:00

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 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

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