feat: Implement the course discovery and catalog page, enabling users to browse, filter, search, and view details of available courses.

This commit is contained in:
supalerk-ar66 2026-01-27 09:51:18 +07:00
parent fb1e7671cc
commit bbee6d3934

View file

@ -294,30 +294,30 @@ onMounted(() => {
</p>
<!-- Course Syllabus -->
<div class="bg-white dark:bg-slate-800 rounded-3xl p-8 shadow-sm border border-slate-100 dark:border-slate-700/50">
<h3 class="text-xl font-bold mb-6 text-slate-900 dark:text-white flex items-center gap-2">
<div class="bg-white rounded-3xl p-8 shadow-sm border border-slate-100">
<h3 class="text-xl font-bold mb-6 text-slate-900 dark:text-black flex items-center gap-2">
<span class="w-1 h-6 bg-blue-500 rounded-full"></span>
{{ $t('course.courseContent') }}
</h3>
<div class="space-y-4">
<div v-for="(chapter, index) in selectedCourse.chapters" :key="chapter.id" class="border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden">
<div class="bg-slate-50 dark:bg-slate-800/80 p-4 flex justify-between items-center cursor-pointer">
<div class="font-bold text-slate-800 dark:text-slate-200">
<div v-for="(chapter, index) in selectedCourse.chapters" :key="chapter.id" class="border border-slate-200 rounded-xl overflow-hidden">
<div class="bg-slate-50 p-4 flex justify-between items-center cursor-pointer">
<div class="font-bold text-slate-800">
<span class="opacity-50 mr-2">Chapter {{ Number(index) + 1 }}</span>
{{ getLocalizedText(chapter.title) }}
</div>
<span class="text-xs font-bold px-3 py-1 bg-white dark:bg-slate-700 rounded-full border border-slate-200 dark:border-slate-600">
<span class="text-xs font-bold px-3 py-1 bg-white rounded-full border border-slate-200">
{{ chapter.lessons ? chapter.lessons.length : 0 }} Lessons
</span>
</div>
<!-- Lessons -->
<div class="divide-y divide-slate-100 dark:divide-slate-700/50 bg-white dark:bg-slate-800">
<div v-for="(lesson, lIndex) in chapter.lessons" :key="lesson.id" class="p-4 flex justify-between items-center hover:bg-slate-50 dark:hover:bg-slate-700/30 transition-colors">
<div class="divide-y divide-slate-100 bg-white">
<div v-for="(lesson, lIndex) in chapter.lessons" :key="lesson.id" class="p-4 flex justify-between items-center hover:bg-slate-50 transition-colors">
<div class="flex items-center gap-3">
<div class="w-6 h-6 rounded-full bg-slate-100 dark:bg-slate-700 flex items-center justify-center text-[10px] font-bold text-slate-500">
{{ Number(lIndex) + 1 }}
</div>
<span class="text-slate-700 dark:text-slate-300 font-medium text-sm">{{ getLocalizedText(lesson.title) }}</span>
<span class="text-slate-700 dark:text-black font-medium text-sm">{{ getLocalizedText(lesson.title) }}</span>
</div>
<span class="text-xs text-slate-400">{{ lesson.duration_minutes || 0 }}:00</span>
</div>
@ -329,14 +329,7 @@ onMounted(() => {
<!-- Sidebar (Right Column) -->
<div class="lg:col-span-4">
<div class="bg-white dark:bg-slate-800 rounded-3xl p-6 shadow-lg border border-slate-100 dark:border-slate-700 sticky top-24">
<div class="mb-8 text-center bg-slate-50 dark:bg-slate-900/50 rounded-2xl p-6 border border-slate-100 dark:border-slate-700">
<div class="text-sm text-slate-500 mb-1 font-medium">{{ selectedCourse.price ? 'ราคาคอร์ส' : 'ราคา' }}</div>
<h2 class="text-4xl font-black text-blue-600 dark:text-blue-400">
{{ selectedCourse.price || 'ฟรี' }}
</h2>
</div>
<div class="bg-white rounded-3xl p-6 shadow-lg border border-slate-100 sticky top-24">
<q-btn
@click="handleEnroll(selectedCourse.id)"
unetab
@ -351,18 +344,18 @@ onMounted(() => {
</template>
</q-btn>
<div class="text-sm space-y-3 pt-4 border-t border-slate-100 dark:border-slate-700">
<div class="flex justify-between text-slate-600 dark:text-slate-400">
<div class="text-sm space-y-3 pt-4 border-t border-slate-100">
<div class="flex justify-between text-slate-600 dark:text-black">
<span>{{ $t('course.certificate') }}</span>
<span class="font-bold text-slate-900 dark:text-white">{{ selectedCourse.have_certificate ? 'มีใบประกาศฯ' : 'ไม่มี' }}</span>
<span class="font-bold text-slate-900 dark:text-black">{{ selectedCourse.have_certificate ? 'มีใบประกาศฯ' : 'ไม่มี' }}</span>
</div>
<div v-if="selectedCourse.instructor_name" class="flex justify-between text-slate-600 dark:text-slate-400">
<div v-if="selectedCourse.instructor_name" class="flex justify-between text-slate-600 dark:text-black">
<span>สอน</span>
<span class="font-bold text-slate-900 dark:text-white">{{ selectedCourse.instructor_name }}</span>
<span class="font-bold text-slate-900 dark:text-black">{{ selectedCourse.instructor_name }}</span>
</div>
<div v-if="selectedCourse.level" class="flex justify-between text-slate-600 dark:text-slate-400">
<div v-if="selectedCourse.level" class="flex justify-between text-slate-600 dark:text-black">
<span>ระด</span>
<span class="font-bold text-slate-900 dark:text-white">{{ selectedCourse.level }}</span>
<span class="font-bold text-slate-900 dark:text-black">{{ selectedCourse.level }}</span>
</div>
</div>
</div>