From dec0fc5da08646252377206004c024bacdbe60d0 Mon Sep 17 00:00:00 2001 From: Missez Date: Mon, 19 Jan 2026 13:06:26 +0700 Subject: [PATCH] feat: implement instructor courses listing page and data service --- .../pages/instructor/courses/index.vue | 284 ++++++++++++++++++ .../services/instructor.service.ts | 131 ++++++++ 2 files changed, 415 insertions(+) create mode 100644 frontend_management/pages/instructor/courses/index.vue create mode 100644 frontend_management/services/instructor.service.ts diff --git a/frontend_management/pages/instructor/courses/index.vue b/frontend_management/pages/instructor/courses/index.vue new file mode 100644 index 00000000..5b73b9eb --- /dev/null +++ b/frontend_management/pages/instructor/courses/index.vue @@ -0,0 +1,284 @@ + + + diff --git a/frontend_management/services/instructor.service.ts b/frontend_management/services/instructor.service.ts new file mode 100644 index 00000000..64e54188 --- /dev/null +++ b/frontend_management/services/instructor.service.ts @@ -0,0 +1,131 @@ +// Course Response structure +export interface CourseResponse { + id: number; + category_id: number; + title: { + en: string; + th: string; + }; + slug: string; + description: { + en: string; + th: string; + }; + thumbnail_url: string | null; + price: string; + is_free: boolean; + have_certificate: boolean; + status: 'DRAFT' | 'PENDING' | 'APPROVED' | 'REJECTED'; + approved_by: number | null; + approved_at: string | null; + rejection_reason: string | null; + created_at: string; + created_by: number; + updated_at: string; + updated_by: number | null; +} + +export interface CoursesListResponse { + code: number; + message: string; + data: CourseResponse[]; + total: number; +} + +// Helper function to get auth token from cookie +const getAuthToken = (): string => { + const tokenCookie = useCookie('token'); + return tokenCookie.value || ''; +}; + +// Mock courses data +const MOCK_COURSES: CourseResponse[] = [ + { + id: 1, + category_id: 1, + title: { en: 'JavaScript Fundamentals', th: 'พื้นฐาน JavaScript' }, + slug: 'javascript-fundamentals', + description: { + en: 'Learn JavaScript fundamentals from scratch', + th: 'เรียนรู้พื้นฐาน JavaScript ตั้งแต่เริ่มต้น' + }, + thumbnail_url: null, + price: '0', + is_free: true, + have_certificate: true, + status: 'APPROVED', + approved_by: 1, + approved_at: '2024-01-15T00:00:00Z', + rejection_reason: null, + created_at: '2024-01-15T00:00:00Z', + created_by: 2, + updated_at: '2024-01-15T00:00:00Z', + updated_by: null + }, + { + id: 2, + category_id: 2, + title: { en: 'React for Beginners', th: 'React สำหรับผู้เริ่มต้น' }, + slug: 'react-for-beginners', + description: { + en: 'Build modern web apps with React', + th: 'สร้างเว็บแอปพลิเคชันด้วย React' + }, + thumbnail_url: null, + price: '990', + is_free: false, + have_certificate: true, + status: 'PENDING', + approved_by: null, + approved_at: null, + rejection_reason: null, + created_at: '2024-02-01T00:00:00Z', + created_by: 2, + updated_at: '2024-02-01T00:00:00Z', + updated_by: null + }, + { + id: 3, + category_id: 1, + title: { en: 'TypeScript Masterclass', th: 'TypeScript ขั้นสูง' }, + slug: 'typescript-masterclass', + description: { + en: 'Master TypeScript for better JavaScript development', + th: 'เรียนรู้ TypeScript เพื่อพัฒนา JavaScript ได้ดียิ่งขึ้น' + }, + thumbnail_url: null, + price: '1290', + is_free: false, + have_certificate: true, + status: 'DRAFT', + approved_by: null, + approved_at: null, + rejection_reason: null, + created_at: '2024-02-15T00:00:00Z', + created_by: 2, + updated_at: '2024-02-15T00:00:00Z', + updated_by: null + } +]; + +export const instructorService = { + async getCourses(): Promise { + const config = useRuntimeConfig(); + const useMockData = config.public.useMockData as boolean; + + if (useMockData) { + await new Promise(resolve => setTimeout(resolve, 500)); + return MOCK_COURSES; + } + + const token = getAuthToken(); + const response = await $fetch('/api/instructors/courses', { + baseURL: config.public.apiBaseUrl as string, + headers: { + Authorization: `Bearer ${token}` + } + }); + + return response.data; + } +};