Skip to content

darrenak403/beyond8-client

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

412 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Beyond8 — AI-Powered Learning Management System

Beyond8 Logo

Beyond8 là nền tảng học trực tuyến (LMS) tích hợp AI, hỗ trợ đa vai trò: Học viên, Giảng viênQuản trị viên. Nền tảng cho phép học viên mua và học các khóa học video, giảng viên tạo và quản lý nội dung, đồng thời cung cấp bộ công cụ quản trị toàn diện cho admin.


📋 Mục lục


👥 Đội ngũ Frontend

Thành viên Vai trò GitHub
Trần Phú Thịnh Frontend Leader @ThinhTP204
Uông Tuấn Vũ Frontend Developer @tuanvu250

✨ Tính năng cốt lõi

Học viên

  • Tìm kiếm và lọc khóa học theo danh mục
  • Mua khóa học qua giỏ hàng, áp dụng mã giảm giá
  • Học video với HLS streaming, theo dõi tiến độ học
  • Làm bài quiz và bài tập (assignment)
  • Nhận chứng chỉ hoàn thành khóa học (PDF)
  • Quản lý hồ sơ, lịch sử thanh toán, thống kê học tập

Giảng viên

  • Tạo và quản lý khóa học, chương học, bài học
  • Quản lý ngân hàng câu hỏi, quiz, bài tập
  • Chấm điểm bài nộp của học viên
  • Theo dõi doanh thu, quản lý ví và rút tiền
  • Tạo mã coupon giảm giá

Quản trị viên

  • Quản lý người dùng, danh mục, khóa học toàn nền tảng
  • Duyệt đơn đăng ký trở thành giảng viên
  • Quản lý ví nền tảng và giao dịch
  • Cấu hình AI prompt và quản lý tính năng AI
  • Thống kê tổng quan hệ thống

Tính năng chung

  • Xác thực JWT với tự động refresh token
  • Thông báo real-time qua SignalR
  • AI Chat tích hợp
  • Đăng ký / đăng nhập, quên mật khẩu, xác thực OTP
  • Đồng bộ trạng thái đăng xuất giữa các tab

🛠️ Tech Stack

Nhóm Công nghệ
Framework Next.js 16 (App Router), React 19, TypeScript
Styling Tailwind CSS, shadcn/ui, Radix UI
State Management Redux Toolkit + redux-persist, TanStack React Query v5
HTTP Client Axios (custom wrapper với interceptor)
Real-time Microsoft SignalR
Form React Hook Form, Formik
Validation Yup
Animation Framer Motion, GSAP
Video Vidstack
Rich Text Tiptap, React Markdown
Charts Recharts
3D Three.js, React Three Fiber
Icons Lucide React, Iconify
Notifications Sonner
PDF jsPDF, html-to-image
Auth JWT Decode, js-cookie, cookies-next
Date Day.js, date-fns
Containerization Docker (multi-stage build)

⚙️ Yêu cầu trước khi chạy

  • Node.js >= 20.x
  • npm >= 10.x (hoặc yarn / pnpm)
  • Docker >= 24.x (nếu chạy bằng Docker)
  • Backend API đang chạy và có thể truy cập

Biến môi trường

Tạo file .env.local tại thư mục gốc dựa theo .env.example:

cp .env.example .env.local

.env.example

# URL của API Gateway backend
NEXT_PUBLIC_API_URL=

# Secret key dùng để mã hóa dữ liệu nhạy cảm (cookie, localStorage)
NEXT_PUBLIC_CRYPTO_SECRET_KEY=your_secret_key_here

🚀 Cài đặt

Cài đặt thông thường

# 1. Clone repository
git clone https://github.com/your-org/beyond8-client.git
cd beyond8-client

# 2. Cài đặt dependencies
npm install

# 3. Tạo file môi trường
cp .env.example .env.local
# Chỉnh sửa .env.local với các giá trị phù hợp

# 4. Chạy development server
npm run dev

Truy cập http://localhost:5173

# Build production
npm run build
npm run start

🐳 Chạy bằng Docker

Development

docker compose -f docker/docker-compose-dev.yml up --build

Production

docker compose -f docker/docker-compose-prod.yml up -d

Build image thủ công

docker build -t beyond8-frontend .
docker run -p 3000:5173 \
  -e NEXT_PUBLIC_API_URL= \
  -e NEXT_PUBLIC_CRYPTO_SECRET_KEY=your_secret \
  beyond8-frontend

Container expose port 5173 bên trong, map ra port tùy ý bên ngoài.


📁 Cấu trúc dự án

