# 🛠ïļ Web Development Documentation: e-Learning Platform (Frontend) āđ€āļ­āļāļŠāļēāļĢāļ‰āļšāļąāļšāļ™āļĩāđ‰āļŠāļĢāļļāļ›āļĢāļēāļĒāļĨāļ°āđ€āļ­āļĩāļĒāļ”āļ—āļēāļ‡āđ€āļ—āļ„āļ™āļīāļ„ āđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡āđ‚āļ„āđ‰āļ” āđāļĨāļ°āļāļēāļĢāļ—āļģāļ‡āļēāļ™āļ‚āļ­āļ‡āļĢāļ°āļšāļš **Frontend-Learner** (āļ­āļąāļ›āđ€āļ”āļ•āļĨāđˆāļēāļŠāļļāļ”) --- ## 🏗ïļ 1. Technical Foundation (āļĢāļēāļāļāļēāļ™āļ—āļēāļ‡āđ€āļ—āļ„āļ™āļīāļ„) āļĢāļ§āļĄāļ‚āđ‰āļ­āļĄāļđāļĨāđ€āļ„āļĢāļ·āđˆāļ­āļ‡āļĄāļ·āļ­, āļĢāļ°āļšāļšāļ„āļ§āļēāļĄāļ›āļĨāļ­āļ”āļ āļąāļĒ āđāļĨāļ°āļ›āļĢāļ°āļŠāļīāļ—āļ˜āļīāļ āļēāļžāļāļēāļĢāļ—āļģāļ‡āļēāļ™āđ„āļ§āđ‰āļ”āđ‰āļ§āļĒāļāļąāļ™ ### 1.1 Tech Stack - **Core:** [Nuxt 3](https://nuxt.com) (Vue 3 Composition API), TypeScript `^5.0` - **UI Framework:** Quasar Framework (via `nuxt-quasar-ui`) - **Styling:** Tailwind CSS (Utility) + Vanilla CSS Variables (Theming/Dark Mode) - **State Management:** `ref`/`reactive` (Local) + `useState` (Global/Shared State) - **Localization:** `@nuxtjs/i18n` (Supports JSON locales in `i18n/locales/`) - **Media Control:** `useMediaPrefs` (Command Pattern for global volume/mute state) ### 1.2 Core Systems & Security - **Authentication:** - āđƒāļŠāđ‰ **JWT** (Access Token 1 āļ§āļąāļ™, Refresh Token 7 āļ§āļąāļ™) - āđ€āļāđ‡āļš Token āđƒāļ™ `useCookie` (Secure, SameSite) - Middleware (`middleware/auth.ts`) āļ›āđ‰āļ­āļ‡āļāļąāļ™ Route āļ•āļēāļĄāļŠāļ–āļēāļ™āļ° - **API Handling:** - āđƒāļŠāđ‰ `runtimeConfig.public.apiBase` āđ€āļŠāļ·āđˆāļ­āļ‡āđ‚āļĒāļ‡ Backend - Auto-attach Bearer Token āđƒāļ™ `useAuth` āđāļĨāļ° `useCourse` - **Performance:** - **Hybrid Progress Saving:** āļšāļąāļ™āļ—āļķāļāđ€āļ§āļĨāļēāđ€āļĢāļĩāļĒāļ™āļĨāļ‡ LocalStorage (āļ–āļĩāđˆ) āđāļĨāļ° Server (Throttle 15s) āđ€āļžāļ·āđˆāļ­āļ„āļ§āļēāļĄāđāļĄāđˆāļ™āļĒāļģāļŠāļđāļ‡āļŠāļļāļ” - **Caching:** āđƒāļŠāđ‰ `useState` āļˆāļģāļ‚āđ‰āļ­āļĄāļđāļĨ Profile āđāļĨāļ° Categories āļĨāļ” request --- ## 📂 2. Frontend Structure (āđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡āļŦāļ™āđ‰āļēāđ€āļ§āđ‡āļšāđāļĨāļ° UI) ### 2.1 Application Routes (`pages/`) | Module | āđ„āļŸāļĨāđŒ | Path | āļŦāļ™āđ‰āļēāļ—āļĩāđˆ | | :---------- | :------------------------- | :---------------------- | :------------------------------------------- | | **Public** | `index.vue` | `/` | āļŦāļ™āđ‰āļēāđāļĢāļ Landing Page | | | `browse/discovery.vue` | `/browse/discovery` | **āļĢāļ°āļšāļšāļ„āđ‰āļ™āļŦāļēāđāļĨāļ° Filter āļ„āļ­āļĢāđŒāļŠ** (Catalog) | | | `course/[id].vue` | `/course/:id` | **āļŦāļ™āđ‰āļēāļĢāļēāļĒāļĨāļ°āđ€āļ­āļĩāļĒāļ”āļ„āļ­āļĢāđŒāļŠ** (Course Detail) | | **Auth** | `auth/login.vue` | `/auth/login` | āđ€āļ‚āđ‰āļēāļŠāļđāđˆāļĢāļ°āļšāļš (āļĢāļ­āļ‡āļĢāļąāļš Remember Me) | | | `auth/register.vue` | `/auth/register` | āļŠāļĄāļąāļ„āļĢāļŠāļĄāļēāļŠāļīāļāļœāļđāđ‰āđ€āļĢāļĩāļĒāļ™ | | | `auth/reset-password.vue` | `/auth/reset-password` | āļ•āļąāđ‰āļ‡āļĢāļŦāļąāļŠāļœāđˆāļēāļ™āđƒāļŦāļĄāđˆ (Reset Flow) | | **Student** | `dashboard/index.vue` | `/dashboard` | āđāļ”āļŠāļšāļ­āļĢāđŒāļ”āļ āļēāļžāļĢāļ§āļĄāļœāļđāđ‰āđ€āļĢāļĩāļĒāļ™ | | | `dashboard/my-courses.vue` | `/dashboard/my-courses` | **āļ„āļ­āļĢāđŒāļŠāļ‚āļ­āļ‡āļ‰āļąāļ™** āđāļĨāļ°āļ”āļēāļ§āļ™āđŒāđ‚āļŦāļĨāļ”āđƒāļšāļ›āļĢāļ°āļāļēāļĻāļŊ | | | `dashboard/profile.vue` | `/dashboard/profile` | āļˆāļąāļ”āļāļēāļĢāđ‚āļ›āļĢāđ„āļŸāļĨāđŒ, āļĢāļđāļ›āļ āļēāļž, āđ€āļ›āļĨāļĩāđˆāļĒāļ™āļĢāļŦāļąāļŠāļœāđˆāļēāļ™ | | | `classroom/learning.vue` | `/classroom/learning` | **āļŦāđ‰āļ­āļ‡āđ€āļĢāļĩāļĒāļ™ (Video Player)** & Announcements | | | `classroom/quiz.vue` | `/classroom/quiz` | āļāļēāļĢāļŠāļ­āļšāļ§āļąāļ”āļœāļĨ (Quiz System) | ### 2.2 Key Components (`components/`) - **Common (`components/common/`):** - `GlobalLoader.vue`: Loading indicator āļ—āļąāđˆāļ§āļ—āļąāđ‰āļ‡āđāļ­āļ› - `LanguageSwitcher.vue`: āļ›āļļāđˆāļĄāđ€āļ›āļĨāļĩāđˆāļĒāļ™āļ āļēāļĐāļē (TH/EN) - `AppHeader.vue`, `MobileNav.vue`: Navigation āļŦāļĨāļąāļ - `FormInput.vue`: Input field āļĄāļēāļ•āļĢāļāļēāļ™ - **Course (`components/course/`):** - `CourseCard.vue`: āļāļēāļĢāđŒāļ”āđāļŠāļ”āļ‡āļœāļĨāļ„āļ­āļĢāđŒāļŠ (āđƒāļŠāđ‰āļ‹āđ‰āļģāļŦāļĨāļēāļĒāļŦāļ™āđ‰āļē) - **User (`components/user/`):** - `UserAvatar.vue`: āđāļŠāļ”āļ‡āļĢāļđāļ›āđ‚āļ›āļĢāđ„āļŸāļĨāđŒ (āļĢāļ­āļ‡āļĢāļąāļš Fallback) --- ## 🧠 3. Logic & Data Layer (Composables) āļĢāļ§āļšāļĢāļ§āļĄ Logic āļŦāļĨāļąāļāđāļĒāļāļŠāđˆāļ§āļ™āļ•āļēāļĄāļŦāļ™āđ‰āļēāļ—āļĩāđˆ (Separation of Concerns) ### 3.1 `useAuth.ts` (Authentication & User) āļˆāļąāļ”āļāļēāļĢāļŠāļ–āļēāļ™āļ°āļœāļđāđ‰āđƒāļŠāđ‰, āļĨāđ‡āļ­āļāļ­āļīāļ™, āđāļĨāļ°āļ„āļ§āļēāļĄāļ›āļĨāļ­āļ”āļ āļąāļĒ - **Key Functions:** `login`, `register`, `fetchUserProfile`, `uploadAvatar`, `sendVerifyEmail` - **Features:** Refresh Token āļ­āļąāļ•āđ‚āļ™āļĄāļąāļ•āļī, āļ•āļĢāļ§āļˆāļŠāļ­āļš Role ### 3.2 `useCourse.ts` (Course & Classroom) āļŦāļąāļ§āđƒāļˆāļŦāļĨāļąāļāļ‚āļ­āļ‡āļāļēāļĢāđ€āļĢāļĩāļĒāļ™āļāļēāļĢāļŠāļ­āļ™ - **Catalog:** `fetchCourses`, `fetchCourseById`, `enrollCourse` - **Classroom:** - `fetchCourseLearningInfo`: āđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡āļšāļ—āđ€āļĢāļĩāļĒāļ™ (Chapters/Lessons) - `fetchLessonContent`: āđ€āļ™āļ·āđ‰āļ­āļŦāļēāļ§āļīāļ”āļĩāđ‚āļ­/Quiz/Attachments - `saveVideoProgress`: āļšāļąāļ™āļ—āļķāļāđ€āļ§āļĨāļēāđ€āļĢāļĩāļĒāļ™ (Sync Server) - `fetchCourseAnnouncements`: āļ”āļķāļ‡āļ›āļĢāļ°āļāļēāļĻāđƒāļ™āļ„āļ­āļĢāđŒāļŠāđ€āļĢāļĩāļĒāļ™ - `getCertificate` / `generateCertificate`: āļ­āļ­āļāđƒāļšāļ›āļĢāļ°āļāļēāļĻāļ™āļĩāļĒāļšāļąāļ•āļĢ ### 3.3 `useMediaPrefs.ts` (Media Control) āļˆāļąāļ”āļāļēāļĢāļāļēāļĢāļ•āļąāđ‰āļ‡āļ„āđˆāļē Media Player - **State:** `volume` (0-1), `muted` (boolean) - **Functions:** `setVolume`, `setMuted`, `applyTo` (apply state to video element) --- ## ðŸŽĻ 4. Design System & Theming ### 4.1 Theme Strategy - **Framework:** Tailwind CSS + Quasar UI - **Dark Mode:** āļĢāļ­āļ‡āļĢāļąāļš Class-based Dark Mode (`.dark`) - **Fonts:** - **Heading:** Prompt, Sarabun (TH), Inter (EN) - **Body:** Sarabun (TH), Inter (EN) - **Handwriting:** (Optional) Dancing Script --- ## 📊 5. Dependency Map (āļ„āļ§āļēāļĄāļŠāļąāļĄāļžāļąāļ™āļ˜āđŒāđ„āļŸāļĨāđŒ) | āļŦāļ™āđ‰āļēāđ€āļ§āđ‡āļš (Page) | Components āļŦāļĨāļąāļ | Composables āļŦāļĨāļąāļ | | :----------------------- | :--------------------------- | :----------------------------------------------------- | | **Login / Register** | `FormInput` | `useAuth`, `useFormValidation` | | **Discovery (Browse)** | `CourseCard` | `useCourse` (Search/Filter), `useCategory` | | **My Courses** | `CourseCard` (with Progress) | `useCourse` (Certificates) | | **Classroom (Learning)** | Video Player, Sidebar | `useCourse` (Progress, Announcements), `useMediaPrefs` | | **Profile** | `UserAvatar`, `FormInput` | `useAuth` (Upload Avatar, Verify Email) | --- ## ✅ 6. Project Status (āļŠāļ–āļēāļ™āļ°āļĨāđˆāļēāļŠāļļāļ”) ### âœĻ Recent Updates (āļ­āļąāļ›āđ€āļ”āļ•āļĨāđˆāļēāļŠāļļāļ”) 1. **Code Optimization (Clean Code):** - **āļĨāļš Mock Data āļ—āļąāđ‰āļ‡āļŦāļĄāļ”:** āļŦāļ™āđ‰āļē `quiz`, `classroom`, `discovery` āđƒāļŠāđ‰āļ‚āđ‰āļ­āļĄāļđāļĨāļˆāļĢāļīāļ‡āļˆāļēāļ API 100% - **āļĨāļš Dead Code:** āļāļģāļˆāļąāļ”āļ•āļąāļ§āđāļ›āļĢāļ—āļĩāđˆāđ„āļĄāđˆāđ„āļ”āđ‰āđƒāļŠāđ‰ (`currentUser` āļ‹āđ‰āļģāļ‹āđ‰āļ­āļ™, `unused intervals`) āđāļĨāļ° `console.log` 2. **Robust Learning System (Classroom):** - **Hybrid Progress Saving:** āļĢāļ°āļšāļšāļšāļąāļ™āļ—āļķāļāđ€āļ§āļĨāļēāđ€āļĢāļĩāļĒāļ™āđāļšāļšāļĨāļđāļāļœāļŠāļĄ (Local + Server) āļ›āđ‰āļ­āļ‡āļāļąāļ™āđ€āļ§āļĨāļēāļŦāļēāļĒāđ€āļĄāļ·āđˆāļ­āđ€āļ™āđ‡āļ•āļŦāļĨāļļāļ”āļŦāļĢāļ·āļ­āļ›āļīāļ”āđāļ—āđ‡āļš - **Announcements:** āđ€āļžāļīāđˆāļĄāđāļ—āđ‡āļšāļ›āļĢāļ°āļāļēāļĻāđƒāļ™ Sidebar āļŦāđ‰āļ­āļ‡āđ€āļĢāļĩāļĒāļ™ āđ€āļŠāļ·āđˆāļ­āļĄāļ•āđˆāļ­ API `course-announcements` āļžāļĢāđ‰āļ­āļĄāđāļˆāđ‰āļ‡āđ€āļ•āļ·āļ­āļ™ "New" - **Video Player:** āļ›āļĢāļąāļšāļ›āļĢāļļāļ‡ UI Player, Volume Persistence (`useMediaPrefs`) 3. **i18n & Configuration:** - **Path Correction:** āđāļāđ‰āđ„āļ‚ `nuxt.config.ts` āđƒāļŦāđ‰āđ€āļĢāļĩāļĒāļāđ„āļŸāļĨāđŒāļ āļēāļĐāļēāļˆāļēāļ `i18n/locales/` āđ„āļ”āđ‰āļ–āļđāļāļ•āđ‰āļ­āļ‡ - **Consistency:** āđ€āļžāļīāđˆāļĄāļ„āļĩāļĒāđŒāļ āļēāļĐāļēāļ—āļĩāđˆāļ‚āļēāļ”āļŦāļēāļĒ (āđ€āļŠāđˆāļ™ `common.close`) āđƒāļ™ `en.json` 4. **Enrollment & User Experience:** - **Smart Enrolled Filter:** āļŦāļ™āđ‰āļē "āļ„āļ­āļĢāđŒāļŠāļ‚āļ­āļ‡āļ‰āļąāļ™" Tab "āļāļģāļĨāļąāļ‡āđ€āļĢāļĩāļĒāļ™" āđāļŠāļ”āļ‡āļ—āļąāđ‰āļ‡āļ„āļ­āļĢāđŒāļŠāļ—āļĩāđˆāđ€āļžāļīāđˆāļ‡āļĨāļ‡āļ—āļ°āđ€āļšāļĩāļĒāļ™ (`ENROLLED`) āđāļĨāļ°āļāļģāļĨāļąāļ‡āđ€āļĢāļĩāļĒāļ™ (`IN_PROGRESS`) - **Certificate System:** āļĢāļ°āļšāļšāļ”āļēāļ§āļ™āđŒāđ‚āļŦāļĨāļ”/āļŠāļĢāđ‰āļēāļ‡āđƒāļšāļ›āļĢāļ°āļāļēāļĻāļŊ āļ­āļąāļ•āđ‚āļ™āļĄāļąāļ•āļīāđ€āļĄāļ·āđˆāļ­āđ€āļĢāļĩāļĒāļ™āļˆāļš 5. **Profile & Security:** - **Email Verification:** āļ›āļļāđˆāļĄāļĒāļ·āļ™āļĒāļąāļ™āļ­āļĩāđ€āļĄāļĨāđāļĨāļ°āļŠāļ–āļēāļ™āļ°āđƒāļ™āļŦāļ™āđ‰āļēāđ‚āļ›āļĢāđ„āļŸāļĨāđŒ - **Avatar Upload:** āļ­āļąāļ›āđ‚āļŦāļĨāļ”āļĢāļđāļ›āļ āļēāļžāļžāļĢāđ‰āļ­āļĄ Preview āđāļĨāļ° Validation (Size/Type)