/** * Onboarding Service - Mirror backend onboarding endpoints * Frontend and backend step names now match directly! */ import { apiClient } from '../client'; import { UserProgress, UpdateStepRequest } from '../types/onboarding'; // Frontend step order for navigation (matches backend ONBOARDING_STEPS) export const FRONTEND_STEP_ORDER = [ 'setup', // Step 1: Basic bakery setup and tenant creation 'smart-inventory-setup', // Step 2: Sales data upload and inventory configuration 'suppliers', // Step 3: Suppliers configuration (optional) 'ml-training', // Step 4: AI model training 'completion' // Step 5: Onboarding completed ]; export class OnboardingService { private readonly baseUrl = '/users/me/onboarding'; async getUserProgress(userId: string): Promise { // Backend uses current user from auth token, so userId parameter is ignored return apiClient.get(`${this.baseUrl}/progress`); } async updateStep(userId: string, stepData: UpdateStepRequest): Promise { // Backend uses current user from auth token, so userId parameter is ignored return apiClient.put(`${this.baseUrl}/step`, stepData); } async markStepCompleted( userId: string, stepName: string, data?: Record ): Promise { // Backend uses current user from auth token, so userId parameter is ignored // Backend expects UpdateStepRequest format for completion const requestBody = { step_name: stepName, completed: true, data: data, }; console.log(`🔄 API call to mark step "${stepName}" as completed:`, requestBody); try { const response = await apiClient.put(`${this.baseUrl}/step`, requestBody); console.log(`✅ Step "${stepName}" marked as completed successfully:`, response); return response; } catch (error) { console.error(`❌ API error marking step "${stepName}" as completed:`, error); throw error; } } async resetProgress(userId: string): Promise { // Note: Backend doesn't have a reset endpoint, this might need to be implemented // For now, we'll throw an error throw new Error('Reset progress functionality not implemented in backend'); } async getStepDetails(stepName: string): Promise<{ name: string; description: string; dependencies: string[]; estimated_time_minutes: number; }> { // This endpoint doesn't exist in backend, we'll need to implement it or mock it throw new Error('getStepDetails functionality not implemented in backend'); } async getAllSteps(): Promise> { // This endpoint doesn't exist in backend, we'll need to implement it or mock it throw new Error('getAllSteps functionality not implemented in backend'); } async getNextStep(): Promise<{ step: string; completed?: boolean }> { // This endpoint exists in backend return apiClient.get(`${this.baseUrl}/next-step`); } async canAccessStep(stepName: string): Promise<{ can_access: boolean; reason?: string }> { // This endpoint exists in backend return apiClient.get(`${this.baseUrl}/can-access/${stepName}`); } async completeOnboarding(): Promise<{ success: boolean; message: string }> { // This endpoint exists in backend return apiClient.post(`${this.baseUrl}/complete`); } /** * Helper method to mark a step as completed (now direct mapping) */ async markStepAsCompleted( stepId: string, data?: Record ): Promise { try { return await this.markStepCompleted('', stepId, data); } catch (error) { console.error(`Error marking step ${stepId} as completed:`, error); throw error; } } /** * Helper method to get the next step based on backend progress */ async getNextStepId(): Promise { try { const result = await this.getNextStep(); return result.step || 'setup'; } catch (error) { console.error('Error getting next step:', error); return 'setup'; } } /** * Helper method to determine which step the user should resume from */ async getResumeStep(): Promise<{ stepId: string; stepIndex: number }> { try { const progress = await this.getUserProgress(''); // If fully completed, go to completion if (progress.fully_completed) { return { stepId: 'completion', stepIndex: FRONTEND_STEP_ORDER.indexOf('completion') }; } // Get the current step from backend const currentStep = progress.current_step; // If current step is user_registered, start from setup const resumeStep = currentStep === 'user_registered' ? 'setup' : currentStep; // Find the step index in our frontend order let stepIndex = FRONTEND_STEP_ORDER.indexOf(resumeStep); if (stepIndex === -1) { stepIndex = 0; // Default to first step } return { stepId: FRONTEND_STEP_ORDER[stepIndex], stepIndex }; } catch (error) { console.error('Error determining resume step:', error); return { stepId: 'setup', stepIndex: 0 }; } } } export const onboardingService = new OnboardingService();