ต้องการเพิ่มฟีเจอร์ใหม่ในระบบ 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 ``` ### ไฟล์แนบ ถ้ามีไฟล์แนบ ให้แสดงรายการไฟล์พร้อมปุ่ม: - ดาวน์โหลด - เปิดไฟล์ ถ้าไม่มีไฟล์แนบ ให้แสดงข้อความ: ```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 สามารถ: - จัดการบทเรียนทั้งหมดได้ - แก้ไขบทเรียนได้ - ลบบทเรียนได้ - เปิด/ปิดการเผยแพร่ได้