diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index f8cf22c1..766aa5c3 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -11,8 +11,10 @@ import { ThemeProvider } from './contexts/ThemeContext';
import { AuthProvider } from './contexts/AuthContext';
import { SSEProvider } from './contexts/SSEContext';
import { SubscriptionEventsProvider } from './contexts/SubscriptionEventsContext';
+import { TourProvider } from './contexts/TourContext';
import GlobalSubscriptionHandler from './components/auth/GlobalSubscriptionHandler';
import { CookieBanner } from './components/ui/CookieConsent';
+import { Tour } from './components/ui/Tour';
import i18n from './i18n';
const queryClient = new QueryClient({
@@ -65,7 +67,10 @@ function App() {
-
+
+
+
+
diff --git a/frontend/src/components/domain/onboarding/UnifiedOnboardingWizard.tsx b/frontend/src/components/domain/onboarding/UnifiedOnboardingWizard.tsx
index 4fcfedd8..778dc9fa 100644
--- a/frontend/src/components/domain/onboarding/UnifiedOnboardingWizard.tsx
+++ b/frontend/src/components/domain/onboarding/UnifiedOnboardingWizard.tsx
@@ -13,6 +13,8 @@ import {
DataSourceChoiceStep,
RegisterTenantStep,
UploadSalesDataStep,
+ ProductCategorizationStep,
+ InitialStockEntryStep,
ProductionProcessesStep,
MLTrainingStep,
CompletionStep
@@ -89,6 +91,22 @@ const OnboardingWizardContent: React.FC = () => {
isConditional: true,
condition: (ctx) => ctx.state.dataSource === 'ai-assisted',
},
+ {
+ id: 'product-categorization',
+ title: t('onboarding:steps.categorization.title', 'Categorizar Productos'),
+ description: t('onboarding:steps.categorization.description', 'Clasifica ingredientes vs productos'),
+ component: ProductCategorizationStep,
+ isConditional: true,
+ condition: (ctx) => ctx.state.dataSource === 'ai-assisted' && ctx.state.aiAnalysisComplete,
+ },
+ {
+ id: 'initial-stock-entry',
+ title: t('onboarding:steps.stock.title', 'Niveles de Stock'),
+ description: t('onboarding:steps.stock.description', 'Cantidades iniciales'),
+ component: InitialStockEntryStep,
+ isConditional: true,
+ condition: (ctx) => ctx.state.dataSource === 'ai-assisted' && ctx.state.categorizationCompleted,
+ },
// Phase 2b: Core Data Entry
{
id: 'suppliers-setup',
@@ -322,6 +340,14 @@ const OnboardingWizardContent: React.FC = () => {
wizardContext.updateAISuggestions(data.aiSuggestions);
wizardContext.setAIAnalysisComplete(true);
}
+ if (currentStep.id === 'product-categorization' && data?.categorizedProducts) {
+ wizardContext.updateCategorizedProducts(data.categorizedProducts);
+ wizardContext.markStepComplete('categorizationCompleted');
+ }
+ if (currentStep.id === 'initial-stock-entry' && data?.productsWithStock) {
+ wizardContext.updateProductsWithStock(data.productsWithStock);
+ wizardContext.markStepComplete('stockEntryCompleted');
+ }
if (currentStep.id === 'inventory-setup') {
wizardContext.markStepComplete('inventoryCompleted');
}
@@ -381,6 +407,12 @@ const OnboardingWizardContent: React.FC = () => {
if (currentStep.id === 'data-source-choice' && data?.dataSource) {
wizardContext.updateDataSource(data.dataSource as DataSource);
}
+ if (currentStep.id === 'product-categorization' && data?.categorizedProducts) {
+ wizardContext.updateCategorizedProducts(data.categorizedProducts);
+ }
+ if (currentStep.id === 'initial-stock-entry' && data?.productsWithStock) {
+ wizardContext.updateProductsWithStock(data.productsWithStock);
+ }
};
// Show loading state
diff --git a/frontend/src/components/domain/onboarding/context/WizardContext.tsx b/frontend/src/components/domain/onboarding/context/WizardContext.tsx
index e9a6a36b..5d66b6d3 100644
--- a/frontend/src/components/domain/onboarding/context/WizardContext.tsx
+++ b/frontend/src/components/domain/onboarding/context/WizardContext.tsx
@@ -23,8 +23,12 @@ export interface WizardState {
uploadedFileSize?: number;
aiSuggestions: AISuggestion[];
aiAnalysisComplete: boolean;
+ categorizedProducts?: any[]; // Products with type classification
+ productsWithStock?: any[]; // Products with initial stock levels
// Setup Progress
+ categorizationCompleted: boolean;
+ stockEntryCompleted: boolean;
suppliersCompleted: boolean;
inventoryCompleted: boolean;
recipesCompleted: boolean;
@@ -47,6 +51,8 @@ export interface WizardContextValue {
updateDataSource: (source: DataSource) => void;
updateAISuggestions: (suggestions: AISuggestion[]) => void;
setAIAnalysisComplete: (complete: boolean) => void;
+ updateCategorizedProducts: (products: any[]) => void;
+ updateProductsWithStock: (products: any[]) => void;
markStepComplete: (step: keyof WizardState) => void;
getVisibleSteps: () => string[];
shouldShowStep: (stepId: string) => boolean;
@@ -58,6 +64,10 @@ const initialState: WizardState = {
dataSource: null,
aiSuggestions: [],
aiAnalysisComplete: false,
+ categorizedProducts: undefined,
+ productsWithStock: undefined,
+ categorizationCompleted: false,
+ stockEntryCompleted: false,
suppliersCompleted: false,
inventoryCompleted: false,
recipesCompleted: false,
@@ -121,6 +131,14 @@ export const WizardProvider: React.FC = ({
setState(prev => ({ ...prev, aiAnalysisComplete: complete }));
};
+ const updateCategorizedProducts = (products: any[]) => {
+ setState(prev => ({ ...prev, categorizedProducts: products }));
+ };
+
+ const updateProductsWithStock = (products: any[]) => {
+ setState(prev => ({ ...prev, productsWithStock: products }));
+ };
+
const markStepComplete = (step: keyof WizardState) => {
setState(prev => ({ ...prev, [step]: true }));
};
@@ -154,6 +172,11 @@ export const WizardProvider: React.FC = ({
if (state.aiAnalysisComplete) {
steps.push('review-suggestions');
+ steps.push('product-categorization');
+ }
+
+ if (state.categorizationCompleted) {
+ steps.push('initial-stock-entry');
}
}
@@ -210,6 +233,8 @@ export const WizardProvider: React.FC = ({
updateDataSource,
updateAISuggestions,
setAIAnalysisComplete,
+ updateCategorizedProducts,
+ updateProductsWithStock,
markStepComplete,
getVisibleSteps,
shouldShowStep,
diff --git a/frontend/src/components/layout/Sidebar/Sidebar.tsx b/frontend/src/components/layout/Sidebar/Sidebar.tsx
index b8373a44..f94eb770 100644
--- a/frontend/src/components/layout/Sidebar/Sidebar.tsx
+++ b/frontend/src/components/layout/Sidebar/Sidebar.tsx
@@ -12,6 +12,7 @@ import { Button } from '../../ui';
import { Badge } from '../../ui';
import { Tooltip } from '../../ui';
import { Avatar } from '../../ui';
+import { TourButton } from '../../ui/Tour/TourButton';
import {
LayoutDashboard,
Package,
@@ -811,6 +812,13 @@ export const Sidebar = forwardRef(({
)}
+ {/* Tour Button */}
+ {!isCollapsed && (
+
+
+
+ )}
+
{/* Navigation */}