245 lines
6.4 KiB
TypeScript
245 lines
6.4 KiB
TypeScript
import { api } from '../axios';
|
|
import {
|
|
Track,
|
|
Exercise,
|
|
ExerciseResult,
|
|
Progress,
|
|
SkillMapData,
|
|
TrackProgress,
|
|
StartExerciseRequest,
|
|
StartExerciseResponse,
|
|
SubmitExerciseRequest,
|
|
SubmitExerciseResponse,
|
|
UseHintRequest,
|
|
UseHintResponse,
|
|
TrackSearchParams,
|
|
PaginatedResponse,
|
|
PaginationParams,
|
|
} from '../types';
|
|
|
|
export const trainingApi = {
|
|
// Get all tracks
|
|
getTracks: (
|
|
params?: TrackSearchParams & PaginationParams
|
|
): Promise<PaginatedResponse<Track>> => {
|
|
return api.get<PaginatedResponse<Track>>('/training/tracks', { params });
|
|
},
|
|
|
|
// Get track by ID
|
|
getTrack: (trackId: string): Promise<Track> => {
|
|
return api.get<Track>(`/training/tracks/${trackId}`);
|
|
},
|
|
|
|
// Get track by slug
|
|
getTrackBySlug: (slug: string): Promise<Track> => {
|
|
return api.get<Track>(`/training/tracks/slug/${slug}`);
|
|
},
|
|
|
|
// Enroll in track
|
|
enrollInTrack: (trackId: string): Promise<TrackProgress> => {
|
|
return api.post<TrackProgress>(`/training/tracks/${trackId}/enroll`);
|
|
},
|
|
|
|
// Unenroll from track
|
|
unenrollFromTrack: (trackId: string): Promise<void> => {
|
|
return api.delete<void>(`/training/tracks/${trackId}/enroll`);
|
|
},
|
|
|
|
// Get track progress
|
|
getTrackProgress: (trackId: string): Promise<TrackProgress> => {
|
|
return api.get<TrackProgress>(`/training/tracks/${trackId}/progress`);
|
|
},
|
|
|
|
// Get exercise by ID
|
|
getExercise: (exerciseId: string): Promise<Exercise> => {
|
|
return api.get<Exercise>(`/training/exercises/${exerciseId}`);
|
|
},
|
|
|
|
// Get exercise by slug
|
|
getExerciseBySlug: (trackSlug: string, exerciseSlug: string): Promise<Exercise> => {
|
|
return api.get<Exercise>(
|
|
`/training/tracks/slug/${trackSlug}/exercises/slug/${exerciseSlug}`
|
|
);
|
|
},
|
|
|
|
// Start exercise
|
|
startExercise: (data: StartExerciseRequest): Promise<StartExerciseResponse> => {
|
|
return api.post<StartExerciseResponse>('/training/exercises/start', data);
|
|
},
|
|
|
|
// Submit exercise
|
|
submitExercise: (data: SubmitExerciseRequest): Promise<SubmitExerciseResponse> => {
|
|
return api.post<SubmitExerciseResponse>('/training/exercises/submit', data);
|
|
},
|
|
|
|
// Get exercise result
|
|
getExerciseResult: (exerciseId: string): Promise<ExerciseResult | null> => {
|
|
return api.get<ExerciseResult | null>(
|
|
`/training/exercises/${exerciseId}/result`
|
|
);
|
|
},
|
|
|
|
// Get available hints
|
|
getAvailableHints: (exerciseId: string): Promise<{
|
|
hints: Array<{
|
|
id: string;
|
|
order: number;
|
|
title: string;
|
|
isUnlocked: boolean;
|
|
costPercentage: number;
|
|
}>;
|
|
usedHints: number;
|
|
totalHints: number;
|
|
}> => {
|
|
return api.get(`/training/exercises/${exerciseId}/hints`);
|
|
},
|
|
|
|
// Use hint
|
|
useHint: (data: UseHintRequest): Promise<UseHintResponse> => {
|
|
return api.post<UseHintResponse>('/training/exercises/use-hint', data);
|
|
},
|
|
|
|
// Get overall progress
|
|
getProgress: (): Promise<Progress> => {
|
|
return api.get<Progress>('/training/progress');
|
|
},
|
|
|
|
// Get skill map
|
|
getSkillMap: (): Promise<SkillMapData> => {
|
|
return api.get<SkillMapData>('/training/skill-map');
|
|
},
|
|
|
|
// Get recommended tracks
|
|
getRecommendedTracks: (limit?: number): Promise<Track[]> => {
|
|
return api.get<Track[]>('/training/recommendations/tracks', {
|
|
params: { limit },
|
|
});
|
|
},
|
|
|
|
// Get recommended exercises
|
|
getRecommendedExercises: (limit?: number): Promise<Exercise[]> => {
|
|
return api.get<Exercise[]>('/training/recommendations/exercises', {
|
|
params: { limit },
|
|
});
|
|
},
|
|
|
|
// Get featured tracks
|
|
getFeaturedTracks: (): Promise<Track[]> => {
|
|
return api.get<Track[]>('/training/tracks/featured');
|
|
},
|
|
|
|
// Get popular tracks
|
|
getPopularTracks: (limit?: number): Promise<Track[]> => {
|
|
return api.get<Track[]>('/training/tracks/popular', {
|
|
params: { limit },
|
|
});
|
|
},
|
|
|
|
// Get enrolled tracks
|
|
getEnrolledTracks: (): Promise<TrackProgress[]> => {
|
|
return api.get<TrackProgress[]>('/training/my-tracks');
|
|
},
|
|
|
|
// Get completed tracks
|
|
getCompletedTracks: (): Promise<TrackProgress[]> => {
|
|
return api.get<TrackProgress[]>('/training/completed-tracks');
|
|
},
|
|
|
|
// Get exercise history (all attempts)
|
|
getExerciseHistory: (
|
|
exerciseId: string
|
|
): Promise<Array<{
|
|
attemptNumber: number;
|
|
submittedAt: string;
|
|
isCorrect: boolean;
|
|
score: number;
|
|
timeSpent: number;
|
|
}>> => {
|
|
return api.get(`/training/exercises/${exerciseId}/history`);
|
|
},
|
|
|
|
// Reset exercise progress
|
|
resetExerciseProgress: (exerciseId: string): Promise<void> => {
|
|
return api.post<void>(`/training/exercises/${exerciseId}/reset`);
|
|
},
|
|
|
|
// Get daily challenge
|
|
getDailyChallenge: (): Promise<Exercise | null> => {
|
|
return api.get<Exercise | null>('/training/daily-challenge');
|
|
},
|
|
|
|
// Get streak info
|
|
getStreakInfo: (): Promise<{
|
|
currentStreak: number;
|
|
longestStreak: number;
|
|
lastActivityDate: string;
|
|
streakFreezeAvailable: boolean;
|
|
}> => {
|
|
return api.get('/training/streak');
|
|
},
|
|
|
|
// Use streak freeze
|
|
useStreakFreeze: (): Promise<{ success: boolean; freezesRemaining: number }> => {
|
|
return api.post('/training/streak/freeze');
|
|
},
|
|
|
|
// Get certificates
|
|
getCertificates: (): Promise<Array<{
|
|
id: string;
|
|
trackId: string;
|
|
trackName: string;
|
|
issuedAt: string;
|
|
certificateUrl: string;
|
|
verificationCode: string;
|
|
}>> => {
|
|
return api.get('/training/certificates');
|
|
},
|
|
|
|
// Generate certificate for completed track
|
|
generateCertificate: (trackId: string): Promise<{
|
|
certificateUrl: string;
|
|
verificationCode: string;
|
|
}> => {
|
|
return api.post(`/training/tracks/${trackId}/certificate`);
|
|
},
|
|
|
|
// Get leaderboard for track
|
|
getTrackLeaderboard: (
|
|
trackId: string,
|
|
params?: PaginationParams
|
|
): Promise<PaginatedResponse<{
|
|
position: number;
|
|
userId: string;
|
|
username: string;
|
|
avatar: string | null;
|
|
score: number;
|
|
completionTime: number;
|
|
completedAt: string;
|
|
}>> => {
|
|
return api.get(`/training/tracks/${trackId}/leaderboard`, { params });
|
|
},
|
|
|
|
// Rate track
|
|
rateTrack: (
|
|
trackId: string,
|
|
rating: number,
|
|
feedback?: string
|
|
): Promise<{ averageRating: number }> => {
|
|
return api.post(`/training/tracks/${trackId}/rate`, { rating, feedback });
|
|
},
|
|
|
|
// Report issue with exercise
|
|
reportExerciseIssue: (
|
|
exerciseId: string,
|
|
type: 'bug' | 'unclear' | 'incorrect' | 'other',
|
|
description: string
|
|
): Promise<void> => {
|
|
return api.post<void>(`/training/exercises/${exerciseId}/report`, {
|
|
type,
|
|
description,
|
|
});
|
|
},
|
|
};
|
|
|
|
export default trainingApi;
|