// 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; }, async createCourse(data: CreateCourseRequest): Promise { const config = useRuntimeConfig(); const useMockData = config.public.useMockData as boolean; if (useMockData) { await new Promise(resolve => setTimeout(resolve, 500)); return { ...MOCK_COURSES[0], id: Date.now(), ...data, price: String(data.price), // Convert number to string to match CourseResponse type status: 'DRAFT', created_at: new Date().toISOString(), updated_at: new Date().toISOString() } as CourseResponse; } const token = getAuthToken(); // Clean data - remove empty thumbnail_url const cleanedData = { ...data }; if (!cleanedData.thumbnail_url) { delete cleanedData.thumbnail_url; } console.log('=== CREATE COURSE DEBUG ==='); console.log('Body:', JSON.stringify({ data: cleanedData }, null, 2)); console.log('==========================='); const response = await $fetch<{ code: number; data: CourseResponse }>('/api/instructors/courses', { method: 'POST', baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` }, body: { data: cleanedData } }); return response.data; }, async getCourseById(courseId: number): Promise { const config = useRuntimeConfig(); const useMockData = config.public.useMockData as boolean; if (useMockData) { await new Promise(resolve => setTimeout(resolve, 500)); return MOCK_COURSE_DETAIL; } const token = getAuthToken(); const response = await $fetch<{ code: number; data: CourseDetailResponse }>(`/api/instructors/courses/${courseId}`, { baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` } }); return response.data; }, async updateCourse(courseId: number, data: CreateCourseRequest): Promise { const config = useRuntimeConfig(); const useMockData = config.public.useMockData as boolean; if (useMockData) { await new Promise(resolve => setTimeout(resolve, 500)); return { ...MOCK_COURSES[0], id: courseId, ...data, price: String(data.price) } as CourseResponse; } const token = getAuthToken(); // Debug log console.log('=== UPDATE COURSE DEBUG ==='); console.log('URL:', `${config.public.apiBaseUrl}/api/instructors/courses/${courseId}`); console.log('Body:', JSON.stringify({ data }, null, 2)); console.log('==========================='); const response = await $fetch<{ code: number; data: CourseResponse }>(`/api/instructors/courses/${courseId}`, { method: 'PUT', baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` }, body: { data } }); return response.data; }, async deleteCourse(courseId: number): Promise { const config = useRuntimeConfig(); const useMockData = config.public.useMockData as boolean; if (useMockData) { await new Promise(resolve => setTimeout(resolve, 500)); return; } const token = getAuthToken(); await $fetch(`/api/instructors/courses/${courseId}`, { method: 'DELETE', baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` } }); }, async sendForReview(courseId: number): Promise { const config = useRuntimeConfig(); const useMockData = config.public.useMockData as boolean; if (useMockData) { await new Promise(resolve => setTimeout(resolve, 500)); return; } const token = getAuthToken(); await $fetch(`/api/instructors/courses/send-review/${courseId}`, { method: 'POST', baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` } }); } }; // Create course request export interface CreateCourseRequest { category_id: number; title: { en: string; th: string; }; slug: string; description: { en: string; th: string; }; thumbnail_url?: string | null; price: number; is_free: boolean; have_certificate: boolean; } // Course detail with chapters and lessons export interface CourseDetailResponse extends CourseResponse { chapters: ChapterResponse[]; } export interface ChapterResponse { id: number; course_id: number; title: { en: string; th: string }; description: { en: string; th: string }; sort_order: number; is_published: boolean; created_at: string; updated_at: string; lessons: LessonResponse[]; } export interface LessonResponse { id: number; chapter_id: number; title: { en: string; th: string }; content: { en: string; th: string } | null; type: 'VIDEO' | 'QUIZ' | 'DOCUMENT'; duration_minutes: number; sort_order: number; is_sequential: boolean; prerequisite_lesson_ids: number[] | null; require_pass_quiz: boolean; is_published: boolean; created_at: string; updated_at: string; quiz: QuizResponse | null; } export interface QuizResponse { id: number; lesson_id: number; title: { en: string; th: string }; description: { en: string; th: string }; passing_score: number; time_limit: number; shuffle_questions: boolean; shuffle_choices: boolean; show_answers_after_completion: boolean; } // Mock course detail const MOCK_COURSE_DETAIL: CourseDetailResponse = { ...MOCK_COURSES[0], chapters: [ { id: 1, course_id: 1, title: { en: 'Chapter 1: Getting Started', th: 'บทที่ 1: เริ่มต้น' }, description: { en: 'Introduction to JavaScript', th: 'แนะนำ JavaScript' }, sort_order: 1, is_published: true, created_at: '2024-01-15T00:00:00Z', updated_at: '2024-01-15T00:00:00Z', lessons: [ { id: 1, chapter_id: 1, title: { en: 'What is JavaScript', th: 'JavaScript คืออะไร' }, content: { en: 'Introduction', th: 'แนะนำ' }, type: 'VIDEO', duration_minutes: 15, sort_order: 1, is_sequential: true, prerequisite_lesson_ids: null, require_pass_quiz: false, is_published: true, created_at: '2024-01-15T00:00:00Z', updated_at: '2024-01-15T00:00:00Z', quiz: null }, { id: 2, chapter_id: 1, title: { en: 'Variables', th: 'ตัวแปร' }, content: { en: 'Learn variables', th: 'เรียนรู้ตัวแปร' }, type: 'VIDEO', duration_minutes: 20, sort_order: 2, is_sequential: true, prerequisite_lesson_ids: null, require_pass_quiz: false, is_published: true, created_at: '2024-01-15T00:00:00Z', updated_at: '2024-01-15T00:00:00Z', quiz: null }, { id: 3, chapter_id: 1, title: { en: 'Chapter 1 Quiz', th: 'แบบทดสอบบทที่ 1' }, content: null, type: 'QUIZ', duration_minutes: 10, sort_order: 3, is_sequential: true, prerequisite_lesson_ids: null, require_pass_quiz: true, is_published: true, created_at: '2024-01-15T00:00:00Z', updated_at: '2024-01-15T00:00:00Z', quiz: { id: 1, lesson_id: 3, title: { en: 'Chapter 1 Quiz', th: 'แบบทดสอบบทที่ 1' }, description: { en: 'Test your knowledge', th: 'ทดสอบความรู้' }, passing_score: 70, time_limit: 10, shuffle_questions: true, shuffle_choices: true, show_answers_after_completion: true } } ] }, { id: 2, course_id: 1, title: { en: 'Chapter 2: Functions', th: 'บทที่ 2: ฟังก์ชัน' }, description: { en: 'Learn about functions', th: 'เรียนรู้เกี่ยวกับฟังก์ชัน' }, sort_order: 2, is_published: true, created_at: '2024-01-15T00:00:00Z', updated_at: '2024-01-15T00:00:00Z', lessons: [ { id: 4, chapter_id: 2, title: { en: 'Creating Functions', th: 'การสร้างฟังก์ชัน' }, content: { en: 'How to create functions', th: 'วิธีสร้างฟังก์ชัน' }, type: 'VIDEO', duration_minutes: 25, sort_order: 1, is_sequential: true, prerequisite_lesson_ids: null, require_pass_quiz: false, is_published: true, created_at: '2024-01-15T00:00:00Z', updated_at: '2024-01-15T00:00:00Z', quiz: null } ] } ] };