ruamtalayAdmin / index.html
zenityx's picture
Update index.html
b067224 verified
<!DOCTYPE html>
<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>