feat: Implement core authentication and course management logic with new discovery and profile pages.
This commit is contained in:
parent
1aa3190ca4
commit
2ffcc36fe4
12 changed files with 397 additions and 89 deletions
|
|
@ -20,36 +20,42 @@ const showDetail = ref(false);
|
|||
const searchQuery = ref("");
|
||||
const isCategoryOpen = ref(true);
|
||||
|
||||
// Mock Course Data
|
||||
const courses = [
|
||||
{
|
||||
id: 1,
|
||||
title: "เบื้องต้นการออกแบบ UX/UI",
|
||||
levelType: "neutral" as const,
|
||||
price: "ฟรี",
|
||||
description: "เรียนรู้พื้นฐานการวาดโครงร่าง...",
|
||||
rating: "4.8",
|
||||
lessons: "12",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "รูปแบบ React ขั้นสูง",
|
||||
levelType: "warning" as const,
|
||||
price: "ฟรี",
|
||||
description: "เจาะลึก HOC, Hooks และอื่นๆ...",
|
||||
rating: "4.9",
|
||||
lessons: "24",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "การตลาดดิจิทัล 101",
|
||||
levelType: "success" as const,
|
||||
price: "ฟรี",
|
||||
description: "คู่มือสมบูรณ์ SEO/SEM...",
|
||||
rating: "4.7",
|
||||
lessons: "18",
|
||||
},
|
||||
];
|
||||
// Courses Data
|
||||
const { fetchCourses, fetchCourseById } = useCourse();
|
||||
const courses = ref<any[]>([]);
|
||||
const isLoading = ref(false);
|
||||
const selectedCourse = ref<any>(null);
|
||||
const isLoadingDetail = ref(false);
|
||||
|
||||
const loadCourses = async () => {
|
||||
isLoading.value = true;
|
||||
const res = await fetchCourses();
|
||||
if (res.success) {
|
||||
courses.value = (res.data || []).map((c: any) => ({
|
||||
...c,
|
||||
rating: "0.0",
|
||||
lessons: "0",
|
||||
levelType: c.levelType || "neutral"
|
||||
}));
|
||||
}
|
||||
isLoading.value = false;
|
||||
};
|
||||
|
||||
const selectCourse = async (id: number) => {
|
||||
isLoadingDetail.value = true;
|
||||
selectedCourse.value = null;
|
||||
showDetail.value = true;
|
||||
|
||||
const res = await fetchCourseById(id);
|
||||
if (res.success) {
|
||||
selectedCourse.value = res.data;
|
||||
}
|
||||
isLoadingDetail.value = false;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
loadCourses();
|
||||
});
|
||||
|
||||
// Categories Data
|
||||
const categories = [
|
||||
|
|
@ -79,12 +85,12 @@ const visibleCategories = computed(() => {
|
|||
|
||||
// Filter Logic based on search query
|
||||
const filteredCourses = computed(() => {
|
||||
if (!searchQuery.value) return courses;
|
||||
if (!searchQuery.value) return courses.value;
|
||||
const query = searchQuery.value.toLowerCase();
|
||||
return courses.filter(
|
||||
return courses.value.filter(
|
||||
(c) =>
|
||||
c.title.toLowerCase().includes(query) ||
|
||||
c.description.toLowerCase().includes(query)
|
||||
c.description?.toLowerCase().includes(query)
|
||||
);
|
||||
});
|
||||
</script>
|
||||
|
|
@ -206,8 +212,9 @@ const filteredCourses = computed(() => {
|
|||
:description="course.description"
|
||||
:rating="course.rating"
|
||||
:lessons="course.lessons"
|
||||
:image="course.thumbnail_url"
|
||||
show-view-details
|
||||
@view-details="showDetail = true"
|
||||
@view-details="selectCourse(course.id)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
|
@ -245,11 +252,20 @@ const filteredCourses = computed(() => {
|
|||
|
||||
<!-- COURSE DETAIL VIEW: Detailed information about a specific course -->
|
||||
<div v-else>
|
||||
<NuxtLink to="/browse" class="btn btn-secondary mb-6 inline-block">
|
||||
← กลับหน้ารายการคอร์ส
|
||||
</NuxtLink>
|
||||
<button
|
||||
@click="showDetail = false"
|
||||
class="btn btn-secondary mb-6 inline-flex items-center gap-2"
|
||||
>
|
||||
<span>←</span> กลับหน้ารายการคอร์ส
|
||||
</button>
|
||||
|
||||
<div class="grid-12">
|
||||
<div v-if="isLoadingDetail" class="flex justify-center py-20">
|
||||
<div class="spinner-border animate-spin inline-block w-8 h-8 border-4 rounded-full" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="selectedCourse" class="grid-12">
|
||||
<!-- Main Content (Left Column) -->
|
||||
<div class="col-span-8">
|
||||
<!-- Hero Video Placeholder -->
|
||||
|
|
@ -265,10 +281,17 @@ const filteredCourses = computed(() => {
|
|||
margin-bottom: 24px;
|
||||
position: relative;
|
||||
border: 1px solid var(--border-color);
|
||||
overflow: hidden;
|
||||
"
|
||||
>
|
||||
<img
|
||||
v-if="selectedCourse.thumbnail_url"
|
||||
:src="selectedCourse.thumbnail_url"
|
||||
class="absolute inset-0 w-full h-full object-cover opacity-50"
|
||||
/>
|
||||
<!-- Play Button -->
|
||||
<div
|
||||
class="relative z-10"
|
||||
style="
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
|
|
@ -295,15 +318,13 @@ const filteredCourses = computed(() => {
|
|||
</div>
|
||||
|
||||
<h1 class="text-[32px] font-bold mb-4 text-slate-900 dark:text-white">
|
||||
เบื้องต้นการออกแบบ UX/UI
|
||||
{{ selectedCourse.title }}
|
||||
</h1>
|
||||
<p
|
||||
class="text-slate-700 dark:text-slate-400 mb-6"
|
||||
style="font-size: 1.1em; line-height: 1.7"
|
||||
>
|
||||
เนื้อหาครอบคลุมทุกอย่างตั้งแต่การวิจัยผู้ใช้ (User Research)
|
||||
ไปจนถึงการทำต้นแบบความละเอียดสูง (High-fidelity Prototyping)
|
||||
เหมาะสำหรับผู้เริ่มต้นที่ต้องการเข้าสู่สายงานออกแบบผลิตภัณฑ์
|
||||
{{ selectedCourse.description }}
|
||||
</p>
|
||||
|
||||
<!-- Learning Objectives -->
|
||||
|
|
@ -391,12 +412,12 @@ const filteredCourses = computed(() => {
|
|||
class="text-primary font-bold"
|
||||
style="font-size: 32px; margin: 0"
|
||||
>
|
||||
ฟรี
|
||||
{{ selectedCourse.price || 'ฟรี' }}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<NuxtLink
|
||||
to="/dashboard/my-courses?enrolled=true"
|
||||
:to="`/dashboard/my-courses?enroll=${selectedCourse.id}`"
|
||||
class="btn btn-primary w-full mb-4 text-white"
|
||||
style="height: 48px; font-size: 16px"
|
||||
>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue