feat: Implement initial e-learning platform frontend including landing page, course discovery, dashboard, and foundational UI components with i18n.
This commit is contained in:
parent
5b9cf72046
commit
3a9da1007b
17 changed files with 1631 additions and 1524 deletions
|
|
@ -1,178 +1,65 @@
|
|||
<script setup lang="ts">
|
||||
/**
|
||||
* @file default.vue
|
||||
* @description Layout หลักสำหรับหน้าเว็บของผู้ใช้ (Authenticated Users)
|
||||
* Uses Quasar QLayout for responsive structure.
|
||||
* @description Master layout for the EduLearn platform.
|
||||
*/
|
||||
|
||||
// Initialize global theme management
|
||||
useThemeMode()
|
||||
|
||||
const { currentUser, logout } = useAuth()
|
||||
const { isDark, set: setTheme } = useThemeMode()
|
||||
const leftDrawerOpen = ref(false)
|
||||
const rightDrawerOpen = ref(false)
|
||||
const leftDrawerOpen = ref(true)
|
||||
|
||||
const toggleLeftDrawer = () => {
|
||||
leftDrawerOpen.value = !leftDrawerOpen.value
|
||||
}
|
||||
|
||||
const toggleRightDrawer = () => {
|
||||
rightDrawerOpen.value = !rightDrawerOpen.value
|
||||
}
|
||||
|
||||
const route = useRoute()
|
||||
// Automatically hide sidebar for learner routes
|
||||
const shouldHideSidebar = computed(() => {
|
||||
const silentRoutes = ['/dashboard', '/browse', '/classroom', '/course']
|
||||
return silentRoutes.some(r => route.path.startsWith(r))
|
||||
// Show sidebar for these routes
|
||||
const isDashboardRoute = computed(() => {
|
||||
const routes = ['/dashboard', '/browse', '/classroom', '/course']
|
||||
return routes.some(r => route.path.startsWith(r))
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-layout view="hHh LpR lFf" class="bg-slate-50 dark:!bg-[#020617] text-slate-900 dark:!text-slate-50">
|
||||
<q-layout view="lHh Lpr lFf" class="bg-[#F8FAFC] 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 border-none shadow-none"
|
||||
class="bg-transparent text-slate-900 dark:!text-white border-none shadow-none"
|
||||
>
|
||||
<AppHeader
|
||||
@toggleSidebar="toggleLeftDrawer"
|
||||
@toggleRightDrawer="toggleRightDrawer"
|
||||
:showSidebarToggle="!shouldHideSidebar"
|
||||
/>
|
||||
<AppHeader @toggleSidebar="toggleLeftDrawer" />
|
||||
</q-header>
|
||||
|
||||
<!-- Sidebar (Drawer - Desktop Left) -->
|
||||
<!-- Navigation Sidebar -->
|
||||
<q-drawer
|
||||
v-if="!shouldHideSidebar"
|
||||
v-model="leftDrawerOpen"
|
||||
show-if-above
|
||||
:width="280"
|
||||
class="bg-white dark:!bg-[#0f172a]"
|
||||
side="left"
|
||||
bordered
|
||||
class="bg-white dark:!bg-[#0f172a] border-none"
|
||||
>
|
||||
<AppSidebar />
|
||||
</q-drawer>
|
||||
|
||||
<!-- Master Mobile Drawer (The Everything Hub) -->
|
||||
<q-drawer
|
||||
v-model="rightDrawerOpen"
|
||||
side="right"
|
||||
overlay
|
||||
class="bg-white dark:!bg-[#0f172a]"
|
||||
:width="300"
|
||||
>
|
||||
<div class="flex flex-col h-full bg-white dark:!bg-[#0f172a] text-slate-900 dark:!text-slate-100">
|
||||
<!-- 1. Account Section -->
|
||||
<div class="p-6 bg-slate-50/50 dark:!bg-slate-800/20">
|
||||
<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/30 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/30 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/30 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>
|
||||
|
||||
<!-- Tools & Settings -->
|
||||
<q-item-label header class="text-[11px] font-black tracking-[0.2em] text-slate-400 uppercase px-6 pb-2 mt-4">เครื่องมือและการตั้งค่า</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] dark:!text-slate-300">จัดการโปรไฟล์</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-white/10">
|
||||
<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 Area -->
|
||||
<q-page-container>
|
||||
<q-page class="relative">
|
||||
<slot />
|
||||
<q-page class="px-3 py-6 md:p-8">
|
||||
<div class="max-w-[1600px] mx-auto">
|
||||
<slot />
|
||||
</div>
|
||||
</q-page>
|
||||
</q-page-container>
|
||||
|
||||
|
||||
</q-layout>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
/* Ensure fonts are applied */
|
||||
.font-inter {
|
||||
font-family: var(--font-main);
|
||||
/* Global Layout Adjustments */
|
||||
.q-drawer--bordered {
|
||||
border-right: 1px solid rgba(0,0,0,0.05) !important;
|
||||
}
|
||||
.dark .q-drawer--bordered {
|
||||
border-right: 1px solid rgba(255,255,255,0.05) !important;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue