122 lines
4.3 KiB
TypeScript
122 lines
4.3 KiB
TypeScript
import { defineStore } from 'pinia';
|
|
import { instructorService } from '~/services/instructor.service';
|
|
|
|
interface Course {
|
|
id: number;
|
|
title: string;
|
|
students: number;
|
|
lessons: number;
|
|
icon: string;
|
|
thumbnail: string | null;
|
|
}
|
|
|
|
interface DashboardStats {
|
|
totalCourses: number;
|
|
totalStudents: number;
|
|
completedStudents: number;
|
|
}
|
|
|
|
interface CourseStatusCounts {
|
|
approved: number;
|
|
pending: number;
|
|
draft: number;
|
|
rejected: number;
|
|
}
|
|
|
|
export const useInstructorStore = defineStore('instructor', {
|
|
state: () => ({
|
|
stats: {
|
|
totalCourses: 0,
|
|
totalStudents: 0,
|
|
completedStudents: 0
|
|
} as DashboardStats,
|
|
|
|
courseStatusCounts: {
|
|
approved: 0,
|
|
pending: 0,
|
|
draft: 0,
|
|
rejected: 0
|
|
} as CourseStatusCounts,
|
|
|
|
recentCourses: [] as Course[],
|
|
loading: false
|
|
}),
|
|
|
|
getters: {
|
|
getDashboardStats: (state) => state.stats,
|
|
getRecentCourses: (state) => state.recentCourses
|
|
},
|
|
|
|
actions: {
|
|
async fetchDashboardData() {
|
|
this.loading = true;
|
|
try {
|
|
// Fetch real courses from API
|
|
const courses = await instructorService.getCourses();
|
|
|
|
// Fetch student counts for each course
|
|
let totalStudents = 0;
|
|
let completedStudents = 0;
|
|
const courseDetails: Course[] = [];
|
|
|
|
for (const course of courses.slice(0, 5)) {
|
|
try {
|
|
// Get student counts
|
|
const studentsResponse = await instructorService.getEnrolledStudents(course.id, 1, 1);
|
|
const courseStudents = studentsResponse.total || 0;
|
|
totalStudents += courseStudents;
|
|
|
|
// Get completed count from full list (if small) or estimate
|
|
if (courseStudents > 0 && courseStudents <= 100) {
|
|
const allStudents = await instructorService.getEnrolledStudents(course.id, 1, 100);
|
|
completedStudents += allStudents.data.filter(s => s.status === 'COMPLETED').length;
|
|
}
|
|
|
|
// Get lesson count from course detail
|
|
const courseDetail = await instructorService.getCourseById(course.id);
|
|
const lessonCount = courseDetail.chapters.reduce((sum, ch) => sum + ch.lessons.length, 0);
|
|
|
|
courseDetails.push({
|
|
id: course.id,
|
|
title: course.title.th,
|
|
students: courseStudents,
|
|
lessons: lessonCount,
|
|
icon: 'book',
|
|
thumbnail: course.thumbnail_url || null
|
|
});
|
|
} catch (e) {
|
|
// Course might not have students endpoint
|
|
courseDetails.push({
|
|
id: course.id,
|
|
title: course.title.th,
|
|
students: 0,
|
|
lessons: 0,
|
|
icon: 'book',
|
|
thumbnail: course.thumbnail_url || null
|
|
});
|
|
}
|
|
}
|
|
|
|
// Update stats
|
|
this.stats.totalCourses = courses.length;
|
|
this.stats.totalStudents = totalStudents;
|
|
this.stats.completedStudents = completedStudents;
|
|
|
|
// Update course status counts
|
|
this.courseStatusCounts = {
|
|
approved: courses.filter(c => c.status === 'APPROVED').length,
|
|
pending: courses.filter(c => c.status === 'PENDING').length,
|
|
draft: courses.filter(c => c.status === 'DRAFT').length,
|
|
rejected: courses.filter(c => c.status === 'REJECTED').length
|
|
};
|
|
|
|
// Update recent courses (first 3)
|
|
this.recentCourses = courseDetails.slice(0, 3);
|
|
} catch (error) {
|
|
console.error('Failed to fetch dashboard data:', error);
|
|
} finally {
|
|
this.loading = false;
|
|
}
|
|
}
|
|
}
|
|
});
|