307 lines
7.2 KiB
Markdown
307 lines
7.2 KiB
Markdown
|
|
# Create Lesson with Files - Simplified API
|
||
|
|
|
||
|
|
## 📝 Create Lesson (One Request)
|
||
|
|
|
||
|
|
### POST `/instructor/courses/:courseId/chapters/:chapterId/lessons`
|
||
|
|
|
||
|
|
สร้าง lesson พร้อม video และ attachments ในครั้งเดียว
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Request Examples
|
||
|
|
|
||
|
|
### 1. Text Lesson (No Files)
|
||
|
|
|
||
|
|
```http
|
||
|
|
POST /api/instructor/courses/1/chapters/1/lessons
|
||
|
|
Authorization: Bearer <token>
|
||
|
|
Content-Type: application/json
|
||
|
|
|
||
|
|
{
|
||
|
|
"title": {
|
||
|
|
"th": "บทที่ 1: แนะนำ",
|
||
|
|
"en": "Lesson 1: Introduction"
|
||
|
|
},
|
||
|
|
"content": {
|
||
|
|
"th": "<p>เนื้อหาบทเรียน...</p>",
|
||
|
|
"en": "<p>Lesson content...</p>"
|
||
|
|
},
|
||
|
|
"type": "text",
|
||
|
|
"sort_order": 1,
|
||
|
|
"is_sequential": true
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 2. Video Lesson (Video Only)
|
||
|
|
|
||
|
|
```http
|
||
|
|
POST /api/instructor/courses/1/chapters/1/lessons
|
||
|
|
Authorization: Bearer <token>
|
||
|
|
Content-Type: multipart/form-data
|
||
|
|
|
||
|
|
title_th: "บทที่ 1: แนะนำ Python"
|
||
|
|
title_en: "Lesson 1: Introduction to Python"
|
||
|
|
content_th: "<p>Python เป็นภาษา...</p>"
|
||
|
|
content_en: "<p>Python is a...</p>"
|
||
|
|
type: "video"
|
||
|
|
sort_order: 1
|
||
|
|
video: <lesson-video.mp4>
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 201**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"id": 1,
|
||
|
|
"chapter_id": 1,
|
||
|
|
"title": {
|
||
|
|
"th": "บทที่ 1: แนะนำ Python",
|
||
|
|
"en": "Lesson 1: Introduction to Python"
|
||
|
|
},
|
||
|
|
"type": "video",
|
||
|
|
"video": {
|
||
|
|
"url": "https://cdn.example.com/videos/lesson-1.m3u8",
|
||
|
|
"duration": "00:15:30",
|
||
|
|
"file_size": 52428800
|
||
|
|
},
|
||
|
|
"attachments": [],
|
||
|
|
"created_at": "2024-12-23T15:00:00Z"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 3. Video + Attachments (Complete)
|
||
|
|
|
||
|
|
```http
|
||
|
|
POST /api/instructor/courses/1/chapters/1/lessons
|
||
|
|
Authorization: Bearer <token>
|
||
|
|
Content-Type: multipart/form-data
|
||
|
|
|
||
|
|
# Lesson Info
|
||
|
|
title_th: "บทที่ 1: แนะนำ Python"
|
||
|
|
title_en: "Lesson 1: Introduction to Python"
|
||
|
|
content_th: "<p>Python เป็นภาษา...</p>"
|
||
|
|
content_en: "<p>Python is a...</p>"
|
||
|
|
type: "video"
|
||
|
|
sort_order: 1
|
||
|
|
is_sequential: true
|
||
|
|
|
||
|
|
# Video
|
||
|
|
video: <lesson-video.mp4>
|
||
|
|
|
||
|
|
# Attachments
|
||
|
|
attachments[]: <slides.pdf>
|
||
|
|
attachments[]: <code.zip>
|
||
|
|
attachments[]: <exercises.docx>
|
||
|
|
|
||
|
|
# Attachment Descriptions
|
||
|
|
descriptions[0][th]: "สไลด์ประกอบการสอน"
|
||
|
|
descriptions[0][en]: "Lecture slides"
|
||
|
|
descriptions[1][th]: "โค้ดตัวอย่าง"
|
||
|
|
descriptions[1][en]: "Sample code"
|
||
|
|
descriptions[2][th]: "แบบฝึกหัด"
|
||
|
|
descriptions[2][en]: "Exercises"
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 201**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"id": 1,
|
||
|
|
"chapter_id": 1,
|
||
|
|
"title": {
|
||
|
|
"th": "บทที่ 1: แนะนำ Python",
|
||
|
|
"en": "Lesson 1: Introduction to Python"
|
||
|
|
},
|
||
|
|
"content": {
|
||
|
|
"th": "<p>Python เป็นภาษา...</p>",
|
||
|
|
"en": "<p>Python is a...</p>"
|
||
|
|
},
|
||
|
|
"type": "video",
|
||
|
|
"sort_order": 1,
|
||
|
|
"is_sequential": true,
|
||
|
|
|
||
|
|
"video": {
|
||
|
|
"url": "https://cdn.example.com/videos/lesson-1.m3u8",
|
||
|
|
"duration": "00:15:30",
|
||
|
|
"file_size": 52428800,
|
||
|
|
"uploaded_at": "2024-12-23T15:00:00Z"
|
||
|
|
},
|
||
|
|
|
||
|
|
"attachments": [
|
||
|
|
{
|
||
|
|
"id": 1,
|
||
|
|
"file_name": "slides.pdf",
|
||
|
|
"file_size": 2048576,
|
||
|
|
"mime_type": "application/pdf",
|
||
|
|
"description": {
|
||
|
|
"th": "สไลด์ประกอบการสอน",
|
||
|
|
"en": "Lecture slides"
|
||
|
|
},
|
||
|
|
"sort_order": 1,
|
||
|
|
"download_url": "/api/lessons/1/attachments/1/download"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"id": 2,
|
||
|
|
"file_name": "code.zip",
|
||
|
|
"file_size": 512000,
|
||
|
|
"mime_type": "application/zip",
|
||
|
|
"description": {
|
||
|
|
"th": "โค้ดตัวอย่าง",
|
||
|
|
"en": "Sample code"
|
||
|
|
},
|
||
|
|
"sort_order": 2,
|
||
|
|
"download_url": "/api/lessons/1/attachments/2/download"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"id": 3,
|
||
|
|
"file_name": "exercises.docx",
|
||
|
|
"file_size": 256000,
|
||
|
|
"mime_type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||
|
|
"description": {
|
||
|
|
"th": "แบบฝึกหัด",
|
||
|
|
"en": "Exercises"
|
||
|
|
},
|
||
|
|
"sort_order": 3,
|
||
|
|
"download_url": "/api/lessons/1/attachments/3/download"
|
||
|
|
}
|
||
|
|
],
|
||
|
|
|
||
|
|
"created_at": "2024-12-23T15:00:00Z"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 4. PDF Lesson (Attachments Only)
|
||
|
|
|
||
|
|
```http
|
||
|
|
POST /api/instructor/courses/1/chapters/1/lessons
|
||
|
|
Authorization: Bearer <token>
|
||
|
|
Content-Type: multipart/form-data
|
||
|
|
|
||
|
|
title_th: "บทที่ 2: เอกสารประกอบ"
|
||
|
|
title_en: "Lesson 2: Reading Materials"
|
||
|
|
type: "pdf"
|
||
|
|
sort_order: 2
|
||
|
|
|
||
|
|
attachments[]: <main-document.pdf>
|
||
|
|
attachments[]: <supplementary.pdf>
|
||
|
|
|
||
|
|
descriptions[0][th]: "เอกสารหลัก"
|
||
|
|
descriptions[0][en]: "Main document"
|
||
|
|
descriptions[1][th]: "เอกสารเพิ่มเติม"
|
||
|
|
descriptions[1][en]: "Supplementary material"
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Add More Files Later
|
||
|
|
|
||
|
|
ถ้าต้องการเพิ่มไฟล์ทีหลัง:
|
||
|
|
|
||
|
|
### POST `/instructor/courses/:courseId/lessons/:lessonId/attachments`
|
||
|
|
|
||
|
|
```http
|
||
|
|
POST /api/instructor/courses/1/lessons/1/attachments
|
||
|
|
Authorization: Bearer <token>
|
||
|
|
Content-Type: multipart/form-data
|
||
|
|
|
||
|
|
attachments[]: <additional-file.pdf>
|
||
|
|
descriptions[0][th]: "ไฟล์เพิ่มเติม"
|
||
|
|
descriptions[0][en]: "Additional file"
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Frontend Example
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
async function createLesson(courseId, chapterId, lessonData) {
|
||
|
|
const formData = new FormData();
|
||
|
|
|
||
|
|
// Basic info
|
||
|
|
formData.append('title_th', lessonData.title.th);
|
||
|
|
formData.append('title_en', lessonData.title.en);
|
||
|
|
formData.append('content_th', lessonData.content.th);
|
||
|
|
formData.append('content_en', lessonData.content.en);
|
||
|
|
formData.append('type', lessonData.type);
|
||
|
|
formData.append('sort_order', lessonData.sortOrder);
|
||
|
|
|
||
|
|
// Video (if exists)
|
||
|
|
if (lessonData.video) {
|
||
|
|
formData.append('video', lessonData.video);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Attachments (if exists)
|
||
|
|
if (lessonData.attachments && lessonData.attachments.length > 0) {
|
||
|
|
lessonData.attachments.forEach((file, index) => {
|
||
|
|
formData.append('attachments[]', file.file);
|
||
|
|
formData.append(`descriptions[${index}][th]`, file.description.th);
|
||
|
|
formData.append(`descriptions[${index}][en]`, file.description.en);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
const response = await fetch(
|
||
|
|
`/api/instructor/courses/${courseId}/chapters/${chapterId}/lessons`,
|
||
|
|
{
|
||
|
|
method: 'POST',
|
||
|
|
headers: {
|
||
|
|
'Authorization': `Bearer ${token}`
|
||
|
|
},
|
||
|
|
body: formData
|
||
|
|
}
|
||
|
|
);
|
||
|
|
|
||
|
|
return await response.json();
|
||
|
|
}
|
||
|
|
|
||
|
|
// Usage
|
||
|
|
const lesson = await createLesson(1, 1, {
|
||
|
|
title: {
|
||
|
|
th: 'บทที่ 1: แนะนำ',
|
||
|
|
en: 'Lesson 1: Introduction'
|
||
|
|
},
|
||
|
|
content: {
|
||
|
|
th: '<p>เนื้อหา...</p>',
|
||
|
|
en: '<p>Content...</p>'
|
||
|
|
},
|
||
|
|
type: 'video',
|
||
|
|
sortOrder: 1,
|
||
|
|
video: videoFile,
|
||
|
|
attachments: [
|
||
|
|
{
|
||
|
|
file: pdfFile,
|
||
|
|
description: { th: 'สไลด์', en: 'Slides' }
|
||
|
|
},
|
||
|
|
{
|
||
|
|
file: zipFile,
|
||
|
|
description: { th: 'โค้ด', en: 'Code' }
|
||
|
|
}
|
||
|
|
]
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Benefits
|
||
|
|
|
||
|
|
✅ **One Request** - ส่งครั้งเดียว ไม่ต้องส่งหลายรอบ
|
||
|
|
✅ **Atomic** - สร้างสำเร็จหรือ fail ทั้งหมด
|
||
|
|
✅ **Faster** - ลด HTTP requests
|
||
|
|
✅ **Better UX** - Instructor ไม่ต้องรอหลายขั้นตอน
|
||
|
|
✅ **Flexible** - เพิ่มไฟล์ทีหลังได้
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Summary
|
||
|
|
|
||
|
|
**Before**: 3 requests
|
||
|
|
1. Create lesson
|
||
|
|
2. Upload video
|
||
|
|
3. Upload attachments
|
||
|
|
|
||
|
|
**After**: 1 request
|
||
|
|
1. Create lesson with everything ✨
|