feat: Implement course discovery page with browsing, filtering, and detailed course views, supported by new course card and category sidebar components and a course composable.
All checks were successful
Build and Deploy Frontend Learner / Build Frontend Learner Docker Image (push) Successful in 38s
Build and Deploy Frontend Learner / Deploy E-learning Frontend Learner to Dev Server (push) Successful in 2s
Build and Deploy Frontend Learner / Notify Deployment Status (push) Successful in 1s
All checks were successful
Build and Deploy Frontend Learner / Build Frontend Learner Docker Image (push) Successful in 38s
Build and Deploy Frontend Learner / Deploy E-learning Frontend Learner to Dev Server (push) Successful in 2s
Build and Deploy Frontend Learner / Notify Deployment Status (push) Successful in 1s
This commit is contained in:
parent
0691ca40cd
commit
4955bc9e5c
4 changed files with 13 additions and 8 deletions
|
|
@ -39,10 +39,11 @@ const emit = defineEmits<{
|
||||||
viewCertificate: []
|
viewCertificate: []
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
const { locale } = useI18n()
|
||||||
const getLocalizedText = (text: string | { th: string; en: string } | undefined) => {
|
const getLocalizedText = (text: string | { th: string; en: string } | undefined) => {
|
||||||
if (!text) return ''
|
if (!text) return ''
|
||||||
if (typeof text === 'string') return text
|
if (typeof text === 'string') return text
|
||||||
return text.th || text.en || ''
|
return text[locale.value] || text.th || text.en || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const displayTitle = computed(() => getLocalizedText(props.title))
|
const displayTitle = computed(() => getLocalizedText(props.title))
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,13 @@ const emit = defineEmits<{
|
||||||
(e: "update:modelValue", value: number[]): void;
|
(e: "update:modelValue", value: number[]): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const { locale, t } = useI18n();
|
||||||
const showAllCategories = ref(false);
|
const showAllCategories = ref(false);
|
||||||
|
|
||||||
const getLocalizedText = (text: any) => {
|
const getLocalizedText = (text: any) => {
|
||||||
if (!text) return "";
|
if (!text) return "";
|
||||||
if (typeof text === "string") return text;
|
if (typeof text === "string") return text;
|
||||||
return text.th || text.en || "";
|
return text[locale.value] || text.th || text.en || "";
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
@ -26,7 +27,7 @@ const getLocalizedText = (text: any) => {
|
||||||
<div class="category-sidebar-root border rounded-2xl overflow-hidden shadow-sm">
|
<div class="category-sidebar-root border rounded-2xl overflow-hidden shadow-sm">
|
||||||
<q-expansion-item
|
<q-expansion-item
|
||||||
expand-separator
|
expand-separator
|
||||||
:label="`หมวดหมู่ (${modelValue.length})`"
|
:label="`${$t('discovery.categoryTitle')} (${modelValue.length})`"
|
||||||
class="category-sidebar-expansion"
|
class="category-sidebar-expansion"
|
||||||
header-class="category-sidebar-header"
|
header-class="category-sidebar-header"
|
||||||
default-opened
|
default-opened
|
||||||
|
|
@ -67,7 +68,7 @@ const getLocalizedText = (text: any) => {
|
||||||
>
|
>
|
||||||
<q-item-section>
|
<q-item-section>
|
||||||
<div class="flex items-center gap-1 text-blue-600 dark:text-blue-400">
|
<div class="flex items-center gap-1 text-blue-600 dark:text-blue-400">
|
||||||
{{ showAllCategories ? "แสดงน้อยลง" : "แสดงเพิ่มเติม" }}
|
{{ showAllCategories ? $t('discovery.showLess') : $t('discovery.showMore') }}
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
class="h-4 w-4"
|
class="h-4 w-4"
|
||||||
|
|
|
||||||
|
|
@ -647,11 +647,12 @@ export const useCourse = () => {
|
||||||
/**
|
/**
|
||||||
* Helper: แปลงข้อมูล 2 ภาษาเป็นข้อความตาม locale ปัจจุบัน หรือค่าที่มีอยู่
|
* Helper: แปลงข้อมูล 2 ภาษาเป็นข้อความตาม locale ปัจจุบัน หรือค่าที่มีอยู่
|
||||||
*/
|
*/
|
||||||
|
const { locale } = useI18n()
|
||||||
const getLocalizedText = (text: string | { th: string; en: string } | undefined | null) => {
|
const getLocalizedText = (text: string | { th: string; en: string } | undefined | null) => {
|
||||||
if (!text) return ''
|
if (!text) return ''
|
||||||
if (typeof text === 'string') return text
|
if (typeof text === 'string') return text
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return text.th || text.en || ''
|
return text[locale.value] || text.th || text.en || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,10 @@ definePageMeta({
|
||||||
middleware: "auth",
|
middleware: "auth",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { t, locale } = useI18n();
|
||||||
|
|
||||||
useHead({
|
useHead({
|
||||||
title: "รายการคอร์ส - e-Learning",
|
title: `${t('sidebar.browseCourses')} - E-Learning Platform`,
|
||||||
});
|
});
|
||||||
|
|
||||||
// ==========================================
|
// ==========================================
|
||||||
|
|
@ -34,14 +36,14 @@ const totalPages = ref(1);
|
||||||
const itemsPerPage = 12;
|
const itemsPerPage = 12;
|
||||||
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
|
||||||
const { currentUser } = useAuth();
|
const { currentUser } = useAuth();
|
||||||
const { fetchCategories } = useCategory();
|
const { fetchCategories } = useCategory();
|
||||||
const { fetchCourses, fetchCourseById, enrollCourse, getLocalizedText } = useCourse();
|
const { fetchCourses, fetchCourseById, enrollCourse, getLocalizedText } = useCourse();
|
||||||
|
|
||||||
|
|
||||||
// 2. Computed Properties
|
// 2. Computed Properties
|
||||||
const sortOption = ref(computed(() => t('discovery.sortRecent')));
|
const sortOption = computed(() => t('discovery.sortRecent'));
|
||||||
const sortOptions = computed(() => [t('discovery.sortRecent')]);
|
const sortOptions = computed(() => [t('discovery.sortRecent')]);
|
||||||
|
|
||||||
const filteredCourses = computed(() => {
|
const filteredCourses = computed(() => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue