feat: implement my courses page with course fetching, filtering, and enrollment/certificate modals.

This commit is contained in:
supalerk-ar66 2026-01-20 15:13:02 +07:00
parent 122bb2332f
commit 36593bc4f1
2 changed files with 121 additions and 36 deletions

View file

@ -33,6 +33,27 @@ interface CourseResponse {
total: number
}
export interface EnrolledCourse {
id: number // enrollment_id
course_id: number
course: Course
status: 'ENROLLED' | 'IN_PROGRESS' | 'COMPLETED' | 'DROPPED'
progress_percentage: number
enrolled_at: string
started_at?: string
completed_at?: string
last_accessed_at?: string
}
interface EnrolledCourseResponse {
code: number
message: string
data: EnrolledCourse[]
total: number
page: number
limit: number
}
export const useCourse = () => {
const config = useRuntimeConfig()
const API_BASE_URL = config.public.apiBase as string
@ -112,10 +133,41 @@ export const useCourse = () => {
}
}
const fetchEnrolledCourses = async (params: { page?: number; limit?: number; status?: string } = {}) => {
try {
const queryParams = new URLSearchParams()
if (params.page) queryParams.append('page', params.page.toString())
if (params.limit) queryParams.append('limit', params.limit.toString())
if (params.status && params.status !== 'ALL') queryParams.append('status', params.status)
const data = await $fetch<EnrolledCourseResponse>(`${API_BASE_URL}/students/courses?${queryParams.toString()}`, {
method: 'GET',
headers: token.value ? {
Authorization: `Bearer ${token.value}`
} : {}
})
return {
success: true,
data: data.data || [],
total: data.total || 0,
page: data.page,
limit: data.limit
}
} catch (err: any) {
console.error('Fetch enrolled courses failed:', err)
return {
success: false,
error: err.data?.message || err.message || 'Error fetching enrolled courses'
}
}
}
return {
fetchCourses,
fetchCourseById,
enrollCourse
enrollCourse,
fetchEnrolledCourses
}
}