Start integrating the onboarding flow with backend 12

This commit is contained in:
Urtzi Alfaro
2025-09-07 17:25:30 +02:00
parent 9005286ada
commit b73f3b4993
32 changed files with 3172 additions and 3087 deletions

View File

@@ -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,
};
};