beyond8-client/
├── app/                          # Next.js App Router
│   ├── (admin)/                  # Route group: Admin
│   │   └── admin/
│   │       ├── dashboard/
│   │       ├── user/
│   │       ├── course/
│   │       ├── category/
│   │       ├── coupon/
│   │       ├── ai-management/
│   │       ├── platform-wallet/
│   │       └── instructor-registration/
│   ├── (auth)/                   # Route group: Xác thực
│   │   ├── login/
│   │   ├── register/
│   │   └── reset-password/
│   ├── (instructor)/             # Route group: Giảng viên
│   │   └── instructor/
│   │       ├── dashboard/
│   │       ├── courses/
│   │       ├── grading/
│   │       ├── question-bank/
│   │       ├── students/
│   │       ├── wallet/
│   │       └── coupon/
│   ├── courses/                  # Marketplace khóa học
│   ├── mybeyond/                 # Dashboard học viên
│   │   ├── mycourse/
│   │   ├── myprofile/
│   │   ├── mycertificate/
│   │   ├── myusage/
│   │   └── payment-history/
│   ├── cart/                     # Giỏ hàng
│   ├── payment/                  # Thanh toán
│   ├── supscription/             # Gói đăng ký
│   ├── landing/                  # Landing page
│   ├── layout.tsx                # Root layout
│   └── globals.css
│
├── components/
│   ├── ui/                       # shadcn/ui base components
│   ├── layout/                   # Header, Footer, Sidebar, Navbar
│   └── widget/                   # Feature widgets (Cart, AI Chat, Dialogs...)
│
├── hooks/                        # Custom React hooks
│
├── lib/
│   ├── api/
│   │   ├── core.ts               # Axios instance + interceptors
│   │   └── services/             # API fetchers theo domain
│   ├── redux/
│   │   ├── store.ts
│   │   └── slices/               # Redux slices (auth,...)
│   ├── providers/                # React context providers
│   ├── realtime/                 # SignalR setup
│   ├── types/                    # TypeScript interfaces
│   └── utils/                    # Helper functions
│
├── utils/                        # Cookie, crypto utilities
├── types/                        # Global type definitions
├── public/                       # Static assets
├── docker/                       # Docker compose files
├── Dockerfile
├── middleware.ts                 # Route protection & role redirect
├── next.config.ts
└── package.json

🔌 Cách fetch API & Custom Hooks

Axios Instance (lib/api/core.ts)

Toàn bộ HTTP request đi qua một Axios instance duy nhất với:

  • Request interceptor: tự động đính kèm Authorization: Bearer <token> từ Redux store
  • Response interceptor: xử lý lỗi 401, tự động refresh token và retry request, queue các request đang chờ để tránh race condition
// lib/api/core.ts
const apiService = {
  get<T>(url: string, params?: object): Promise<T>
  post<T, D>(url: string, data: D): Promise<T>
  put<T, D>(url: string, data: D): Promise<T>
  patch<T, D>(url: string, data: D): Promise<T>
  delete<T>(url: string): Promise<T>
  upload<T>(url: string, formData: FormData, onProgress?: (pct: number) => void): Promise<T>
}

API Services (lib/api/services/)

Mỗi domain có một file fetcher riêng, export các hàm gọi API thuần túy:

// lib/api/services/fetchCourse.ts
export const getCourses = (params: CourseParams) =>
  apiService.get<CourseListResponse>('/courses', params)

export const getCourseDetail = (courseId: string) =>
  apiService.get<CourseDetail>(`/courses/${courseId}`)

export const createCourse = (data: CreateCourseDto) =>
  apiService.post<Course, CreateCourseDto>('/courses', data)

Custom Hooks với React Query

Các custom hook trong hooks/ bọc React Query để cung cấp data fetching có cache, loading state và error handling:

// hooks/useCourse.ts
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { getCourses, createCourse } from '@/lib/api/services/fetchCourse'

// Query hook — đọc dữ liệu
export const useCourses = (params: CourseParams) => {
  return useQuery({
    queryKey: ['courses', params],
    queryFn: () => getCourses(params),
    staleTime: 60_000,
  })
}

// Mutation hook — ghi dữ liệu
export const useCreateCourse = () => {
  const queryClient = useQueryClient()
  return useMutation({
    mutationFn: createCourse,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['courses'] })
    },
  })
}

Sử dụng trong component:

const CourseList = () => {
  const { data, isLoading, error } = useCourses({ page: 1, limit: 10 })
  const { mutate: create, isPending } = useCreateCourse()

  if (isLoading) return <Skeleton />
  if (error) return <ErrorMessage />

  return (
    <>
      {data?.items.map(course => <CourseCard key={course.id} course={course} />)}
      <Button onClick={() => create(newCourseData)} disabled={isPending}>
        Tạo khóa học
      </Button>
    </>
  )
}

Luồng xác thực (Auth Flow)

Đăng nhập
  → nhận accessToken + refreshToken
  → lưu vào Redux store (persist sang localStorage) + cookie
  → middleware.ts kiểm tra token và role để redirect đúng dashboard
  → khi token hết hạn: interceptor tự động gọi refresh endpoint
  → đồng bộ đăng xuất giữa các tab qua useAuthSyncAcrossTabs

About

Official frontend client for the Beyond8 education platform. Built with Next.js, TypeScript, and optimized for high-performance learning experiences.

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages