Support multiple languages
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useNavigate, useSearchParams } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button } from '../../ui/Button';
|
||||
import { Card, CardHeader, CardBody } from '../../ui/Card';
|
||||
import { useAuth } from '../../../contexts/AuthContext';
|
||||
@@ -29,40 +30,41 @@ interface StepProps {
|
||||
isLastStep: boolean;
|
||||
}
|
||||
|
||||
// Steps must match backend ONBOARDING_STEPS exactly
|
||||
// Note: "user_registered" is auto-completed and not shown in UI
|
||||
const STEPS: StepConfig[] = [
|
||||
{
|
||||
id: 'setup',
|
||||
title: 'Registrar Panadería',
|
||||
description: 'Configura la información básica de tu panadería',
|
||||
component: RegisterTenantStep,
|
||||
},
|
||||
{
|
||||
id: 'smart-inventory-setup',
|
||||
title: 'Configurar Inventario',
|
||||
description: 'Sube datos de ventas y configura tu inventario inicial',
|
||||
component: UploadSalesDataStep,
|
||||
},
|
||||
{
|
||||
id: 'ml-training',
|
||||
title: 'Entrenamiento IA',
|
||||
description: 'Entrena tu modelo de inteligencia artificial personalizado',
|
||||
component: MLTrainingStep,
|
||||
},
|
||||
{
|
||||
id: 'completion',
|
||||
title: 'Configuración Completa',
|
||||
description: '¡Bienvenido a tu sistema de gestión inteligente!',
|
||||
component: CompletionStep,
|
||||
},
|
||||
];
|
||||
|
||||
export const OnboardingWizard: React.FC = () => {
|
||||
const { t } = useTranslation();
|
||||
const [searchParams] = useSearchParams();
|
||||
const navigate = useNavigate();
|
||||
const { user } = useAuth();
|
||||
|
||||
// Steps must match backend ONBOARDING_STEPS exactly
|
||||
// Note: "user_registered" is auto-completed and not shown in UI
|
||||
const STEPS: StepConfig[] = [
|
||||
{
|
||||
id: 'setup',
|
||||
title: t('onboarding:wizard.steps.setup.title', 'Registrar Panadería'),
|
||||
description: t('onboarding:wizard.steps.setup.description', 'Configura la información básica de tu panadería'),
|
||||
component: RegisterTenantStep,
|
||||
},
|
||||
{
|
||||
id: 'smart-inventory-setup',
|
||||
title: t('onboarding:wizard.steps.smart_inventory_setup.title', 'Configurar Inventario'),
|
||||
description: t('onboarding:wizard.steps.smart_inventory_setup.description', 'Sube datos de ventas y configura tu inventario inicial'),
|
||||
component: UploadSalesDataStep,
|
||||
},
|
||||
{
|
||||
id: 'ml-training',
|
||||
title: t('onboarding:wizard.steps.ml_training.title', 'Entrenamiento IA'),
|
||||
description: t('onboarding:wizard.steps.ml_training.description', 'Entrena tu modelo de inteligencia artificial personalizado'),
|
||||
component: MLTrainingStep,
|
||||
},
|
||||
{
|
||||
id: 'completion',
|
||||
title: t('onboarding:wizard.steps.completion.title', 'Configuración Completa'),
|
||||
description: t('onboarding:wizard.steps.completion.description', '¡Bienvenido a tu sistema de gestión inteligente!'),
|
||||
component: CompletionStep,
|
||||
},
|
||||
];
|
||||
|
||||
// Check if this is a fresh onboarding (new tenant creation)
|
||||
const isNewTenant = searchParams.get('new') === 'true';
|
||||
|
||||
@@ -277,7 +279,7 @@ export const OnboardingWizard: React.FC = () => {
|
||||
}
|
||||
|
||||
// Don't advance automatically on error - user should see the issue
|
||||
alert(`Error al completar paso "${currentStep.title}": ${errorMessage}`);
|
||||
alert(`${t('onboarding:errors.step_failed', 'Error al completar paso')} "${currentStep.title}": ${errorMessage}`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -289,7 +291,7 @@ export const OnboardingWizard: React.FC = () => {
|
||||
<CardBody>
|
||||
<div className="flex items-center justify-center space-x-3">
|
||||
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-[var(--color-primary)]"></div>
|
||||
<p className="text-[var(--text-secondary)] text-sm sm:text-base">Cargando tu progreso...</p>
|
||||
<p className="text-[var(--text-secondary)] text-sm sm:text-base">{t('common:loading', 'Cargando tu progreso...')}</p>
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
@@ -311,17 +313,17 @@ export const OnboardingWizard: React.FC = () => {
|
||||
</div>
|
||||
<div>
|
||||
<h2 className="text-base sm:text-lg font-semibold text-[var(--text-primary)] mb-2">
|
||||
Error al cargar progreso
|
||||
{t('onboarding:errors.network_error', 'Error al cargar progreso')}
|
||||
</h2>
|
||||
<p className="text-sm sm:text-base text-[var(--text-secondary)] mb-4 px-2">
|
||||
No pudimos cargar tu progreso de configuración. Puedes continuar desde el inicio.
|
||||
{t('onboarding:errors.try_again', 'No pudimos cargar tu progreso de configuración. Puedes continuar desde el inicio.')}
|
||||
</p>
|
||||
<Button
|
||||
onClick={() => setIsInitialized(true)}
|
||||
variant="primary"
|
||||
size="lg"
|
||||
>
|
||||
Continuar
|
||||
{t('onboarding:wizard.navigation.next', 'Continuar')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -350,10 +352,10 @@ export const OnboardingWizard: React.FC = () => {
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm font-medium text-[var(--text-primary)]">
|
||||
Creando Nueva Organización
|
||||
{t('onboarding:wizard.title', 'Creando Nueva Organización')}
|
||||
</p>
|
||||
<p className="text-xs text-[var(--text-secondary)]">
|
||||
Configurarás una nueva panadería desde cero. Este proceso es independiente de tus organizaciones existentes.
|
||||
{t('onboarding:wizard.subtitle', 'Configurarás una nueva panadería desde cero. Este proceso es independiente de tus organizaciones existentes.')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -366,21 +368,21 @@ export const OnboardingWizard: React.FC = () => {
|
||||
<div className="flex flex-col sm:flex-row sm:justify-between sm:items-center mb-4 space-y-2 sm:space-y-0">
|
||||
<div className="text-center sm:text-left">
|
||||
<h1 className="text-xl sm:text-2xl font-bold text-[var(--text-primary)]">
|
||||
{isNewTenant ? 'Crear Nueva Organización' : 'Bienvenido a Bakery IA'}
|
||||
{isNewTenant ? t('onboarding:wizard.title', 'Crear Nueva Organización') : t('onboarding:wizard.title', 'Bienvenido a Bakery IA')}
|
||||
</h1>
|
||||
<p className="text-[var(--text-secondary)] text-xs sm:text-sm mt-1">
|
||||
{isNewTenant
|
||||
? 'Configura tu nueva panadería desde cero'
|
||||
: 'Configura tu sistema de gestión inteligente paso a paso'
|
||||
? t('onboarding:wizard.subtitle', 'Configura tu nueva panadería desde cero')
|
||||
: t('onboarding:wizard.subtitle', 'Configura tu sistema de gestión inteligente paso a paso')
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
<div className="text-center sm:text-right">
|
||||
<div className="text-sm text-[var(--text-secondary)]">
|
||||
Paso {currentStepIndex + 1} de {STEPS.length}
|
||||
{t('onboarding:wizard.progress.step_of', 'Paso {{current}} de {{total}}', { current: currentStepIndex + 1, total: STEPS.length })}
|
||||
</div>
|
||||
<div className="text-xs text-[var(--text-tertiary)]">
|
||||
{Math.round(progressPercentage)}% completado
|
||||
{Math.round(progressPercentage)}% {t('onboarding:wizard.progress.completed', 'completado')}
|
||||
{isNewTenant && <span className="text-[var(--color-primary)] ml-1">(nuevo)</span>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user