ต้องการเพิ่มฟีเจอร์ใหม่ในระบบ 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 สามารถ:

- จัดการบทเรียนทั้งหมดได้
- แก้ไขบทเรียนได้
- ลบบทเรียนได้
- เปิด/ปิดการเผยแพร่ได้
