feat: student page and create email verification page.
This commit is contained in:
parent
52d86400b3
commit
e8a10e5024
6 changed files with 894 additions and 8 deletions
|
|
@ -80,6 +80,88 @@ export interface SearchInstructorsResponse {
|
|||
data: SearchInstructorResult[];
|
||||
}
|
||||
|
||||
export interface EnrolledStudentResponse {
|
||||
user_id: number;
|
||||
username: string;
|
||||
email: string;
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
avatar_url: string | null;
|
||||
enrolled_at: string;
|
||||
progress_percentage: number;
|
||||
status: 'ENROLLED' | 'COMPLETED' | 'DROPPED';
|
||||
}
|
||||
|
||||
export interface EnrolledStudentsListResponse {
|
||||
code: number;
|
||||
message: string;
|
||||
data: EnrolledStudentResponse[];
|
||||
total: number;
|
||||
page: number;
|
||||
limit: number;
|
||||
}
|
||||
|
||||
export interface StudentSearchResult {
|
||||
user_id: number;
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
export interface StudentSearchResponse {
|
||||
code: number;
|
||||
message: string;
|
||||
data: StudentSearchResult[];
|
||||
}
|
||||
|
||||
// Student Detail with Progress interfaces
|
||||
export interface StudentDetailLesson {
|
||||
lesson_id: number;
|
||||
lesson_title: { th: string; en: string };
|
||||
lesson_type: string;
|
||||
sort_order: number;
|
||||
is_completed: boolean;
|
||||
completed_at: string | null;
|
||||
video_progress_seconds: number;
|
||||
video_duration_seconds: number;
|
||||
video_progress_percentage: number;
|
||||
last_watched_at: string | null;
|
||||
}
|
||||
|
||||
export interface StudentDetailChapter {
|
||||
chapter_id: number;
|
||||
chapter_title: { th: string; en: string };
|
||||
sort_order: number;
|
||||
lessons: StudentDetailLesson[];
|
||||
completed_lessons: number;
|
||||
total_lessons: number;
|
||||
}
|
||||
|
||||
export interface StudentDetailData {
|
||||
student: {
|
||||
user_id: number;
|
||||
username: string;
|
||||
email: string;
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
avatar_url: string | null;
|
||||
};
|
||||
enrollment: {
|
||||
status: string;
|
||||
progress_percentage: number;
|
||||
enrolled_at: string;
|
||||
};
|
||||
chapters: StudentDetailChapter[];
|
||||
total_completed_lessons: number;
|
||||
total_lessons: number;
|
||||
}
|
||||
|
||||
export interface StudentDetailResponse {
|
||||
code: number;
|
||||
message: string;
|
||||
data: StudentDetailData;
|
||||
}
|
||||
|
||||
// Helper function to get auth token from cookie
|
||||
const getAuthToken = (): string => {
|
||||
const tokenCookie = useCookie('token');
|
||||
|
|
@ -212,6 +294,37 @@ export const instructorService = {
|
|||
return await authRequest<ApiResponse<void>>(`/api/instructors/courses/send-review/${courseId}`, { method: 'POST' });
|
||||
},
|
||||
|
||||
async getEnrolledStudents(
|
||||
courseId: number,
|
||||
page: number = 1,
|
||||
limit: number = 10,
|
||||
search?: string,
|
||||
status?: string
|
||||
): Promise<EnrolledStudentsListResponse> {
|
||||
let url = `/api/instructors/courses/${courseId}/students?page=${page}&limit=${limit}`;
|
||||
if (search) {
|
||||
url += `&search=${encodeURIComponent(search)}`;
|
||||
}
|
||||
if (status && status !== 'all') {
|
||||
url += `&status=${status}`;
|
||||
}
|
||||
return await authRequest<EnrolledStudentsListResponse>(url);
|
||||
},
|
||||
|
||||
async searchStudentsInCourse(courseId: number, query: string, limit: number = 5): Promise<StudentSearchResult[]> {
|
||||
const response = await authRequest<StudentSearchResponse>(
|
||||
`/api/instructors/courses/${courseId}/students/search?query=${encodeURIComponent(query)}&limit=${limit}`
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
async getStudentDetail(courseId: number, studentId: number): Promise<StudentDetailData> {
|
||||
const response = await authRequest<StudentDetailResponse>(
|
||||
`/api/instructors/courses/${courseId}/students/${studentId}`
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
async getChapters(courseId: number): Promise<ChapterResponse[]> {
|
||||
// Get chapters from course detail endpoint
|
||||
const response = await authRequest<{ code: number; data: { chapters: ChapterResponse[] } }>(
|
||||
|
|
@ -515,6 +628,7 @@ export interface QuizResponse {
|
|||
shuffle_questions: boolean;
|
||||
shuffle_choices: boolean;
|
||||
show_answers_after_completion: boolean;
|
||||
is_skippable: boolean;
|
||||
created_at?: string;
|
||||
updated_at?: string;
|
||||
questions?: QuizQuestionResponse[];
|
||||
|
|
@ -528,6 +642,7 @@ export interface UpdateQuizSettingsRequest {
|
|||
shuffle_questions: boolean;
|
||||
shuffle_choices: boolean;
|
||||
show_answers_after_completion: boolean;
|
||||
is_skippable: boolean;
|
||||
}
|
||||
|
||||
export interface CreateChapterRequest {
|
||||
|
|
@ -562,6 +677,7 @@ export interface CreateLessonRequest {
|
|||
export interface UpdateLessonRequest {
|
||||
title: { th: string; en: string };
|
||||
content?: { th: string; en: string } | null;
|
||||
prerequisite_lesson_ids?: number[] | null;
|
||||
}
|
||||
|
||||
export interface AttachmentResponse {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue