Fix new Frontend 6

This commit is contained in:
Urtzi Alfaro
2025-08-04 07:37:19 +02:00
parent 77ccd486e9
commit 0e2c6dd54e

View File

@@ -2,6 +2,10 @@ import React, { useState } from 'react';
import { ChevronLeft, ChevronRight, Upload, MapPin, Store, Factory, Check } from 'lucide-react';
import toast from 'react-hot-toast';
import { useTenant, useTraining, useData, useAuth } from '../../api/hooks';
import { TenantCreate } from '../../api/types';
import { UserResponse } from '../../api/types';
interface OnboardingPageProps {
user: any;
onComplete: () => void;
@@ -34,6 +38,11 @@ const OnboardingPage: React.FC<OnboardingPageProps> = ({ user, onComplete }) =>
hasHistoricalData: false
});
const { createTenant, isLoading: tenantLoading } = useTenant();
const { startTrainingJob } = useTraining();
const { uploadSalesHistory, validateSalesData, uploadProgress } = useData();
const [ setUploadProgress ] = useState<number>(0);
const steps = [
{ id: 1, title: 'Datos de Panadería', icon: Store },
{ id: 2, title: 'Productos y Servicios', icon: Factory },
@@ -81,76 +90,131 @@ const OnboardingPage: React.FC<OnboardingPageProps> = ({ user, onComplete }) =>
};
const handleComplete = async () => {
if (!validateCurrentStep()) return;
setIsLoading(true);
try {
// Step 1: Register tenant/bakery
const tenantResponse = await fetch('/api/v1/tenants/register', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${localStorage.getItem('auth_token')}`
},
body: JSON.stringify({
name: bakeryData.name,
address: bakeryData.address,
business_type: bakeryData.businessType,
coordinates: bakeryData.coordinates,
products: bakeryData.products
})
});
if (!tenantResponse.ok) {
throw new Error('Error al registrar la panadería');
}
const tenantData = await tenantResponse.json();
const tenantId = tenantData.tenant.id;
// Step 2: Upload CSV data if provided
// Step 1: Create tenant using the API service
const tenantData: TenantCreate = {
name: bakeryData.name,
address: bakeryData.address,
business_type: bakeryData.businessType,
coordinates: bakeryData.coordinates,
products: bakeryData.products,
has_historical_data: bakeryData.hasHistoricalData,
};
const newTenant = await createTenant(tenantData);
const tenantId = newTenant.id;
// Step 2: Validate and Upload CSV file if provided
if (bakeryData.hasHistoricalData && bakeryData.csvFile) {
const formData = new FormData();
formData.append('file', bakeryData.csvFile);
try {
// Step 2.1: First validate the CSV data
toast.loading('Validando datos del archivo CSV...', { id: 'csv-validation' });
const validationResult = await validateSalesData(tenantId, bakeryData.csvFile);
toast.dismiss('csv-validation');
// Check validation result
if (!validationResult.success) {
// Validation failed - show errors but let user decide
const errorMessages = validationResult.errors?.slice(0, 3).join(', ') || 'Errores de validación';
const hasMoreErrors = validationResult.errors && validationResult.errors.length > 3;
toast.error(
`Errores en el archivo CSV: ${errorMessages}${hasMoreErrors ? '...' : ''}. Revisa la consola para más detalles.`
);
console.error('CSV validation errors:', validationResult.errors);
console.warn('CSV validation warnings:', validationResult.warnings);
// Don't proceed with upload if validation fails
throw new Error('Validación del CSV falló');
}
// Validation passed - show summary and proceed
if (validationResult.warnings && validationResult.warnings.length > 0) {
toast.warn(`CSV validado con ${validationResult.warnings.length} advertencias. Continuando con la subida...`);
console.warn('CSV validation warnings:', validationResult.warnings);
} else {
toast.success('CSV validado correctamente. Procediendo con la subida...');
}
// Step 2.2: Now upload the validated CSV
toast.loading('Subiendo datos históricos...', { id: 'csv-upload' });
const uploadResult = await uploadSalesHistory(tenantId, bakeryData.csvFile, {
source: 'onboarding_upload',
validate_only: false,
onProgress: (progress) => {
setUploadProgress(progress.percentage);
}
});
toast.dismiss('csv-upload');
// Check upload result
if (uploadResult.success) {
toast.success(
`¡Datos históricos subidos exitosamente! ${uploadResult.records_created} de ${uploadResult.records_processed} registros procesados.`
);
// Show additional info if some records failed
if (uploadResult.records_failed > 0) {
toast.warn(
`${uploadResult.records_failed} registros fallaron durante la subida. Success rate: ${uploadResult.success_rate?.toFixed(1)}%`
);
console.warn('Upload errors:', uploadResult.errors);
}
// Log warnings for debugging
if (uploadResult.warnings && uploadResult.warnings.length > 0) {
console.info('Upload warnings:', uploadResult.warnings);
}
const uploadResponse = await fetch(`/api/v1/tenants/${tenantId}/data/upload`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${localStorage.getItem('auth_token')}`
},
body: formData
});
if (!uploadResponse.ok) {
throw new Error('Error al subir los datos históricos');
try {
// Start training process (if you have a training service)
await startTrainingJob(tenantId);
toast.success('¡Entrenamiento del modelo iniciado!');
} catch (trainingError) {
console.warn('Training start failed:', trainingError);
// Don't fail onboarding if training fails to start
}
} else {
// Upload failed
throw new Error(`Upload failed: ${uploadResult.errors?.join(', ') || 'Unknown error'}`);
}
// Reset progress when done
setUploadProgress(0);
} catch (uploadError) {
// Handle validation or upload error gracefully
console.error('CSV validation/upload error:', uploadError);
const errorMessage = uploadError instanceof Error ? uploadError.message : 'Error desconocido';
if (errorMessage.includes('Validación')) {
toast.error('No se pudieron subir los datos históricos debido a errores de validación. La configuración se completó sin datos históricos.');
} else {
toast.warn(`Error al procesar archivo CSV: ${errorMessage}. La configuración se completó sin datos históricos.`);
}
}
// Step 3: Start training process
const trainingResponse = await fetch(`/api/v1/tenants/${tenantId}/training/start`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${localStorage.getItem('auth_token')}`
},
body: JSON.stringify({
products: bakeryData.products
})
});
if (!trainingResponse.ok) {
throw new Error('Error al iniciar el entrenamiento del modelo');
}
toast.success('¡Datos subidos! El entrenamiento del modelo comenzará pronto.');
}
toast.success('¡Configuración completada! Bienvenido a PanIA');
toast.success('¡Configuración completada exitosamente!');
onComplete();
} catch (error: any) {
} catch (error) {
console.error('Onboarding completion error:', error);
toast.error(error.message || 'Error al completar la configuración');
const errorMessage = error instanceof Error ? error.message : 'Error al completar la configuración';
toast.error(errorMessage);
} finally {
setIsLoading(false);
setUploadProgress(0); // Reset progress in case of error
}
};