feat: add initial frontend pages for course browsing, recommendations, and user dashboard.
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 3s
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 3s
Build and Deploy Frontend Learner / Notify Deployment Status (push) Successful in 1s
This commit is contained in:
parent
0588ad7acd
commit
01d249c19a
14 changed files with 570 additions and 267 deletions
|
|
@ -8,8 +8,6 @@
|
||||||
import { ref, computed } from "vue";
|
import { ref, computed } from "vue";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
/** Controls visibility of the search bar */
|
|
||||||
showSearch?: boolean;
|
|
||||||
/** Controls visibility of the sidebar toggle button */
|
/** Controls visibility of the sidebar toggle button */
|
||||||
showSidebarToggle?: boolean;
|
showSidebarToggle?: boolean;
|
||||||
/** Type of navigation links to display */
|
/** Type of navigation links to display */
|
||||||
|
|
@ -19,6 +17,8 @@ const props = defineProps<{
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
/** Emitted when the hamburger menu is clicked */
|
/** Emitted when the hamburger menu is clicked */
|
||||||
toggleSidebar: [];
|
toggleSidebar: [];
|
||||||
|
/** Emitted when the mobile menu toggle is clicked */
|
||||||
|
toggleRightDrawer: [];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
@ -34,150 +34,135 @@ const navTypeComputed = computed(() => {
|
||||||
: "public";
|
: "public";
|
||||||
});
|
});
|
||||||
|
|
||||||
const searchText = ref("");
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<q-toolbar class="bg-white text-slate-900 h-16 shadow-sm border-none p-0">
|
<q-toolbar class="bg-white dark:!bg-[#0f172a] text-slate-900 dark:!text-white h-16 border-none p-0 overflow-visible">
|
||||||
<div
|
<div class="w-full px-4 md:px-12 flex items-center h-full no-wrap relative">
|
||||||
class="container mx-auto w-full px-6 md:px-12 flex items-center h-full"
|
|
||||||
>
|
<!-- Mobile Sidebar Toggle (For non-learner routes) -->
|
||||||
<!-- Mobile Menu Toggle -->
|
|
||||||
<q-btn
|
<q-btn
|
||||||
v-if="showSidebarToggle !== false && navTypeComputed !== 'learner'"
|
v-if="showSidebarToggle !== false && navTypeComputed !== 'learner' && $q.screen.lt.md"
|
||||||
flat
|
flat
|
||||||
round
|
round
|
||||||
dense
|
dense
|
||||||
icon="menu"
|
icon="menu"
|
||||||
class="lg:hidden mr-2 text-gray-500"
|
class="mr-2 text-gray-500"
|
||||||
@click="$emit('toggleSidebar')"
|
@click="$emit('toggleSidebar')"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- Branding -->
|
<!-- Branding: Logo + Name -->
|
||||||
<div
|
<div
|
||||||
class="flex items-center gap-3 cursor-pointer group"
|
class="flex items-center gap-3 cursor-pointer group flex-shrink-0"
|
||||||
@click="navigateTo('/dashboard')"
|
@click="navigateTo('/dashboard')"
|
||||||
>
|
>
|
||||||
<div
|
<div class="w-10 h-10 rounded-xl bg-blue-600 flex items-center justify-center text-white font-black shadow-lg shadow-blue-600/30 group-hover:scale-110 transition-transform flex-shrink-0">
|
||||||
class="w-10 h-10 rounded-xl bg-blue-600 flex items-center justify-center text-white font-black shadow-lg shadow-blue-600/30 group-hover:scale-110 transition-transform"
|
|
||||||
>
|
|
||||||
E
|
E
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col text-left">
|
||||||
<span
|
<span class="font-black text-[15px] md:text-lg leading-none tracking-tight text-slate-900 dark:text-white group-hover:text-blue-600 transition-colors">E-Learning</span>
|
||||||
class="font-black text-lg leading-none tracking-tight text-slate-900 group-hover:text-blue-600 transition-colors"
|
<span class="text-[9px] md:text-[10px] font-bold uppercase tracking-[0.2em] leading-none mt-1 text-slate-500">Platform</span>
|
||||||
>E-Learning</span
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="text-[10px] font-bold uppercase tracking-[0.2em] leading-none mt-1 text-slate-500"
|
|
||||||
>Platform</span
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
|
||||||
class="flex items-center min-w-[200px] md:min-w-[320px] max-w-sm ml-8 mr-8 h-10"
|
|
||||||
>
|
|
||||||
<q-input
|
|
||||||
v-model="searchText"
|
|
||||||
dense
|
|
||||||
borderless
|
|
||||||
:placeholder="$t('menu.searchCourses')"
|
|
||||||
class="search-input w-full bg-slate-100/60 px-4 rounded-full transition-all duration-300 focus-within:bg-white focus-within:ring-1 focus-within:ring-blue-100 h-full flex items-center"
|
|
||||||
@keyup.enter="navigateTo(`/browse/discovery?search=${searchText}`)"
|
|
||||||
>
|
|
||||||
<template #prepend>
|
|
||||||
<q-icon name="search" size="xs" class="text-blue-600" />
|
|
||||||
</template>
|
|
||||||
</q-input>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Desktop Navigation -->
|
<!-- Desktop Navigation -->
|
||||||
<nav class="flex items-center gap-8 text-[14px] font-bold text-slate-600">
|
<nav class="header-desktop items-center gap-6 lg:gap-8 text-[14px] font-bold ml-12 flex-shrink-0 h-full">
|
||||||
<!-- Learner Navigation (Dashboard Mode) -->
|
<NuxtLink to="/dashboard" class="nav-link" exact-active-class="active">{{ $t("sidebar.overview") }}</NuxtLink>
|
||||||
<template v-if="navTypeComputed === 'learner'">
|
<NuxtLink to="/browse/discovery" class="nav-link" active-class="active">{{ $t("landing.allCourses") }}</NuxtLink>
|
||||||
<NuxtLink
|
<NuxtLink to="/dashboard/my-courses" class="nav-link" exact-active-class="active">{{ $t("sidebar.myCourses") || 'คอร์สเรียนของฉัน' }}</NuxtLink>
|
||||||
to="/dashboard"
|
|
||||||
class="hover:text-blue-600 transition-colors uppercase tracking-wider"
|
|
||||||
active-class="text-blue-600"
|
|
||||||
>
|
|
||||||
{{ $t("sidebar.overview") }}
|
|
||||||
</NuxtLink>
|
|
||||||
<NuxtLink
|
|
||||||
to="/browse/discovery"
|
|
||||||
class="hover:text-blue-600 transition-colors uppercase tracking-wider"
|
|
||||||
active-class="text-blue-600"
|
|
||||||
>
|
|
||||||
{{ $t("landing.allCourses") }}
|
|
||||||
</NuxtLink>
|
|
||||||
|
|
||||||
<NuxtLink
|
|
||||||
to="/dashboard/my-courses"
|
|
||||||
class="hover:text-blue-600 transition-colors uppercase tracking-wider"
|
|
||||||
active-class="text-blue-600"
|
|
||||||
>
|
|
||||||
{{ $t("sidebar.myCourses") || "คอร์สเรียนของฉัน" }}
|
|
||||||
</NuxtLink>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<!-- Public Navigation (Default) -->
|
|
||||||
<template v-else>
|
|
||||||
<div
|
|
||||||
class="cursor-pointer hover:text-purple-600 flex items-center gap-1 transition-colors"
|
|
||||||
>
|
|
||||||
คอร์สเรียนทั้งหมด <q-icon name="keyboard_arrow_down" />
|
|
||||||
<q-menu>
|
|
||||||
<q-list dense style="min-width: 150px">
|
|
||||||
<q-item clickable v-close-popup to="/browse">
|
|
||||||
<q-item-section>ทั้งหมด</q-item-section>
|
|
||||||
</q-item>
|
|
||||||
</q-list>
|
|
||||||
</q-menu>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="cursor-pointer hover:text-purple-600 flex items-center gap-1 transition-colors"
|
|
||||||
>
|
|
||||||
หลักสูตร Onsite <q-icon name="keyboard_arrow_down" />
|
|
||||||
</div>
|
|
||||||
<NuxtLink
|
|
||||||
to="/browse/recommended"
|
|
||||||
class="hover:text-purple-600 transition-colors"
|
|
||||||
>
|
|
||||||
คอร์สแนะนำ
|
|
||||||
</NuxtLink>
|
|
||||||
<div class="cursor-pointer hover:text-purple-600 transition-colors">
|
|
||||||
บทความ
|
|
||||||
</div>
|
|
||||||
<div class="cursor-pointer hover:text-purple-600 transition-colors">
|
|
||||||
สมาชิกรายปี
|
|
||||||
</div>
|
|
||||||
<div class="cursor-pointer hover:text-purple-600 transition-colors">
|
|
||||||
สำหรับองค์กร
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<q-space />
|
<q-space />
|
||||||
|
|
||||||
<!-- Right Actions -->
|
<!-- Right Section: Tools -->
|
||||||
<div class="flex items-center gap-2 sm:gap-4 text-gray-500">
|
<div class="flex items-center gap-2 flex-shrink-0 no-wrap">
|
||||||
<!-- Search Icon -->
|
|
||||||
|
<!-- Desktop Only Tools -->
|
||||||
|
<div class="header-desktop items-center gap-4 flex-shrink-0">
|
||||||
|
<LanguageSwitcher />
|
||||||
|
<UserMenu />
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Language -->
|
<!-- Mobile/Tablet Tools Hidden (Moved to Drawer) -->
|
||||||
<LanguageSwitcher />
|
<!-- Just keep space between logo and hamburger -->
|
||||||
|
|
||||||
<!-- User Profile -->
|
<!-- Mobile/Tablet Hamburger -->
|
||||||
<UserMenu />
|
<q-btn
|
||||||
|
flat
|
||||||
|
round
|
||||||
|
dense
|
||||||
|
icon="menu"
|
||||||
|
class="header-mobile text-slate-700 dark:text-white bg-slate-100 dark:bg-slate-800 flex-shrink-0"
|
||||||
|
style="width: 40px; height: 40px; min-width: 40px;"
|
||||||
|
@click="$emit('toggleRightDrawer')"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</q-toolbar>
|
</q-toolbar>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.search-input :deep(.q-field__control) {
|
/* High Priority Visibility Logic */
|
||||||
border-radius: 9999px; /* Full rounded */
|
@media (max-width: 1023px) {
|
||||||
|
.header-desktop {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.header-mobile {
|
||||||
|
display: flex !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.search-input :deep(.q-field__control:before) {
|
|
||||||
border-color: #e2e8f0; /* slate-200 */
|
@media (min-width: 1024px) {
|
||||||
|
.header-mobile {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.header-desktop {
|
||||||
|
display: flex !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
color: #64748b; /* slate-500 */
|
||||||
|
text-decoration: none;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
white-space: nowrap;
|
||||||
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link:hover {
|
||||||
|
color: #2563eb; /* blue-600 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link.active {
|
||||||
|
color: #2563eb; /* blue-600 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 50%;
|
||||||
|
width: 0;
|
||||||
|
height: 3px;
|
||||||
|
background-color: #2563eb;
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
border-top-right-radius: 4px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link.active::after {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.router-link-active {
|
||||||
|
color: #2563eb !important;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
/**
|
/**
|
||||||
* @file LandingFooter.vue
|
* @file LandingFooter.vue
|
||||||
* @description Footer component for the landing page
|
* @description Footer component for the landing page - Adjusted to Image 2 (E-Learning Platform Branding)
|
||||||
*/
|
*/
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
@ -23,17 +23,6 @@
|
||||||
<p class="text-slate-500 text-sm leading-relaxed max-w-xs">
|
<p class="text-slate-500 text-sm leading-relaxed max-w-xs">
|
||||||
แพลตฟอร์มการเรียนรู้ออนไลน์ที่มุ่งเน้นการพัฒนาทักษะดิจิทัลสำหรับคนรุ่นใหม่ เรียนรู้ได้ทุกที่ ทุกเวลา กับผู้เชี่ยวชาญตัวจริง
|
แพลตฟอร์มการเรียนรู้ออนไลน์ที่มุ่งเน้นการพัฒนาทักษะดิจิทัลสำหรับคนรุ่นใหม่ เรียนรู้ได้ทุกที่ ทุกเวลา กับผู้เชี่ยวชาญตัวจริง
|
||||||
</p>
|
</p>
|
||||||
<div class="flex gap-3">
|
|
||||||
<a href="#" class="w-9 h-9 rounded-full bg-white border border-slate-200 flex items-center justify-center text-slate-400 hover:bg-blue-600 hover:text-white hover:border-blue-600 transition-all">
|
|
||||||
<q-icon name="facebook" size="18px" />
|
|
||||||
</a>
|
|
||||||
<a href="#" class="w-9 h-9 rounded-full bg-white border border-slate-200 flex items-center justify-center text-slate-400 hover:bg-sky-400 hover:text-white hover:border-sky-400 transition-all">
|
|
||||||
<q-icon name="flutter_dash" size="18px" />
|
|
||||||
</a>
|
|
||||||
<a href="#" class="w-9 h-9 rounded-full bg-white border border-slate-200 flex items-center justify-center text-slate-400 hover:bg-pink-600 hover:text-white hover:border-pink-600 transition-all">
|
|
||||||
<q-icon name="camera_alt" size="18px" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Links -->
|
<!-- Links -->
|
||||||
|
|
@ -58,40 +47,51 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Contact -->
|
<!-- Contact (Bronco Hourse Data) -->
|
||||||
<div>
|
<div class="space-y-6">
|
||||||
<h4 class="font-bold text-slate-900 mb-6 text-base">ติดต่อเรา</h4>
|
<h4 class="font-bold text-slate-900 text-base">ติดต่อเรา</h4>
|
||||||
<ul class="space-y-4 text-sm text-slate-500">
|
<div class="flex flex-col gap-5">
|
||||||
<li class="flex items-start gap-3">
|
<!-- Location -->
|
||||||
<div class="w-8 h-8 rounded-lg bg-blue-50 flex items-center justify-center shrink-0 text-blue-600 mt-[-2px]">
|
<div class="flex flex-row items-start gap-4 flex-nowrap">
|
||||||
<q-icon name="location_on" size="18px" />
|
<div class="w-10 h-10 rounded-xl bg-blue-50 flex items-center justify-center shrink-0 text-blue-600 shadow-sm">
|
||||||
|
<q-icon name="location_on" size="20px" />
|
||||||
</div>
|
</div>
|
||||||
<span class="leading-relaxed">123 อาคารสยามทาวเวอร์ ชั้น 15 เขตปทุมวัน กรุงเทพฯ 10330</span>
|
<div class="flex flex-col gap-1 min-w-0">
|
||||||
</li>
|
<span class="font-bold text-slate-900 text-sm leading-tight pt-1">Bronco Hourse</span>
|
||||||
<li class="flex items-center gap-3">
|
<p class="text-slate-500 text-[11px] leading-relaxed">
|
||||||
<div class="w-8 h-8 rounded-lg bg-blue-50 flex items-center justify-center shrink-0 text-blue-600">
|
74/2 Wiang Kaew Road, Tambon Si Phum, Amphoe Mueang Chiang Mai, Chang Wat Chiang Mai 50200
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Phone -->
|
||||||
|
<div class="flex flex-row items-center gap-4 flex-nowrap">
|
||||||
|
<div class="w-10 h-10 rounded-xl bg-blue-50 flex items-center justify-center shrink-0 text-blue-600 shadow-sm">
|
||||||
<q-icon name="phone" size="18px" />
|
<q-icon name="phone" size="18px" />
|
||||||
</div>
|
</div>
|
||||||
<span>02-123-4567</span>
|
<a href="tel:052-076-025" class="text-slate-600 hover:text-blue-600 font-semibold text-sm transition-colors truncate">
|
||||||
</li>
|
052-076-025
|
||||||
<li class="flex items-center gap-3">
|
</a>
|
||||||
<div class="w-8 h-8 rounded-lg bg-blue-50 flex items-center justify-center shrink-0 text-blue-600">
|
</div>
|
||||||
|
|
||||||
|
<!-- Email -->
|
||||||
|
<div class="flex flex-row items-center gap-4 flex-nowrap">
|
||||||
|
<div class="w-10 h-10 rounded-xl bg-blue-50 flex items-center justify-center shrink-0 text-blue-600 shadow-sm">
|
||||||
<q-icon name="email" size="18px" />
|
<q-icon name="email" size="18px" />
|
||||||
</div>
|
</div>
|
||||||
<span>support@elearning.com</span>
|
<a href="mailto:info@chamomind.com" class="text-slate-600 hover:text-blue-600 font-semibold text-sm transition-colors truncate">
|
||||||
</li>
|
info@chamomind.com
|
||||||
</ul>
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pt-8 border-t border-slate-200 flex flex-col md:flex-row justify-between items-center gap-4">
|
<!-- Bottom Bar (Centered Copyright) -->
|
||||||
<p class="text-sm text-slate-500 text-center md:text-left">
|
<div class="pt-8 border-t border-slate-200 text-center">
|
||||||
© {{ new Date().getFullYear() }} E-Learning Platform. All rights reserved.
|
<p class="text-sm text-slate-400 font-medium tracking-wide">
|
||||||
|
Copyright © CHAMOMIND CO., LTD. 2023
|
||||||
</p>
|
</p>
|
||||||
<div class="flex gap-6 text-sm font-medium text-slate-500">
|
|
||||||
<a href="#" class="hover:text-blue-600 transition-colors">Privacy Policy</a>
|
|
||||||
<a href="#" class="hover:text-blue-600 transition-colors">Terms of Service</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
|
||||||
|
|
@ -171,6 +171,7 @@ export const useCourse = () => {
|
||||||
category_id?: number;
|
category_id?: number;
|
||||||
page?: number;
|
page?: number;
|
||||||
limit?: number;
|
limit?: number;
|
||||||
|
search?: string;
|
||||||
random?: boolean;
|
random?: boolean;
|
||||||
is_recommended?: boolean;
|
is_recommended?: boolean;
|
||||||
forceRefresh?: boolean
|
forceRefresh?: boolean
|
||||||
|
|
@ -193,6 +194,7 @@ export const useCourse = () => {
|
||||||
if (apiParams.category_id) queryParams.append('category_id', apiParams.category_id.toString())
|
if (apiParams.category_id) queryParams.append('category_id', apiParams.category_id.toString())
|
||||||
if (apiParams.page) queryParams.append('page', apiParams.page.toString())
|
if (apiParams.page) queryParams.append('page', apiParams.page.toString())
|
||||||
if (apiParams.limit) queryParams.append('limit', apiParams.limit.toString())
|
if (apiParams.limit) queryParams.append('limit', apiParams.limit.toString())
|
||||||
|
if (apiParams.search) queryParams.append('search', apiParams.search)
|
||||||
if (apiParams.random !== undefined) queryParams.append('random', apiParams.random.toString())
|
if (apiParams.random !== undefined) queryParams.append('random', apiParams.random.toString())
|
||||||
if (apiParams.is_recommended !== undefined) queryParams.append('is_recommended', apiParams.is_recommended.toString())
|
if (apiParams.is_recommended !== undefined) queryParams.append('is_recommended', apiParams.is_recommended.toString())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -291,5 +291,16 @@
|
||||||
"statusNotStarted": "Not Started",
|
"statusNotStarted": "Not Started",
|
||||||
"alertIncomplete": "Please answer all questions",
|
"alertIncomplete": "Please answer all questions",
|
||||||
"yourAnswer": "Your Answer"
|
"yourAnswer": "Your Answer"
|
||||||
|
},
|
||||||
|
"footer": {
|
||||||
|
"location": "LOCATION",
|
||||||
|
"connectWithUs": "CONNECT WITH US",
|
||||||
|
"broncoHorse": "Bronco Hourse",
|
||||||
|
"address": "123 อาคารสยามทาวเวอร์ ชั้น 15 เขตปทุมวัน กรุงเทพฯ 10330",
|
||||||
|
"emailLabel": "Email",
|
||||||
|
"emailValue": "info{'@'}chamomind.com",
|
||||||
|
"telLabel": "Tel",
|
||||||
|
"telValue": "02-123-4567",
|
||||||
|
"copyright": "© 2026 E-Learning Platform. All rights reserved."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@
|
||||||
"myCourses": "คอร์สของฉัน",
|
"myCourses": "คอร์สของฉัน",
|
||||||
"browseCourses": "ค้นหาคอร์ส",
|
"browseCourses": "ค้นหาคอร์ส",
|
||||||
"onlineCourses": "คอร์สออนไลน์",
|
"onlineCourses": "คอร์สออนไลน์",
|
||||||
"recommendedCourses": "คอร์สเรียนออนไลน์แนะนำ",
|
"recommendedCourses": "คอร์สเรียนแนะนำ",
|
||||||
"announcements": "ข่าวประกาศ",
|
"announcements": "ข่าวประกาศ",
|
||||||
"profile": "บัญชีผู้ใช้"
|
"profile": "บัญชีผู้ใช้"
|
||||||
},
|
},
|
||||||
|
|
@ -107,7 +107,8 @@
|
||||||
"backToCatalog": "กลับหน้ารายการคอร์ส",
|
"backToCatalog": "กลับหน้ารายการคอร์ส",
|
||||||
"selectable": "รายการที่เลือก",
|
"selectable": "รายการที่เลือก",
|
||||||
"foundTotal": "พบทั้งหมด",
|
"foundTotal": "พบทั้งหมด",
|
||||||
"items": "รายการ"
|
"items": "รายการ",
|
||||||
|
"subtitle": "เลือกเรียนรู้ทักษะใหม่ๆ จากหลักสูตรคุณภาพที่คัดสรรมาเพื่อคุณ"
|
||||||
},
|
},
|
||||||
"myCourses": {
|
"myCourses": {
|
||||||
"filterAll": "ทั้งหมด",
|
"filterAll": "ทั้งหมด",
|
||||||
|
|
@ -291,5 +292,16 @@
|
||||||
"statusNotStarted": "ยังไม่ทำ",
|
"statusNotStarted": "ยังไม่ทำ",
|
||||||
"alertIncomplete": "กรุณาเลือกคำตอบให้ครบทุกข้อ",
|
"alertIncomplete": "กรุณาเลือกคำตอบให้ครบทุกข้อ",
|
||||||
"yourAnswer": "คำตอบของคุณ"
|
"yourAnswer": "คำตอบของคุณ"
|
||||||
|
},
|
||||||
|
"footer": {
|
||||||
|
"location": "สถานที่ตั้ง",
|
||||||
|
"connectWithUs": "ติดต่อเรา",
|
||||||
|
"broncoHorse": "Bronco Hourse",
|
||||||
|
"address": "123 อาคารสยามทาวเวอร์ ชั้น 15 เขตปทุมวัน กรุงเทพฯ 10330",
|
||||||
|
"emailLabel": "อีเมล",
|
||||||
|
"emailValue": "info{'@'}chamomind.com",
|
||||||
|
"telLabel": "เบอร์โทรศัพท์",
|
||||||
|
"telValue": "02-123-4567",
|
||||||
|
"copyright": "© 2026 E-Learning Platform. All rights reserved."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,12 @@
|
||||||
// Initialize global theme management
|
// Initialize global theme management
|
||||||
useThemeMode()
|
useThemeMode()
|
||||||
|
|
||||||
// No sidebar logic needed here as we are removing it
|
const { currentUser, logout } = useAuth()
|
||||||
|
const { isDark, set: setTheme } = useThemeMode()
|
||||||
|
const rightDrawerOpen = ref(false)
|
||||||
|
const toggleRightDrawer = () => {
|
||||||
|
rightDrawerOpen.value = !rightDrawerOpen.value
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -17,9 +22,122 @@ useThemeMode()
|
||||||
<q-header
|
<q-header
|
||||||
class="bg-white/80 dark:!bg-[#0f172a]/80 backdrop-blur-md text-slate-900 dark:!text-white"
|
class="bg-white/80 dark:!bg-[#0f172a]/80 backdrop-blur-md text-slate-900 dark:!text-white"
|
||||||
>
|
>
|
||||||
<AppHeader :showSidebarToggle="false" navType="learner" />
|
<AppHeader
|
||||||
|
@toggleRightDrawer="toggleRightDrawer"
|
||||||
|
:showSidebarToggle="false"
|
||||||
|
navType="learner"
|
||||||
|
/>
|
||||||
</q-header>
|
</q-header>
|
||||||
|
|
||||||
|
<!-- Master Mobile Drawer (The Everything Hub) -->
|
||||||
|
<q-drawer
|
||||||
|
v-model="rightDrawerOpen"
|
||||||
|
side="right"
|
||||||
|
overlay
|
||||||
|
bordered
|
||||||
|
class="bg-white dark:!bg-[#0f172a]"
|
||||||
|
:width="300"
|
||||||
|
>
|
||||||
|
<div class="flex flex-col h-full bg-white dark:bg-[#0f172a]">
|
||||||
|
<!-- 1. Account Section (Premium Look) -->
|
||||||
|
<div class="p-6 bg-slate-50/50 dark:bg-slate-800/30 border-b border-slate-100 dark:border-slate-800">
|
||||||
|
<div class="flex items-center justify-between mb-8">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<div class="w-8 h-8 rounded-lg bg-blue-600 flex items-center justify-center text-white font-black">E</div>
|
||||||
|
<span class="font-black text-lg text-slate-900 dark:text-white">E-Learning</span>
|
||||||
|
</div>
|
||||||
|
<q-btn flat round dense icon="close" class="text-slate-400" @click="rightDrawerOpen = false" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center gap-4 py-2">
|
||||||
|
<q-avatar size="64px" class="shadow-lg border-2 border-white dark:border-slate-700">
|
||||||
|
<img :src="currentUser?.photoURL || 'https://cdn.quasar.dev/img/avatar.png'" />
|
||||||
|
</q-avatar>
|
||||||
|
<div class="overflow-hidden">
|
||||||
|
<p class="font-bold text-slate-900 dark:text-white mb-0 truncate text-lg">
|
||||||
|
{{ currentUser?.firstName || 'Guest' }} {{ currentUser?.lastName || '' }}
|
||||||
|
</p>
|
||||||
|
<p class="text-xs text-slate-500 dark:text-slate-400 truncate">{{ currentUser?.email || 'e-learning@platform.com' }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 2. Integrated Content Hub -->
|
||||||
|
<div class="flex-grow overflow-y-auto pt-4">
|
||||||
|
<q-list padding class="text-slate-600 dark:text-slate-300">
|
||||||
|
<!-- Navigation -->
|
||||||
|
<q-item-label header class="text-[11px] font-black tracking-[0.2em] text-slate-400 uppercase px-6 pb-2">เมนูหลัก</q-item-label>
|
||||||
|
|
||||||
|
<q-item to="/dashboard" clickable v-ripple class="px-6 py-4" active-class="bg-blue-50 text-blue-600 dark:bg-blue-900/20 dark:text-blue-400 font-bold" @click="rightDrawerOpen = false">
|
||||||
|
<q-item-section avatar><q-icon name="dashboard" size="24px" /></q-item-section>
|
||||||
|
<q-item-section><span class="text-[15px] font-bold">{{ $t("sidebar.overview") }}</span></q-item-section>
|
||||||
|
</q-item>
|
||||||
|
|
||||||
|
<q-item to="/browse/discovery" clickable v-ripple class="px-6 py-4" active-class="bg-blue-50 text-blue-600 dark:bg-blue-900/20 dark:text-blue-400 font-bold" @click="rightDrawerOpen = false">
|
||||||
|
<q-item-section avatar><q-icon name="explore" size="24px" /></q-item-section>
|
||||||
|
<q-item-section><span class="text-[15px] font-bold">{{ $t("landing.allCourses") }}</span></q-item-section>
|
||||||
|
</q-item>
|
||||||
|
|
||||||
|
<q-item to="/dashboard/my-courses" clickable v-ripple class="px-6 py-4" active-class="bg-blue-50 text-blue-600 dark:bg-blue-900/20 dark:text-blue-400 font-bold" @click="rightDrawerOpen = false">
|
||||||
|
<q-item-section avatar><q-icon name="school" size="24px" /></q-item-section>
|
||||||
|
<q-item-section><span class="text-[15px] font-bold">{{ $t("sidebar.myCourses") || 'คอร์สเรียนของฉัน' }}</span></q-item-section>
|
||||||
|
</q-item>
|
||||||
|
|
||||||
|
<q-separator class="my-4 mx-6 opacity-50" />
|
||||||
|
|
||||||
|
<!-- Tools & Settings -->
|
||||||
|
<q-item-label header class="text-[11px] font-black tracking-[0.2em] text-slate-400 uppercase px-6 pb-2">เครื่องมือและการตั้งค่า</q-item-label>
|
||||||
|
|
||||||
|
<!-- Language Selection -->
|
||||||
|
<q-item class="px-6 py-2">
|
||||||
|
<q-item-section avatar><q-icon name="language" size="22px" /></q-item-section>
|
||||||
|
<q-item-section>
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<span class="font-bold text-[14px]">ภาษา</span>
|
||||||
|
<LanguageSwitcher dense />
|
||||||
|
</div>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
|
||||||
|
<!-- Dark Mode Toggle -->
|
||||||
|
<q-item class="px-6 py-2">
|
||||||
|
<q-item-section avatar><q-icon :name="isDark ? 'dark_mode' : 'light_mode'" size="22px" /></q-item-section>
|
||||||
|
<q-item-section>
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<span class="font-bold text-[14px]">โหมดกลางคืน</span>
|
||||||
|
<q-toggle
|
||||||
|
:model-value="isDark"
|
||||||
|
@update:model-value="setTheme"
|
||||||
|
color="blue"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
|
||||||
|
<q-item clickable v-ripple @click="navigateTo('/dashboard/profile'); rightDrawerOpen = false" class="px-6 py-4">
|
||||||
|
<q-item-section avatar><q-icon name="person_outline" size="24px" /></q-item-section>
|
||||||
|
<q-item-section><span class="font-bold text-[15px]">จัดการโปรไฟล์</span></q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</q-list>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 3. Bottom Actions -->
|
||||||
|
<div class="p-6 mt-auto border-t border-slate-100 dark:border-slate-800">
|
||||||
|
<q-btn
|
||||||
|
unelevated
|
||||||
|
class="full-width rounded-xl bg-red-50 text-red-600 dark:bg-red-900/20 dark:text-red-400 font-bold py-3 no-caps transition-all active:scale-95"
|
||||||
|
@click="logout"
|
||||||
|
>
|
||||||
|
<q-icon name="logout" size="20px" class="mr-2" />
|
||||||
|
ออกจากระบบ
|
||||||
|
</q-btn>
|
||||||
|
<div class="text-center mt-6">
|
||||||
|
<span class="text-[10px] font-bold uppercase tracking-[0.2em] text-slate-300 dark:text-slate-600">E-Learning Platform v1.0</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</q-drawer>
|
||||||
|
|
||||||
<!-- Sidebar Removed for this layout -->
|
<!-- Sidebar Removed for this layout -->
|
||||||
|
|
||||||
<!-- Main Content -->
|
<!-- Main Content -->
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,19 @@
|
||||||
// Initialize global theme management
|
// Initialize global theme management
|
||||||
useThemeMode()
|
useThemeMode()
|
||||||
|
|
||||||
|
const { currentUser, logout } = useAuth()
|
||||||
|
const { isDark, set: setTheme } = useThemeMode()
|
||||||
const leftDrawerOpen = ref(false)
|
const leftDrawerOpen = ref(false)
|
||||||
|
const rightDrawerOpen = ref(false)
|
||||||
|
|
||||||
const toggleLeftDrawer = () => {
|
const toggleLeftDrawer = () => {
|
||||||
leftDrawerOpen.value = !leftDrawerOpen.value
|
leftDrawerOpen.value = !leftDrawerOpen.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const toggleRightDrawer = () => {
|
||||||
|
rightDrawerOpen.value = !rightDrawerOpen.value
|
||||||
|
}
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
// Automatically hide sidebar for learner routes
|
// Automatically hide sidebar for learner routes
|
||||||
const shouldHideSidebar = computed(() => {
|
const shouldHideSidebar = computed(() => {
|
||||||
|
|
@ -25,12 +33,16 @@ const shouldHideSidebar = computed(() => {
|
||||||
<q-layout view="hHh LpR lFf" class="bg-slate-50 dark:!bg-[#020617] text-slate-900 dark:!text-slate-50">
|
<q-layout view="hHh LpR lFf" class="bg-slate-50 dark:!bg-[#020617] text-slate-900 dark:!text-slate-50">
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<q-header
|
<q-header
|
||||||
class="bg-white/80 dark:!bg-[#0f172a]/80 backdrop-blur-md text-slate-900 dark:!text-white"
|
class="bg-white/80 dark:!bg-[#0f172a]/80 backdrop-blur-md text-slate-900 dark:!text-white border-none shadow-none"
|
||||||
>
|
>
|
||||||
<AppHeader @toggleSidebar="toggleLeftDrawer" :showSidebarToggle="!shouldHideSidebar" />
|
<AppHeader
|
||||||
|
@toggleSidebar="toggleLeftDrawer"
|
||||||
|
@toggleRightDrawer="toggleRightDrawer"
|
||||||
|
:showSidebarToggle="!shouldHideSidebar"
|
||||||
|
/>
|
||||||
</q-header>
|
</q-header>
|
||||||
|
|
||||||
<!-- Sidebar (Drawer) -->
|
<!-- Sidebar (Drawer - Desktop Left) -->
|
||||||
<q-drawer
|
<q-drawer
|
||||||
v-if="!shouldHideSidebar"
|
v-if="!shouldHideSidebar"
|
||||||
v-model="leftDrawerOpen"
|
v-model="leftDrawerOpen"
|
||||||
|
|
@ -41,6 +53,115 @@ const shouldHideSidebar = computed(() => {
|
||||||
<AppSidebar />
|
<AppSidebar />
|
||||||
</q-drawer>
|
</q-drawer>
|
||||||
|
|
||||||
|
<!-- Master Mobile Drawer (The Everything Hub) -->
|
||||||
|
<q-drawer
|
||||||
|
v-model="rightDrawerOpen"
|
||||||
|
side="right"
|
||||||
|
overlay
|
||||||
|
bordered
|
||||||
|
class="bg-white dark:!bg-[#0f172a]"
|
||||||
|
:width="300"
|
||||||
|
>
|
||||||
|
<div class="flex flex-col h-full bg-white dark:bg-[#0f172a]">
|
||||||
|
<!-- 1. Account Section -->
|
||||||
|
<div class="p-6 bg-slate-50/50 dark:bg-slate-800/30 border-b border-slate-100 dark:border-slate-800">
|
||||||
|
<div class="flex items-center justify-between mb-8">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<div class="w-8 h-8 rounded-lg bg-blue-600 flex items-center justify-center text-white font-black">E</div>
|
||||||
|
<span class="font-black text-lg text-slate-900 dark:text-white">E-Learning</span>
|
||||||
|
</div>
|
||||||
|
<q-btn flat round dense icon="close" class="text-slate-400" @click="rightDrawerOpen = false" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center gap-4 py-2">
|
||||||
|
<q-avatar size="64px" class="shadow-lg border-2 border-white dark:border-slate-700">
|
||||||
|
<img :src="currentUser?.photoURL || 'https://cdn.quasar.dev/img/avatar.png'" />
|
||||||
|
</q-avatar>
|
||||||
|
<div class="overflow-hidden">
|
||||||
|
<p class="font-bold text-slate-900 dark:text-white mb-0 truncate text-lg">
|
||||||
|
{{ currentUser?.firstName || 'Guest' }} {{ currentUser?.lastName || '' }}
|
||||||
|
</p>
|
||||||
|
<p class="text-xs text-slate-500 dark:text-slate-400 truncate">{{ currentUser?.email || 'e-learning@platform.com' }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 2. Integrated Content Hub -->
|
||||||
|
<div class="flex-grow overflow-y-auto pt-4">
|
||||||
|
<q-list padding class="text-slate-600 dark:text-slate-300">
|
||||||
|
<!-- Navigation -->
|
||||||
|
<q-item-label header class="text-[11px] font-black tracking-[0.2em] text-slate-400 uppercase px-6 pb-2">เมนูหลัก</q-item-label>
|
||||||
|
|
||||||
|
<q-item to="/dashboard" clickable v-ripple class="px-6 py-4" active-class="bg-blue-50 text-blue-600 dark:bg-blue-900/20 dark:text-blue-400 font-bold" @click="rightDrawerOpen = false">
|
||||||
|
<q-item-section avatar><q-icon name="dashboard" size="24px" /></q-item-section>
|
||||||
|
<q-item-section><span class="text-[15px] font-bold">{{ $t("sidebar.overview") }}</span></q-item-section>
|
||||||
|
</q-item>
|
||||||
|
|
||||||
|
<q-item to="/browse/discovery" clickable v-ripple class="px-6 py-4" active-class="bg-blue-50 text-blue-600 dark:bg-blue-900/20 dark:text-blue-400 font-bold" @click="rightDrawerOpen = false">
|
||||||
|
<q-item-section avatar><q-icon name="explore" size="24px" /></q-item-section>
|
||||||
|
<q-item-section><span class="text-[15px] font-bold">{{ $t("landing.allCourses") }}</span></q-item-section>
|
||||||
|
</q-item>
|
||||||
|
|
||||||
|
<q-item to="/dashboard/my-courses" clickable v-ripple class="px-6 py-4" active-class="bg-blue-50 text-blue-600 dark:bg-blue-900/20 dark:text-blue-400 font-bold" @click="rightDrawerOpen = false">
|
||||||
|
<q-item-section avatar><q-icon name="school" size="24px" /></q-item-section>
|
||||||
|
<q-item-section><span class="text-[15px] font-bold">{{ $t("sidebar.myCourses") || 'คอร์สเรียนของฉัน' }}</span></q-item-section>
|
||||||
|
</q-item>
|
||||||
|
|
||||||
|
<q-separator class="my-4 mx-6 opacity-50" />
|
||||||
|
|
||||||
|
<!-- Tools & Settings -->
|
||||||
|
<q-item-label header class="text-[11px] font-black tracking-[0.2em] text-slate-400 uppercase px-6 pb-2">เครื่องมือและการตั้งค่า</q-item-label>
|
||||||
|
|
||||||
|
<!-- Language Selection -->
|
||||||
|
<q-item class="px-6 py-2">
|
||||||
|
<q-item-section avatar><q-icon name="language" size="22px" /></q-item-section>
|
||||||
|
<q-item-section>
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<span class="font-bold text-[14px]">ภาษา</span>
|
||||||
|
<LanguageSwitcher dense />
|
||||||
|
</div>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
|
||||||
|
<!-- Dark Mode Toggle -->
|
||||||
|
<q-item class="px-6 py-2">
|
||||||
|
<q-item-section avatar><q-icon :name="isDark ? 'dark_mode' : 'light_mode'" size="22px" /></q-item-section>
|
||||||
|
<q-item-section>
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<span class="font-bold text-[14px]">โหมดกลางคืน</span>
|
||||||
|
<q-toggle
|
||||||
|
:model-value="isDark"
|
||||||
|
@update:model-value="setTheme"
|
||||||
|
color="blue"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
|
||||||
|
<q-item clickable v-ripple @click="navigateTo('/dashboard/profile'); rightDrawerOpen = false" class="px-6 py-4">
|
||||||
|
<q-item-section avatar><q-icon name="person_outline" size="24px" /></q-item-section>
|
||||||
|
<q-item-section><span class="font-bold text-[15px]">จัดการโปรไฟล์</span></q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</q-list>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 3. Bottom Actions -->
|
||||||
|
<div class="p-6 mt-auto border-t border-slate-100 dark:border-slate-800">
|
||||||
|
<q-btn
|
||||||
|
unelevated
|
||||||
|
class="full-width rounded-xl bg-red-50 text-red-600 dark:bg-red-900/20 dark:text-red-400 font-bold py-3 no-caps transition-all active:scale-95"
|
||||||
|
@click="logout"
|
||||||
|
>
|
||||||
|
<q-icon name="logout" size="20px" class="mr-2" />
|
||||||
|
ออกจากระบบ
|
||||||
|
</q-btn>
|
||||||
|
<div class="text-center mt-6">
|
||||||
|
<span class="text-[10px] font-bold uppercase tracking-[0.2em] text-slate-300 dark:text-slate-600">E-Learning Platform v1.0</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</q-drawer>
|
||||||
|
|
||||||
<!-- Main Content -->
|
<!-- Main Content -->
|
||||||
<q-page-container>
|
<q-page-container>
|
||||||
<q-page class="relative">
|
<q-page class="relative">
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ export default defineNuxtConfig({
|
||||||
{ name: "viewport", content: "width=device-width, initial-scale=1" },
|
{ name: "viewport", content: "width=device-width, initial-scale=1" },
|
||||||
],
|
],
|
||||||
link: [
|
link: [
|
||||||
|
{ rel: 'icon', type: 'image/png', href: '/img/logo.png' },
|
||||||
{
|
{
|
||||||
rel: "stylesheet",
|
rel: "stylesheet",
|
||||||
// โหลด Font: Inter, Prompt, Sarabun
|
// โหลด Font: Inter, Prompt, Sarabun
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,7 @@ const loadCourses = async (page = 1) => {
|
||||||
|
|
||||||
const res = await fetchCourses({
|
const res = await fetchCourses({
|
||||||
category_id: categoryId,
|
category_id: categoryId,
|
||||||
|
search: searchQuery.value,
|
||||||
page: page,
|
page: page,
|
||||||
limit: itemsPerPage,
|
limit: itemsPerPage,
|
||||||
forceRefresh: true,
|
forceRefresh: true,
|
||||||
|
|
@ -155,31 +156,56 @@ onMounted(() => {
|
||||||
<!-- CATALOG VIEW: Browse courses -->
|
<!-- CATALOG VIEW: Browse courses -->
|
||||||
<div v-if="!showDetail">
|
<div v-if="!showDetail">
|
||||||
<!-- Top Header Area -->
|
<!-- Top Header Area -->
|
||||||
<div class="flex flex-col gap-6 mb-10">
|
<!-- New Enhanced Search Section (Image 1 Style) -->
|
||||||
<div class="flex items-start gap-4 mb-4">
|
<div class="bg-blue-50/50 dark:bg-blue-900/10 rounded-[2.5rem] p-8 md:p-10 mb-8 border border-blue-100/50 dark:border-blue-500/10 transition-colors duration-300">
|
||||||
<span
|
<div class="flex items-center gap-4 mb-2">
|
||||||
class="w-1.5 h-10 md:h-12 bg-blue-600 rounded-full shadow-lg shadow-blue-500/50 mt-1 flex-shrink-0"
|
<span class="w-2 h-8 bg-blue-600 rounded-full shadow-lg shadow-blue-500/30"></span>
|
||||||
></span>
|
<h1 class="text-2xl md:text-3xl font-black text-slate-900 dark:text-white">
|
||||||
<div>
|
{{ $t("discovery.title") }}
|
||||||
<h1
|
</h1>
|
||||||
class="text-3xl md:text-4xl font-black text-slate-900 dark:text-white leading-tight"
|
|
||||||
>
|
|
||||||
{{ $t("discovery.title") }}
|
|
||||||
</h1>
|
|
||||||
<p
|
|
||||||
v-if="filteredCourses.length > 0"
|
|
||||||
class="text-slate-500 dark:text-slate-400 mt-1 font-medium"
|
|
||||||
>
|
|
||||||
{{ $t("discovery.foundTotal") }}
|
|
||||||
<span class="text-blue-600 font-bold leading-none">{{
|
|
||||||
filteredCourses.length
|
|
||||||
}}</span>
|
|
||||||
{{ $t("discovery.items") }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<p class="text-slate-500 dark:text-slate-400 font-medium mb-8">
|
||||||
|
{{ $t("discovery.subtitle") }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="flex flex-col md:flex-row gap-4">
|
||||||
|
<!-- Search Input -->
|
||||||
|
<div class="relative flex-1 group">
|
||||||
|
<div class="absolute left-5 top-1/2 -translate-y-1/2 text-slate-400 group-focus-within:text-blue-600 transition-colors">
|
||||||
|
<q-icon name="search" size="24px" />
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
v-model="searchQuery"
|
||||||
|
type="text"
|
||||||
|
:placeholder="$t('discovery.searchPlaceholder') || 'ค้นหาคอร์สที่น่าสนใจที่นี่...'"
|
||||||
|
class="w-full pl-14 pr-6 py-3.5 bg-white dark:bg-slate-800 border-2 border-transparent rounded-2xl text-slate-900 dark:text-white placeholder-slate-400 focus:outline-none focus:border-blue-500/20 focus:ring-4 focus:ring-blue-500/5 transition-all text-base font-medium shadow-sm"
|
||||||
|
@keyup.enter="loadCourses(1)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Search Button -->
|
||||||
|
<q-btn
|
||||||
|
unelevated
|
||||||
|
color="primary"
|
||||||
|
class="px-8 h-[52px] rounded-2xl font-black shadow-lg shadow-blue-600/20 hover:scale-[1.02] transition-transform"
|
||||||
|
no-caps
|
||||||
|
@click="loadCourses(1)"
|
||||||
|
>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<q-icon name="search" size="20px" />
|
||||||
|
<span class="text-base">ค้นหา</span>
|
||||||
|
</div>
|
||||||
|
</q-btn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Unified Filter Section: Categories -->
|
<div class="flex items-center justify-between mb-4 px-2">
|
||||||
|
<div class="text-slate-500 dark:text-slate-400 text-sm font-bold uppercase tracking-wider">
|
||||||
|
{{ $t("discovery.foundTotal") }} <span class="text-blue-600">{{ filteredCourses.length }}</span> {{ $t("discovery.items") }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Unified Filter Section: Categories -->
|
||||||
<div
|
<div
|
||||||
class="bg-white dark:bg-slate-900/50 p-2 rounded-2xl border border-slate-100 dark:border-white/5 inline-flex flex-wrap items-center gap-1.5 shadow-sm"
|
class="bg-white dark:bg-slate-900/50 p-2 rounded-2xl border border-slate-100 dark:border-white/5 inline-flex flex-wrap items-center gap-1.5 shadow-sm"
|
||||||
>
|
>
|
||||||
|
|
@ -212,7 +238,6 @@ onMounted(() => {
|
||||||
:label="getLocalizedText(cat.name)"
|
:label="getLocalizedText(cat.name)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Main Layout: Grid Only -->
|
<!-- Main Layout: Grid Only -->
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ const filteredCourses = computed(() => {
|
||||||
|
|
||||||
<!-- Main Title -->
|
<!-- Main Title -->
|
||||||
<h1 class="text-4xl md:text-6xl font-black text-slate-900 mb-6 tracking-tight py-2 slide-up leading-[1.2] overflow-visible" style="animation-delay: 0.1s;">
|
<h1 class="text-4xl md:text-6xl font-black text-slate-900 mb-6 tracking-tight py-2 slide-up leading-[1.2] overflow-visible" style="animation-delay: 0.1s;">
|
||||||
คอร์สเรียนออนไลน์<span class="text-gradient-cyan">ทั้งหมด</span>
|
คอร์สเรียน<span class="text-gradient-cyan">ทั้งหมด</span>
|
||||||
</h1>
|
</h1>
|
||||||
<!-- Subtitle -->
|
<!-- Subtitle -->
|
||||||
<p class="text-slate-400 text-xl max-w-2xl mx-auto leading-relaxed slide-up" style="animation-delay: 0.2s;">
|
<p class="text-slate-400 text-xl max-w-2xl mx-auto leading-relaxed slide-up" style="animation-delay: 0.2s;">
|
||||||
|
|
@ -163,30 +163,42 @@ const filteredCourses = computed(() => {
|
||||||
<!-- Content Frame Container -->
|
<!-- Content Frame Container -->
|
||||||
<div class="glass-premium rounded-[3rem] p-8 md:p-12 shadow-xl shadow-blue-900/5">
|
<div class="glass-premium rounded-[3rem] p-8 md:p-12 shadow-xl shadow-blue-900/5">
|
||||||
|
|
||||||
<div class="flex flex-col md:flex-row md:items-center justify-between gap-8 mb-8">
|
<!-- New Enhanced Search Section (Image 2 Style) -->
|
||||||
<h2 class="text-2xl font-black text-slate-900 flex items-center gap-3">
|
<div class="bg-blue-50/50 rounded-[2.5rem] p-8 md:p-10 mb-6 border border-blue-100/50">
|
||||||
<span class="w-2 h-8 bg-blue-600 rounded-full"/>
|
<h2 class="text-2xl md:text-3xl font-black text-slate-900 mb-2">คอร์สเรียนทั้งหมด</h2>
|
||||||
รายการคอร์สเรียน
|
<p class="text-slate-500 font-medium mb-8">พัฒนาทักษะใหม่ๆ กับผู้เชี่ยวชาญจากทั่วโลก</p>
|
||||||
</h2>
|
|
||||||
|
<div class="flex flex-col md:flex-row gap-4">
|
||||||
<!-- Search Bar (Compact) -->
|
<!-- Search Input -->
|
||||||
<div class="relative max-w-md w-full">
|
<div class="relative flex-1 group">
|
||||||
<div class="relative group">
|
<div class="absolute left-5 top-1/2 -translate-y-1/2 text-slate-400 group-focus-within:text-blue-600 transition-colors">
|
||||||
<input
|
<q-icon name="search" size="24px" />
|
||||||
v-model="searchQuery"
|
|
||||||
type="text"
|
|
||||||
class="w-full pl-12 pr-6 py-3 bg-slate-100 border border-slate-200 rounded-xl text-slate-900 placeholder-slate-400 focus:outline-none focus:bg-white focus: focus:ring-2 focus:ring-blue-500/50 transition-all font-medium"
|
|
||||||
placeholder="ค้นหาบทเรียน..."
|
|
||||||
>
|
|
||||||
<div class="absolute left-4 top-1/2 -translate-y-1/2 text-slate-400">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
|
<input
|
||||||
|
v-model="searchQuery"
|
||||||
|
type="text"
|
||||||
|
placeholder="ค้นหาชื่อคอร์ส..."
|
||||||
|
class="w-full pl-14 pr-6 py-4 bg-white border-2 border-transparent rounded-2xl text-slate-900 placeholder-slate-400 focus:outline-none focus:border-blue-500/20 focus:ring-4 focus:ring-blue-500/5 transition-all text-lg font-medium shadow-sm"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Search Button -->
|
||||||
|
<q-btn
|
||||||
|
unelevated
|
||||||
|
color="primary"
|
||||||
|
class="px-4 h-16 rounded-2xl font-black shadow-lg shadow-blue-600/20 hover:scale-[1.02] transition-transform"
|
||||||
|
no-caps
|
||||||
|
>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<q-icon name="search" size="20px" />
|
||||||
|
<span class="text-base">ค้นหา</span>
|
||||||
|
</div>
|
||||||
|
</q-btn>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Category Filter Tabs with Scroll Buttons -->
|
<!-- Category Filter Tabs with Scroll Buttons -->
|
||||||
<div class="relative mb-8">
|
<div class="relative mb-8">
|
||||||
<!-- Left Scroll Button -->
|
<!-- Left Scroll Button -->
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ const filteredCourses = computed(() => {
|
||||||
<!-- Tagline Badge -->
|
<!-- Tagline Badge -->
|
||||||
<!-- Main Title -->
|
<!-- Main Title -->
|
||||||
<h1 class="text-4xl md:text-6xl font-black text-slate-900 mb-6 tracking-tight py-2 slide-up leading-[1.2] overflow-visible" style="animation-delay: 0.1s;">
|
<h1 class="text-4xl md:text-6xl font-black text-slate-900 mb-6 tracking-tight py-2 slide-up leading-[1.2] overflow-visible" style="animation-delay: 0.1s;">
|
||||||
คอร์สเรียนออนไลน์<span class="text-gradient-cyan">แนะนำ</span>
|
คอร์สเรียน<span class="text-gradient-cyan">แนะนำ</span>
|
||||||
</h1>
|
</h1>
|
||||||
<!-- Subtitle -->
|
<!-- Subtitle -->
|
||||||
<p class="text-slate-400 text-xl max-w-2xl mx-auto leading-relaxed slide-up" style="animation-delay: 0.2s;">
|
<p class="text-slate-400 text-xl max-w-2xl mx-auto leading-relaxed slide-up" style="animation-delay: 0.2s;">
|
||||||
|
|
@ -130,27 +130,37 @@ const filteredCourses = computed(() => {
|
||||||
<!-- Content Frame Container -->
|
<!-- Content Frame Container -->
|
||||||
<div class="glass-premium rounded-[3rem] p-8 md:p-12 shadow-xl shadow-blue-900/5">
|
<div class="glass-premium rounded-[3rem] p-8 md:p-12 shadow-xl shadow-blue-900/5">
|
||||||
|
|
||||||
<div class="flex flex-col md:flex-row md:items-center justify-between gap-8 mb-8">
|
<!-- New Enhanced Search Section (Image 2 Style) -->
|
||||||
<h2 class="text-2xl font-black text-slate-900 flex items-center gap-3">
|
<div class="bg-blue-50/50 rounded-[2.5rem] p-8 md:p-10 mb-6 border border-blue-100/50">
|
||||||
<span class="w-2 h-8 bg-blue-600 rounded-full"/>
|
<h2 class="text-2xl md:text-3xl font-black text-slate-900 mb-2">คอร์สเรียนแนะนำ</h2>
|
||||||
คอร์สที่คุณห้ามพลาด
|
<p class="text-slate-500 font-medium mb-8">คัดสรรเนื้อหาคุณภาพสูงที่คุณไม่ควรพลาด</p>
|
||||||
</h2>
|
|
||||||
|
<div class="flex flex-col md:flex-row gap-4">
|
||||||
<!-- Search Bar (Compact) -->
|
<!-- Search Input -->
|
||||||
<div class="relative max-w-md w-full">
|
<div class="relative flex-1 group">
|
||||||
<div class="relative group">
|
<div class="absolute left-5 top-1/2 -translate-y-1/2 text-slate-400 group-focus-within:text-blue-600 transition-colors">
|
||||||
<input
|
<q-icon name="search" size="24px" />
|
||||||
v-model="searchQuery"
|
|
||||||
type="text"
|
|
||||||
class="w-full pl-12 pr-6 py-3 bg-slate-100 border border-slate-200 rounded-xl text-slate-900 placeholder-slate-400 focus:outline-none focus:bg-white focus: focus:ring-2 focus:ring-blue-500/50 transition-all font-medium"
|
|
||||||
placeholder="ค้นหาคอร์สแนะนำ..."
|
|
||||||
>
|
|
||||||
<div class="absolute left-4 top-1/2 -translate-y-1/2 text-slate-400">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
|
<input
|
||||||
|
v-model="searchQuery"
|
||||||
|
type="text"
|
||||||
|
placeholder="ค้นหาชื่อคอร์สแนะนำ..."
|
||||||
|
class="w-full pl-14 pr-6 py-4 bg-white border-2 border-transparent rounded-2xl text-slate-900 placeholder-slate-400 focus:outline-none focus:border-blue-500/20 focus:ring-4 focus:ring-blue-500/5 transition-all text-lg font-medium shadow-sm"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Search Button -->
|
||||||
|
<q-btn
|
||||||
|
unelevated
|
||||||
|
color="primary"
|
||||||
|
class="px-4 h-16 rounded-2xl font-black shadow-lg shadow-blue-600/20 hover:scale-[1.02] transition-transform"
|
||||||
|
no-caps
|
||||||
|
>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<q-icon name="search" size="20px" />
|
||||||
|
<span class="text-base">ค้นหา</span>
|
||||||
|
</div>
|
||||||
|
</q-btn>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -171,11 +171,11 @@ const sideCourses = computed(() => enrolledCourses.value.slice(1, 3));
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 items-start">
|
||||||
<!-- Hero Card (Left) -->
|
<!-- Hero Card (Left) -->
|
||||||
<div
|
<div
|
||||||
v-if="heroCourse"
|
v-if="heroCourse"
|
||||||
class="relative group cursor-pointer rounded-2xl overflow-hidden bg-white dark:bg-[#1e293b] shadow-sm border border-gray-100 dark:border-slate-700 hover:shadow-md transition-all h-[320px]"
|
class="relative group cursor-pointer rounded-2xl overflow-hidden bg-white dark:bg-[#1e293b] shadow-sm border border-gray-100 dark:border-slate-700 hover:shadow-md transition-all h-[260px] md:h-[320px]"
|
||||||
@click="
|
@click="
|
||||||
navigateTo(`/classroom/learning?course_id=${heroCourse.id}`)
|
navigateTo(`/classroom/learning?course_id=${heroCourse.id}`)
|
||||||
"
|
"
|
||||||
|
|
@ -233,7 +233,7 @@ const sideCourses = computed(() => enrolledCourses.value.slice(1, 3));
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Side List (Right) -->
|
<!-- Side List (Right) -->
|
||||||
<div class="flex flex-col gap-4 h-[320px]">
|
<div class="flex flex-col gap-4">
|
||||||
<div
|
<div
|
||||||
v-for="course in sideCourses"
|
v-for="course in sideCourses"
|
||||||
:key="course.id"
|
:key="course.id"
|
||||||
|
|
@ -313,7 +313,7 @@ const sideCourses = computed(() => enrolledCourses.value.slice(1, 3));
|
||||||
<!-- Content when courses exist -->
|
<!-- Content when courses exist -->
|
||||||
<div
|
<div
|
||||||
v-if="libraryCourses.length > 0"
|
v-if="libraryCourses.length > 0"
|
||||||
class="grid grid-cols-1 md:grid-cols-3 gap-6"
|
class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6"
|
||||||
>
|
>
|
||||||
<!-- Course Cards -->
|
<!-- Course Cards -->
|
||||||
<CourseCard
|
<CourseCard
|
||||||
|
|
@ -382,7 +382,7 @@ const sideCourses = computed(() => enrolledCourses.value.slice(1, 3));
|
||||||
|
|
||||||
<!-- Recommended Grid (3 columns) -->
|
<!-- Recommended Grid (3 columns) -->
|
||||||
<div
|
<div
|
||||||
class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 animate-fade-in"
|
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6 animate-fade-in"
|
||||||
>
|
>
|
||||||
<CourseCard
|
<CourseCard
|
||||||
v-for="course in recommendedCourses"
|
v-for="course in recommendedCourses"
|
||||||
|
|
|
||||||
|
|
@ -151,48 +151,54 @@ const validCourseId = computed(() => {
|
||||||
|
|
||||||
|
|
||||||
<!-- Page Header & Filters (Unified Layout) -->
|
<!-- Page Header & Filters (Unified Layout) -->
|
||||||
<div class="mb-8">
|
<!-- New Enhanced Search Section (Image 2 Style) -->
|
||||||
<div class="flex items-start gap-4 mb-2">
|
<div class="bg-blue-50/50 dark:bg-blue-900/10 rounded-[2.5rem] p-8 md:p-10 mb-6 border border-blue-100/50 dark:border-blue-500/10">
|
||||||
<span class="w-1.5 h-10 md:h-12 bg-blue-600 rounded-full shadow-lg shadow-blue-500/50 mt-1 flex-shrink-0"></span>
|
<h2 class="text-2xl md:text-3xl font-black text-slate-900 dark:text-white mb-2">คอร์สของฉัน</h2>
|
||||||
<div>
|
<p class="text-slate-500 dark:text-slate-400 font-medium mb-8">ติดตามความคืบหน้าและเรียนรู้ต่อจากจุดที่ค้างไว้</p>
|
||||||
<h1 class="text-3xl md:text-4xl font-black text-slate-900 dark:text-white leading-tight">
|
|
||||||
{{ $t('sidebar.myCourses') }}
|
<div class="flex flex-col md:flex-row gap-4">
|
||||||
</h1>
|
<!-- Search Input -->
|
||||||
|
<div class="relative flex-1 group">
|
||||||
|
<div class="absolute left-5 top-1/2 -translate-y-1/2 text-slate-400 group-focus-within:text-blue-600 transition-colors">
|
||||||
|
<q-icon name="search" size="24px" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<input
|
||||||
|
v-model="searchQuery"
|
||||||
|
type="text"
|
||||||
|
placeholder="ค้นหาชื่อคอร์สของฉัน..."
|
||||||
|
class="w-full pl-14 pr-6 py-3.5 bg-white dark:bg-slate-800 border-2 border-transparent rounded-2xl text-slate-900 dark:text-white placeholder-slate-400 focus:outline-none focus:border-blue-500/20 focus:ring-4 focus:ring-blue-500/5 transition-all text-base font-medium shadow-sm"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Search Button -->
|
||||||
|
<q-btn
|
||||||
|
unelevated
|
||||||
|
color="primary"
|
||||||
|
class="px-8 h-[52px] rounded-2xl font-black shadow-lg shadow-blue-600/20 hover:scale-[1.02] transition-transform"
|
||||||
|
no-caps
|
||||||
|
>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<q-icon name="search" size="20px" />
|
||||||
|
<span class="text-base">ค้นหา</span>
|
||||||
|
</div>
|
||||||
|
</q-btn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col md:flex-row md:items-center justify-between gap-4 mt-4">
|
<div class="flex flex-col md:flex-row md:items-center justify-between gap-4 mb-8">
|
||||||
<!-- Filter Tabs (Horizontal Bar) -->
|
<!-- Filter Tabs (Horizontal Bar) -->
|
||||||
<div class="bg-white dark:bg-slate-900/50 p-1.5 rounded-2xl border border-slate-100 dark:border-white/5 inline-flex items-center gap-1 shadow-sm">
|
<div class="bg-white dark:bg-slate-900/50 p-1.5 rounded-2xl border border-slate-100 dark:border-white/5 inline-flex items-center gap-1 shadow-sm">
|
||||||
<q-btn
|
<q-btn
|
||||||
v-for="filter in ['all', 'progress', 'completed']"
|
v-for="filter in ['all', 'progress', 'completed']"
|
||||||
:key="filter"
|
:key="filter"
|
||||||
@click="activeFilter = filter as any"
|
@click="activeFilter = filter as any"
|
||||||
flat
|
flat
|
||||||
rounded
|
rounded
|
||||||
dense
|
dense
|
||||||
class="px-5 py-2 font-bold transition-all text-[11px] uppercase tracking-wider"
|
class="px-5 py-2 font-bold transition-all text-[11px] uppercase tracking-wider"
|
||||||
:class="activeFilter === filter ? 'bg-blue-600 text-white shadow-md shadow-blue-600/20' : 'text-slate-600 dark:text-slate-400 hover:bg-slate-50 dark:hover:bg-slate-800'"
|
:class="activeFilter === filter ? 'bg-blue-600 text-white shadow-md shadow-blue-600/20' : 'text-slate-600 dark:text-slate-400 hover:bg-slate-50 dark:hover:bg-slate-800'"
|
||||||
:label="$t(`myCourses.filter${filter.charAt(0).toUpperCase() + filter.slice(1)}`)"
|
:label="$t(`myCourses.filter${filter.charAt(0).toUpperCase() + filter.slice(1)}`)"
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Search Input -->
|
|
||||||
<div class="w-full md:w-72">
|
|
||||||
<q-input
|
|
||||||
v-model="searchQuery"
|
|
||||||
dense
|
|
||||||
outlined
|
|
||||||
rounded
|
|
||||||
:placeholder="$t('discovery.searchPlaceholder')"
|
|
||||||
class="search-input shadow-sm"
|
|
||||||
bg-color="transparent"
|
|
||||||
>
|
|
||||||
<template v-slot:prepend>
|
|
||||||
<q-icon name="search" class="text-slate-400" />
|
|
||||||
</template>
|
|
||||||
</q-input>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
BIN
Frontend-Learner/public/img/logo.png
Normal file
BIN
Frontend-Learner/public/img/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 246 KiB |
Loading…
Add table
Add a link
Reference in a new issue