Fix new Frontend 12

This commit is contained in:
Urtzi Alfaro
2025-08-04 18:21:42 +02:00
parent d4c276c888
commit 35b02ca364
6 changed files with 528 additions and 174 deletions

View File

@@ -2,6 +2,8 @@ import React, { useState, useEffect, useCallback } from 'react';
import { ChevronLeft, ChevronRight, Upload, MapPin, Store, Factory, Check, Brain, Clock, CheckCircle, AlertTriangle, Loader } from 'lucide-react';
import toast from 'react-hot-toast';
import EnhancedTrainingProgress from '../../components/EnhancedTrainingProgress';
import {
useTenant,
useTraining,
@@ -352,11 +354,30 @@ const OnboardingPage: React.FC<OnboardingPageProps> = ({ user, onComplete }) =>
setCurrentStep(5);
};
const formatTimeRemaining = (seconds: number): string => {
const minutes = Math.floor(seconds / 60);
const secs = seconds % 60;
return `${minutes}:${secs.toString().padStart(2, '0')}`;
};
const handleTrainingTimeout = () => {
// Option 1: Navigate to dashboard with limited functionality
onComplete(); // This calls your existing completion handler
// Option 2: Show a custom modal or message
// setShowLimitedAccessMessage(true);
// Option 3: Set a flag to enable partial dashboard access
// setLimitedAccess(true);
};
// Then update the EnhancedTrainingProgress call:
<EnhancedTrainingProgress
progress={{
progress: trainingProgress.progress,
status: trainingProgress.status,
currentStep: trainingProgress.currentStep,
productsCompleted: trainingProgress.productsCompleted,
productsTotal: trainingProgress.productsTotal,
estimatedTimeRemaining: trainingProgress.estimatedTimeRemaining,
error: trainingProgress.error
}}
onTimeout={handleTrainingTimeout}
/>
const renderStep = () => {
switch (currentStep) {
@@ -672,133 +693,24 @@ const OnboardingPage: React.FC<OnboardingPageProps> = ({ user, onComplete }) =>
);
case 4:
return (
<div className="space-y-6">
<div className="text-center">
<div className="mx-auto w-16 h-16 bg-primary-100 rounded-full flex items-center justify-center mb-4">
<Brain className="h-8 w-8 text-primary-600" />
</div>
<h3 className="text-lg font-semibold text-gray-900 mb-2">
🧠 Entrenando tu modelo de predicción
</h3>
<p className="text-gray-600 mb-8">
Estamos procesando tus datos históricos para crear predicciones personalizadas
</p>
</div>
{/* WebSocket Connection Status */}
{tenantId && trainingJobId && (
<div className="mb-4 text-xs text-gray-500 flex items-center">
<div className={`w-2 h-2 rounded-full mr-2 ${
isConnected ? 'bg-green-500' : 'bg-red-500'
}`} />
{isConnected ? 'Conectado a actualizaciones en tiempo real' : 'Reconectando...'}
</div>
)}
<div className="space-y-4">
<div className="flex justify-between items-center text-sm">
<span className="text-gray-600">{trainingProgress.currentStep}</span>
<span className="text-gray-500">
{trainingProgress.progress}% completado
</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-3">
<div
className="bg-gradient-to-r from-primary-500 to-primary-600 h-3 rounded-full transition-all duration-1000 ease-out"
style={{ width: `${trainingProgress.progress}%` }}
/>
</div>
{trainingProgress.productsTotal > 0 && (
<div className="flex justify-between items-center text-sm text-gray-600">
<span>
📦 Productos: {trainingProgress.productsCompleted}/{trainingProgress.productsTotal}
</span>
{trainingProgress.estimatedTimeRemaining > 0 && (
<span className="flex items-center">
<Clock className="h-4 w-4 mr-1" />
{formatTimeRemaining(trainingProgress.estimatedTimeRemaining)} restante
</span>
)}
</div>
)}
</div>
{/* Training Status */}
<div className="bg-gray-50 rounded-xl p-6">
{trainingProgress.status === 'running' && (
<div className="flex items-center text-blue-700">
<Loader className="h-5 w-5 mr-3 animate-spin" />
<div>
<div className="font-medium">Entrenamiento en progreso</div>
<div className="text-sm text-blue-600">
Tu modelo está aprendiendo de los patrones históricos de ventas
</div>
</div>
</div>
)}
{trainingProgress.status === 'completed' && (
<div className="flex items-center text-green-700">
<CheckCircle className="h-5 w-5 mr-3" />
<div>
<div className="font-medium">¡Entrenamiento completado!</div>
<div className="text-sm text-green-600">
Tu modelo está listo para generar predicciones precisas
</div>
</div>
</div>
)}
{trainingProgress.status === 'failed' && (
<div className="space-y-4">
<div className="flex items-center text-red-700">
<AlertTriangle className="h-5 w-5 mr-3" />
<div>
<div className="font-medium">Error en el entrenamiento</div>
<div className="text-sm text-red-600">
{trainingProgress.error || 'Ha ocurrido un error durante el entrenamiento'}
</div>
</div>
</div>
<div className="flex space-x-3">
<button
onClick={handleRetryTraining}
className="flex-1 px-4 py-2 bg-primary-500 text-white rounded-lg hover:bg-primary-600 transition-colors"
>
Reintentar entrenamiento
</button>
<button
onClick={handleSkipTraining}
className="flex-1 px-4 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors"
>
Continuar sin entrenar
</button>
</div>
</div>
)}
</div>
{/* Educational Content */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 text-sm">
<div className="bg-blue-50 p-4 rounded-lg">
<div className="font-medium text-blue-900 mb-2">¿Qué está pasando?</div>
<div className="text-blue-700">
Nuestro sistema está analizando patrones estacionales, tendencias de demanda y factores externos para crear un modelo personalizado para tu panadería.
</div>
</div>
<div className="bg-green-50 p-4 rounded-lg">
<div className="font-medium text-green-900 mb-2">Beneficios esperados</div>
<div className="text-green-700">
Predicciones de demanda precisas, reducción de desperdicio, optimización de stock y mejor planificación de producción.
</div>
</div>
</div>
</div>
);
return (
<EnhancedTrainingProgress
progress={{
progress: trainingProgress.progress,
status: trainingProgress.status,
currentStep: trainingProgress.currentStep,
productsCompleted: trainingProgress.productsCompleted,
productsTotal: trainingProgress.productsTotal,
estimatedTimeRemaining: trainingProgress.estimatedTimeRemaining,
error: trainingProgress.error
}}
onTimeout={() => {
// Handle timeout - either navigate to dashboard or show limited access
console.log('Training timeout - user wants to continue to dashboard');
// You can add your custom timeout logic here
}}
/>
);
case 5:
return (