Files
bakery-ia/frontend/src/api/services/onboarding.ts

145 lines
4.9 KiB
TypeScript
Raw Normal View History

/**
* 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<UserProgress> {
// Backend uses current user from auth token, so userId parameter is ignored
return apiClient.get<UserProgress>(`${this.baseUrl}/progress`);
}
async updateStep(userId: string, stepData: UpdateStepRequest): Promise<UserProgress> {
// Backend uses current user from auth token, so userId parameter is ignored
return apiClient.put<UserProgress>(`${this.baseUrl}/step`, stepData);
}
async markStepCompleted(
userId: string,
stepName: string,
data?: Record<string, any>
): Promise<UserProgress> {
// Backend uses current user from auth token, so userId parameter is ignored
// Backend expects UpdateStepRequest format for completion
return apiClient.put<UserProgress>(`${this.baseUrl}/step`, {
step_name: stepName,
completed: true,
data: data,
});
}
async resetProgress(userId: string): Promise<UserProgress> {
// 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<Array<{
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('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<string, any>
): Promise<UserProgress> {
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<string> {
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();