feat: Add dashboard, course discovery, and quiz pages to introduce core e-learning functionalities.
This commit is contained in:
parent
f6bbd60f2b
commit
db9ff684ae
3 changed files with 38 additions and 269 deletions
|
|
@ -360,71 +360,33 @@ const filteredCourses = computed(() => {
|
|||
{{ getLocalizedText(selectedCourse.description) }}
|
||||
</p>
|
||||
|
||||
<!-- Learning Objectives -->
|
||||
<div class="card mb-6">
|
||||
<h3 class="font-bold mb-4 text-slate-900 dark:text-white">
|
||||
{{ $t('course.whatYouWillLearn') }}
|
||||
</h3>
|
||||
<ul
|
||||
class="grid-12"
|
||||
style="grid-template-columns: 1fr 1fr; gap: 12px"
|
||||
>
|
||||
<li class="flex gap-2 text-sm text-slate-700 dark:text-slate-300">
|
||||
<span style="color: var(--success)">✓</span> วิธีการวิจัยผู้ใช้
|
||||
(User Research)
|
||||
</li>
|
||||
<li class="flex gap-2 text-sm text-slate-700 dark:text-slate-300">
|
||||
<span style="color: var(--success)">✓</span>
|
||||
การวาดโครงร่างและทำต้นแบบ
|
||||
</li>
|
||||
<li class="flex gap-2 text-sm text-slate-700 dark:text-slate-300">
|
||||
<span style="color: var(--success)">✓</span> ระบบการออกแบบ
|
||||
(Design Systems)
|
||||
</li>
|
||||
<li class="flex gap-2 text-sm text-slate-700 dark:text-slate-300">
|
||||
<span style="color: var(--success)">✓</span> การทดสอบการใช้งาน
|
||||
(Usability Testing)
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Course Syllabus / Outline -->
|
||||
<div class="card">
|
||||
<!-- Course Syllabus / Outline (Dynamic) -->
|
||||
<div class="card" v-if="selectedCourse.chapters && selectedCourse.chapters.length > 0">
|
||||
<h3 class="font-bold mb-4 text-slate-900 dark:text-white">
|
||||
{{ $t('course.courseContent') }}
|
||||
</h3>
|
||||
<!-- Chapter 1 -->
|
||||
<div class="mb-4">
|
||||
<div v-for="chapter in selectedCourse.chapters" :key="chapter.id" class="mb-4">
|
||||
<div
|
||||
class="flex justify-between p-4 rounded mb-2"
|
||||
style="background: #f3f4f6; border: 1px solid #e5e7eb"
|
||||
>
|
||||
<span class="font-bold text-slate-900 dark:text-slate-900"
|
||||
>01. {{ $t('course.introduction') }}</span
|
||||
>{{ getLocalizedText(chapter.title) }}</span
|
||||
>
|
||||
<span class="text-sm text-slate-600 dark:text-slate-400"
|
||||
>3 {{ $t('course.lessons') }}</span
|
||||
>{{ chapter.lessons ? chapter.lessons.length : 0 }} {{ $t('course.lessons') }}</span
|
||||
>
|
||||
</div>
|
||||
<div style="padding-left: 16px">
|
||||
<div style="padding-left: 16px" v-if="chapter.lessons">
|
||||
<div
|
||||
v-for="lesson in chapter.lessons"
|
||||
:key="lesson.id"
|
||||
class="flex justify-between py-2 border-b"
|
||||
style="border-color: var(--neutral-100)"
|
||||
>
|
||||
<span class="text-sm text-slate-700 dark:text-slate-300">1.1 การออกแบบ UX คืออะไร?</span>
|
||||
<span class="text-sm text-slate-700 dark:text-slate-300">{{ getLocalizedText(lesson.title) }}</span>
|
||||
<span class="text-sm text-slate-600 dark:text-slate-400"
|
||||
>10:00</span
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="flex justify-between py-2 border-b"
|
||||
style="border-color: var(--neutral-100)"
|
||||
>
|
||||
<span class="text-sm text-slate-700 dark:text-slate-300"
|
||||
>1.2 กระบวนการคิดเชิงออกแบบ (Design Thinking)</span
|
||||
>
|
||||
<span class="text-sm text-slate-600 dark:text-slate-400"
|
||||
>15:30</span
|
||||
>{{ lesson.duration_minutes || 0 }}:00</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -460,19 +422,12 @@ const filteredCourses = computed(() => {
|
|||
</button>
|
||||
|
||||
<div class="text-sm text-slate-600 dark:text-slate-400 mb-4">
|
||||
<div
|
||||
class="flex justify-between py-2 border-b"
|
||||
style="border-color: var(--neutral-100)"
|
||||
>
|
||||
<span>ระยะเวลา</span>
|
||||
<span class="font-bold">4.5 ชั่วโมง</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex justify-between py-2 border-b"
|
||||
style="border-color: var(--neutral-100)"
|
||||
>
|
||||
<span>{{ $t('course.certificate') }}</span>
|
||||
<span class="font-bold">{{ $t('course.available') }}</span>
|
||||
<span class="font-bold">{{ selectedCourse.have_certificate ? $t('course.available') : '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ onUnmounted(() => {
|
|||
|
||||
<div class="text-center mb-10">
|
||||
<h2 class="text-[32px] font-black text-slate-900 dark:text-white mb-2 tracking-tight">แบบทดสอบท้ายบท</h2>
|
||||
<p class="text-[13px] font-bold text-slate-500 dark:text-slate-400 uppercase tracking-widest leading-none">เบื้องต้นการออกแบบ UX/UI</p>
|
||||
<p class="text-[13px] font-bold text-slate-500 dark:text-slate-400 uppercase tracking-widest leading-none">เตรียมความพร้อมก่อนเริ่มทำ</p>
|
||||
</div>
|
||||
|
||||
<!-- Instruction Box -->
|
||||
|
|
@ -116,27 +116,11 @@ onUnmounted(() => {
|
|||
<ul class="space-y-4">
|
||||
<li class="flex items-start gap-3">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-blue-500 mt-1.5 flex-shrink-0"/>
|
||||
<span class="text-[14px] text-slate-600 dark:text-slate-300 font-medium leading-relaxed">แบบทดสอบนี้มีทั้งหมด <strong class="text-slate-900 dark:text-white">10 ข้อ</strong></span>
|
||||
</li>
|
||||
<li class="flex items-start gap-3">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-blue-500 mt-1.5 flex-shrink-0"/>
|
||||
<span class="text-[14px] text-slate-600 dark:text-slate-300 font-medium leading-relaxed">เกณฑ์การผ่าน <strong class="text-slate-900 dark:text-white">80% ขึ้นไป</strong></span>
|
||||
</li>
|
||||
<li class="flex items-start gap-3">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-blue-500 mt-1.5 flex-shrink-0"/>
|
||||
<span class="text-[14px] text-slate-600 dark:text-slate-300 font-medium leading-relaxed">เวลาในการทำ: <strong class="text-slate-900 dark:text-white">30 นาที</strong></span>
|
||||
</li>
|
||||
<li class="flex items-start gap-3">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-blue-500 mt-1.5 flex-shrink-0"/>
|
||||
<span class="text-[14px] text-slate-600 dark:text-slate-300 font-medium leading-relaxed">ไม่สามารถหยุดเวลาชั่วคราวได้เมื่อเริ่มทำแบบทดสอบแล้ว</span>
|
||||
<span class="text-[14px] text-slate-600 dark:text-slate-300 font-medium leading-relaxed">ตั้งใจทำแบบทดสอบเพื่อวัดผลการเรียนรู้</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="text-[13px] font-black text-slate-400 dark:text-slate-500 mb-10 flex items-center justify-between px-2">
|
||||
<span>คะแนนที่ดีที่สุด: <span class="text-slate-900 dark:text-white">-</span></span>
|
||||
</div>
|
||||
|
||||
<!-- Action Button -->
|
||||
<button
|
||||
class="w-full py-5 bg-blue-600 hover:bg-blue-500 text-white rounded-[20px] font-black text-[14px] tracking-wider transition-all shadow-xl shadow-blue-600/20 active:scale-[0.98]"
|
||||
|
|
@ -147,154 +131,27 @@ onUnmounted(() => {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. TAKING SCREEN -->
|
||||
<div v-if="currentScreen === 'taking'" class="w-full max-w-[840px] animate-fade-in py-12">
|
||||
<div class="bg-white dark:!bg-[#1e293b] border border-slate-200 dark:border-white/5 rounded-[32px] p-8 md:p-14 shadow-2xl backdrop-blur-sm">
|
||||
<div class="flex items-center justify-between mb-10 pb-6 border-b border-slate-100 dark:border-white/5">
|
||||
<div>
|
||||
<div class="text-[10px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-[0.2em] mb-2">ข้อที่ 1 จาก 10</div>
|
||||
<!-- Progress Line -->
|
||||
<div class="w-48 h-1 bg-slate-100 dark:bg-white/5 rounded-full overflow-hidden">
|
||||
<div class="h-full bg-blue-500" style="width: 10%;"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Timer Display -->
|
||||
<div class="flex items-center gap-3 px-5 py-2.5 bg-amber-50 dark:bg-amber-500/10 border border-amber-200 dark:border-amber-500/20 rounded-2xl text-amber-600 dark:text-amber-500">
|
||||
<span class="text-sm">⏱</span>
|
||||
<span class="text-[15px] font-black font-mono tracking-widest">{{ timerDisplay }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-12">
|
||||
<h2 class="text-[22px] font-black text-slate-900 dark:text-white leading-tight mb-8">ข้อใดต่อไปนี้คือหลักการแรกของ User Experience (UX) ตามโมเดลของ Peter Morville?</h2>
|
||||
|
||||
<!-- Question Options -->
|
||||
<div class="space-y-4">
|
||||
<button v-for="i in 4" :key="i" class="w-full p-6 text-left rounded-2xl border border-slate-200 dark:border-white/5 bg-slate-50 dark:bg-white/5 hover:bg-white hover:border-blue-500 hover:shadow-lg dark:hover:bg-white/10 transition-all flex items-center gap-4 group">
|
||||
<div class="w-6 h-6 rounded-full border-2 border-slate-300 dark:border-slate-700 flex items-center justify-center group-hover:border-blue-500 transition-colors">
|
||||
<div class="w-2.5 h-2.5 rounded-full bg-blue-500 opacity-0 group-focus:opacity-100"/>
|
||||
</div>
|
||||
<span class="text-[15px] font-medium text-slate-700 dark:text-slate-300 group-hover:text-slate-900 dark:group-hover:text-white">ตัวเลือกที่ {{ i }} สำหรับคำตอบที่เป็นไปได้</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between items-center">
|
||||
<button class="px-8 py-3 text-slate-400 dark:text-slate-500 font-bold hover:text-slate-600 dark:hover:text-white transition-colors">ย้อนกลับ</button>
|
||||
<button class="px-10 py-4 bg-blue-600 text-white rounded-2xl font-black text-sm shadow-lg shadow-blue-600/20" @click="submitQuiz(false)">ถัดไป</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 2. TAKING SCREEN (Placeholder for Real API) -->
|
||||
<div v-if="currentScreen === 'taking'" class="w-full max-w-[840px] animate-fade-in py-12 text-center">
|
||||
<div class="bg-white dark:!bg-[#1e293b] rounded-[32px] p-10 shadow-xl">
|
||||
<h2 class="text-xl font-bold mb-4">ส่วนนี้อยู่ระหว่างการเชื่อมต่อกับระบบข้อสอบจริง</h2>
|
||||
<p class="text-slate-500">ระบบข้อสอบจะสามารถใช้งานได้เมื่อมีการเชื่อมต่อ API สมบูรณ์</p>
|
||||
<button @click="currentScreen = 'result'" class="mt-8 btn btn-primary">ข้ามไปหน้าผลลัพธ์ (จำลอง)</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 3. RESULT SCREEN -->
|
||||
<!-- 3. RESULT SCREEN (Empty/Placeholder) -->
|
||||
<div v-if="currentScreen === 'result'" class="w-full max-w-[640px] animate-fade-in py-12">
|
||||
<div class="bg-white dark:!bg-[#1e293b] border border-slate-200 dark:border-white/5 rounded-[40px] p-10 md:p-14 shadow-2xl text-center backdrop-blur-sm">
|
||||
<!-- Trophy Icon -->
|
||||
<div class="w-20 h-20 rounded-full bg-emerald-500/10 border border-emerald-500/20 flex items-center justify-center mx-auto mb-10 shadow-inner">
|
||||
<span class="text-4xl">🏆</span>
|
||||
</div>
|
||||
|
||||
<h2 class="text-[32px] font-black text-slate-900 dark:text-white mb-2 tracking-tight">ยินดีด้วยคุณสอบผ่าน!</h2>
|
||||
<p class="text-[13px] font-bold text-slate-500 dark:text-slate-500 uppercase tracking-widest mb-12">คุณทำคะแนนได้ยอดเยี่ยมและผ่านเกณฑ์การทดสอบ</p>
|
||||
|
||||
<!-- Stats Boxes -->
|
||||
<div class="grid grid-cols-3 gap-4 mb-14">
|
||||
<div class="p-6 rounded-[24px] bg-slate-50 dark:bg-[#0b121f]/60 border border-slate-100 dark:border-white/5 shadow-inner">
|
||||
<div class="text-[9px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-[0.2em] mb-3">คะแนน</div>
|
||||
<div class="text-[20px] font-black text-blue-600 dark:text-blue-500">90%</div>
|
||||
</div>
|
||||
<div class="p-6 rounded-[24px] bg-slate-50 dark:bg-[#0b121f]/60 border border-slate-100 dark:border-white/5 shadow-inner">
|
||||
<div class="text-[9px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-[0.2em] mb-3">ตอบถูก</div>
|
||||
<div class="text-[20px] font-black text-emerald-600 dark:text-emerald-500">9/10</div>
|
||||
</div>
|
||||
<div class="p-6 rounded-[24px] bg-slate-50 dark:bg-[#0b121f]/60 border border-slate-100 dark:border-white/5 shadow-inner">
|
||||
<div class="text-[9px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-[0.2em] mb-3">เวลาที่ใช้</div>
|
||||
<div class="text-[20px] font-black text-slate-900 dark:text-white">12:45</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Buttons -->
|
||||
<div class="space-y-4">
|
||||
<button
|
||||
class="w-full py-5 bg-blue-600 hover:bg-blue-500 text-white rounded-[24px] font-black text-[14px] tracking-wider transition-all shadow-xl shadow-blue-600/20"
|
||||
@click="showReview"
|
||||
>
|
||||
ดูเฉลย
|
||||
</button>
|
||||
<NuxtLink
|
||||
to="/dashboard"
|
||||
class="w-full py-5 bg-slate-100 dark:bg-[#1e293b] hover:bg-slate-200 dark:hover:bg-[#253347] text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white rounded-[24px] font-black text-[14px] tracking-wider transition-all border border-slate-200 dark:border-white/5 block"
|
||||
>
|
||||
กลับไปหน้าหลัก
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 4. REVIEW SCREEN -->
|
||||
<div v-if="currentScreen === 'review'" class="w-full max-w-[840px] animate-fade-in py-12">
|
||||
<div class="mb-10 flex items-center justify-between">
|
||||
<h2 class="text-[24px] font-black text-slate-900 dark:text-white tracking-tight">ดูเฉลยและทบทวนรายข้อ</h2>
|
||||
<button class="text-[13px] font-black text-slate-400 hover:text-slate-600 dark:hover:text-white transition-colors flex items-center gap-2" @click="currentScreen = 'result'"/>
|
||||
</div>
|
||||
|
||||
<div class="space-y-6">
|
||||
<!-- Review Item: Correct Answer -->
|
||||
<div class="bg-white dark:bg-[#1e293b]/40 border border-emerald-500/20 rounded-[32px] p-8 md:p-10 shadow-xl backdrop-blur-sm relative overflow-hidden group">
|
||||
<div class="absolute left-0 top-0 bottom-0 w-1.5 bg-emerald-500"/>
|
||||
<div class="flex items-center gap-2 mb-6 text-[10px] font-black uppercase tracking-widest">
|
||||
<span class="text-emerald-500">✓ ตอบถูก</span>
|
||||
<span class="text-slate-600 dark:text-slate-500">• ข้อที่ 1</span>
|
||||
</div>
|
||||
<h3 class="text-[18px] font-black text-slate-900 dark:text-white leading-tight mb-8">ข้อใดต่อไปนี้อธิบายกระบวนการออกแบบ "Double Diamond" ได้ดีที่สุด?</h3>
|
||||
|
||||
<div class="space-y-3 mb-8">
|
||||
<div class="p-5 rounded-2xl bg-emerald-50 dark:bg-emerald-500/5 border border-emerald-500/20 text-emerald-600 dark:text-emerald-400 font-bold text-[14px] flex items-center justify-between">
|
||||
<span>กระบวนการแตกประเด็นเพื่อค้นหา/พัฒนา และสรุปประเด็นเพื่อกำหนด/ส่งมอบ</span>
|
||||
<span class="text-xs">✓</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-slate-50 dark:bg-[#0b121f]/60 p-6 rounded-2xl border border-slate-100 dark:border-white/5">
|
||||
<h4 class="text-[11px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest mb-3">คำอธิบาย:</h4>
|
||||
<p class="text-[14px] text-slate-600 dark:text-slate-400 leading-relaxed font-medium">
|
||||
Double Diamond ประกอบด้วย 4 ขั้นตอนหลัก: Discover, Define, Develop และ Deliver ซึ่งเน้นการสลับกันระหว่างความคิดสร้างสรรค์แบบเปิดกว้าง (Divergent) และการคัดกรองเพื่อให้ได้ข้อสรุป (Convergent)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Review Item: Incorrect Answer -->
|
||||
<div class="bg-white dark:bg-[#1e293b]/40 border border-red-500/20 rounded-[32px] p-8 md:p-10 shadow-xl backdrop-blur-sm relative overflow-hidden">
|
||||
<div class="absolute left-0 top-0 bottom-0 w-1.5 bg-red-500"/>
|
||||
<div class="flex items-center gap-2 mb-6 text-[10px] font-black uppercase tracking-widest">
|
||||
<span class="text-red-500">✗ ตอบผิด</span>
|
||||
<span class="text-slate-600 dark:text-slate-500">• ข้อที่ 2</span>
|
||||
</div>
|
||||
<h3 class="text-[18px] font-black text-slate-900 dark:text-white leading-tight mb-8">เป้าหมายหลักของ User Research คืออะไร?</h3>
|
||||
|
||||
<div class="space-y-3 mb-8">
|
||||
<div class="p-5 rounded-2xl bg-red-50 dark:bg-white/5 border border-red-500/30 text-red-500 dark:text-red-400 font-medium text-[14px]">
|
||||
<span class="opacity-50 line-through">เพื่อให้แน่ใจว่าดีไซน์ที่ทำออกมาสวยงามที่สุด</span>
|
||||
<span class="ml-2 text-[10px] bg-red-500/20 px-2 py-0.5 rounded text-red-600 dark:text-red-500">คำตอบของคุณ</span>
|
||||
</div>
|
||||
<div class="p-5 rounded-2xl bg-emerald-50 dark:bg-emerald-500/5 border border-emerald-500/20 text-emerald-600 dark:text-emerald-400 font-bold text-[14px] flex items-center justify-between">
|
||||
<span>เพื่อทำความเข้าใจความต้องการ ปัญหา และพฤติกรรมของผู้ใช้ที่แท้จริง</span>
|
||||
<span class="text-[10px] bg-emerald-500/20 px-2 py-0.5 rounded text-emerald-600 dark:text-emerald-400">คำตอบที่ถูกต้อง</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-slate-50 dark:bg-[#0b121f]/60 p-6 rounded-2xl border border-slate-100 dark:border-white/5">
|
||||
<h4 class="text-[11px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest mb-3">คำอธิบาย:</h4>
|
||||
<p class="text-[14px] text-slate-600 dark:text-slate-400 leading-relaxed font-medium">
|
||||
User Research ไม่ใช่แค่การดูความสวยงาม แต่คือการหา "Insights" เพื่อนำมาแก้ปัญหาให้ตรงจุด ลดความเสี่ยงในการสร้างของที่ผู้ใช้งานไม่ได้ต้องการจริงๆ
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="mt-12 flex justify-center">
|
||||
<button class="px-10 py-4 bg-slate-100 hover:bg-slate-200 dark:bg-white/5 dark:hover:bg-white/10 text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white rounded-[20px] font-black text-sm border border-slate-200 dark:border-white/5 transition-all" @click="currentScreen = 'result'">กลับไปหน้าสรุปผล</button>
|
||||
<div class="bg-white dark:!bg-[#1e293b] rounded-[40px] p-10 shadow-2xl text-center">
|
||||
<h2 class="text-2xl font-black mb-4">จบการทำแบบทดสอบ</h2>
|
||||
<div class="space-y-4 mt-8">
|
||||
<NuxtLink
|
||||
to="/classroom/learning"
|
||||
class="w-full py-5 bg-slate-100 text-slate-600 rounded-[24px] font-black text-[14px] block"
|
||||
>
|
||||
กลับไปหน้าบทเรียน
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
|
|
|||
|
|
@ -25,14 +25,6 @@ const getLocalizedText = (text: string | { th: string; en: string } | undefined)
|
|||
return text.th || text.en || ''
|
||||
}
|
||||
|
||||
// Mock data: Recent Course Progress
|
||||
const recentCourse = {
|
||||
title: 'เบื้องต้นการออกแบบ UX/UI',
|
||||
lesson: 'บทที่ 3: พื้นฐานการวาดโครงร่าง (Wireframing Basics)',
|
||||
progress: 65,
|
||||
image: 'https://images.unsplash.com/photo-1586717791821-3f44a563de4c?w=400&auto=format&fit=crop&q=60'
|
||||
}
|
||||
|
||||
// Recommended Courses State
|
||||
const recommendedCourses = ref<any[]>([])
|
||||
|
||||
|
|
@ -56,9 +48,9 @@ onMounted(async () => {
|
|||
title: getLocalizedText(c.title),
|
||||
category: getLocalizedText(catMap.get(c.category_id)) || 'General', // Map Category ID to Name
|
||||
duration: c.lessons ? `${c.lessons} บทเรียน` : 'พร้อมเรียน', // Use lesson count or default
|
||||
image: c.thumbnail_url || 'https://images.unsplash.com/photo-1498050108023-c5249f4df085?w=400&q=80',
|
||||
badge: 'Recommended',
|
||||
badgeType: 'warning'
|
||||
image: c.thumbnail_url || '',
|
||||
badge: '', // No mock badge
|
||||
badgeType: ''
|
||||
}))
|
||||
}
|
||||
})
|
||||
|
|
@ -83,43 +75,6 @@ onMounted(async () => {
|
|||
|
||||
<!-- Main Content Area -->
|
||||
<div class="lg:col-span-12">
|
||||
<!-- Section: Continue Learning -->
|
||||
<div class="flex items-center justify-between mb-8">
|
||||
<h2 class="text-2xl font-black flex items-center gap-3 tracking-tight text-slate-900 dark:text-white">
|
||||
<span class="w-1.5 h-8 bg-blue-500 rounded-full shadow-[0_0_15px_rgba(59,130,246,0.5)]"/>
|
||||
{{ $t('menu.continueLearning') }}
|
||||
</h2>
|
||||
<NuxtLink to="/classroom/learning" class="text-sm font-black text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 transition-colors uppercase tracking-widest">{{ $t('menu.goToLesson') }} →</NuxtLink>
|
||||
</div>
|
||||
|
||||
<!-- Featured Current Course Card -->
|
||||
<div class="p-0 overflow-hidden group mb-12 border border-slate-200 dark:border-white/5 rounded-3xl shadow-sm dark:shadow-2xl transition-all hover:-translate-y-1 dark:hover:-translate-y-1" style="background-color: var(--bg-surface);">
|
||||
<div class="flex flex-col md:flex-row">
|
||||
<!-- Course Image -->
|
||||
<div class="md:w-2/5 aspect-video md:aspect-auto overflow-hidden relative rounded-t-3xl md:rounded-l-3xl md:rounded-tr-none">
|
||||
<img :src="recentCourse.image" :alt="recentCourse.title" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-700" >
|
||||
<div class="absolute inset-0 bg-gradient-to-t from-slate-900/30 via-transparent to-transparent opacity-40 dark:opacity-60 dark:from-[#0f172a]"/>
|
||||
</div>
|
||||
<!-- Course Details & Progress -->
|
||||
<div class="p-8 md:p-10 flex-1 flex flex-col justify-center" style="background-color: var(--bg-surface);">
|
||||
<span class="text-[10px] font-black uppercase tracking-[0.2em] text-blue-700 dark:text-blue-400 mb-3">{{ $t('course.currentlyLearning') }}</span>
|
||||
<h3 class="text-3xl font-black mb-2 leading-tight text-slate-900 dark:text-white group-hover:text-blue-700 dark:group-hover:text-blue-400 transition-colors">{{ recentCourse.title }}</h3>
|
||||
<p class="text-slate-700 dark:text-slate-400 text-base mb-8 font-medium">{{ recentCourse.lesson }}</p>
|
||||
|
||||
<!-- Progress Bar -->
|
||||
<div class="mt-auto bg-slate-100 dark:bg-slate-900/50 p-6 rounded-3xl border border-slate-200 dark:border-white/5">
|
||||
<div class="flex justify-between items-center mb-3">
|
||||
<span class="text-xs font-black text-slate-800 dark:text-slate-500 uppercase tracking-widest">{{ $t('course.progress') }}</span>
|
||||
<span class="text-sm font-black text-blue-700 dark:text-blue-400">{{ recentCourse.progress }}%</span>
|
||||
</div>
|
||||
<div class="h-2.5 w-full bg-slate-300 dark:bg-slate-700 rounded-full overflow-hidden shadow-inner">
|
||||
<div class="h-full bg-gradient-to-r from-blue-600 to-blue-500 rounded-full shadow-[0_0_10px_rgba(59,130,246,0.3)] transition-all duration-1000" :style="{ width: `${recentCourse.progress}%` }"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Section: Recommended Courses -->
|
||||
<div class="mb-8">
|
||||
<h2 class="text-2xl font-black flex items-center gap-3 tracking-tight text-slate-900 dark:text-white">
|
||||
|
|
@ -132,8 +87,10 @@ onMounted(async () => {
|
|||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
<NuxtLink v-for="(course, idx) in recommendedCourses" :key="course.id" to="/browse/discovery" class="p-0 overflow-hidden group border border-slate-200 dark:border-white/5 rounded-3xl shadow-sm dark:shadow-xl transition-all hover:-translate-y-1 dark:hover:-translate-y-1 block" style="background-color: var(--bg-surface);">
|
||||
<div class="h-48 overflow-hidden relative rounded-t-3xl">
|
||||
<img :src="course.image" :alt="course.title" class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700" >
|
||||
<span v-if="course.badge" :class="`absolute top-5 left-5 status-pill status-${course.badgeType} shadow-lg font-black text-[9px]`">{{ course.badge }}</span>
|
||||
<img v-if="course.image" :src="course.image" :alt="course.title" class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700" >
|
||||
<div v-else class="w-full h-full bg-slate-200 dark:bg-slate-700 flex items-center justify-center">
|
||||
<span class="text-4xl">📚</span>
|
||||
</div>
|
||||
<div class="absolute inset-x-0 bottom-0 h-1/2 bg-gradient-to-t from-slate-900/20 dark:from-[#1e293b] to-transparent"/>
|
||||
</div>
|
||||
<div class="p-7" style="background-color: var(--bg-surface);">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue