Spaces:
Running
Running
| <html lang="th"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>รวมทะเล ข้าวต้มปลา - แอดมิน</title> | |
| <link rel="stylesheet" href="style.css"> | |
| <style> | |
| .admin-table { width:100%; border-collapse: collapse; margin: 16px 0;} | |
| .admin-table th, .admin-table td { border: 1px solid #d0e5f7; padding: 7px 8px;} | |
| .admin-table th { background: #e6f3ff;} | |
| .admin-table td { font-size: 1.03em;} | |
| .delete-btn, .bill-btn { | |
| padding: 4px 10px; | |
| border-radius: 7px; | |
| border: none; | |
| background: #c92424; | |
| color: #fff; | |
| font-size: 0.99em; | |
| cursor: pointer; | |
| margin-left: 3px; | |
| } | |
| .bill-btn { background: #217722; margin-left:0;} | |
| .delete-btn:hover { background: #b30000;} | |
| .bill-btn:hover { background: #125a17;} | |
| .table-picker { margin-top: 10px; margin-bottom: 10px; } | |
| #admin-status { color: #2570b9; font-weight: bold; } | |
| @media (max-width:600px) { | |
| .admin-table td, .admin-table th { padding: 4px 2px; font-size: 0.96em;} | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <h1>รวมทะเล ข้าวต้มปลา <span style="font-size:0.6em;font-weight:400;">(admin)</span></h1> | |
| <label for="tableSel">เลือกโต๊ะ:</label> | |
| <select id="tableSel" class="table-picker"></select> | |
| <button class="bill-btn" id="billBtn" style="margin-left:12px;">เช็คบิลโต๊ะนี้</button> | |
| <div id="admin-status"></div> | |
| <div id="admin-order"></div> | |
| </div> | |
| <script> | |
| const scriptURL = "https://api.sheetbest.com/sheets/67a68e64-dca9-4eea-99b7-0431c5786cf6"; | |
| async function fetchAllOrders() { | |
| const res = await fetch(scriptURL); | |
| return await res.json(); | |
| } | |
| function getTableList(data) { | |
| // เอาเฉพาะเลขโต๊ะที่มีรายการ status = unpaid | |
| return [...new Set(data.filter(i=>i.status=="unpaid").map(i=>i.table).filter(Boolean))].sort((a,b)=>a-b); | |
| } | |
| function getOrderSummary(data, tableNum) { | |
| // SUM qty ทุกแถวที่ status=unpaid ของโต๊ะนี้ | |
| const rows = data.filter( | |
| i => String(i.table).trim() === String(tableNum) && (i.status ?? "unpaid") === "unpaid" | |
| ); | |
| const summary = {}; | |
| rows.forEach(row => { | |
| const qty = Number(row.qty || 1); | |
| if (!summary[row.menu]) summary[row.menu] = { qty: 0, price: Number(row.price) || 0 }; | |
| summary[row.menu].qty += qty; | |
| summary[row.menu].price = Number(row.price) || 0; | |
| }); | |
| // ไม่แสดงถ้า qty <= 0 | |
| Object.keys(summary).forEach(menu => { | |
| if (summary[menu].qty <= 0) delete summary[menu]; | |
| }); | |
| return summary; | |
| } | |
| async function renderAdminTable() { | |
| document.getElementById('admin-order').innerHTML = '<div style="color:#ccc">กำลังโหลด...</div>'; | |
| const data = await fetchAllOrders(); | |
| const tableList = getTableList(data); | |
| const sel = document.getElementById('tableSel'); | |
| sel.innerHTML = tableList.map(t=>`<option value="${t}">${t}</option>`).join(''); | |
| const curTable = sel.value || tableList[0]; | |
| if (!curTable) { | |
| document.getElementById('admin-order').innerHTML = "<div style='color:#bbb'>ยังไม่มีออเดอร์</div>"; | |
| document.getElementById('billBtn').disabled = true; | |
| return; | |
| } | |
| const summary = getOrderSummary(data, curTable); | |
| let total = 0; | |
| let html = `<table class="admin-table"> | |
| <tr> | |
| <th>เมนู</th><th>จำนวน</th><th>ราคา/หน่วย</th><th>รวม</th><th>ลบ</th> | |
| </tr>`; | |
| for (const [name, item] of Object.entries(summary)) { | |
| total += item.qty * item.price; | |
| html += `<tr> | |
| <td>${name}</td> | |
| <td>${item.qty}</td> | |
| <td>${item.price}</td> | |
| <td>${item.qty * item.price}</td> | |
| <td> | |
| <button class="delete-btn" onclick="deleteMenu('${curTable}','${name}',${item.price},1)">ลบ 1</button> | |
| <button class="delete-btn" onclick="deleteMenu('${curTable}','${name}',${item.price},${item.qty})">ลบทั้งหมด</button> | |
| </td> | |
| </tr>`; | |
| } | |
| html += `<tr> | |
| <td colspan="3" style="text-align:right;font-weight:bold;">รวม</td> | |
| <td style="font-weight:bold;color:#1b77c2;">${total}</td> | |
| <td></td> | |
| </tr></table>`; | |
| document.getElementById('admin-order').innerHTML = html; | |
| document.getElementById('billBtn').disabled = Object.keys(summary).length === 0; | |
| } | |
| // -- ลบเมนู (Soft Delete: เพิ่มแถวใหม่เป็น qty ติดลบ) -- | |
| async function deleteMenu(table, menu, price, qty) { | |
| if (!confirm(`ยืนยันลบ "${menu}" (${qty}) ?`)) return; | |
| await fetch(scriptURL, { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ | |
| table: table, | |
| menu: menu, | |
| price: price, | |
| qty: -qty, | |
| status: "unpaid", | |
| note: "admin delete" | |
| }) | |
| }); | |
| document.getElementById('admin-status').textContent = 'ลบเมนูเรียบร้อย!'; | |
| setTimeout(()=>{document.getElementById('admin-status').textContent='';},1000); | |
| renderAdminTable(); | |
| } | |
| // -- เช็คบิล (Soft Delete: ลบทุกเมนูในโต๊ะ) -- | |
| document.getElementById('billBtn').onclick = async function() { | |
| const table = document.getElementById('tableSel').value; | |
| const data = await fetchAllOrders(); | |
| const summary = getOrderSummary(data, table); | |
| if (Object.keys(summary).length === 0) return; | |
| if (!confirm(`เช็คบิลโต๊ะ ${table} และลบออเดอร์ทั้งหมด?`)) return; | |
| // ใส่แถว qty ติดลบของแต่ละเมนู | |
| for (const [name, item] of Object.entries(summary)) { | |
| if (item.qty > 0) { | |
| await fetch(scriptURL, { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ | |
| table: table, | |
| menu: name, | |
| price: item.price, | |
| qty: -item.qty, | |
| status: "unpaid", | |
| note: "admin bill" | |
| }) | |
| }); | |
| } | |
| } | |
| document.getElementById('admin-status').textContent = 'เช็คบิลสำเร็จ!'; | |
| setTimeout(()=>{document.getElementById('admin-status').textContent='';},1200); | |
| renderAdminTable(); | |
| } | |
| // -- อัปเดตรายการเมื่อเลือกโต๊ะ -- | |
| document.getElementById('tableSel').onchange = renderAdminTable; | |
| // -- init -- | |
| renderAdminTable(); | |
| </script> | |
| </body> | |
| </html> | |