This commit is contained in:
2026-07-16 09:53:14 +07:00
parent 0fc112a2e8
commit 29cec708a3
1236 changed files with 212848 additions and 0 deletions

373
plans/online-lessons.md Normal file
View File

@@ -0,0 +1,373 @@
ต้องการเพิ่มฟีเจอร์ใหม่ในระบบ Training System ชื่อ **บทเรียนออนไลน์ (Online Lessons)** โดยให้มีลักษณะคล้ายเมนู **ประกาศ** เดิม แต่เปลี่ยนวัตถุประสงค์เป็นการจัดการบทเรียนออนไลน์สำหรับ HRD และแสดงบทเรียนให้พนักงานเข้าไปเรียนได้
## 1. เมนูที่ต้องเพิ่ม
### สำหรับ HRD/Admin
เพิ่มเมนูใหม่ชื่อ:
**เพิ่มบทเรียนออนไลน์**
ใช้สำหรับให้ HRD เพิ่ม แก้ไข ลบ และเผยแพร่บทเรียนออนไลน์
Path แนะนำ:
```txt
/dashboard/online-lessons/manage
```
หรือ
```txt
/dashboard/online-lessons-admin
```
### สำหรับพนักงาน
เพิ่มเมนูใหม่ชื่อ:
**บทเรียนออนไลน์**
ใช้สำหรับให้พนักงานเปิดดูบทเรียน วิดีโอ และดาวน์โหลดไฟล์แนบ
Path แนะนำ:
```txt
/dashboard/online-lessons
```
---
## 2. สิทธิ์การเข้าถึง
### HRD/Admin
สามารถทำได้ดังนี้:
- เพิ่มบทเรียนออนไลน์
- แก้ไขบทเรียน
- ลบบทเรียน
- เปิด/ปิดการเผยแพร่
- แนบไฟล์เอกสาร
- เพิ่มลิงก์วิดีโอ หรืออัปโหลดวิดีโอ
- กำหนดสถานะบทเรียน
### Employee
สามารถทำได้ดังนี้:
- ดูรายการบทเรียนออนไลน์ที่เผยแพร่แล้วเท่านั้น
- เปิดดูวิดีโอ
- อ่านรายละเอียดบทเรียน
- ดาวน์โหลดไฟล์แนบ
- ไม่สามารถเพิ่ม แก้ไข หรือลบบทเรียนได้
---
## 3. ข้อมูลของบทเรียนออนไลน์
ให้สร้างข้อมูล Online Lesson โดยมี fields ประมาณนี้:
```ts
{
id: string;
title: string;
description?: string;
category?: string;
videoUrl?: string;
videoFileUrl?: string;
attachmentUrl?: string;
attachmentName?: string;
thumbnailUrl?: string;
status: "draft" | "published" | "archived";
isPublished: boolean;
publishedAt?: Date;
createdBy: string;
updatedBy?: string;
createdAt: Date;
updatedAt: Date;
}
```
---
## 4. หน้าจอ HRD: เพิ่มบทเรียนออนไลน์
ให้ทำหน้า Layout คล้ายเมนู **ประกาศ**
### รายการบทเรียน
แสดงเป็นตาราง มี columns:
- ชื่อบทเรียน
- หมวดหมู่
- ประเภทวิดีโอ
- ไฟล์แนบ
- สถานะ
- วันที่เผยแพร่
- ผู้สร้าง
- จัดการ
### ปุ่มหลัก
- เพิ่มบทเรียนออนไลน์
- ค้นหา
- Filter สถานะ
- Filter หมวดหมู่
- View
- Pagination
---
## 5. ฟอร์มเพิ่ม / แก้ไขบทเรียน
ฟอร์มควรมี fields ดังนี้:
### ข้อมูลหลัก
- ชื่อบทเรียน
- รายละเอียดบทเรียน
- หมวดหมู่
- สถานะ: Draft / Published / Archived
### วิดีโอ
ให้รองรับ 2 แบบ:
1. ใส่ลิงก์วิดีโอ เช่น YouTube, Google Drive, OneDrive, SharePoint หรือ URL ภายนอก
2. อัปโหลดไฟล์วิดีโอ เช่น `.mp4`, `.webm`, `.mov`
### เอกสารแนบ
ให้แนบไฟล์ประกอบบทเรียนได้ เช่น:
- PDF
- Word
- Excel
- PowerPoint
- รูปภาพ
- ZIP
### รูปปกบทเรียน
- อัปโหลด Thumbnail หรือไม่มีก็ได้
- ถ้าไม่มีรูป ให้แสดง icon default เหมือนระบบประกาศ
---
## 6. หน้าจอพนักงาน: บทเรียนออนไลน์
ให้แสดงเฉพาะบทเรียนที่สถานะเป็น `published` หรือ `isPublished = true`
### รูปแบบการแสดงผล
แนะนำให้แสดงเป็น Card Grid คล้ายประกาศ
แต่ละ Card แสดง:
- รูปปก หรือ icon default
- ชื่อบทเรียน
- รายละเอียดสั้น ๆ
- หมวดหมู่
- วันที่เผยแพร่
- ปุ่ม “เปิดบทเรียน”
---
## 7. หน้ารายละเอียดบทเรียน
เมื่อพนักงานกดเปิดบทเรียน ให้แสดงหน้า Detail
ข้อมูลที่ต้องแสดง:
- ชื่อบทเรียน
- รายละเอียด
- วิดีโอ
- ไฟล์แนบ
- วันที่เผยแพร่
### การแสดงวิดีโอ
ถ้าเป็น `videoUrl` ให้ embed หรือเปิดผ่าน iframe/player ถ้ารองรับ
ถ้าเป็น `videoFileUrl` ให้ใช้ HTML video player:
```tsx
<video controls className="w-full rounded-xl">
<source src={lesson.videoFileUrl} />
</video>
```
### ไฟล์แนบ
ถ้ามีไฟล์แนบ ให้แสดงรายการไฟล์พร้อมปุ่ม:
- ดาวน์โหลด
- เปิดไฟล์
ถ้าไม่มีไฟล์แนบ ให้แสดงข้อความ:
```txt
ไม่มีไฟล์แนบ
```
---
## 8. UI/UX
ให้ดีไซน์เหมือนเมนูประกาศเดิม
- ใช้ Card
- ใช้ Badge แสดงสถานะ
- ใช้ icon default ถ้าไม่มีรูปปก
- ใช้ Empty State เมื่อไม่มีบทเรียน
- ใช้ Confirm Dialog ก่อนลบ
- ใช้ Toast แจ้งผลสำเร็จ/ผิดพลาด
- รองรับ Responsive
- ใช้ Theme สีเดียวกับระบบเดิม
---
## 9. Validation
ใช้ Zod validation
เงื่อนไข:
- ชื่อบทเรียน: required
- รายละเอียด: optional
- ต้องมีอย่างน้อย 1 อย่างระหว่าง `videoUrl` หรือ `videoFile`
- สถานะ: required
- ไฟล์แนบ: optional
ตัวอย่าง validation:
```ts
const onlineLessonSchema = z
.object({
title: z.string().min(1, "กรุณากรอกชื่อบทเรียน"),
description: z.string().optional(),
category: z.string().optional(),
videoUrl: z
.string()
.url("URL วิดีโอไม่ถูกต้อง")
.optional()
.or(z.literal("")),
videoFile: z.any().optional(),
attachmentFile: z.any().optional(),
status: z.enum(["draft", "published", "archived"]),
})
.refine((data) => data.videoUrl || data.videoFile, {
message: "กรุณาใส่ลิงก์วิดีโอหรืออัปโหลดไฟล์วิดีโอ",
path: ["videoUrl"],
});
```
---
## 10. Database / Prisma Model
เพิ่ม model สำหรับ OnlineLesson
```prisma
model OnlineLesson {
id String @id @default(cuid())
title String
description String? @db.Text
category String?
videoUrl String?
videoFileUrl String?
attachmentUrl String?
attachmentName String?
thumbnailUrl String?
status String @default("draft")
isPublished Boolean @default(false)
publishedAt DateTime?
createdBy String?
updatedBy String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
```
---
## 11. API / Actions
สร้าง server actions หรือ API สำหรับ:
- createOnlineLesson
- updateOnlineLesson
- deleteOnlineLesson
- getOnlineLessonsForAdmin
- getPublishedOnlineLessons
- getOnlineLessonById
- uploadOnlineLessonFile
---
## 12. Sidebar Menu
เพิ่มเมนูใน Sidebar
### สำหรับ HRD/Admin
```txt
เพิ่มบทเรียนออนไลน์
```
Icon แนะนำ:
- BookOpen
- Video
- GraduationCap
- FileVideo
### สำหรับ Employee
```txt
บทเรียนออนไลน์
```
Icon แนะนำ:
- BookOpen
- PlayCircle
- MonitorPlay
---
## 13. ข้อจำกัด
ห้ามกระทบเมนูเดิม เช่น:
- ประกาศ
- หลักสูตร
- ประวัติการอบรม
- รายชื่อพนักงาน
- รายงาน
ห้ามแก้ Business Logic เดิมของระบบอบรม
ให้เพิ่มเป็น Module ใหม่แยกออกมา
---
## 14. ผลลัพธ์ที่ต้องการ
เมื่อ HRD เพิ่มบทเรียนออนไลน์และตั้งสถานะเป็น Published
พนักงานจะเห็นบทเรียนนั้นในเมนู **บทเรียนออนไลน์**
พนักงานสามารถ:
- เปิดดูวิดีโอได้
- อ่านรายละเอียดบทเรียนได้
- ดาวน์โหลดไฟล์แนบได้
HRD สามารถ:
- จัดการบทเรียนทั้งหมดได้
- แก้ไขบทเรียนได้
- ลบบทเรียนได้
- เปิด/ปิดการเผยแพร่ได้