Start integrating the onboarding flow with backend 17

This commit is contained in:
Urtzi Alfaro
2025-09-08 16:02:20 +02:00
parent 54102f7f4b
commit 201817a1be
6 changed files with 353 additions and 103 deletions

View File

@@ -184,6 +184,25 @@ export const useOnboardingActions = () => {
return result.success;
}, [store, salesProcessing]);
const generateProductSuggestions = useCallback(async (productList: string[]): Promise<boolean> => {
console.log('🎬 Actions - generateProductSuggestions started for', productList.length, 'products');
store.setLoading(true);
const result = await salesProcessing.generateProductSuggestions(productList);
console.log('🎬 Actions - generateProductSuggestions result:', result);
store.setLoading(false);
if (!result.success) {
console.error('❌ Actions - Suggestions generation failed:', result.error);
store.setError(result.error || 'Error generating product suggestions');
} else {
console.log('✅ Actions - Product suggestions generated successfully');
}
return result.success;
}, [store, salesProcessing]);
const createInventoryFromSuggestions = useCallback(async (
suggestions: ProductSuggestionResponse[]
): Promise<boolean> => {
@@ -306,6 +325,7 @@ export const useOnboardingActions = () => {
// Step-specific actions
createTenant,
processSalesFile,
generateProductSuggestions, // New function for separated suggestion generation
createInventoryFromSuggestions,
importSalesData,
startTraining,

View File

@@ -73,7 +73,7 @@ export interface OnboardingData {
files?: {
salesData?: File;
};
processingStage?: 'upload' | 'validating' | 'analyzing' | 'review' | 'completed' | 'error';
processingStage?: 'upload' | 'validating' | 'validated' | 'analyzing' | 'review' | 'completed' | 'error';
processingResults?: {
is_valid: boolean;
total_records: number;
@@ -161,7 +161,7 @@ export interface TenantCreationState extends ServiceState<BakeryRegistration> {
}
export interface SalesProcessingState extends ServiceState<any> {
stage: 'idle' | 'validating' | 'analyzing' | 'completed' | 'error';
stage: 'idle' | 'validating' | 'validated' | 'analyzing' | 'completed' | 'error';
progress: number;
currentMessage: string;
validationResults: any | null;

View File

@@ -17,15 +17,15 @@ export const useSalesProcessing = () => {
// Simple, direct state management
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [suggestions, setSuggestions] = useState<ProductSuggestionResponse[] | null>(null);
const [stage, setStage] = useState<'idle' | 'validating' | 'analyzing' | 'completed' | 'error'>('idle');
const [suggestions, setSuggestions] = useState<ProductSuggestionResponse[]>([]);
const [stage, setStage] = useState<'idle' | 'validating' | 'validated' | 'analyzing' | 'completed' | 'error'>('idle');
const [progress, setProgress] = useState(0);
const [currentMessage, setCurrentMessage] = useState('');
const [validationResults, setValidationResults] = useState<any | null>(null);
const updateProgress = useCallback((
progressValue: number,
stageValue: 'idle' | 'validating' | 'analyzing' | 'completed' | 'error',
stageValue: 'idle' | 'validating' | 'validated' | 'analyzing' | 'completed' | 'error',
message: string,
onProgress?: ProgressCallback
) => {
@@ -158,18 +158,68 @@ export const useSalesProcessing = () => {
throw new Error('No se encontraron productos válidos en el archivo');
}
// Stage 2: Generate AI suggestions
updateProgress(60, 'analyzing', 'Identificando productos únicos...', onProgress);
updateProgress(70, 'analyzing', 'Generando sugerencias de IA...', onProgress);
// Stage 2: File validation completed - WAIT FOR USER CONFIRMATION
updateProgress(100, 'validated', 'Archivo validado correctamente. Esperando confirmación del usuario...', onProgress);
// Store validation results and wait for user action
setValidationResults(validationResult);
console.log('✅ File validation completed:', validationResult.product_list?.length, 'products found');
// Update onboarding store - ONLY with validation results
setStepData('smart-inventory-setup', {
files: { salesData: file },
processingStage: 'validated', // Changed from 'completed'
processingResults: validationResult,
// DON'T set suggestions here - they will be generated later
});
console.log('📊 Updated onboarding store with suggestions');
return {
success: true,
validationResults: validationResult,
// No suggestions returned from processFile - they will be generated separately
};
} catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Error procesando el archivo';
setError(errorMessage);
updateProgress(0, 'error', errorMessage, onProgress);
return {
success: false,
};
} finally {
setIsLoading(false);
}
}, [updateProgress, currentTenant, validateFile, extractProductList, setStepData]);
const generateProductSuggestions = useCallback(async (
productList: string[],
onProgress?: ProgressCallback
): Promise<{
success: boolean;
suggestions?: ProductSuggestionResponse[];
error?: string;
}> => {
console.log('🚀 Generating product suggestions for', productList.length, 'products');
setIsLoading(true);
setError(null);
try {
updateProgress(10, 'analyzing', 'Iniciando análisis de productos...', onProgress);
updateProgress(30, 'analyzing', 'Identificando productos únicos...', onProgress);
updateProgress(50, 'analyzing', 'Generando sugerencias de IA...', onProgress);
let suggestions: ProductSuggestionResponse[] = [];
let suggestionError: string | null = null;
try {
updateProgress(70, 'analyzing', 'Generando sugerencias de IA...', onProgress);
suggestions = await generateSuggestions(validationResult.product_list);
updateProgress(70, 'analyzing', 'Consultando servicios de IA...', onProgress);
suggestions = await generateSuggestions(productList);
console.log('🔍 After generateSuggestions call:', {
console.log('🔍 Generated suggestions:', {
suggestionsReceived: suggestions?.length || 0,
});
} catch (error) {
@@ -177,11 +227,10 @@ export const useSalesProcessing = () => {
suggestionError = errorMessage;
console.error('❌ Suggestions generation failed:', errorMessage);
// Still continue with empty suggestions - user can manually add products later
// Create basic suggestions from product names as fallback
updateProgress(80, 'analyzing', 'Preparando productos básicos...', onProgress);
// Create basic suggestions from product names as fallback
suggestions = validationResult.product_list.map((productName, index) => ({
suggestions = productList.map((productName, index) => ({
suggestion_id: `manual-${index}`,
original_name: productName,
suggested_name: productName,
@@ -200,42 +249,40 @@ export const useSalesProcessing = () => {
}
updateProgress(90, 'analyzing', 'Analizando patrones de venta...', onProgress);
updateProgress(100, 'completed', 'Procesamiento completado exitosamente', onProgress);
updateProgress(100, 'completed', 'Sugerencias generadas correctamente', onProgress);
// Update state with suggestions (even if empty or fallback)
// Update state with suggestions
setSuggestions(suggestions || []);
setValidationResults(validationResult);
console.log('✅ Processing completed:', suggestions?.length || 0, 'suggestions generated');
console.log('✅ Suggestions generation completed:', suggestions?.length || 0, 'suggestions');
// Update onboarding store
setStepData('smart-inventory-setup', {
files: { salesData: file },
// Update onboarding store with suggestions
setStepData('smart-inventory-setup', (prevData) => ({
...prevData,
processingStage: 'completed',
processingResults: validationResult,
suggestions: suggestions || [],
suggestionError: suggestionError,
});
console.log('📊 Updated onboarding store with suggestions');
}));
return {
success: true,
validationResults: validationResult,
suggestions: suggestions || [],
error: suggestionError || undefined,
};
} catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Error procesando el archivo';
const errorMessage = error instanceof Error ? error.message : 'Error generando sugerencias';
setError(errorMessage);
updateProgress(0, 'error', errorMessage, onProgress);
return {
success: false,
error: errorMessage,
};
} finally {
setIsLoading(false);
}
}, [updateProgress, currentTenant, validateFile, extractProductList, generateSuggestions, setStepData]);
}, [updateProgress, generateSuggestions, setStepData]);
const clearError = useCallback(() => {
setError(null);
@@ -244,7 +291,7 @@ export const useSalesProcessing = () => {
const reset = useCallback(() => {
setIsLoading(false);
setError(null);
setSuggestions(null);
setSuggestions([]);
setStage('idle');
setProgress(0);
setCurrentMessage('');
@@ -263,7 +310,7 @@ export const useSalesProcessing = () => {
// Actions
processFile,
generateSuggestions,
generateProductSuggestions, // New separated function
clearError,
reset,
};

View File

@@ -67,7 +67,7 @@ export const useOnboarding = () => {
progress: salesProcessing.progress,
currentMessage: salesProcessing.currentMessage,
validationResults: salesProcessing.validationResults,
suggestions: salesProcessing.suggestions,
suggestions: Array.isArray(salesProcessing.suggestions) ? salesProcessing.suggestions : [],
},
inventorySetup: {
@@ -123,6 +123,7 @@ export const useOnboarding = () => {
// Step-specific actions
createTenant: actions.createTenant,
processSalesFile: actions.processSalesFile,
generateProductSuggestions: actions.generateProductSuggestions, // New separated function
createInventoryFromSuggestions: actions.createInventoryFromSuggestions,
importSalesData: actions.importSalesData,
startTraining: actions.startTraining,