Fix new Frontend 15

This commit is contained in:
Urtzi Alfaro
2025-08-04 21:46:12 +02:00
parent 8bb14ecc4f
commit 32a7b913d0
10 changed files with 705 additions and 217 deletions

View File

@@ -51,7 +51,7 @@ const OnboardingPage: React.FC<OnboardingPageProps> = ({ user, onComplete }) =>
name: '',
address: '',
businessType: 'individual',
products: [],
products: MADRID_PRODUCTS, // Automatically assign all products
hasHistoricalData: false
});
@@ -64,13 +64,11 @@ const OnboardingPage: React.FC<OnboardingPageProps> = ({ user, onComplete }) =>
const steps = [
{ id: 1, title: 'Datos de Panadería', icon: Store },
{ id: 2, title: 'Productos y Servicios', icon: Factory },
{ id: 3, title: 'Datos Históricos', icon: Upload },
{ id: 4, title: 'Entrenamiento IA', icon: Brain },
{ id: 5, title: 'Configuración Final', icon: Check }
{ id: 2, title: 'Datos Históricos', icon: Upload },
{ id: 3, title: 'Entrenamiento IA', icon: Brain },
{ id: 4, title: 'Configuración Final', icon: Check }
];
const [trainingProgress, setTrainingProgress] = useState<TrainingProgress>({
progress: 0,
status: 'pending',
@@ -123,7 +121,7 @@ const OnboardingPage: React.FC<OnboardingPageProps> = ({ user, onComplete }) =>
// Auto-advance to final step after 2 seconds
setTimeout(() => {
setCurrentStep(5);
setCurrentStep(4);
}, 2000);
} else if (messageType === 'failed' || messageType === 'training_failed' || messageType === 'training_error') {
@@ -161,7 +159,7 @@ const OnboardingPage: React.FC<OnboardingPageProps> = ({ user, onComplete }) =>
// Connect to WebSocket when training starts
useEffect(() => {
if (tenantId && trainingJobId && currentStep === 4) {
if (tenantId && trainingJobId && currentStep === 3) {
connect();
}
@@ -172,9 +170,42 @@ const OnboardingPage: React.FC<OnboardingPageProps> = ({ user, onComplete }) =>
};
}, [tenantId, trainingJobId, currentStep, connect, disconnect, isConnected]);
const storeTenantId = (tenantId: string) => {
try {
// Method 1: Store tenant ID directly
localStorage.setItem('current_tenant_id', tenantId);
// Method 2: Update user_data to include tenant_id
const existingUserData = localStorage.getItem('user_data');
if (existingUserData) {
const userData = JSON.parse(existingUserData);
userData.current_tenant_id = tenantId;
userData.tenant_id = tenantId; // Backup key
localStorage.setItem('user_data', JSON.stringify(userData));
} else {
// Create user_data with tenant info if it doesn't exist
localStorage.setItem('user_data', JSON.stringify({
current_tenant_id: tenantId,
tenant_id: tenantId
}));
}
// Method 3: Store in a dedicated tenant context
localStorage.setItem('tenant_context', JSON.stringify({
current_tenant_id: tenantId,
last_updated: new Date().toISOString()
}));
console.log('✅ Tenant ID stored successfully:', tenantId);
} catch (error) {
console.error('❌ Failed to store tenant ID:', error);
}
};
const handleNext = () => {
if (validateCurrentStep()) {
if (currentStep === 3) {
if (currentStep === 2) {
// Always proceed to training step after CSV upload
startTraining();
} else {
@@ -200,12 +231,6 @@ const OnboardingPage: React.FC<OnboardingPageProps> = ({ user, onComplete }) =>
}
return true;
case 2:
if (bakeryData.products.length === 0) {
toast.error('Selecciona al menos un producto');
return false;
}
return true;
case 3:
if (!bakeryData.csvFile) {
toast.error('Por favor, selecciona un archivo con tus datos históricos');
return false;
@@ -235,7 +260,7 @@ const OnboardingPage: React.FC<OnboardingPageProps> = ({ user, onComplete }) =>
};
const startTraining = async () => {
setCurrentStep(4);
setCurrentStep(3);
setIsLoading(true);
try {
@@ -259,6 +284,7 @@ const OnboardingPage: React.FC<OnboardingPageProps> = ({ user, onComplete }) =>
const tenant = await createTenant(tenantData);
setTenantId(tenant.id);
storeTenantId(tenant.id);
// Step 2: Validate and Upload CSV file if provided
if (bakeryData.csvFile) {
@@ -327,7 +353,7 @@ const OnboardingPage: React.FC<OnboardingPageProps> = ({ user, onComplete }) =>
const handleComplete = async () => {
if (!validateCurrentStep()) return;
if (currentStep < 4) {
if (currentStep < 3) {
// Start training process
await startTraining();
} else {
@@ -354,7 +380,7 @@ const OnboardingPage: React.FC<OnboardingPageProps> = ({ user, onComplete }) =>
icon: '',
duration: 4000
});
setCurrentStep(5);
setCurrentStep(4);
};
const handleTrainingTimeout = () => {
@@ -461,52 +487,6 @@ const OnboardingPage: React.FC<OnboardingPageProps> = ({ user, onComplete }) =>
);
case 2:
return (
<div className="space-y-6">
<div>
<h3 className="text-lg font-semibold text-gray-900 mb-4">
Productos y Servicios
</h3>
<p className="text-gray-600 mb-6">
Selecciona los productos que vendes regularmente. Esto nos ayudará a crear predicciones más precisas.
</p>
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-3">
{MADRID_PRODUCTS.map((product) => (
<button
key={product}
type="button"
onClick={() => {
setBakeryData(prev => ({
...prev,
products: prev.products.includes(product)
? prev.products.filter(p => p !== product)
: [...prev.products, product]
}));
}}
className={`p-3 text-sm rounded-xl border transition-all ${
bakeryData.products.includes(product)
? 'border-primary-500 bg-primary-50 text-primary-700'
: 'border-gray-300 hover:border-gray-400'
}`}
>
{product}
</button>
))}
</div>
{bakeryData.products.length > 0 && (
<div className="mt-4 p-4 bg-green-50 rounded-xl">
<p className="text-sm text-green-700">
{bakeryData.products.length} productos seleccionados
</p>
</div>
)}
</div>
</div>
);
case 3:
return (
<div className="space-y-6">
<div>
@@ -695,7 +675,7 @@ const OnboardingPage: React.FC<OnboardingPageProps> = ({ user, onComplete }) =>
</div>
);
case 4:
case 3:
return (
<EnhancedTrainingProgress
progress={{
@@ -715,7 +695,7 @@ const OnboardingPage: React.FC<OnboardingPageProps> = ({ user, onComplete }) =>
/>
);
case 5:
case 4:
return (
<div className="text-center space-y-6">
<div className="mx-auto w-16 h-16 bg-green-100 rounded-full flex items-center justify-center">
@@ -832,7 +812,7 @@ const OnboardingPage: React.FC<OnboardingPageProps> = ({ user, onComplete }) =>
</button>
{/* Dynamic Next/Complete Button */}
{currentStep < 4 ? (
{currentStep < 3 ? (
<button
onClick={handleNext}
disabled={isLoading}
@@ -850,7 +830,7 @@ const OnboardingPage: React.FC<OnboardingPageProps> = ({ user, onComplete }) =>
</>
)}
</button>
) : currentStep === 4 ? (
) : currentStep === 3 ? (
// Training step - show different buttons based on status
<div className="flex space-x-3">
{trainingProgress.status === 'failed' ? (
@@ -877,7 +857,7 @@ const OnboardingPage: React.FC<OnboardingPageProps> = ({ user, onComplete }) =>
</>
) : trainingProgress.status === 'completed' ? (
<button
onClick={() => setCurrentStep(5)}
onClick={() => setCurrentStep(4)}
className="flex items-center px-6 py-2 bg-green-500 text-white rounded-xl hover:bg-green-600 transition-all hover:shadow-lg"
>
Continuar