# 🛠ïļ Web Development Documentation: e-Learning Platform (Frontend) āđ€āļ­āļāļŠāļēāļĢāļ‰āļšāļąāļšāļ™āļĩāđ‰āļŠāļĢāļļāļ›āļĢāļēāļĒāļĨāļ°āđ€āļ­āļĩāļĒāļ”āļ—āļēāļ‡āđ€āļ—āļ„āļ™āļīāļ„ āđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡āđ‚āļ„āđ‰āļ” āđāļĨāļ°āļāļēāļĢāļ—āļģāļ‡āļēāļ™āļ‚āļ­āļ‡āļĢāļ°āļšāļš **Frontend-Learner** (āļ­āļąāļ›āđ€āļ”āļ•āļĨāđˆāļēāļŠāļļāļ”: āļāļļāļĄāļ āļēāļžāļąāļ™āļ˜āđŒ 2026) --- ## 🏗ïļ 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 āļ•āļēāļĄāļŠāļ–āļēāļ™āļ° - **Remember Me:** āļĢāļ°āļšāļšāļˆāļ”āļˆāļģāļ­āļĩāđ€āļĄāļĨāļĨāļ‡āđƒāļ™ `localStorage` (āļˆāļģāđāļĒāļāļˆāļēāļ session, āđ„āļĄāđˆāļ–āļđāļāļĨāļšāđ€āļĄāļ·āđˆāļ­ Logout) - **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 - **Code Quality:** āļĨāļš Log, Dead logic āđāļĨāļ° Redundant comments āļ—āļąāđˆāļ§āļ—āļąāđ‰āļ‡āđ‚āļ›āļĢāđ€āļˆāļāļ•āđŒ (Clean Code Phase) --- ## 📂 2. Frontend Structure (āđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡āļŦāļ™āđ‰āļēāđ€āļ§āđ‡āļšāđāļĨāļ° UI) ### 2.1 Application Routes (`pages/`) | Module | āđ„āļŸāļĨāđŒ | Path | āļŦāļ™āđ‰āļēāļ—āļĩāđˆ | | :---------- | :------------------------- | :---------------------- | :-------------------------------------------- | | **Public** | `index.vue` | `/` | āļŦāļ™āđ‰āļēāđāļĢāļ Landing Page (**Forced Light Mode**) | | | `browse/discovery.vue` | `/browse/discovery` | **āļĢāļ°āļšāļšāļ„āđ‰āļ™āļŦāļēāđāļĨāļ° Filter āļ„āļ­āļĢāđŒāļŠ** (Catalog) | | | `course/[id].vue` | `/course/:id` | **āļŦāļ™āđ‰āļēāļĢāļēāļĒāļĨāļ°āđ€āļ­āļĩāļĒāļ”āļ„āļ­āļĢāđŒāļŠ** (Course Detail) | | **Auth** | `auth/login.vue` | `/auth/login` | āđ€āļ‚āđ‰āļēāļŠāļđāđˆāļĢāļ°āļšāļš (**Remember Me**, **Light Mode**) | | | `auth/register.vue` | `/auth/register` | āļŠāļĄāļąāļ„āļĢāļŠāļĄāļēāļŠāļīāļāļœāļđāđ‰āđ€āļĢāļĩāļĒāļ™ (**Light Mode**) | | | `auth/forgot-password.vue` | `/auth/forgot-password` | āļāļđāđ‰āļ„āļ·āļ™āļĢāļŦāļąāļŠāļœāđˆāļēāļ™ (**Light Mode**) | | **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` | āļāļēāļĢāļŠāļ­āļšāļ§āļąāļ”āļœāļĨ (**API-Driven Logic**) | ### 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`: āļāļēāļĢāđŒāļ”āđāļŠāļ”āļ‡āļœāļĨāļ„āļ­āļĢāđŒāļŠ (āđƒāļŠāđ‰āļ‹āđ‰āļģāļŦāļĨāļēāļĒāļŦāļ™āđ‰āļē) - **Discovery (`components/discovery/`):** - `CategorySidebar.vue`: Sidebar āļ•āļąāļ§āļāļĢāļ­āļ‡āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāđāļšāļšāļĒāđˆāļ­/āļ‚āļĒāļēāļĒāđ„āļ”āđ‰ - `CourseDetailView.vue`: āļŦāļ™āđ‰āļēāļĢāļēāļĒāļĨāļ°āđ€āļ­āļĩāļĒāļ”āļ„āļ­āļĢāđŒāļŠāļ‚āļ™āļēāļ”āđƒāļŦāļāđˆ (Video Preview + Syllabus) - **Classroom (`components/classroom/`):** - `CurriculumSidebar.vue`: Sidebar āļšāļ—āđ€āļĢāļĩāļĒāļ™āđāļĨāļ°āļŠāļ–āļēāļ™āļ°āļāļēāļĢāđ€āļĢāļĩāļĒāļ™ - `AnnouncementModal.vue`: Modal āđāļŠāļ”āļ‡āļ›āļĢāļ°āļāļēāļĻāļ‚āļ­āļ‡āļ„āļ­āļĢāđŒāļŠ - `VideoPlayer.vue`: Video Player āļžāļĢāđ‰āļ­āļĄ Custom Controls - **User / Profile (`components/user/`, `components/profile/`):** - `UserAvatar.vue`: āđāļŠāļ”āļ‡āļĢāļđāļ›āđ‚āļ›āļĢāđ„āļŸāļĨāđŒ (āļĢāļ­āļ‡āļĢāļąāļš Fallback) - `ProfileEditForm.vue`: āļŸāļ­āļĢāđŒāļĄāđāļāđ‰āđ„āļ‚āļ‚āđ‰āļ­āļĄāļđāļĨāļŠāđˆāļ§āļ™āļ•āļąāļ§ - `PasswordChangeForm.vue`: āļŸāļ­āļĢāđŒāļĄāđ€āļ›āļĨāļĩāđˆāļĒāļ™āļĢāļŦāļąāļŠāļœāđˆāļēāļ™ --- ## 🧠 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, **Logout Logic āļ—āļĩāđˆāđ„āļĄāđˆāļĨāļšāļ‚āđ‰āļ­āļĄāļđāļĨāļˆāļ”āļˆāļģāļœāļđāđ‰āđƒāļŠāđ‰** ### 3.2 `useCourse.ts` (Course & Classroom) āļŦāļąāļ§āđƒāļˆāļŦāļĨāļąāļāļ‚āļ­āļ‡āļāļēāļĢāđ€āļĢāļĩāļĒāļ™āļāļēāļĢāļŠāļ­āļ™ - **Catalog:** `fetchCourses`, `fetchCourseById`, `enrollCourse` - **Classroom:** - `fetchCourseLearningInfo`: āđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡āļšāļ—āđ€āļĢāļĩāļĒāļ™ (Chapters/Lessons) - `fetchLessonContent`: āđ€āļ™āļ·āđ‰āļ­āļŦāļēāļ§āļīāļ”āļĩāđ‚āļ­/Quiz/Attachments - `saveVideoProgress`: āļšāļąāļ™āļ—āļķāļāđ€āļ§āļĨāļēāđ€āļĢāļĩāļĒāļ™ (Sync Server) ### 3.3 `useQuizRunner.ts` (Quiz System) āļˆāļąāļ”āļāļēāļĢ Logic āļāļēāļĢāļ—āļģāļ‚āđ‰āļ­āļŠāļ­āļš (Production-Ready) - **Logic:** āļ„āļ§āļšāļ„āļļāļĄāļāļēāļĢāđ€āļ›āļĨāļĩāđˆāļĒāļ™āļ‚āđ‰āļ­, āļāļēāļĢāļŠāđˆāļ‡āļ„āļģāļ•āļ­āļš, āđāļĨāļ°āļāļēāļĢāļĢāļąāļšāļœāļĨāļĨāļąāļžāļ˜āđŒāļˆāļēāļ API - **Cleanup:** āļĨāļš Mock delays āđāļĨāļ° Simulation logic āļ­āļ­āļāļ—āļąāđ‰āļ‡āļŦāļĄāļ”āđ€āļžāļ·āđˆāļ­āđƒāļŦāđ‰āļ—āļģāļ‡āļēāļ™āļĢāđˆāļ§āļĄāļāļąāļš API āļˆāļĢāļīāļ‡āđ„āļ”āđ‰āļ—āļąāļ™āļ—āļĩ --- ## ðŸŽĻ 4. Design System & Theming ### 4.1 Theme Strategy - **Framework:** Tailwind CSS + Quasar UI - **Light/Dark Mode Policy:** - **Public Pages:** āļšāļąāļ‡āļ„āļąāļš **Light Mode** (Landing, Course Detail, Auth) āđ€āļžāļ·āđˆāļ­āļ āļēāļžāļĨāļąāļāļĐāļ“āđŒāđāļšāļĢāļ™āļ”āđŒāļ—āļĩāđˆāļŠāļ°āļ­āļēāļ”āļ•āļē - **Dashboard/Learning:** āļĢāļ­āļ‡āļĢāļąāļš **Dark Mode** āđ€āļ•āđ‡āļĄāļĢāļđāļ›āđāļšāļš (Oceanic Theme) - **Visual Fixes:** āđāļāđ‰āđ„āļ‚āļ›āļąāļāļŦāļē "Dark Frame" āđƒāļ™āļŦāļ™āđ‰āļē Auth āđ‚āļ”āļĒāļāļēāļĢāļšāļąāļ‡āļ„āļąāļšāļŠāđ„āļ•āļĨāđŒāļĢāļ°āļ”āļąāļš HTML/Body --- ## 📊 5. Dependency Map (āļ„āļ§āļēāļĄāļŠāļąāļĄāļžāļąāļ™āļ˜āđŒāđ„āļŸāļĨāđŒ) | āļŦāļ™āđ‰āļēāđ€āļ§āđ‡āļš (Page) | Components āļŦāļĨāļąāļ | Composables āļŦāļĨāļąāļ | | :----------------------- | :--------------------------- | :----------------------------------------------------- | | **Login / Register** | `FormInput` | `useAuth` (Remember Me), `useFormValidation` | | **Discovery (Browse)** | `CourseCard` | `useCourse` (Search/Filter), `useCategory` | | **My Courses** | `CourseCard` (with Progress) | `useCourse` (Certificates) | | **Classroom (Learning)** | Video Player, Sidebar | `useCourse` (Progress, Announcements), `useMediaPrefs` | | **Quiz** | `QuizHeader`, `QuizContent` | `useQuizRunner` (Real API Integration) | | **Profile** | `UserAvatar`, `FormInput` | `useAuth` (Upload Avatar, Verify Email) | --- ## ✅ 6. Project Status (āļŠāļ–āļēāļ™āļ°āļĨāđˆāļēāļŠāļļāļ”) ### âœĻ Recent Updates (āļāļļāļĄāļ āļēāļžāļąāļ™āļ˜āđŒ 2026) 1. **System-Wide Code Cleanup (Phase Final):** - **Refactoring:** āļ›āļąāļ”āļāļ§āļēāļ”āđ‚āļ„āđ‰āļ”āđƒāļ™āļŦāļ™āđ‰āļē `learning`, `quiz`, `discovery`, `dashboard` āđāļĨāļ° `profile` - **Logging:** āļĨāļš `console.log` āļĄāļŦāļēāļĻāļēāļĨ āđāļĨāļ° logic āļ‹āđ‰āļģāļ‹āđ‰āļ­āļ™āļ—āļĩāđˆāļ•āļāļ„āđ‰āļēāļ‡āļˆāļēāļāļāļēāļĢāļžāļąāļ’āļ™āļē - **Structure:** āļˆāļąāļ”āļāļĨāļļāđˆāļĄāļŠāđ„āļ•āļĨāđŒāđāļĨāļ°āļŸāļąāļ‡āļāđŒāļŠāļąāļ™āđƒāļŦāđ‰āđ€āļ›āđ‡āļ™āļĢāļ°āđ€āļšāļĩāļĒāļš āļ­āđˆāļēāļ™āļ‡āđˆāļēāļĒāļ‚āļķāđ‰āļ™āļ•āļēāļĄāļĄāļēāļ•āļĢāļāļēāļ™ Clean Code 2. **Authentication & Security Polish:** - **Remember Me:** āļžāļąāļ’āļ™āļēāļĢāļ°āļšāļšāļˆāļ”āļˆāļģāļ­āļĩāđ€āļĄāļĨāđƒāļ™āļŦāļ™āđ‰āļē Login āđƒāļŦāđ‰āđ€āļŠāļ–āļĩāļĒāļĢ (āđƒāļŠāđ‰ `localStorage`) - **Smart Logout:** āļ›āļĢāļąāļšāļ›āļĢāļļāļ‡ `useAuth.logout` āđƒāļŦāđ‰āļĨāļšāļ‚āđ‰āļ­āļĄāļđāļĨ Session āđāļ•āđˆāđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨāļ—āļĩāđˆāļœāļđāđ‰āđƒāļŠāđ‰āļŠāļąāđˆāļ‡āļˆāļģāđ„āļ§āđ‰ (āļ­āļĩāđ€āļĄāļĨ) 3. **UI & Aesthetics (Premium Fixes):** - **Theme Enforcement:** āļšāļąāļ‡āļ„āļąāļšāļŦāļ™āđ‰āļēāļŠāļēāļ˜āļēāļĢāļ“āļ° (Landing/Auth) āđƒāļŦāđ‰āđ€āļ›āđ‡āļ™ Light Mode 100% āļžāļĢāđ‰āļ­āļĄāđāļāđ‰āļ›āļąāļāļŦāļēāļāļĢāļ­āļšāļĄāļ·āļ” (Dark Frame) āļ•āļāļ„āđ‰āļēāļ‡ - **Dark Mode Optimization:** āļ›āļĢāļąāļšāļ›āļĢāļļāļ‡āļŠāļĩāđāļĨāļ° Contrast āđƒāļ™āļŦāļ™āđ‰āļē Dashboard āđāļĨāļ° Profile āđƒāļŦāđ‰āļŠāļ§āļĒāļ‡āļēāļĄāđāļĨāļ°āļ­āđˆāļēāļ™āļ‡āđˆāļēāļĒāļ‚āļķāđ‰āļ™āđƒāļ™āđ‚āļŦāļĄāļĄāļ·āļ” 4. **Quiz System Productionization:** - **useQuizRunner:** āđāļ›āļĨāļ‡āļĢāđˆāļēāļ‡āļˆāļēāļ Mock system āđ€āļ›āđ‡āļ™ API-Ready system (āļĨāļš simulation logic āļ—āļąāđ‰āļ‡āļŦāļĄāļ”) - **Quiz UI:** āļ›āļĢāļąāļšāļ›āļĢāļļāļ‡āļāļēāļĢāļ™āļģāļ—āļēāļ‡āđāļĨāļ°āļŠāļ–āļēāļ™āļ°āļāļēāļĢāļ—āļģāļ‚āđ‰āļ­āļŠāļ­āļšāđƒāļŦāđ‰āļĨāļ·āđˆāļ™āđ„āļŦāļĨ 5. **Performance & Stability:** - āđāļāđ‰āđ„āļ‚āļ›āļąāļāļŦāļēāļāļēāļĢāđ€āļŠāļ·āđˆāļ­āļĄāļ•āđˆāļ­ Media (`ERR_CONNECTION_FAILED`) āļœāđˆāļēāļ™āļāļēāļĢāļ›āļĢāļąāļšāļ›āļĢāļļāļ‡ config - āļ›āļĢāļąāļšāļ›āļĢāļļāļ‡āļāļēāļĢāđ‚āļŦāļĨāļ”āļ‚āđ‰āļ­āļĄāļđāļĨāđ€āļšāļ·āđ‰āļ­āļ‡āļŦāļĨāļąāļ‡āļ”āđ‰āļ§āļĒ `useAsyncData` āđƒāļŦāđ‰āļĄāļĩāļ„āļ§āļēāļĄāđ€āļŠāļ–āļĩāļĒāļĢāļĄāļēāļāļ‚āļķāđ‰āļ™