diff --git a/admin/order_view.php b/admin/order_view.php index adb4672..debcb03 100644 --- a/admin/order_view.php +++ b/admin/order_view.php @@ -14,7 +14,7 @@ if (!$id) { // Fetch Order Details $stmt = $pdo->prepare("SELECT o.*, ot.name as outlet_name, pt.name as payment_type_name, - c.name as customer_name, c.phone as customer_phone, c.email as customer_email, c.address as customer_address, + c.name as customer_name, c.phone as customer_phone, c.email as customer_email, c.address as customer_address, o.car_plate, u.username as created_by_username FROM orders o LEFT JOIN outlets ot ON o.outlet_id = ot.id @@ -293,6 +293,13 @@ $vat_rate = (float)($company_settings['vat_rate'] ?? 0); Customer ID: # + +
+ + Car Plate: + +
+
diff --git a/admin/orders.php b/admin/orders.php index fa9ad9f..9422f25 100644 --- a/admin/orders.php +++ b/admin/orders.php @@ -282,6 +282,7 @@ include 'includes/header.php'; Cashier Customer Type + Car Plate VAT Total @@ -309,6 +310,9 @@ include 'includes/header.php';
+ +
+ diff --git a/api/kitchen.php b/api/kitchen.php index fca76e8..19a2acb 100644 --- a/api/kitchen.php +++ b/api/kitchen.php @@ -14,7 +14,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { // Kitchen sees: pending, preparing, ready $stmt = $pdo->prepare(" SELECT - o.id, o.table_number, o.order_type, o.status, o.created_at, o.customer_name, + o.id, o.table_number, o.order_type, o.status, o.created_at, o.ready_time, o.customer_name, o.car_plate, o.user_id, oi.quantity, COALESCE(p.name, oi.product_name) as product_name, COALESCE(v.name, oi.variant_name) as variant_name FROM orders o JOIN order_items oi ON o.id = oi.order_id @@ -38,6 +38,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { 'status' => $row['status'], 'created_at' => $row['created_at'], 'customer_name' => $row['customer_name'], + 'car_plate' => $row['car_plate'], + 'ready_time' => $row['ready_time'], +'user_id' => $row['user_id'], 'is_online_order' => ($row['user_id'] === null && $row['order_type'] !== 'dine-in'), 'is_table_order' => ($row['user_id'] === null && $row['order_type'] === 'dine-in'), 'items' => [] ]; } diff --git a/api/order.php b/api/order.php index e316b43..7f47608 100644 --- a/api/order.php +++ b/api/order.php @@ -70,9 +70,37 @@ try { } // Customer Handling + $register_customer = !empty($data['register_customer']); $customer_id = !empty($data['customer_id']) ? intval($data['customer_id']) : null; $customer_name = $data['customer_name'] ?? null; $customer_phone = $data['customer_phone'] ?? null; + $car_plate = $data['car_plate'] ?? null; + $prep_time_minutes = isset($data['prep_time_minutes']) ? intval($data['prep_time_minutes']) : null; + $ready_time = null; + if ($prep_time_minutes > 0) { + $ready_time = date("Y-m-d H:i:s", strtotime("+$prep_time_minutes minutes")); + } + + $register_customer = !empty($data['register_customer']); + if (!$customer_id && $customer_phone && $register_customer) { + $stmt = $pdo->prepare("SELECT id FROM customers WHERE phone = ?"); + $stmt->execute([$customer_phone]); + $existing = $stmt->fetch(); + if ($existing) { + $customer_id = $existing['id']; + } else { + $stmt = $pdo->prepare("INSERT INTO customers (name, phone) VALUES (?, ?)"); + $stmt->execute([$customer_name, $customer_phone]); + $customer_id = $pdo->lastInsertId(); + } + } else if (!$customer_id && $customer_phone && !$register_customer) { + $stmt = $pdo->prepare("SELECT id FROM customers WHERE phone = ?"); + $stmt->execute([$customer_phone]); + $existing = $stmt->fetch(); + if ($existing) { + $customer_id = $existing['id']; + } + } // Fetch Loyalty Settings $settingsStmt = $pdo->query("SELECT is_enabled, points_per_order, points_for_free_meal FROM loyalty_settings WHERE id = 1"); @@ -309,13 +337,13 @@ try { if ($is_update) { $stmt = $pdo->prepare("UPDATE orders SET outlet_id = ?, table_id = ?, table_number = ?, order_type = ?, - customer_id = ?, customer_name = ?, customer_phone = ?, + customer_id = ?, customer_name = ?, customer_phone = ?, car_plate = ?, ready_time = ?, payment_type_id = ?, total_amount = ?, discount = ?, vat = ?, user_id = ?, commission_amount = ?, status = 'pending' WHERE id = ?"); $stmt->execute([ $outlet_id, $table_id, $table_number, $order_type, - $customer_id, $customer_name, $customer_phone, + $customer_id, $customer_name, $customer_phone, $car_plate, $ready_time, $payment_type_id, $final_total, 0, $calculated_vat, $user_id, $commission_amount, $order_id ]); @@ -323,8 +351,8 @@ try { $delStmt = $pdo->prepare("DELETE FROM order_items WHERE order_id = ?"); $delStmt->execute([$order_id]); } else { - $stmt = $pdo->prepare("INSERT INTO orders (outlet_id, table_id, table_number, order_type, customer_id, customer_name, customer_phone, payment_type_id, total_amount, discount, vat, user_id, commission_amount, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'pending')"); - $stmt->execute([$outlet_id, $table_id, $table_number, $order_type, $customer_id, $customer_name, $customer_phone, $payment_type_id, $final_total, 0, $calculated_vat, $user_id, $commission_amount]); + $stmt = $pdo->prepare("INSERT INTO orders (outlet_id, table_id, table_number, order_type, customer_id, customer_name, customer_phone, car_plate, ready_time, payment_type_id, total_amount, discount, vat, user_id, commission_amount, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'pending')"); + $stmt->execute([$outlet_id, $table_id, $table_number, $order_type, $customer_id, $customer_name, $customer_phone, $car_plate, $ready_time, $payment_type_id, $final_total, 0, $calculated_vat, $user_id, $commission_amount]); $order_id = $pdo->lastInsertId(); } diff --git a/assets/js/main.js b/assets/js/main.js index 232d351..5f0b592 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -25,6 +25,7 @@ document.addEventListener('DOMContentLoaded', () => { } }) : null; + window.showToast = showToast; function showToast(msg, type = 'primary') { if (!Toast) { console.log(`Toast: ${msg} (${type})`); diff --git a/customer_profile.php b/customer_profile.php new file mode 100644 index 0000000..d62439b --- /dev/null +++ b/customer_profile.php @@ -0,0 +1,143 @@ +prepare("SELECT * FROM customers WHERE phone = ?"); + $stmt->execute([$phone]); + $customer = $stmt->fetch(PDO::FETCH_ASSOC); + if ($customer) { + $stmt_orders = $pdo->prepare("SELECT o.id, o.created_at, o.total_amount, o.status, o.car_plate, o.ready_time, + (SELECT GROUP_CONCAT(CONCAT(oi.quantity, 'x ', oi.product_name) SEPARATOR ', ') FROM order_items oi WHERE oi.order_id = o.id) as items_summary + FROM orders o WHERE o.customer_id = ? ORDER BY o.created_at DESC"); + $stmt_orders->execute([$customer['id']]); + $orders = $stmt_orders->fetchAll(PDO::FETCH_ASSOC); + $stmt_points = $pdo->prepare("SELECT * FROM loyalty_points_history WHERE customer_id = ? ORDER BY created_at DESC"); + $stmt_points->execute([$customer['id']]); + $points_history = $stmt_points->fetchAll(PDO::FETCH_ASSOC); + } else { + $error = "Customer not found with this phone number."; + } +} +?> + + + + + + My Profile - <?= htmlspecialchars($settings['company_name'] ?? 'Order Online') ?> + + + + + + +
+ +

My Profile

+

View orders & loyalty points

+
+
+ +
+

Login to view profile

+ +
+ +
+
+ + +
+ +
+
+ +
+
Welcome back,
+

+
+
Available Points
+ +
+
+
Order History
+ +

No orders found.

+ + +
+
+ Order # + +
+
+
+
+ +
+ +
OMR
+
+ + +
Points History
+ +

No points history found.

+ +
+
+ +
+
+
+
+
+
+
+ 0 ? '+' : '' ?> +
+
+
+ +
+
+ +
+ Logout +
+ +
+ + + diff --git a/db/migrations/047_add_car_plate_to_orders.sql b/db/migrations/047_add_car_plate_to_orders.sql new file mode 100644 index 0000000..4391e9b --- /dev/null +++ b/db/migrations/047_add_car_plate_to_orders.sql @@ -0,0 +1,18 @@ +-- Add car_plate column to orders table +SET @dbname = DATABASE(); +SET @tablename = "orders"; +SET @columnname = "car_plate"; +SET @preparedStatement = (SELECT IF( + ( + SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS + WHERE + (table_name = @tablename) + AND (table_schema = @dbname) + AND (column_name = @columnname) + ) > 0, + "SELECT 1", + "ALTER TABLE orders ADD COLUMN car_plate VARCHAR(50) DEFAULT NULL AFTER customer_phone;" +)); +PREPARE alterIfNotExists FROM @preparedStatement; +EXECUTE alterIfNotExists; +DEALLOCATE PREPARE alterIfNotExists; diff --git a/db/migrations/048_add_ready_time_to_orders.sql b/db/migrations/048_add_ready_time_to_orders.sql new file mode 100644 index 0000000..bf4395a --- /dev/null +++ b/db/migrations/048_add_ready_time_to_orders.sql @@ -0,0 +1 @@ +ALTER TABLE orders ADD COLUMN ready_time DATETIME NULL AFTER created_at; \ No newline at end of file diff --git a/includes/PrinterService.php b/includes/PrinterService.php index 92fc9f8..9707195 100644 --- a/includes/PrinterService.php +++ b/includes/PrinterService.php @@ -59,6 +59,15 @@ class PrinterService { $out .= $esc . "a" . "\x00"; // Left align $out .= "Order ID: #" . $order['id'] . "\n"; $out .= "Date: " . ($order['created_at'] ?? date('Y-m-d H:i:s')) . "\n"; + if (!empty($order['customer_name'])) { + $out .= "Customer: " . $order['customer_name'] . "\n"; + } + if (!empty($order['customer_phone'])) { + $out .= "Phone: " . $order['customer_phone'] . "\n"; + } + if (!empty($order['car_plate'])) { + $out .= "Car Plate: " . $order['car_plate'] . "\n"; + } $out .= $line; foreach ($items as $item) { diff --git a/index.php b/index.php index a943053..3b818a6 100644 --- a/index.php +++ b/index.php @@ -230,6 +230,11 @@ $baseUrl = get_base_url(); + + +

Online Order

+

Place an order for pickup or delivery.

+
diff --git a/kitchen.php b/kitchen.php index 6d21885..c57994d 100644 --- a/kitchen.php +++ b/kitchen.php @@ -147,12 +147,74 @@ const COMPANY_SETTINGS = ; const BASE_URL = ''; let activeOrders = []; +let seenOrderIds = new Set(); +let isFirstLoad = true; +const audioCtx = new (window.AudioContext || window.webkitAudioContext)(); + +document.addEventListener('click', () => { + if (audioCtx && audioCtx.state === 'suspended') { + audioCtx.resume(); + } +}); + +function playOnlineSound() { + if (audioCtx && audioCtx.state === 'suspended') audioCtx.resume(); + [0, 0.15, 0.3].forEach(startTime => { + const osc = audioCtx.createOscillator(); + const gainNode = audioCtx.createGain(); + osc.type = 'square'; + osc.frequency.setValueAtTime(800, audioCtx.currentTime + startTime); + gainNode.gain.setValueAtTime(0.1, audioCtx.currentTime + startTime); + gainNode.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + startTime + 0.1); + osc.connect(gainNode); + gainNode.connect(audioCtx.destination); + osc.start(audioCtx.currentTime + startTime); + osc.stop(audioCtx.currentTime + startTime + 0.15); + }); +} + +function playTableSound() { + if (audioCtx && audioCtx.state === 'suspended') audioCtx.resume(); + [0, 0.3].forEach(startTime => { + const osc = audioCtx.createOscillator(); + const gainNode = audioCtx.createGain(); + osc.type = 'sine'; + osc.frequency.setValueAtTime(500, audioCtx.currentTime + startTime); + gainNode.gain.setValueAtTime(0.2, audioCtx.currentTime + startTime); + gainNode.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + startTime + 0.25); + osc.connect(gainNode); + gainNode.connect(audioCtx.destination); + osc.start(audioCtx.currentTime + startTime); + osc.stop(audioCtx.currentTime + startTime + 0.3); + }); +} async function fetchOrders() { try { const response = await fetch('api/kitchen.php?outlet_id=' + OUTLET_ID); if (!response.ok) throw new Error('Network response was not ok'); const orders = await response.json(); + + let newOnlineCount = 0; + let newTableCount = 0; + + orders.forEach(order => { + if (!seenOrderIds.has(order.id)) { + if (!isFirstLoad) { + if (order.is_online_order) newOnlineCount++; + else if (order.is_table_order) newTableCount++; + } + seenOrderIds.add(order.id); + } + }); + + if (newOnlineCount > 0) { + playOnlineSound(); + } else if (newTableCount > 0) { + playTableSound(); + } + + isFirstLoad = false; activeOrders = orders; renderOrders(orders); } catch (error) { @@ -160,6 +222,21 @@ async function fetchOrders() { } } +function updateTimers() { + document.querySelectorAll('.countdown-timer').forEach(el => { const readyTime = parseInt(el.getAttribute('data-ready-time')); + const now = new Date().getTime(); + const diff = readyTime - now; + if (diff > 0) { + const m = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); + const s = Math.floor((diff % (1000 * 60)) / 1000); + el.querySelector('span').innerText = `Ready in: ${m}m ${s}s`; + } else { + el.querySelector('span').innerText = 'Should be ready!'; + } + }); +} +setInterval(updateTimers, 1000); + function renderOrders(orders) { const grid = document.getElementById('kitchen-grid'); @@ -207,6 +284,8 @@ function renderOrders(orders) {
${order.order_type === 'dine-in' ? `Table ${order.table_number}` : order.order_type.toUpperCase()} ${order.customer_name ? `
${order.customer_name}` : ''} + ${order.car_plate ? `
${order.car_plate}` : ''} + ${order.ready_time ? `
` : ''}
diff --git a/online_order.php b/online_order.php new file mode 100644 index 0000000..97daad1 --- /dev/null +++ b/online_order.php @@ -0,0 +1,894 @@ + [ + 'order_online' => 'اطلب عبر الإنترنت', + 'my_profile_points' => 'ملفي الشخصي والنقاط', + 'table' => 'طاولة', + 'all' => 'الكل', + 'add_to_cart' => 'أضف إلى السلة', + 'options' => 'الخيارات', + 'view_cart' => 'عرض السلة', + 'review_order' => 'مراجعة الطلب', + 'name' => 'الاسم', + 'your_name' => 'اسمك', + 'phone' => 'رقم الهاتف', + 'your_phone' => 'رقم هاتفك', + 'car_plate' => 'رقم لوحة السيارة (اختياري)', + 'car_plate_placeholder' => 'مثال: 1234 أ', + 'ready_in' => 'وقت التحضير', + 'ready_asap' => 'في أسرع وقت', + 'ready_10m' => 'بعد 10 دقائق', + 'ready_15m' => 'بعد 15 دقيقة', + 'ready_20m' => 'بعد 20 دقيقة', + 'ready_30m' => 'بعد 30 دقيقة', + 'register_to_earn' => 'سجل لكسب النقاط وعرض السجل', + 'subtotal' => 'المجموع الفرعي', + 'total' => 'المجموع', + 'place_order' => 'تأكيد الطلب', + 'please_select_option' => 'يرجى تحديد خيار', + 'please_enter_details' => 'يرجى إدخال اسمك ورقم هاتفك.', + 'order_placed_success' => 'تم الطلب بنجاح!', + 'error' => 'خطأ:', + 'failed_to_place' => 'فشل في إتمام الطلب. يرجى المحاولة مرة أخرى.', + 'all_rights_reserved' => 'جميع الحقوق محفوظة.', + 'not_found' => 'لم يتم العثور على الطاولة. يرجى الاتصال بالموظفين.', + 'language' => 'English' + ], + 'en' => [ + 'order_online' => 'Order Online', + 'my_profile_points' => 'My Profile & Points', + 'table' => 'Table', + 'all' => 'All', + 'add_to_cart' => 'Add to Cart', + 'options' => 'Options', + 'view_cart' => 'View Cart', + 'review_order' => 'Review Order', + 'name' => 'Name', + 'your_name' => 'Your Name', + 'phone' => 'Phone', + 'your_phone' => 'Your Phone Number', + 'car_plate' => 'Car Plate No. (Optional)', + 'car_plate_placeholder' => 'e.g. 1234 A', + 'ready_in' => 'Ready In', + 'ready_asap' => 'ASAP', + 'ready_10m' => 'After 10 mins', + 'ready_15m' => 'After 15 mins', + 'ready_20m' => 'After 20 mins', + 'ready_30m' => 'After 30 mins', + 'register_to_earn' => 'Register to earn points and view history', + 'subtotal' => 'Subtotal', + 'total' => 'Total', + 'place_order' => 'Place Order', + 'please_select_option' => 'Please select an option', + 'please_enter_details' => 'Please enter your name and phone number.', + 'order_placed_success' => 'Order placed successfully!', + 'error' => 'Error:', + 'failed_to_place' => 'Failed to place order. Please try again.', + 'all_rights_reserved' => 'All rights reserved.', + 'not_found' => 'Table not found. Please contact staff.', + 'language' => 'عربي' + ] +]; + +function tt($key) { + global $translations, $lang; + return $translations[$lang][$key] ?? $key; +} + +$pdo = db(); +$settings = get_company_settings(); + +$table_id = isset($_GET['table_id']) ? (int)$_GET['table_id'] : (isset($_GET['table']) ? (int)$_GET['table'] : 0); +$table_info = null; + +if ($table_id === 0 && isset($_GET['table_number'])) { + $stmt = $pdo->prepare('SELECT id FROM `tables` WHERE table_number = ? AND is_deleted = 0 LIMIT 1'); + $stmt->execute([$_GET['table_number']]); + $table_id = (int)$stmt->fetchColumn(); +} +if ($table_id > 0) { + try { + $stmt = $pdo->prepare(" + SELECT t.id, t.table_number AS table_name, a.outlet_id, o.name AS outlet_name, o.name_ar AS outlet_name_ar + FROM `tables` t + JOIN areas a ON t.area_id = a.id + JOIN outlets o ON a.outlet_id = o.id + WHERE t.id = ? + "); + $stmt->execute([$table_id]); + $table_info = $stmt->fetch(); + + if (!$table_info) { + die(tt('not_found')); + } + } catch (PDOException $e) { + die("Database error: " . $e->getMessage()); + } +} + +$outlet_id = (int)($table_info['outlet_id'] ?? 0); +$categories = $pdo->query("SELECT * FROM categories WHERE is_deleted = 0 ORDER BY sort_order")->fetchAll(); +$all_products = $pdo->query("SELECT p.*, c.name as category_name, c.name_ar as category_name_ar FROM products p JOIN categories c ON p.category_id = c.id WHERE p.is_deleted = 0 AND p.show_in_qorder = 1 AND c.is_deleted = 0")->fetchAll(); + +// Fetch variants +$variants_raw = $pdo->query("SELECT * FROM product_variants WHERE is_deleted = 0 ORDER BY price_adjustment ASC")->fetchAll(); +$variants_by_product = []; +foreach ($variants_raw as $v) { + $variants_by_product[$v['product_id']][] = $v; +} + +// Build translated structures for JS +$js_products = array_map(function($p) use ($is_ar) { + $p['display_name'] = ($is_ar && !empty($p['name_ar'])) ? $p['name_ar'] : $p['name']; + return $p; +}, $all_products); + +$js_variants = []; +foreach ($variants_by_product as $pid => $vars) { + $js_variants[$pid] = array_map(function($v) use ($is_ar) { + $v['display_name'] = ($is_ar && !empty($v['name_ar'])) ? $v['name_ar'] : $v['name']; + return $v; + }, $vars); +} +?> + + + + + + <?= htmlspecialchars($settings['company_name'] ?? tt('order_online')) ?> + + + + + + + + + + + + + + + +
+
+ + + + + + + + +

+

+ +

+
+ +
+
+ +
+
+
+ +
+ + + + +
+ +
+
+
+ + <?= htmlspecialchars($p['display_name']) ?> + +
+ +
+
+

+
+ + +
+
+
+
+ +
+
+ + + + + +
+
+ 0 + 0.00 +
+ + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/patch_badge.php b/patch_badge.php deleted file mode 100644 index 2b45e29..0000000 --- a/patch_badge.php +++ /dev/null @@ -1,23 +0,0 @@ - - - Loyalty - - -HTML; - -$replace = $search . << - - QR Menu - - -HTML; - -$content = str_replace($search, $replace, $content); -file_put_contents('admin/products.php', $content); -echo "Badge added.\n"; \ No newline at end of file diff --git a/pos.php b/pos.php index 8ae9e51..ecf1d4d 100644 --- a/pos.php +++ b/pos.php @@ -486,6 +486,87 @@ $vat_rate = (float)($settings['vat_rate'] ?? 0); } }; const t = (key) => translations[LANG][key] || key; + + // --- Audio Notifications Polling --- + let seenOrderIds = new Set(); + let isFirstLoad = true; + const audioCtx = new (window.AudioContext || window.webkitAudioContext)(); + + document.addEventListener('click', () => { + if (audioCtx && audioCtx.state === 'suspended') { + audioCtx.resume(); + } + }); + + function playOnlineSound() { + if (audioCtx && audioCtx.state === 'suspended') audioCtx.resume(); + [0, 0.15, 0.3].forEach(startTime => { + const osc = audioCtx.createOscillator(); + const gainNode = audioCtx.createGain(); + osc.type = 'square'; + osc.frequency.setValueAtTime(800, audioCtx.currentTime + startTime); + gainNode.gain.setValueAtTime(0.1, audioCtx.currentTime + startTime); + gainNode.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + startTime + 0.1); + osc.connect(gainNode); + gainNode.connect(audioCtx.destination); + osc.start(audioCtx.currentTime + startTime); + osc.stop(audioCtx.currentTime + startTime + 0.15); + }); + } + + function playTableSound() { + if (audioCtx && audioCtx.state === 'suspended') audioCtx.resume(); + [0, 0.3].forEach(startTime => { + const osc = audioCtx.createOscillator(); + const gainNode = audioCtx.createGain(); + osc.type = 'sine'; + osc.frequency.setValueAtTime(500, audioCtx.currentTime + startTime); + gainNode.gain.setValueAtTime(0.2, audioCtx.currentTime + startTime); + gainNode.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + startTime + 0.25); + osc.connect(gainNode); + gainNode.connect(audioCtx.destination); + osc.start(audioCtx.currentTime + startTime); + osc.stop(audioCtx.currentTime + startTime + 0.3); + }); + } + + async function pollForNewOrders() { + if (!CURRENT_OUTLET || !CURRENT_OUTLET.id) return; + try { + const response = await fetch('api/kitchen.php?outlet_id=' + CURRENT_OUTLET.id); + if (!response.ok) return; + const orders = await response.json(); + + let newOnlineCount = 0; + let newTableCount = 0; + + orders.forEach(order => { + if (!seenOrderIds.has(order.id)) { + if (!isFirstLoad) { + if (order.is_online_order) newOnlineCount++; + else if (order.is_table_order) newTableCount++; + } + seenOrderIds.add(order.id); + } + }); + + if (newOnlineCount > 0) { + playOnlineSound(); + if (typeof showToast === 'function') showToast('New Online Order!', 'warning'); + } else if (newTableCount > 0) { + playTableSound(); + if (typeof showToast === 'function') showToast('New Table Order!', 'info'); + } + + isFirstLoad = false; + } catch (e) { + // Ignore polling errors + } + } + + setInterval(pollForNewOrders, 10000); + pollForNewOrders(); + // ------------------------------------