feat: Introduce comprehensive course management features for admin, including recommended, pending, and detailed course views, and instructor course listing with a lesson preview component.
All checks were successful
Build and Deploy Frontend Management to Dev Server / Build Frontend Management Docker Image (push) Successful in 46s
Build and Deploy Frontend Management to Dev Server / Deploy E-learning Frontend Management to Dev Server (push) Successful in 4s
Build and Deploy Frontend Management to Dev Server / Notify Deployment Status (push) Successful in 2s

This commit is contained in:
Missez 2026-02-20 14:33:08 +07:00
parent 0f92f0d00c
commit f26a94076c
6 changed files with 141 additions and 23 deletions

View file

@ -196,6 +196,47 @@
</q-card-actions>
</q-card>
</q-dialog>
<!-- Clone Course Dialog -->
<q-dialog v-model="cloneDialog">
<q-card style="min-width: 400px">
<q-card-section class="row items-center q-pb-none">
<div class="text-h6">ทำสำเนาหลกสตร</div>
<q-space />
<q-btn icon="close" flat round dense v-close-popup />
</q-card-section>
<q-card-section>
<div class="mb-4">
กรณาระบอสำหรบหลกสตรใหม
</div>
<q-input
v-model="cloneCourseTitleTh"
label="ชื่อหลักสูตร (ภาษาไทย)"
outlined
autofocus
class="mb-4"
:rules="[val => !!val || 'กรุณากรอกชื่อหลักสูตรภาษาไทย']"
/>
<q-input
v-model="cloneCourseTitleEn"
label="Course Name (English)"
outlined
:rules="[val => !!val || 'Please enter course name in English']"
/>
</q-card-section>
<q-card-actions align="right" class="text-primary q-pt-none q-pb-md q-px-md">
<q-btn flat label="ยกเลิก" v-close-popup color="grey" />
<q-btn
label="ยืนยันการทำสำเนา"
color="primary"
@click="confirmClone"
:loading="cloneLoading"
/>
</q-card-actions>
</q-card>
</q-dialog>
</div>
</template>
@ -296,15 +337,45 @@ const formatDate = (date: string) => {
year: '2-digit'
});
};
// Clone Dialog
const cloneDialog = ref(false);
const cloneLoading = ref(false);
const cloneCourseTitleTh = ref('');
const cloneCourseTitleEn = ref('');
const courseToClone = ref<CourseResponse | null>(null);
const duplicateCourse = (course: CourseResponse) => {
$q.notify({
type: 'info',
message: `กำลังทำสำเนา "${course.title.th}"...`,
position: 'top'
});
courseToClone.value = course;
cloneCourseTitleTh.value = `${course.title.th} (Copy)`;
cloneCourseTitleEn.value = `${course.title.en} (Copy)`;
cloneDialog.value = true;
};
const confirmClone = async () => {
if (!courseToClone.value || !cloneCourseTitleTh.value || !cloneCourseTitleEn.value) return;
cloneLoading.value = true;
try {
const response = await instructorService.cloneCourse(courseToClone.value.id, cloneCourseTitleTh.value, cloneCourseTitleEn.value);
$q.notify({
type: 'positive',
message: response.message || 'ทำสำเนาหลักสูตรสำเร็จ',
position: 'top'
});
cloneDialog.value = false;
fetchCourses(); // Refresh list
} catch (error: any) {
$q.notify({
type: 'negative',
message: error.data?.message || 'ไม่สามารถทำสำเนาหลักสูตรได้',
position: 'top'
});
} finally {
cloneLoading.value = false;
}
};
const confirmDelete = (course: CourseResponse) => {
$q.dialog({
title: 'ยืนยันการลบ',