Start integrating the onboarding flow with backend 12
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
/**
|
||||
* Progress tracking service - Clean, standardized implementation
|
||||
*/
|
||||
|
||||
import { useCallback, useEffect } from 'react';
|
||||
import { onboardingService } from '../../../../api/services/onboarding';
|
||||
import { createServiceHook } from '../utils/createServiceHook';
|
||||
import type { ProgressTrackingState } from '../core/types';
|
||||
import type { UserProgress } from '../../../../api/types/onboarding';
|
||||
|
||||
const useProgressTrackingService = createServiceHook<ProgressTrackingState>({
|
||||
initialState: {
|
||||
progress: null,
|
||||
isInitialized: false,
|
||||
isCompleted: false,
|
||||
completionPercentage: 0,
|
||||
currentBackendStep: null,
|
||||
},
|
||||
});
|
||||
|
||||
export const useProgressTracking = () => {
|
||||
const service = useProgressTrackingService();
|
||||
|
||||
// Load initial progress from backend
|
||||
const loadProgress = useCallback(async (): Promise<UserProgress | null> => {
|
||||
const result = await service.executeAsync(async () => {
|
||||
const progress = await onboardingService.getUserProgress('');
|
||||
|
||||
// Update service state with additional computed values
|
||||
const updatedData = {
|
||||
...service.data!,
|
||||
progress,
|
||||
isInitialized: true,
|
||||
isCompleted: progress?.fully_completed || false,
|
||||
completionPercentage: progress?.completion_percentage || 0,
|
||||
currentBackendStep: progress?.current_step || null,
|
||||
};
|
||||
|
||||
service.setSuccess(updatedData);
|
||||
|
||||
return progress;
|
||||
});
|
||||
|
||||
return result.data || null;
|
||||
}, [service]);
|
||||
|
||||
// Mark a step as completed and save to backend
|
||||
const markStepCompleted = useCallback(async (
|
||||
stepId: string,
|
||||
data?: Record<string, any>
|
||||
): Promise<boolean> => {
|
||||
const result = await service.executeAsync(async () => {
|
||||
const updatedProgress = await onboardingService.markStepAsCompleted(stepId, data);
|
||||
|
||||
// Update service state
|
||||
service.setSuccess({
|
||||
...service.data!,
|
||||
progress: updatedProgress,
|
||||
isCompleted: updatedProgress?.fully_completed || false,
|
||||
completionPercentage: updatedProgress?.completion_percentage || 0,
|
||||
currentBackendStep: updatedProgress?.current_step || null,
|
||||
});
|
||||
|
||||
console.log(`✅ Step "${stepId}" marked as completed in backend`);
|
||||
return updatedProgress;
|
||||
});
|
||||
|
||||
if (!result.success) {
|
||||
console.error(`❌ Error marking step "${stepId}" as completed:`, result.error);
|
||||
}
|
||||
|
||||
return result.success;
|
||||
}, [service]);
|
||||
|
||||
// Get the next step the user should work on
|
||||
const getNextStep = useCallback(async (): Promise<string> => {
|
||||
try {
|
||||
return await onboardingService.getNextStepId();
|
||||
} catch (error) {
|
||||
console.error('Error getting next step:', error);
|
||||
return 'setup';
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Get the step and index where user should resume
|
||||
const getResumePoint = useCallback(async (): Promise<{ stepId: string; stepIndex: number }> => {
|
||||
try {
|
||||
return await onboardingService.getResumeStep();
|
||||
} catch (error) {
|
||||
console.error('Error getting resume point:', error);
|
||||
return { stepId: 'setup', stepIndex: 0 };
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Complete the entire onboarding process
|
||||
const completeOnboarding = useCallback(async (): Promise<boolean> => {
|
||||
const result = await service.executeAsync(async () => {
|
||||
const result = await onboardingService.completeOnboarding();
|
||||
|
||||
if (result.success) {
|
||||
// Reload progress to get updated status
|
||||
await loadProgress();
|
||||
console.log('🎉 Onboarding completed successfully!');
|
||||
return result;
|
||||
}
|
||||
|
||||
throw new Error('Failed to complete onboarding');
|
||||
});
|
||||
|
||||
return result.success;
|
||||
}, [service, loadProgress]);
|
||||
|
||||
// Check if user can access a specific step
|
||||
const canAccessStep = useCallback(async (stepId: string): Promise<boolean> => {
|
||||
try {
|
||||
const result = await onboardingService.canAccessStep(stepId);
|
||||
return result.can_access;
|
||||
} catch (error) {
|
||||
console.error(`Error checking access for step "${stepId}":`, error);
|
||||
return true; // Allow access on error
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Auto-load progress on hook initialization
|
||||
useEffect(() => {
|
||||
if (!service.data?.isInitialized) {
|
||||
loadProgress();
|
||||
}
|
||||
}, [loadProgress, service.data?.isInitialized]);
|
||||
|
||||
return {
|
||||
// State
|
||||
isLoading: service.isLoading,
|
||||
error: service.error,
|
||||
progress: service.data?.progress || null,
|
||||
isInitialized: service.data?.isInitialized || false,
|
||||
isCompleted: service.data?.isCompleted || false,
|
||||
completionPercentage: service.data?.completionPercentage || 0,
|
||||
currentBackendStep: service.data?.currentBackendStep || null,
|
||||
|
||||
// Actions
|
||||
loadProgress,
|
||||
markStepCompleted,
|
||||
getNextStep,
|
||||
getResumePoint,
|
||||
completeOnboarding,
|
||||
canAccessStep,
|
||||
clearError: service.clearError,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user