const { useState, useEffect } = React; const { Save, Check, Copy, FileText, Mail, ShieldAlert, Database, ExternalLink } = window.lucide; function SettingsPanel({ onSettingsSaved }) { const [settings, setSettings] = useState(null); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [copied, setCopied] = useState(false); const [success, setSuccess] = useState(false); useEffect(() => { fetchSettings(); }, []); const fetchSettings = async () => { try { const res = await fetch('api.php?action=settings'); if (res.ok) { const text = await res.text(); try { const data = JSON.parse(text); setSettings(data); } catch (jsonErr) { console.error('Expected JSON from api.php?action=settings but got HTML/text:', text.substring(0, 100)); } } } catch (e) { console.error('Failed to fetch settings:', e); } finally { setLoading(false); } }; const handleSave = async (e) => { e.preventDefault(); if (!settings) return; setSaving(true); setSuccess(false); try { const res = await fetch('api.php?action=settings', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(settings) }); if (res.ok) { setSuccess(true); if (onSettingsSaved) onSettingsSaved(); setTimeout(() => setSuccess(false), 3000); } } catch (err) { console.error('Failed to save settings:', err); } finally { setSaving(false); } }; const appsScriptCode = `function doPost(e) { try { var data = JSON.parse(e.postData.contents); var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); // หากชีตว่างเปล่า ให้สร้างหัวคอลัมน์ (Headers) if (sheet.getLastRow() == 0) { sheet.appendRow([ "วันที่ประมวลผล (Timestamp)", "แพลตฟอร์ม (Category)", "เลขที่สั่งซื้อ (Order ID)", "ชื่อผู้รับ (Customer Name)", "ชื่อสินค้า (Product Name)", "ราคาต่อหน่วย (Unit Price)", "จำนวน (Quantity)", "จำนวนเงินรวม (Item Amount)", "ยอดชำระทั้งสิ้น (Total Paid Amount)" ]); } // เพิ่มข้อมูลสินค้าทีละแถวลงในชีต data.items.forEach(function(item) { sheet.appendRow([ new Date(data.timestamp).toLocaleString("th-TH"), data.category, data.orderId || "", data.customerName || "", item.productName, item.price, item.quantity, item.amount, data.totalAmount ]); }); return ContentService.createTextOutput(JSON.stringify({ status: "success", message: "Rows appended successfully" })) .setMimeType(ContentService.MimeType.JSON); } catch (error) { return ContentService.createTextOutput(JSON.stringify({ status: "error", message: error.toString() })) .setMimeType(ContentService.MimeType.JSON); } }`; const handleCopyScript = () => { navigator.clipboard.writeText(appsScriptCode); setCopied(true); setTimeout(() => setCopied(false), 2000); }; if (loading) { return (
); } if (!settings) { return
ผิดพลาดในการโหลดตั้งค่า
; } return (
{/* Settings Form */}

การตั้งค่าระบบเชื่อมต่อ (System Configurations)

{/* Section 1: Google Sheets */}

1. Google Sheets Integration

ส่งข้อมูลสแกนไปยัง Google Sheet ของคุณอัตโนมัติ

{settings.sheetsEnabled && (
setSettings({ ...settings, sheetsWebhookUrl: e.target.value })} className="w-full text-sm px-4 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-indigo-100 focus:border-indigo-500 outline-none transition-all" />
setSettings({ ...settings, googleSheetUrl: e.target.value })} className="w-full text-sm px-4 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-indigo-100 focus:border-indigo-500 outline-none transition-all" />
)}
{/* Section 2: Email Notification */}

2. Email Notification System

แจ้งเตือนข้อมูลสรุปทันทีเมื่อสแกนเสร็จสิ้น

{settings.emailEnabled && (
setSettings({ ...settings, targetEmail: e.target.value })} className="w-full text-sm px-4 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-indigo-100 focus:border-indigo-500 outline-none transition-all" />

* ระบบเปิดใช้งานแบบจำลองจดหมาย (Simulated Mail) ทันทีเพื่อบันทึกและแสดงผล HTML อีเมลที่แท้จริงให้ทดสอบดูได้ในแถบ "จดหมายแจ้งเตือน"

ตั้งค่า SMTP เพื่อส่งอีเมลจริง (ถ้ามี)
setSettings({ ...settings, smtpHost: e.target.value })} className="w-full text-xs px-3 py-1.5 bg-white border border-gray-200 rounded" />
setSettings({ ...settings, smtpPort: parseInt(e.target.value) || 0 })} className="w-full text-xs px-3 py-1.5 bg-white border border-gray-200 rounded" />
setSettings({ ...settings, smtpUser: e.target.value })} className="w-full text-xs px-3 py-1.5 bg-white border border-gray-200 rounded" />
setSettings({ ...settings, smtpPass: e.target.value })} className="w-full text-xs px-3 py-1.5 bg-white border border-gray-200 rounded" />
setSettings({ ...settings, smtpSecure: e.target.checked })} className="rounded text-indigo-600 focus:ring-indigo-500" />
)}
{/* Section 3: Gemini API Key */}

3. Custom Gemini API Key

ใส่ API Key ของคุณเองเพื่อนำระบบไปรันใช้งานจริงภายนอกได้อิสระ

setSettings({ ...settings, geminiApiKey: e.target.value })} className="w-full text-sm px-4 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-indigo-100 focus:border-indigo-500 outline-none transition-all font-mono" />

💡 วิธีเอาคีย์ฟรีมาใช้: ไปที่ Google AI Studio ล็อกอินด้วย Gmail แล้วกดปุ่ม "Get API key" เพื่อสร้างคีย์ส่วนตัวฟรีได้เลยครับ!

{success ? ( บันทึกการตั้งค่าเรียบร้อยแล้ว! ) : }
{/* Tutorial panel on Google Apps Script */}

โค้ด Google Apps Script

ก๊อปปี้โค้ด JavaScript ด้านล่างนี้ไปวางในเครื่องมือ Apps Script ของ Google Sheets เพื่อเชื่อมต่อแบบเรียลไทม์:

{appsScriptCode}
{/* Setup Instructions card */}

ขั้นตอนการเชื่อมต่อ Google Sheets ใน 3 นาที

  1. เปิด Google Sheet ใหม่ขึ้นมา จากนั้นกดที่เมนู ส่วนขยาย > Apps Script (Extensions)
  2. ลบโค้ดเริ่มต้นออกให้หมด แล้ววางโค้ดที่คุณเพิ่งคัดลอกจากด้านบนลงไป
  3. กดปุ่ม บันทึก (Save) ด้านบน จากนั้นกดปุ่ม การทำให้ใช้งานได้ใหม่ > การทำให้ใช้งานได้รายการใหม่ (New Deployment)
  4. เลือกประเภทเป็น เว็บแอป (Web App) ตั้งค่ารายละเอียดดังนี้:
    • เรียกใช้ในฐานะ: ฉัน (อีเมลของคุณ)
    • ผู้มีสิทธิ์เข้าถึง: ทุกคน (Anyone)
  5. กด ทำให้ใช้งานได้ (Deploy) แล้วอนุญาตสิทธิ์เข้าถึงให้เรียบร้อย (กด Advanced > Go to Untitled project และ Allow)
  6. คัดลอก URL เว็บแอป (Web App URL) ที่ได้ มากรอกลงในช่อง Webhook URL ฝั่งซ้าย แล้วบันทึก!
{settings.googleSheetUrl && (
เข้าดู Google Sheet ของคุณ
)}
); } window.SettingsPanel = SettingsPanel;