// API Response structure for user list export interface AdminUserResponse { id: number; username: string; email: string; created_at: string; updated_at: string; role: { code: string; name: { en: string; th: string; }; }; avatar_url?: string; profile: { prefix: { en: string; th: string; }; first_name: string; last_name: string; avatar_url: string | null; birth_date: string | null; phone: string | null; }; } export interface ApiResponse { code: number; message: string; data: T; } export interface UsersListResponse { code: number; message: string; data: AdminUserResponse[]; } // Pending Course interfaces export interface PendingCourseUser { id: number; email: string; username: string; } export interface PendingCourseInstructor { user_id: number; is_primary: boolean; user: PendingCourseUser; } export interface PendingCourseSubmission { id: number; submitted_by: number; created_at: string; submitter: PendingCourseUser; } export interface PendingCourse { id: number; title: { th: string; en: string; }; slug: string; description: { th: string; en: string; }; thumbnail_url: string | null; status: string; created_at: string; updated_at: string; created_by: number; creator: PendingCourseUser; instructors: PendingCourseInstructor[]; chapters_count: number; lessons_count: number; latest_submission: PendingCourseSubmission | null; } export interface PendingCoursesListResponse { code: number; message: string; data: PendingCourse[]; total: number; } // Course Detail interfaces for admin review export interface CourseCategory { id: number; name: { th: string; en: string; }; } export interface CourseLesson { id: number; title: { th: string; en: string; }; type: string; sort_order: number; is_published: boolean; } export interface CourseChapter { id: number; title: { th: string; en: string; }; sort_order: number; is_published: boolean; lessons: CourseLesson[]; } export interface ApprovalHistory { id: number; action: string; comment: string | null; created_at: string; submitter: PendingCourseUser; reviewer: PendingCourseUser | null; } export interface CourseDetailForReview { id: number; title: { th: string; en: string; }; slug: string; description: { th: string; en: string; }; thumbnail_url: string | null; price: number; is_free: boolean; have_certificate: boolean; status: string; created_at: string; updated_at: string; category: CourseCategory; creator: PendingCourseUser; instructors: PendingCourseInstructor[]; chapters: CourseChapter[]; approval_history: ApprovalHistory[]; } export interface CourseDetailForReviewResponse { code: number; message: string; data: CourseDetailForReview; } // Category interfaces export interface CategoryResponse { id: number; name: { en: string; th: string; }; slug: string; description: { en: string; th: string; }; icon: string; sort_order: number; is_active: boolean; created_at: string; created_by: number; updated_at: string; updated_by: number | null; } export interface CategoriesListResponse { code: number; message: string; data: { categories: CategoryResponse[]; }; } export interface CreateCategoryRequest { name: { en: string; th: string; }; slug: string; description: { en: string; th: string; }; created_by?: number; } export interface UpdateCategoryRequest { id: number; name: { en: string; th: string; }; slug: string; description: { en: string; th: string; }; } // Audit Logs Interfaces export interface AuditLog { id: number; user_id: number; action: string; entity_type: string; entity_id: number; old_value: string | null; new_value: string | null; ip_address: string | null; user_agent: string | null; metadata: string | null; created_at: string; user: { email: string; username: string; id: number; } | null; } export interface AuditLogsListResponse { data: AuditLog[]; pagination: { totalPages: number; total: number; limit: number; page: number; }; } export interface AuditLogStats { totalLogs: number; todayLogs: number; actionSummary: { action: string; count: number; }[]; recentActivity: AuditLog[]; } export interface RecommendedCourse { id: number; title: { th: string; en: string; }; slug: string; description: { th: string; en: string; }; thumbnail_url: string | null; price: number; is_free: boolean; have_certificate: boolean; is_recommended: boolean; status: string; created_at: string; updated_at: string; category: { id: number; name: { th: string; en: string; }; }; instructors: { user_id: number; is_primary: boolean; user: { id: number; username: string; email: string; }; }[]; creator: { id: number; username: string; email: string; }; chapters_count: number; lessons_count: number; } export interface RecommendedCoursesListResponse { code: number; message: string; data: RecommendedCourse[]; total: number; } // Helper function to get auth token from cookie const getAuthToken = (): string => { const tokenCookie = useCookie('token'); return tokenCookie.value || ''; }; export const adminService = { async getUsers(): Promise { const config = useRuntimeConfig(); const token = getAuthToken(); const response = await $fetch('/api/admin/usermanagement/users', { baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` } }); return response.data; }, async getUserById(id: number): Promise { const config = useRuntimeConfig(); const token = getAuthToken(); const response = await $fetch(`/api/admin/usermanagement/users/${id}`, { baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` } }); return response; }, async updateUserRole(userId: number, roleId: number): Promise> { const config = useRuntimeConfig(); const token = getAuthToken(); const response = await $fetch>(`/api/admin/usermanagement/role/${userId}`, { method: 'PUT', baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` }, body: { id: userId, role_id: roleId } }); return response; }, async deleteUser(userId: number): Promise> { const config = useRuntimeConfig(); const token = getAuthToken(); const response = await $fetch>(`/api/admin/usermanagement/users/${userId}`, { method: 'DELETE', baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` } }); return response; }, // ============ Pending Courses ============ async getPendingCourses(): Promise { const config = useRuntimeConfig(); const token = getAuthToken(); const response = await $fetch('/api/admin/courses/pending', { baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` } }); return response.data; }, async getCourseForReview(courseId: number): Promise { const config = useRuntimeConfig(); const token = getAuthToken(); const response = await $fetch(`/api/admin/courses/${courseId}`, { baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` } }); return response.data; }, async approveCourse(courseId: number, comment?: string): Promise> { const config = useRuntimeConfig(); const token = getAuthToken(); const response = await $fetch>(`/api/admin/courses/${courseId}/approve`, { method: 'POST', baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` }, body: { comment: comment || '' } }); return response; }, async rejectCourse(courseId: number, comment: string): Promise> { const config = useRuntimeConfig(); const token = getAuthToken(); const response = await $fetch>(`/api/admin/courses/${courseId}/reject`, { method: 'POST', baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` }, body: { comment } }); return response; }, // ============ Categories ============ async getCategories(): Promise { const config = useRuntimeConfig(); const token = getAuthToken(); const response = await $fetch('/api/categories', { baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` } }); return response.data.categories; }, async createCategory(data: CreateCategoryRequest): Promise> { const config = useRuntimeConfig(); const token = getAuthToken(); const response = await $fetch>('/api/admin/categories', { method: 'POST', baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` }, body: data }); return response; }, async updateCategory(id: number, data: UpdateCategoryRequest): Promise> { const config = useRuntimeConfig(); const token = getAuthToken(); const response = await $fetch>(`/api/admin/categories/${id}`, { method: 'PUT', baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` }, body: data }); return response; }, async deleteCategory(id: number): Promise> { const config = useRuntimeConfig(); const token = getAuthToken(); const response = await $fetch>(`/api/admin/categories/${id}`, { method: 'DELETE', baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` } }); return response; }, // ============ Audit Logs ============ async getAuditLogs( page: number = 1, limit: number = 20, filters: { userId?: number; action?: string; entityType?: string; entityId?: number; startDate?: string; endDate?: string; } = {} ): Promise { const config = useRuntimeConfig(); const token = getAuthToken(); let query: any = { page, limit }; if (filters.userId) query.userId = filters.userId; if (filters.action) query.action = filters.action; if (filters.entityType) query.entityType = filters.entityType; if (filters.entityId) query.entityId = filters.entityId; if (filters.startDate) query.startDate = filters.startDate; if (filters.endDate) query.endDate = filters.endDate; const response = await $fetch('/api/admin/audit-logs', { baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` }, query }); return response; }, async getAuditLogById(id: number): Promise { const config = useRuntimeConfig(); const token = getAuthToken(); const response = await $fetch(`/api/admin/audit-logs/${id}`, { baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` } }); return response; }, async getAuditLogStats(): Promise { const config = useRuntimeConfig(); const token = getAuthToken(); const response = await $fetch('/api/admin/audit-logs/stats/summary', { baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` } }); return response; }, async getAuditLogsByEntity(entityType: string, entityId: number): Promise { const config = useRuntimeConfig(); const token = getAuthToken(); const response = await $fetch(`/api/admin/audit-logs/entity/${entityType}/${entityId}`, { baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` } }); return response; }, async getAuditLogsByUser(userId: number, limit: number = 20): Promise { const config = useRuntimeConfig(); const token = getAuthToken(); const response = await $fetch(`/api/admin/audit-logs/user/${userId}/activity`, { baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` }, query: { limit } }); return response; }, async cleanupAuditLogs(days: number = 90): Promise> { const config = useRuntimeConfig(); const token = getAuthToken(); const response = await $fetch>('/api/admin/audit-logs/cleanup', { method: 'DELETE', baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` }, query: { days } }); return response; }, // ============ Recommended Courses ============ async getRecommendedCourses(): Promise { const config = useRuntimeConfig(); const token = getAuthToken(); const response = await $fetch('/api/admin/recommended-courses', { baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` } }); return response.data; }, async getRecommendedCourseById(id: number): Promise { const config = useRuntimeConfig(); const token = getAuthToken(); const response = await $fetch>(`/api/admin/recommended-courses/${id}`, { baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` } }); return response.data; }, async toggleCourseRecommendation(courseId: number, isRecommended: boolean): Promise> { const config = useRuntimeConfig(); const token = getAuthToken(); const response = await $fetch>(`/api/admin/recommended-courses/${courseId}/toggle`, { method: 'PUT', baseURL: config.public.apiBaseUrl as string, headers: { Authorization: `Bearer ${token}` }, query: { is_recommended: isRecommended } }); return response; } };