รายละเอียดทั้งหมด
Prompt: สร้างระบบ Photo Album Gallery ด้วย Google Apps Script
เป้าหมาย
สร้างเว็บแอปพลิเคชันที่สมบูรณ์แบบสำหรับจัดเก็บและแสดงผลอัลบั้มรูปภาพโดยใช้ Google Apps Script, Google Drive และ Google Sheets เป็นฐานข้อมูล
ข้อกำหนดของไฟล์
ต้องสร้างไฟล์ 2 ไฟล์:
Code.gs: สำหรับโค้ดฝั่ง Backend ทั้งหมด
index.html: สำหรับโค้ดฝั่ง Frontend (HTML, CSS, JavaScript) ทั้งหมด
1. ข้อกำหนดสำหรับ Backend (Code.gs)
การเชื่อมต่อและฐานข้อมูล
Google Drive: ใช้ DRIVE_FOLDER_ID (ระบุ ID) เป็นโฟลเดอร์หลักในการจัดเก็บโฟลเดอร์ย่อยของแต่ละอัลบั้ม
Google Sheets (ฐานข้อมูล): ใช้ SPREADSHEET_ID (ระบุ ID) เป็นฐานข้อมูล
โครงสร้างชีต:
ชีต Albums: ต้องมีคอลัมน์: ID (UUID เฉพาะ), Name, Description, Created Date, Photo Count (ตัวเลข), View Count (ตัวเลข), Folder ID (รหัสโฟลเดอร์ใน Drive)
ชีต Photos: ต้องมีคอลัมน์: Photo ID (รหัสไฟล์ใน Drive), Album ID (เชื่อมโยงกับ Albums.ID), Filename, Created Date
ฟังก์ชัน Helper:
initializeSheet(spreadsheet, sheetName, headers): สำหรับสร้างชีต Albums และ Photos หากยังไม่มี
getColumnIndexes(sheet): สำหรับอ่านลำดับคอลัมน์จาก Header เพื่อให้โค้ดทนทานต่อการสลับคอลัมน์
ฟังก์ชันหลัก
getAlbums():
อ่านข้อมูลจากชีต Albums ทั้งหมด
ค้นหารูปหน้าปก (Cover Image) โดยการดึงรูปแรกจากชีต Photos ที่มี Album ID ตรงกัน (ต้องใช้วิธีที่มีประสิทธิภาพ เช่น การสร้าง Map ไม่ใช่การวนลูปเพื่อโทรหา Drive API)
ต้องเรียงลำดับอัลบั้มจาก "ใหม่สุดไปเก่าสุด" (ตาม Created Date descending)
ส่งคืนข้อมูลเป็น Array of Objects
getPhotos(albumId):
อ่านข้อมูลจากชีต Photos โดยกรองจาก albumId ที่ระบุเท่านั้น
ต้องเรียงลำดับรูปภาพจาก "ใหม่สุดไปเก่าสุด" (ตาม Created Date descending)
ส่งคืน URL สำหรับแสดงผล (ใช้ lh5.googleusercontent.com/d/FILE_ID) และ URL สำหรับดาวน์โหลด (ใช้ drive.google.com/uc?export=download&id=FILE_ID)
createAlbum(name, description):
สร้างโฟลเดอร์ใหม่ใน Google Drive ภายใต้ DRIVE_FOLDER_ID
เพิ่มแถวใหม่ในชีต Albums พร้อม ID (UUID), Name, Description, Created Date, Folder ID (จากโฟลเดอร์ที่เพิ่งสร้าง) และตั้งค่าเริ่มต้น Photo Count = 0, View Count = 0
uploadPhoto(albumId, fileName, base64Data, mimeType):
ค้นหา Folder ID จากชีต Albums โดยใช้ albumId
สร้างไฟล์รูปภาพจาก base64Data ในโฟลเดอร์นั้น
ตั้งค่าการแชร์ไฟล์เป็น "Anyone with the link can view"
เพิ่มแถวใหม่ในชีต Photos พร้อม Photo ID, Album ID, Filename, Created Date
เรียกใช้ updatePhotoCount(albumId)
ส่งคืนรายละเอียดไฟล์ (fileId, fileUrl, downloadUrl) กลับไปยัง Frontend
deleteAlbum(albumId):
ค้นหา Folder ID จากชีต Albums
สั่งย้ายโฟลเดอร์ใน Drive ไปที่ถังขยะ (.setTrashed(true))
ลบแถวของอัลบั้มออกจากชีต Albums
ลบแถวของรูปภาพทั้งหมดที่เกี่ยวข้องกับ albumId นี้ออกจากชีต Photos
deletePhoto(photoId, albumId):
สั่งย้ายไฟล์ใน Drive ไปที่ถังขยะ (.setTrashed(true))
ลบแถวของรูปภาพออกจากชีต Photos โดยใช้ photoId
เรียกใช้ updatePhotoCount(albumId)
updateAlbum(albumId, newName, newDescription):
อัปเดต Name และ Description ในแถวของอัลบั้มนั้นในชีต Albums
ค้นหา Folder ID และสั่งเปลี่ยนชื่อโฟลเดอร์ใน Drive ด้วย
Counters (ต้องใช้ LockService):
updatePhotoCount(albumId): นับจำนวนแถวในชีต Photos ที่ตรงกับ albumId แล้วอัปเดตตัวเลขในคอลัมน์ Photo Count ของชีต Albums
updateViewCount(albumId): เพิ่มค่า View Count ขึ้น 1 ในชีต Albums
2. ข้อกำหนดสำหรับ Frontend (index.html)
การออกแบบ (UI/UX)
Framework: ใช้ Bootstrap 5 และ Bootstrap Icons
Style:
พื้นหลังแบบ Gradient (ไล่สี)
ดีไซน์แบบ Card-based ที่ทันสมัยและตอบสนอง (Responsive)
ใช้ SweetAlert2 สำหรับการแจ้งเตือนทั้งหมด (ห้ามใช้ alert())
ต้องมี Loading Spinners แสดงระหว่างรอข้อมูลจาก Backend
โครงสร้างหน้า
สร้างเป็น Single Page Application (SPA) โดยใช้ JavaScript ในการสลับการแสดงผลระหว่าง 2 ส่วนหลัก:
Home View (#homeView):
Stats Dashboard: แสดงการ์ด 4 ใบ: อัลบั้มทั้งหมด, รูปภาพทั้งหมด, การดูทั้งหมด, รูปเฉลี่ยต่ออัลบั้ม
Search Bar: ช่องค้นหาสำหรับกรองอัลบั้ม (ทำงานฝั่ง Client-side) โดยค้นหาจาก album.name และ album.description
Album Grid (#albumsGrid): แสดงอัลบั้มทั้งหมดเป็นตารางแบบ Grid
ต้องมีสถานะ "ไม่พบอัลบั้ม" และ "ไม่พบผลการค้นหา"
Album View (#albumView):
Breadcrumb: สำหรับนำทางกลับหน้าหลัก
แสดงชื่อและคำอธิบายของอัลบั้มที่เลือก
Photo Grid (#photosGrid): แสดงรูปภาพทั้งหมดในอัลบั้มนั้น
ต้องมีสถานะ "ยังไม่มีรูปภาพ"
ฟังก์ชันการทำงาน
Admin Login:
ใช้รหัสผ่านแบบง่ายคือ admin1234
ใช้ sessionStorage เพื่อเก็บสถานะการล็อกอิน
แสดง/ซ่อนปุ่ม Admin (.admin-only, .admin-controls) ตามสถานะการล็อกอิน
ผู้ใช้ทั่วไป (Public):
สามารถดูอัลบั้มและรูปภาพได้
สามารถดาวน์โหลดรูปภาพได้ (ต้องมีปุ่มดาวน์โหลดที่รูปภาพแต่ละใบ)
ผู้ดูแลระบบ (Admin):
สามารถ สร้าง, แก้ไข, ลบ อัลบั้มได้
สามารถ อัปโหลด, ลบ รูปภาพได้
Photo Modal (Lightbox):
เมื่อคลิกที่รูปภาพ ให้แสดง Modal ขนาดใหญ่
ใน Modal ต้องแสดงชื่อไฟล์และปุ่มดาวน์โหลด
การนำทางรูปภาพ (สำคัญ):
ต้องมีปุ่มลูกศร "ถัดไป" (>) และ "ก่อนหน้า" (<) ภายใน Modal
ต้องรองรับการกดปุ่มลูกศรซ้าย/ขวาบนคีย์บอร์ดเพื่อเลื่อนดูรูปภาพถัดไป/ก่อนหน้าในอัลบั้มนั้นได้
การสื่อสาร:
ใช้ google.script.run เพื่อเรียกใช้ฟังก์ชันฝั่ง Code.gs ทั้งหมด