feat: add instructor endpoints for student progress tracking and quiz score management
Add four new instructor endpoints: getEnrolledStudents to view all enrolled students with progress, getQuizScores to view quiz scores for all students in a lesson, getQuizAttemptDetail to view detailed quiz attempt for a specific student, and searchStudents to search enrolled students by name/email/username. Add getQuizAttempts endpoint for students to retrieve their own quiz attempt history. All endpoints include
This commit is contained in:
parent
a648c41b72
commit
80d7372dfa
6 changed files with 832 additions and 1 deletions
|
|
@ -198,3 +198,157 @@ export interface GetCourseApprovalsResponse {
|
|||
data: CourseApprovalData[];
|
||||
total: number;
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Enrolled Students (Instructor)
|
||||
// ============================================
|
||||
|
||||
export interface GetEnrolledStudentsInput {
|
||||
token: string;
|
||||
course_id: number;
|
||||
page?: number;
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export interface EnrolledStudentData {
|
||||
user_id: number;
|
||||
username: string;
|
||||
email: string;
|
||||
first_name: string | null;
|
||||
last_name: string | null;
|
||||
avatar_url: string | null;
|
||||
enrolled_at: Date;
|
||||
progress_percentage: number;
|
||||
status: string;
|
||||
}
|
||||
|
||||
export interface GetEnrolledStudentsResponse {
|
||||
code: number;
|
||||
message: string;
|
||||
data: EnrolledStudentData[];
|
||||
total: number;
|
||||
page: number;
|
||||
limit: number;
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Quiz Scores by Lesson (Instructor)
|
||||
// ============================================
|
||||
|
||||
export interface GetQuizScoresInput {
|
||||
token: string;
|
||||
course_id: number;
|
||||
lesson_id: number;
|
||||
page?: number;
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export interface StudentQuizScoreData {
|
||||
user_id: number;
|
||||
username: string;
|
||||
email: string;
|
||||
first_name: string | null;
|
||||
last_name: string | null;
|
||||
avatar_url: string | null;
|
||||
latest_attempt: {
|
||||
id: number;
|
||||
score: number;
|
||||
total_score: number;
|
||||
is_passed: boolean;
|
||||
attempt_number: number;
|
||||
completed_at: Date | null;
|
||||
} | null;
|
||||
best_score: number | null;
|
||||
total_attempts: number;
|
||||
is_passed: boolean;
|
||||
}
|
||||
|
||||
export interface GetQuizScoresResponse {
|
||||
code: number;
|
||||
message: string;
|
||||
data: {
|
||||
lesson_id: number;
|
||||
lesson_title: MultiLanguageText;
|
||||
quiz_id: number;
|
||||
quiz_title: MultiLanguageText;
|
||||
passing_score: number;
|
||||
total_score: number;
|
||||
students: StudentQuizScoreData[];
|
||||
};
|
||||
total: number;
|
||||
page: number;
|
||||
limit: number;
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Quiz Attempt Detail (Instructor)
|
||||
// ============================================
|
||||
|
||||
export interface GetQuizAttemptDetailInput {
|
||||
token: string;
|
||||
course_id: number;
|
||||
lesson_id: number;
|
||||
student_id: number;
|
||||
}
|
||||
|
||||
export interface QuizAttemptDetailData {
|
||||
attempt_id: number;
|
||||
quiz_id: number;
|
||||
student: {
|
||||
user_id: number;
|
||||
username: string;
|
||||
email: string;
|
||||
first_name: string | null;
|
||||
last_name: string | null;
|
||||
};
|
||||
score: number;
|
||||
total_score: number;
|
||||
total_questions: number;
|
||||
correct_answers: number;
|
||||
is_passed: boolean;
|
||||
passing_score: number;
|
||||
attempt_number: number;
|
||||
started_at: Date;
|
||||
completed_at: Date | null;
|
||||
answers_review: {
|
||||
question_id: number;
|
||||
question_text: MultiLanguageText;
|
||||
selected_choice_id: number | null;
|
||||
selected_choice_text: MultiLanguageText | null;
|
||||
correct_choice_id: number;
|
||||
correct_choice_text: MultiLanguageText;
|
||||
is_correct: boolean;
|
||||
score: number;
|
||||
question_score: number;
|
||||
}[];
|
||||
}
|
||||
|
||||
export interface GetQuizAttemptDetailResponse {
|
||||
code: number;
|
||||
message: string;
|
||||
data: QuizAttemptDetailData;
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Search Students in Course (Instructor)
|
||||
// ============================================
|
||||
|
||||
export interface SearchStudentsInput {
|
||||
token: string;
|
||||
course_id: number;
|
||||
query: string;
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export interface SearchStudentData {
|
||||
user_id: number;
|
||||
first_name: string | null;
|
||||
last_name: string | null;
|
||||
email: string;
|
||||
}
|
||||
|
||||
export interface SearchStudentsResponse {
|
||||
code: number;
|
||||
message: string;
|
||||
data: SearchStudentData[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -369,3 +369,41 @@ export interface SubmitQuizResponse {
|
|||
is_course_completed?: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Get Quiz Attempts (Student)
|
||||
// ============================================
|
||||
|
||||
export interface GetQuizAttemptsInput {
|
||||
token: string;
|
||||
course_id: number;
|
||||
lesson_id: number;
|
||||
}
|
||||
|
||||
export interface QuizAttemptData {
|
||||
id: number;
|
||||
quiz_id: number;
|
||||
score: number;
|
||||
total_score: number;
|
||||
total_questions: number;
|
||||
correct_answers: number;
|
||||
is_passed: boolean;
|
||||
attempt_number: number;
|
||||
started_at: Date;
|
||||
completed_at: Date | null;
|
||||
}
|
||||
|
||||
export interface GetQuizAttemptsResponse {
|
||||
code: number;
|
||||
message: string;
|
||||
data: {
|
||||
lesson_id: number;
|
||||
lesson_title: MultiLangText;
|
||||
quiz_id: number;
|
||||
quiz_title: MultiLangText;
|
||||
passing_score: number;
|
||||
attempts: QuizAttemptData[];
|
||||
best_score: number | null;
|
||||
latest_attempt: QuizAttemptData | null;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue