Este es el repositorio para el frontend de la aplicación Contabot, desarrollada con Next.js y TypeScript.
Contabot Frontend es una interfaz de usuario web diseñada para interactuar con los servicios de Contabot. Permite a los usuarios gestionar, visualizar y analizar facturas electrónicas (CFDI). Las características principales incluyen la autenticación de usuarios, la carga de archivos CFDI, y la visualización de datos y estadísticas en un dashboard.
- Autenticación de Usuario: Formulario de inicio de sesión para acceder a la aplicación.
- Carga de CFDI: Funcionalidad para arrastrar y soltar archivos CFDI para su procesamiento.
- Visualización de Datos: Tabla para mostrar los datos extraídos de los archivos CFDI.
- Dashboard: Panel con estadísticas y gráficos (usando Recharts) para analizar la información de los CFDI.
- Navegación: Menú de navegación para moverse entre las diferentes secciones de la aplicación.
- Framework: Next.js
- Lenguaje: TypeScript
- Librería UI: React
- Estilos: Tailwind CSS
- Peticiones HTTP: Axios
- Carga de Archivos: React Dropzone
- Gráficos: Recharts
- Linting: ESLint
/
├── app/ # Contiene las páginas y rutas de la aplicación
│ ├── dashboard/ # Página del dashboard
│ ├── datos/ # Página para visualización de datos
│ ├── login/ # Página de inicio de sesión
│ └── upload/ # Página para carga de archivos
├── components/ # Componentes reutilizables de React
├── lib/ # Módulos de lógica de negocio (API, auth, etc.)
├── public/ # Archivos estáticos
└── ...
Sigue estos pasos para levantar el entorno de desarrollo local.
-
Clona el repositorio:
git clone <URL_DEL_REPOSITORIO> cd contabot-frontend
-
Instala las dependencias:
npm install
-
Inicia el servidor de desarrollo: El comando
devutiliza Turbopack para un rendimiento más rápido.npm run dev
-
Abre tu navegador: Visita http://localhost:3000 para ver la aplicación.
En el archivo package.json encontrarás los siguientes scripts:
npm run dev: Inicia la aplicación en modo de desarrollo con Turbopack.npm run build: Compila la aplicación para producción.npm run start: Inicia un servidor de producción.npm run lint: Ejecuta ESLint para analizar el código en busca de errores.
Sistema web de automatización contable con procesamiento inteligente de CFDIs mediante IA.
- Descripción del Proyecto
- Tecnologías Utilizadas
- Arquitectura del Sistema
- Instalación y Configuración
- Estructura del Proyecto
- Funcionalidades Implementadas
- Flujo de Autenticación
- Integración con Backend
- Almacenamiento de Datos
- Componentes Principales
- Guía de Desarrollo
- Variables de Entorno
- Credenciales de Prueba
- Troubleshooting
ContaBot IA es un sistema completo de automatización contable que permite:
- Subir y procesar CFDIs (archivos XML de facturas electrónicas)
- Clasificación automática mediante Machine Learning
- Visualización de estadísticas y gráficas en tiempo real
- Dashboard interactivo con KPIs y análisis de datos
- Sistema de autenticación seguro
- Next.js 14 - Framework de React con App Router
- TypeScript - Tipado estático
- React 18 - Librería de UI
- Tailwind CSS - Framework de utilidades CSS
- Gradientes personalizados - Diseño moderno
- Recharts - Librería de gráficas React
- LineChart (tendencias mensuales)
- BarChart (categorías)
- React Dropzone - Drag & drop de archivos
- Axios - Cliente HTTP para API calls
- LocalStorage - Persistencia de datos del cliente
- React State Management - useState, useEffect
- Node.js 18+ instalado
- npm o yarn
- Backend Go corriendo en
localhost:8080(para producción)
- Clonar el repositorio
git clone <repository-url>
cd contabot-frontend
2. **Instalar dependencias**
```bashnpm install
echo "NEXT_PUBLIC_API_URL=http://localhost:8080" > .env.local
4. **Iniciar servidor de desarrollo**
```bash
📦 Instalación y Configuración
### Prerrequisitos
- Node.js 18+ instalado
- npm o yarn
- Backend Go corriendo en `localhost:8080` (para producción)
### Pasos de Instalación
1. **Clonar el repositorio**
```bash
git clone <repository-url>
cd contabot-frontend
Instalar dependencias
bashnpm install
Configurar variables de entorno
bash# Crear archivo .env.local en la raíz del proyecto
echo "NEXT_PUBLIC_API_URL=http://localhost:8080" > .env.local
Iniciar servidor de desarrollo
bashnpm run dev
Abrir en navegador
http://localhost:3000
📁 Estructura del Proyecto
contabot-frontend/
│
├── app/ # Next.js App Router
│ ├── page.tsx # Página raíz (redirección)
│ ├── layout.tsx # Layout principal
│ ├── globals.css # Estilos globales
│ │
│ ├── login/ # Ruta /login
│ │ └── page.tsx # Página de login
│ │
│ ├── dashboard/ # Ruta /dashboard
│ │ └── page.tsx # Dashboard principal
│ │
│ ├── upload/ # Ruta /upload
│ │ └── page.tsx # Página de subida de archivos
│ │
│ └── datos/ # Ruta /datos
│ └── page.tsx # Página de historial y tabla
│
├── components/ # Componentes reutilizables
│ ├── LoginForm.tsx # Formulario de login (tema oscuro)
│ ├── Navigation.tsx # Barra de navegación
│ ├── CFDIUploader.tsx # Componente de upload con drag & drop
│ ├── CFDITable.tsx # Tabla de datos con filtros
│ └── DashboardStats.tsx # Estadísticas y gráficas
│
├── lib/ # Utilidades y lógica de negocio
│ ├── auth.ts # Sistema de autenticación
│ ├── api.ts # Cliente API para backend
│ ├── storage.ts # Manejo de localStorage
│ └── types.ts # Definiciones TypeScript
│
├── public/ # Archivos estáticos
│
├── .env.local # Variables de entorno (no subir a git)
├── .gitignore # Archivos ignorados por git
├── next.config.js # Configuración de Next.js
├── package.json # Dependencias del proyecto
├── tailwind.config.ts # Configuración de Tailwind
├── tsconfig.json # Configuración de TypeScript
└── README.md # Este archivo
✨ Funcionalidades Implementadas
1. Sistema de Autenticación
✅ Login con email y password
✅ Validación de credenciales
✅ Persistencia de sesión (localStorage)
✅ Protección de rutas privadas
✅ Logout funcional
✅ Toggle para mostrar/ocultar contraseña
✅ Mensajes de error claros
2. Dashboard Principal
✅ 4 KPIs principales
Total procesado (dinero)
Documentos procesados
Documentos pendientes
Tasa de éxito
✅ Gráfica de línea (tendencia mensual)
✅ Gráfica de barras (categorías)
✅ Actividad reciente
✅ Top 5 proveedores
✅ Datos en tiempo real desde localStorage
3. Subida de Archivos (Upload)
✅ Drag & drop de archivos XML
✅ Click para seleccionar archivos
✅ Soporte para múltiples archivos
✅ Validación de formato (solo XML)
✅ Estados visuales (cargando, éxito, error)
✅ Tarjetas con información detallada del CFDI
✅ Contador de estadísticas en tiempo real
✅ Botón para limpiar resultados
✅ Integración con backend API
4. Página de Datos
✅ Tabla completa de CFDIs procesados
✅ Búsqueda en tiempo real
✅ Filtros por tipo de comprobante
✅ Ordenamiento (fecha, monto, nombre)
✅ Tarjetas de estadísticas
✅ Estados vacíos informativos
5. Navegación
✅ Barra de navegación persistente
✅ 3 secciones: Dashboard, Subir CFDIs, Datos
✅ Indicador de sección activa
✅ Información de usuario
✅ Botón de logout
✅ Responsive (móvil y desktop)
🔐 Flujo de Autenticación
Diagrama de Flujo
Usuario → / (página raíz)
│
├─ ¿Autenticado?
│ │
│ ├─ SÍ → /dashboard
│ │
│ └─ NO → /login
│
Usuario ingresa credenciales
│
├─ Credenciales correctas
│ │
│ ├─ Guardar en localStorage
│ └─ Redirigir a /dashboard
│
└─ Credenciales incorrectas
└─ Mostrar error
Implementación Técnica
Archivo: lib/auth.ts
login(email, password) - Valida credenciales
saveUser(user) - Guarda sesión en localStorage
getUser() - Obtiene usuario actual
logout() - Cierra sesión
isAuthenticated() - Verifica si hay sesión activa
Protección de Rutas:
Todas las páginas privadas verifican autenticación:
typescriptuseEffect(() => {
const currentUser = getUser();
if (!currentUser) {
router.push('/login');
}
}, [router]);
🔌 Integración con Backend
Endpoint Principal
Base URL: http://localhost:8080 (configurable en .env.local)
POST /api/v1/process-cfdi
Content-Type: multipart/form-data
Body: FormData con archivo XML
Timeout: 10 segundos
Ejemplo de Request
typescriptconst formData = new FormData();
formData.append('cfdi', file); // File object
const response = await axios.post(
'http://localhost:8080/api/v1/process-cfdi',
formData,
{
headers: {
'Content-Type': 'multipart/form-data',
},
timeout: 10000,
}
);
Estructura de Response Esperada
typescript{
"status": "success",
"cfdi": {
"version": "4.0",
"fecha": "2024-10-05T14:30:00",
"total": 1250.50,
"subTotal": 1000.00,
"moneda": "MXN",
"tipoComprobante": "I",
"emisor": {
"rfc": "XAXX010101000",
"nombre": "Gasolinera Norte SA de CV",
"regimenFiscal": "601"
},
"receptor": {
"rfc": "CACX7605101P8",
"nombre": "ACME Corp",
"usoCFDI": "G03"
}
},
"features": {} // Opcional: datos adicionales del ML
}
Manejo de Errores
El frontend maneja automáticamente:
❌ Backend no disponible → "No se puede conectar al servidor"
❌ Timeout (>10s) → "Error de conexión"
❌ Archivo inválido → Muestra mensaje del backend
❌ Error del servidor → Muestra error específico
💾 Almacenamiento de Datos
LocalStorage Schema
Key: contabot_cfdis
Estructura:
typescript[
{
"id": "1696785600000",
"fileName": "factura_001.xml",
"processedAt": "2024-10-08T10:30:00.000Z",
"data": {
"status": "success",
"cfdi": { /* estructura completa del CFDI */ }
}
},
// ... más registros
]
Funciones de Storage (lib/storage.ts)
typescript// Guardar un CFDI procesado
saveCFDI(fileName: string, data: ProcessedResponse): void
// Obtener todos los CFDIs
getAllCFDIs(): SavedCFDI[]
// Limpiar todos los datos
clearAllCFDIs(): void
// Obtener estadísticas calculadas
getCFDIStats(): {
totalAmount: number,
totalCount: number,
successCount: number,
avgTicket: number,
monthlyData: Array,
categoryData: Array,
topProviders: Array
}
Categorización Automática
El sistema clasifica automáticamente los CFDIs por categoría basándose en el nombre del emisor:
Palabras claveCategoríagasolinera, gas, pemexGasolinarestaurante, comida, alimentoAlimentaciónoffice, papelería, depotPapeleríacfe, telmex, servicioServiciosotrosOtros
🧩 Componentes Principales
1. LoginForm (components/LoginForm.tsx)
Diseño: Corporativo Oscuro (tema dark)
Props: Ninguno
Estado interno:
email: string
password: string
loading: boolean
error: string
showPassword: boolean
Funcionalidades:
Formulario controlado con validación
Toggle de visibilidad de contraseña
Manejo de errores con animaciones
Redirección automática tras login exitoso
2. Navigation (components/Navigation.tsx)
Props:
typescript{
userName: string,
userEmail: string
}
Características:
Navegación entre 3 secciones
Indicador visual de sección activa
Información de usuario
Botón de logout
Responsive (modo móvil con scroll horizontal)
3. CFDIUploader (components/CFDIUploader.tsx)
Props: Ninguno
Estado interno:
files: FileStatus[] - Lista de archivos procesados
uploading: boolean - Estado de carga global
Funcionalidades:
Drag & drop de archivos
Procesamiento secuencial
Estados visuales por archivo
Guardado automático en localStorage
Tarjetas detalladas con información del CFDI
Tipos de datos del CFDI:
Emisor (nombre, RFC, régimen fiscal)
Monto total y subtotal
Fecha de emisión
Tipo de comprobante
Versión del CFDI
4. DashboardStats (components/DashboardStats.tsx)
Props: Ninguno
Características:
Carga datos desde localStorage al montar
4 KPIs con gradientes
2 gráficas interactivas (Recharts)
Actividad reciente (últimos 4 archivos)
Top 5 proveedores con barras de progreso
Estados vacíos informativos
Gráficas:
LineChart: Ingresos vs Egresos por mes
BarChart: Distribución por categorías
5. CFDITable (components/CFDITable.tsx)
Props: Ninguno
Funcionalidades:
Tabla completa de registros
Búsqueda por nombre, RFC o archivo
Filtros por tipo de comprobante
Ordenamiento múltiple
3 tarjetas de estadísticas
Responsive con scroll horizontal
Columnas de la tabla:
Emisor (con icono)
RFC
Tipo de comprobante (badge colorido)
Monto
Fecha de emisión
Fecha de procesamiento
👨💻 Guía de Desarrollo
Comandos Disponibles
bash# Desarrollo
npm run dev # Inicia servidor de desarrollo en localhost:3000
# Producción
npm run build # Construye la aplicación para producción
npm start # Inicia el servidor de producción
# Utilidades
npm run lint # Ejecuta ESLint
Agregar Nueva Página
Crear carpeta en app/:
bashmkdir app/mi-nueva-pagina
touch app/mi-nueva-pagina/page.tsx
Crear componente:
typescript'use client';
export default function MiNuevaPagina() {
return (
<div>
<h1>Mi Nueva Página</h1>
</div>
);
}
Agregar a navegación (components/Navigation.tsx):
typescript{
name: 'Mi Página',
path: '/mi-nueva-pagina',
icon: <svg>...</svg>
}
Agregar Nuevo Componente
Crear archivo en components/:
bashtouch components/MiComponente.tsx
Estructura básica:
typescript'use client'; // Si usa hooks o estado
interface MiComponenteProps {
title: string;
}
export default function MiComponente({ title }: MiComponenteProps) {
return (
<div className="p-4 bg-white rounded-lg">
<h2>{title}</h2>
</div>
);
}
Importar en la página:
typescriptimport MiComponente from '@/components/MiComponente';
Trabajar con LocalStorage
Guardar datos:
typescriptimport { saveCFDI } from '@/lib/storage';
saveCFDI('archivo.xml', responseData);
Leer datos:
typescriptimport { getAllCFDIs, getCFDIStats } from '@/lib/storage';
const cfdis = getAllCFDIs();
const stats = getCFDIStats();
Limpiar datos:
typescriptimport { clearAllCFDIs } from '@/lib/storage';
clearAllCFDIs();
Agregar Nueva Gráfica
Importar componente de Recharts:
typescriptimport { PieChart, Pie, Cell } from 'recharts';
Preparar datos:
typescriptconst data = [
{ name: 'Categoría A', value: 400 },
{ name: 'Categoría B', value: 300 },
];
Renderizar:
typescript<ResponsiveContainer width="100%" height={300}>
<PieChart>
<Pie data={data} dataKey="value" nameKey="name" />
</PieChart>
</ResponsiveContainer>
🔧 Variables de Entorno
Archivo: .env.local (crear en raíz del proyecto)
bash# URL del backend API
NEXT_PUBLIC_API_URL=http://localhost:8080
# Opcional: agregar más variables según necesidad
# NEXT_PUBLIC_ANOTHER_VAR=valor
Importante:
Variables con NEXT_PUBLIC_ son visibles en el cliente
No subir .env.local a git (ya está en .gitignore)
Crear .env.example para documentar variables necesarias
🔑 Credenciales de Prueba
Para testing del sistema de login:
📧 Email: admin@contabot.com
🔒 Password: admin123
Nota: Estas credenciales están hardcodeadas en lib/auth.ts para desarrollo. En producción, conectar con backend real.
Para cambiar las credenciales:
Editar lib/auth.ts, línea 11-16:
typescriptif (email === 'TU_EMAIL' && password === 'TU_PASSWORD') {
resolve({
email: email,
name: 'Tu Nombre',
});
}
🐛 Troubleshooting
Error: "Cannot connect to localhost:8080"
Causa: El backend Go no está corriendo.
Solución:
Verificar que el backend esté corriendo: curl http://localhost:8080/health
Si no está disponible, el frontend mostrará el error correctamente
El desarrollo del frontend puede continuar sin backend
Error: "Module not found: react-dropzone"
Causa: Dependencias no instaladas.
Solución:
bashnpm install
Error: "Hydration failed"
Causa: Diferencia entre renderizado del servidor y cliente.
Solución:
Verificar que componentes con 'use client' no usen datos del servidor directamente
Usar useEffect para cargar datos del cliente
Gráficas no se muestran
Causa: Recharts no instalado o datos vacíos.
Solución:
bashnpm install recharts
Si el problema persiste, verificar que hay datos en localStorage:
javascript// En consola del navegador
localStorage.getItem('contabot_cfdis')
CORS Error al llamar al backend
Causa: Backend no tiene CORS configurado.
Solución: El backend debe agregar headers CORS:
go// Ejemplo en Go
c := cors.New(cors.Options{
AllowedOrigins: []string{"http://localhost:3000"},
AllowedMethods: []string{"GET", "POST", "OPTIONS"},
AllowedHeaders: []string{"*"},
})
Estilos de Tailwind no se aplican
Causa: Servidor de desarrollo debe reiniciarse.
Solución:
Detener servidor: Ctrl + C
Reiniciar: npm run dev
Limpiar caché si persiste: rm -rf .next
📚 Recursos Adicionales
Documentación Oficial
Next.js Documentation
React Documentation
TypeScript Handbook
Tailwind CSS
Recharts
React Dropzone
Tutoriales Recomendados
Next.js App Router: https://nextjs.org/docs/app
TypeScript con React: https://react-typescript-cheatsheet.netlify.app/
Tailwind UI Components: https://tailwindui.com/components
🤝 Contribución
Workflow de Desarrollo
Crear rama feature:
bashgit checkout -b feature/nueva-funcionalidad
Hacer cambios y commits:
bashgit add .
git commit -m "feat: agregar nueva funcionalidad"
Push y crear Pull Request:
bashgit push origin feature/nueva-funcionalidad
Convenciones de Código
Commits:
feat: Nueva funcionalidad
fix: Corrección de bug
docs: Cambios en documentación
style: Cambios de formato (no afectan lógica)
refactor: Refactorización de código
test: Agregar o modificar tests
Nombres de archivos:
Componentes: PascalCase.tsx
Utilidades: camelCase.ts
Páginas: page.tsx (Next.js convention)
Estructura de componentes:
typescript'use client'; // Si necesario
import { useState } from 'react';
interface MiComponenteProps {
// Props tipadas
}
export default function MiComponente({ prop1 }: MiComponenteProps) {
// Estado
const [state, setState] = useState();
// Funciones
const handleClick = () => {};
// Render
return (
<div>
{/* JSX */}
</div>
);
}
📞 Contacto y Soporte
Para dudas o problemas:
Crear un issue en el repositorio
Contactar al equipo de desarrollo
Revisar la documentación oficial de las tecnologías