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,7 +8,12 @@
|
|||
// Initialize global theme management
|
||||
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>
|
||||
|
||||
<template>
|
||||
|
|
@ -17,9 +22,122 @@ useThemeMode()
|
|||
<q-header
|
||||
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>
|
||||
|
||||
<!-- 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 -->
|
||||
|
||||
<!-- Main Content -->
|
||||
|
|
|
|||
|
|
@ -8,11 +8,19 @@
|
|||
// Initialize global theme management
|
||||
useThemeMode()
|
||||
|
||||
const { currentUser, logout } = useAuth()
|
||||
const { isDark, set: setTheme } = useThemeMode()
|
||||
const leftDrawerOpen = ref(false)
|
||||
const rightDrawerOpen = ref(false)
|
||||
|
||||
const toggleLeftDrawer = () => {
|
||||
leftDrawerOpen.value = !leftDrawerOpen.value
|
||||
}
|
||||
|
||||
const toggleRightDrawer = () => {
|
||||
rightDrawerOpen.value = !rightDrawerOpen.value
|
||||
}
|
||||
|
||||
const route = useRoute()
|
||||
// Automatically hide sidebar for learner routes
|
||||
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">
|
||||
<!-- 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>
|
||||
|
||||
<!-- Sidebar (Drawer) -->
|
||||
<!-- Sidebar (Drawer - Desktop Left) -->
|
||||
<q-drawer
|
||||
v-if="!shouldHideSidebar"
|
||||
v-model="leftDrawerOpen"
|
||||
|
|
@ -41,6 +53,115 @@ const shouldHideSidebar = computed(() => {
|
|||
<AppSidebar />
|
||||
</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 -->
|
||||
<q-page-container>
|
||||
<q-page class="relative">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue