Start integrating the onboarding flow with backend 13
This commit is contained in:
@@ -55,7 +55,8 @@ src/hooks/business/onboarding/
|
||||
├── core/
|
||||
│ ├── store.ts # Zustand centralized store
|
||||
│ ├── actions.ts # Business logic orchestration
|
||||
│ └── types.ts # Complete type definitions
|
||||
│ ├── types.ts # Complete type definitions
|
||||
│ └── useAutoResume.ts # Auto-resume wrapper
|
||||
├── services/
|
||||
│ ├── useTenantCreation.ts # Tenant service
|
||||
│ ├── useSalesProcessing.ts # Sales processing service
|
||||
@@ -65,10 +66,9 @@ src/hooks/business/onboarding/
|
||||
│ └── useResumeLogic.ts # Resume service
|
||||
├── utils/
|
||||
│ └── createServiceHook.ts # Service factory
|
||||
├── config/
|
||||
│ └── steps.ts # Step definitions and validation
|
||||
├── useOnboarding.ts # Main unified hook
|
||||
├── useAutoResume.ts # Auto-resume wrapper
|
||||
├── steps.ts # Step definitions
|
||||
├── types.ts # Legacy type exports
|
||||
└── index.ts # Clean exports
|
||||
```
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Onboarding step definitions and validation logic
|
||||
*/
|
||||
|
||||
import type { OnboardingStep, OnboardingData } from './types';
|
||||
import type { OnboardingStep, OnboardingData } from '../core/types';
|
||||
|
||||
export const DEFAULT_STEPS: OnboardingStep[] = [
|
||||
{
|
||||
@@ -10,7 +10,7 @@ import { useSalesProcessing } from '../services/useSalesProcessing';
|
||||
import { useInventorySetup } from '../services/useInventorySetup';
|
||||
import { useTrainingOrchestration } from '../services/useTrainingOrchestration';
|
||||
import { useProgressTracking } from '../services/useProgressTracking';
|
||||
import { getStepById } from '../steps';
|
||||
import { getStepById } from '../config/steps';
|
||||
import type { ProductSuggestionResponse } from '../core/types';
|
||||
import type { BakeryRegistration } from '../../../../api';
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { create } from 'zustand';
|
||||
import { devtools } from 'zustand/middleware';
|
||||
import type { OnboardingData, OnboardingStep, OnboardingProgress } from './types';
|
||||
import { DEFAULT_STEPS } from '../steps';
|
||||
import { DEFAULT_STEPS } from '../config/steps';
|
||||
|
||||
interface OnboardingStore {
|
||||
// Flow state
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Auto-resume hook - Simple wrapper around resume logic service
|
||||
*/
|
||||
|
||||
import { useResumeLogic } from './services/useResumeLogic';
|
||||
import { useResumeLogic } from '../services/useResumeLogic';
|
||||
|
||||
export const useAutoResume = () => {
|
||||
const resumeLogic = useResumeLogic();
|
||||
@@ -7,7 +7,7 @@
|
||||
export type * from './core/types';
|
||||
|
||||
// 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)
|
||||
export { useOnboardingStore } from './core/store';
|
||||
@@ -23,7 +23,7 @@ export { useResumeLogic } from './services/useResumeLogic';
|
||||
|
||||
// Main hooks - PRIMARY INTERFACE for components
|
||||
export { useOnboarding } from './useOnboarding';
|
||||
export { useAutoResume } from './useAutoResume';
|
||||
export { useAutoResume } from './core/useAutoResume';
|
||||
|
||||
// Utility
|
||||
export { createServiceHook } from './utils/createServiceHook';
|
||||
@@ -2,7 +2,7 @@
|
||||
* Progress tracking service - Clean, standardized implementation
|
||||
*/
|
||||
|
||||
import { useCallback, useEffect } from 'react';
|
||||
import { useCallback, useEffect, useRef } from 'react';
|
||||
import { onboardingService } from '../../../../api/services/onboarding';
|
||||
import { createServiceHook } from '../utils/createServiceHook';
|
||||
import type { ProgressTrackingState } from '../core/types';
|
||||
@@ -20,6 +20,7 @@ const useProgressTrackingService = createServiceHook<ProgressTrackingState>({
|
||||
|
||||
export const useProgressTracking = () => {
|
||||
const service = useProgressTrackingService();
|
||||
const initializationAttempted = useRef(false);
|
||||
|
||||
// Load initial progress from backend
|
||||
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(() => {
|
||||
if (!service.data?.isInitialized) {
|
||||
if (!service.data?.isInitialized && !initializationAttempted.current && !service.isLoading) {
|
||||
initializationAttempted.current = true;
|
||||
loadProgress();
|
||||
}
|
||||
}, [loadProgress, service.data?.isInitialized]);
|
||||
}, [service.data?.isInitialized, service.isLoading]); // Remove loadProgress from deps
|
||||
|
||||
return {
|
||||
// State
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Resume logic service - Clean, standardized implementation
|
||||
*/
|
||||
|
||||
import { useCallback, useEffect } from 'react';
|
||||
import { useCallback, useEffect, useRef } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useOnboardingStore } from '../core/store';
|
||||
import { useProgressTracking } from './useProgressTracking';
|
||||
@@ -22,6 +22,7 @@ export const useResumeLogic = () => {
|
||||
const navigate = useNavigate();
|
||||
const progressTracking = useProgressTracking();
|
||||
const { setCurrentStep } = useOnboardingStore();
|
||||
const resumeAttempted = useRef(false);
|
||||
|
||||
// Check if user should resume onboarding
|
||||
const checkForResume = useCallback(async (): Promise<boolean> => {
|
||||
@@ -114,12 +115,13 @@ export const useResumeLogic = () => {
|
||||
}
|
||||
}, [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(() => {
|
||||
if (progressTracking.isInitialized && !service.data?.isCheckingResume) {
|
||||
if (progressTracking.isInitialized && !service.data?.isCheckingResume && !resumeAttempted.current) {
|
||||
resumeAttempted.current = true;
|
||||
handleAutoResume();
|
||||
}
|
||||
}, [progressTracking.isInitialized, handleAutoResume, service.data?.isCheckingResume]);
|
||||
}, [progressTracking.isInitialized, service.data?.isCheckingResume]); // Remove handleAutoResume from deps
|
||||
|
||||
return {
|
||||
// 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