Start integrating the onboarding flow with backend 13
This commit is contained in:
@@ -455,7 +455,7 @@ export const SmartInventorySetupStep: React.FC<OnboardingStepProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 className="text-3xl font-bold text-[var(--text-primary)] mb-4">
|
<h3 className="text-3xl font-bold text-[var(--text-primary)] mb-4">
|
||||||
Sube tu historial de ventas
|
Sube tus datos de ventas de forma segura: tú eres el propietario de esos datos, nosotros solo los optimizamos.
|
||||||
</h3>
|
</h3>
|
||||||
<p className="text-[var(--text-secondary)] text-xl leading-relaxed max-w-md mx-auto">
|
<p className="text-[var(--text-secondary)] text-xl leading-relaxed max-w-md mx-auto">
|
||||||
Arrastra y suelta tu archivo aquí, o <span className="text-[var(--color-primary)] font-semibold">haz clic para seleccionar</span>
|
Arrastra y suelta tu archivo aquí, o <span className="text-[var(--color-primary)] font-semibold">haz clic para seleccionar</span>
|
||||||
@@ -771,7 +771,7 @@ export const SmartInventorySetupStep: React.FC<OnboardingStepProps> = ({
|
|||||||
{/* Information */}
|
{/* Information */}
|
||||||
<Card className="p-4 bg-[var(--color-info)]/5 border-[var(--color-info)]/20">
|
<Card className="p-4 bg-[var(--color-info)]/5 border-[var(--color-info)]/20">
|
||||||
<h4 className="font-medium text-[var(--color-info)] mb-2">
|
<h4 className="font-medium text-[var(--color-info)] mb-2">
|
||||||
📦 Inventario Inteligente:
|
📦 Sube tus datos de ventas de forma segura: tú eres el propietario, nosotros solo los optimizamos.:
|
||||||
</h4>
|
</h4>
|
||||||
<ul className="text-sm text-[var(--color-info)] space-y-1">
|
<ul className="text-sm text-[var(--color-info)] space-y-1">
|
||||||
<li>• <strong>Configuración automática</strong> - Los niveles de stock se calculan basándose en tus datos de ventas</li>
|
<li>• <strong>Configuración automática</strong> - Los niveles de stock se calculan basándose en tus datos de ventas</li>
|
||||||
|
|||||||
@@ -55,7 +55,8 @@ src/hooks/business/onboarding/
|
|||||||
├── core/
|
├── core/
|
||||||
│ ├── store.ts # Zustand centralized store
|
│ ├── store.ts # Zustand centralized store
|
||||||
│ ├── actions.ts # Business logic orchestration
|
│ ├── actions.ts # Business logic orchestration
|
||||||
│ └── types.ts # Complete type definitions
|
│ ├── types.ts # Complete type definitions
|
||||||
|
│ └── useAutoResume.ts # Auto-resume wrapper
|
||||||
├── services/
|
├── services/
|
||||||
│ ├── useTenantCreation.ts # Tenant service
|
│ ├── useTenantCreation.ts # Tenant service
|
||||||
│ ├── useSalesProcessing.ts # Sales processing service
|
│ ├── useSalesProcessing.ts # Sales processing service
|
||||||
@@ -65,10 +66,9 @@ src/hooks/business/onboarding/
|
|||||||
│ └── useResumeLogic.ts # Resume service
|
│ └── useResumeLogic.ts # Resume service
|
||||||
├── utils/
|
├── utils/
|
||||||
│ └── createServiceHook.ts # Service factory
|
│ └── createServiceHook.ts # Service factory
|
||||||
|
├── config/
|
||||||
|
│ └── steps.ts # Step definitions and validation
|
||||||
├── useOnboarding.ts # Main unified hook
|
├── useOnboarding.ts # Main unified hook
|
||||||
├── useAutoResume.ts # Auto-resume wrapper
|
|
||||||
├── steps.ts # Step definitions
|
|
||||||
├── types.ts # Legacy type exports
|
|
||||||
└── index.ts # Clean exports
|
└── index.ts # Clean exports
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Onboarding step definitions and validation logic
|
* Onboarding step definitions and validation logic
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { OnboardingStep, OnboardingData } from './types';
|
import type { OnboardingStep, OnboardingData } from '../core/types';
|
||||||
|
|
||||||
export const DEFAULT_STEPS: OnboardingStep[] = [
|
export const DEFAULT_STEPS: OnboardingStep[] = [
|
||||||
{
|
{
|
||||||
@@ -10,7 +10,7 @@ import { useSalesProcessing } from '../services/useSalesProcessing';
|
|||||||
import { useInventorySetup } from '../services/useInventorySetup';
|
import { useInventorySetup } from '../services/useInventorySetup';
|
||||||
import { useTrainingOrchestration } from '../services/useTrainingOrchestration';
|
import { useTrainingOrchestration } from '../services/useTrainingOrchestration';
|
||||||
import { useProgressTracking } from '../services/useProgressTracking';
|
import { useProgressTracking } from '../services/useProgressTracking';
|
||||||
import { getStepById } from '../steps';
|
import { getStepById } from '../config/steps';
|
||||||
import type { ProductSuggestionResponse } from '../core/types';
|
import type { ProductSuggestionResponse } from '../core/types';
|
||||||
import type { BakeryRegistration } from '../../../../api';
|
import type { BakeryRegistration } from '../../../../api';
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
import { create } from 'zustand';
|
import { create } from 'zustand';
|
||||||
import { devtools } from 'zustand/middleware';
|
import { devtools } from 'zustand/middleware';
|
||||||
import type { OnboardingData, OnboardingStep, OnboardingProgress } from './types';
|
import type { OnboardingData, OnboardingStep, OnboardingProgress } from './types';
|
||||||
import { DEFAULT_STEPS } from '../steps';
|
import { DEFAULT_STEPS } from '../config/steps';
|
||||||
|
|
||||||
interface OnboardingStore {
|
interface OnboardingStore {
|
||||||
// Flow state
|
// Flow state
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Auto-resume hook - Simple wrapper around resume logic service
|
* Auto-resume hook - Simple wrapper around resume logic service
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useResumeLogic } from './services/useResumeLogic';
|
import { useResumeLogic } from '../services/useResumeLogic';
|
||||||
|
|
||||||
export const useAutoResume = () => {
|
export const useAutoResume = () => {
|
||||||
const resumeLogic = useResumeLogic();
|
const resumeLogic = useResumeLogic();
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
export type * from './core/types';
|
export type * from './core/types';
|
||||||
|
|
||||||
// Steps configuration
|
// Steps configuration
|
||||||
export { DEFAULT_STEPS, getStepById, getStepIndex, canAccessStep, calculateProgress } from './steps';
|
export { DEFAULT_STEPS, getStepById, getStepIndex, canAccessStep, calculateProgress } from './config/steps';
|
||||||
|
|
||||||
// Core architecture (for advanced usage)
|
// Core architecture (for advanced usage)
|
||||||
export { useOnboardingStore } from './core/store';
|
export { useOnboardingStore } from './core/store';
|
||||||
@@ -23,7 +23,7 @@ export { useResumeLogic } from './services/useResumeLogic';
|
|||||||
|
|
||||||
// Main hooks - PRIMARY INTERFACE for components
|
// Main hooks - PRIMARY INTERFACE for components
|
||||||
export { useOnboarding } from './useOnboarding';
|
export { useOnboarding } from './useOnboarding';
|
||||||
export { useAutoResume } from './useAutoResume';
|
export { useAutoResume } from './core/useAutoResume';
|
||||||
|
|
||||||
// Utility
|
// Utility
|
||||||
export { createServiceHook } from './utils/createServiceHook';
|
export { createServiceHook } from './utils/createServiceHook';
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
* Progress tracking service - Clean, standardized implementation
|
* Progress tracking service - Clean, standardized implementation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useCallback, useEffect } from 'react';
|
import { useCallback, useEffect, useRef } from 'react';
|
||||||
import { onboardingService } from '../../../../api/services/onboarding';
|
import { onboardingService } from '../../../../api/services/onboarding';
|
||||||
import { createServiceHook } from '../utils/createServiceHook';
|
import { createServiceHook } from '../utils/createServiceHook';
|
||||||
import type { ProgressTrackingState } from '../core/types';
|
import type { ProgressTrackingState } from '../core/types';
|
||||||
@@ -20,6 +20,7 @@ const useProgressTrackingService = createServiceHook<ProgressTrackingState>({
|
|||||||
|
|
||||||
export const useProgressTracking = () => {
|
export const useProgressTracking = () => {
|
||||||
const service = useProgressTrackingService();
|
const service = useProgressTrackingService();
|
||||||
|
const initializationAttempted = useRef(false);
|
||||||
|
|
||||||
// Load initial progress from backend
|
// Load initial progress from backend
|
||||||
const loadProgress = useCallback(async (): Promise<UserProgress | null> => {
|
const loadProgress = useCallback(async (): Promise<UserProgress | null> => {
|
||||||
@@ -121,12 +122,13 @@ export const useProgressTracking = () => {
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Auto-load progress on hook initialization
|
// Auto-load progress on hook initialization - PREVENT multiple attempts
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!service.data?.isInitialized) {
|
if (!service.data?.isInitialized && !initializationAttempted.current && !service.isLoading) {
|
||||||
|
initializationAttempted.current = true;
|
||||||
loadProgress();
|
loadProgress();
|
||||||
}
|
}
|
||||||
}, [loadProgress, service.data?.isInitialized]);
|
}, [service.data?.isInitialized, service.isLoading]); // Remove loadProgress from deps
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// State
|
// State
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Resume logic service - Clean, standardized implementation
|
* Resume logic service - Clean, standardized implementation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useCallback, useEffect } from 'react';
|
import { useCallback, useEffect, useRef } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { useOnboardingStore } from '../core/store';
|
import { useOnboardingStore } from '../core/store';
|
||||||
import { useProgressTracking } from './useProgressTracking';
|
import { useProgressTracking } from './useProgressTracking';
|
||||||
@@ -22,6 +22,7 @@ export const useResumeLogic = () => {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const progressTracking = useProgressTracking();
|
const progressTracking = useProgressTracking();
|
||||||
const { setCurrentStep } = useOnboardingStore();
|
const { setCurrentStep } = useOnboardingStore();
|
||||||
|
const resumeAttempted = useRef(false);
|
||||||
|
|
||||||
// Check if user should resume onboarding
|
// Check if user should resume onboarding
|
||||||
const checkForResume = useCallback(async (): Promise<boolean> => {
|
const checkForResume = useCallback(async (): Promise<boolean> => {
|
||||||
@@ -114,12 +115,13 @@ export const useResumeLogic = () => {
|
|||||||
}
|
}
|
||||||
}, [checkForResume, resumeFlow]);
|
}, [checkForResume, resumeFlow]);
|
||||||
|
|
||||||
// Auto-check for resume when the hook is first used
|
// Auto-check for resume when the hook is first used - PREVENT multiple attempts
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (progressTracking.isInitialized && !service.data?.isCheckingResume) {
|
if (progressTracking.isInitialized && !service.data?.isCheckingResume && !resumeAttempted.current) {
|
||||||
|
resumeAttempted.current = true;
|
||||||
handleAutoResume();
|
handleAutoResume();
|
||||||
}
|
}
|
||||||
}, [progressTracking.isInitialized, handleAutoResume, service.data?.isCheckingResume]);
|
}, [progressTracking.isInitialized, service.data?.isCheckingResume]); // Remove handleAutoResume from deps
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// State
|
// State
|
||||||
|
|||||||
@@ -1,112 +0,0 @@
|
|||||||
/**
|
|
||||||
* Shared types for onboarding hooks
|
|
||||||
*/
|
|
||||||
|
|
||||||
import type {
|
|
||||||
BakeryRegistration,
|
|
||||||
ProductSuggestionResponse,
|
|
||||||
BusinessModelAnalysisResponse,
|
|
||||||
User
|
|
||||||
} from '../../../api';
|
|
||||||
|
|
||||||
// Re-export for convenience
|
|
||||||
export type { ProductSuggestionResponse, BusinessModelAnalysisResponse };
|
|
||||||
|
|
||||||
export interface OnboardingStep {
|
|
||||||
id: string;
|
|
||||||
title: string;
|
|
||||||
description: string;
|
|
||||||
isRequired: boolean;
|
|
||||||
isCompleted: boolean;
|
|
||||||
validation?: (data: OnboardingData) => string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface OnboardingData {
|
|
||||||
// Step 1: Setup
|
|
||||||
bakery?: BakeryRegistration;
|
|
||||||
|
|
||||||
// Step 2: Data Processing
|
|
||||||
files?: {
|
|
||||||
salesData?: File;
|
|
||||||
};
|
|
||||||
processingStage?: 'upload' | 'validating' | 'analyzing' | 'review' | 'completed' | 'error';
|
|
||||||
processingResults?: {
|
|
||||||
is_valid: boolean;
|
|
||||||
total_records: number;
|
|
||||||
unique_products: number;
|
|
||||||
product_list: string[];
|
|
||||||
validation_errors: string[];
|
|
||||||
validation_warnings: string[];
|
|
||||||
summary: {
|
|
||||||
date_range: string;
|
|
||||||
total_sales: number;
|
|
||||||
average_daily_sales: number;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Step 3: Sales Validation (merged data processing + review)
|
|
||||||
suggestions?: ProductSuggestionResponse[];
|
|
||||||
detectedProducts?: any[]; // Products detected from AI analysis
|
|
||||||
approvedSuggestions?: ProductSuggestionResponse[];
|
|
||||||
approvedProducts?: ProductSuggestionResponse[];
|
|
||||||
reviewCompleted?: boolean;
|
|
||||||
|
|
||||||
// Step 4: Inventory
|
|
||||||
inventoryItems?: any[];
|
|
||||||
inventoryMapping?: { [productName: string]: string };
|
|
||||||
inventoryConfigured?: boolean;
|
|
||||||
salesImportResult?: {
|
|
||||||
success: boolean;
|
|
||||||
imported: boolean;
|
|
||||||
records_created: number;
|
|
||||||
message: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Step 5: Suppliers
|
|
||||||
suppliers?: any[];
|
|
||||||
supplierMappings?: any[];
|
|
||||||
|
|
||||||
// Step 6: ML Training
|
|
||||||
trainingStatus?: 'idle' | 'validating' | 'training' | 'completed' | 'failed';
|
|
||||||
trainingProgress?: number;
|
|
||||||
trainingJob?: any;
|
|
||||||
trainingLogs?: any[];
|
|
||||||
trainingMetrics?: any;
|
|
||||||
autoStartTraining?: boolean;
|
|
||||||
|
|
||||||
// Step 7: Completion
|
|
||||||
completionStats?: {
|
|
||||||
totalProducts: number;
|
|
||||||
inventoryItems: number;
|
|
||||||
suppliersConfigured: number;
|
|
||||||
mlModelAccuracy: number;
|
|
||||||
estimatedTimeSaved: string;
|
|
||||||
completionScore: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Cross-step data sharing
|
|
||||||
allStepData?: { [stepId: string]: any };
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface OnboardingProgress {
|
|
||||||
currentStep: number;
|
|
||||||
totalSteps: number;
|
|
||||||
completedSteps: number;
|
|
||||||
isComplete: boolean;
|
|
||||||
progressPercentage: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface OnboardingError {
|
|
||||||
step?: string;
|
|
||||||
message: string;
|
|
||||||
details?: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Processing progress callback
|
|
||||||
export type ProgressCallback = (progress: number, stage: string, message: string) => void;
|
|
||||||
|
|
||||||
// Step validation function
|
|
||||||
export type StepValidator = (data: OnboardingData) => string | null;
|
|
||||||
|
|
||||||
// Step update callback
|
|
||||||
export type StepDataUpdater = (stepId: string, data: Partial<OnboardingData>) => void;
|
|
||||||
Reference in New Issue
Block a user