Autosave: 20260224-140900

This commit is contained in:
Flatlogic Bot 2026-02-24 14:09:00 +00:00
parent a8bbec67c9
commit 68b1e34fe9
3 changed files with 323 additions and 1172 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

File diff suppressed because it is too large Load Diff

490
pos.php
View File

@ -85,21 +85,47 @@ if (!$loyalty_settings) {
<link rel="stylesheet" href="assets/css/custom.css?v=<?= time() ?>">
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<style>
body { height: 100vh; overflow: hidden; font-family: 'Inter', 'Noto Sans Arabic', sans-serif; } /* Fix body for scrolling areas */
body { height: 100vh; overflow: hidden; font-family: 'Inter', 'Noto Sans Arabic', sans-serif; background: #f4f7f6; }
.scrollable-y { overflow-y: auto; height: 100%; scrollbar-width: thin; }
.category-sidebar { height: calc(100vh - 60px); background: #f8f9fa; }
.product-area { height: calc(100vh - 60px); background: #fff; }
.cart-sidebar { height: calc(100vh - 60px); background: #fff; border-left: 1px solid #dee2e6; display: flex; flex-direction: column; }
.product-card { transition: transform 0.1s; cursor: pointer; }
.product-card:active { transform: scale(0.98); }
.category-btn { text-align: left; border: none; background: none; padding: 10px 15px; width: 100%; display: block; border-radius: 8px; color: #333; font-weight: 500; font-size: 0.95rem; }
.category-btn:hover { background-color: #e9ecef; }
.category-btn.active { background-color: #0d6efd; color: white; }
.search-dropdown { position: absolute; width: 100%; z-index: 1000; max-height: 200px; overflow-y: auto; display: none; }
.payment-btn { height: 70px; font-size: 1.05rem; font-weight: bold; }
.btn-lg { font-size: 1.1rem; padding: 0.75rem 1rem; }
.pos-layout { height: calc(100vh - 60px); }
.pos-categories { background: #fff; height: 100%; border-right: 1px solid #e0e0e0; }
.pos-products { background: #f8fafc; height: 100%; display: flex; flex-direction: column; }
.pos-cart { background: #fff; height: 100%; border-left: 1px solid #e0e0e0; display: flex; flex-direction: column; }
.product-card { transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); cursor: pointer; border: 1px solid transparent !important; background: #fff; }
.product-card:active { transform: scale(0.95); }
.product-card:hover { border-color: #0d6efd !important; box-shadow: 0 4px 12px rgba(0,0,0,0.08) !important; }
.category-btn { text-align: left; border: none; background: none; padding: 12px 10px; width: 100%; display: block; border-radius: 12px; color: #64748b; font-weight: 700; transition: all 0.2s; }
.category-btn:hover { background-color: #f1f5f9; color: #0f172a; }
.category-btn.active { background-color: #0d6efd; color: white; box-shadow: 0 4px 6px -1px rgba(13, 110, 253, 0.3); }
.search-dropdown { position: absolute; width: 100%; z-index: 1000; max-height: 200px; overflow-y: auto; display: none; }
/* Compact Card adjustments */
.card-img-container { height: 75px; position: relative; background: #f1f5f9; }
.card-img-container img { height: 100%; width: 100%; object-fit: cover; transition: transform 0.3s; }
.product-card:hover .card-img-container img { transform: scale(1.05); }
.product-title { font-size: 0.75rem; line-height: 1.2; height: 1.8rem; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; font-weight: 700; color: #1e293b; }
.product-price-tag { font-size: 0.85rem; color: #0d6efd; font-weight: 700; }
.product-cat-name { font-size: 0.65rem; color: #94a3b8; }
/* Custom Grid for 8 columns */
@media (min-width: 1200px) {
.row-cols-xl-8 > * { flex: 0 0 auto; width: 12.5%; }
}
@media (min-width: 1400px) {
.row-cols-xxl-10 > * { flex: 0 0 auto; width: 10%; }
}
@media (max-width: 576px) {
.card-img-container { height: 65px; }
.pos-categories { width: 65px !important; flex: 0 0 65px !important; }
.category-btn span { display: none; }
.category-btn i { font-size: 1.4rem !important; margin-bottom: 0 !important; }
.category-btn img { width: 28px !important; height: 28px !important; margin-bottom: 0 !important; }
.pos-products { flex: 1; }
}
/* Print Styles */
@media print {
.no-print { display: none !important; }
.print-only { display: block !important; }
@ -109,56 +135,40 @@ if (!$loyalty_settings) {
</style>
</head>
<body>
<!-- Print Container for QR codes, etc. -->
<div class="print-only" id="print-section"></div>
<div class="container-fluid p-0 no-print">
<!-- Header/Navbar -->
<nav class="navbar navbar-expand-lg border-bottom px-3 py-2 bg-white sticky-top">
<nav class="navbar navbar-expand-lg border-bottom px-3 py-0 bg-white sticky-top" style="height: 60px;">
<div class="container-fluid p-0">
<a class="navbar-brand fw-bold d-flex align-items-center" href="pos.php">
<?php if (!empty($settings['logo_url'])): ?>
<img src="<?= htmlspecialchars($settings['logo_url']) ?>" alt="Logo" height="30" class="me-2">
<img src="<?= htmlspecialchars($settings['logo_url']) ?>" alt="Logo" height="28" class="me-2">
<?php endif; ?>
<span><?= htmlspecialchars($settings['company_name']) ?></span>
<span class="badge bg-primary ms-2 fs-6 fw-normal"><?= htmlspecialchars($current_outlet_name) ?></span>
<span class="d-none d-sm-inline" style="letter-spacing: -0.5px;"><?= htmlspecialchars($settings['company_name']) ?></span>
<span class="badge bg-primary-subtle text-primary ms-2 fs-7 fw-semibold rounded-pill px-2 border border-primary-subtle"><?= htmlspecialchars($current_outlet_name) ?></span>
</a>
<div class="ms-auto d-flex align-items-center gap-3">
<!-- Outlet Selector in Header -->
<div class="dropdown me-2">
<button class="btn btn-outline-secondary btn-sm dropdown-toggle rounded-pill px-3" type="button" data-bs-toggle="dropdown">
<i class="bi bi-shop me-1"></i> Switch Outlet
<div class="ms-auto d-flex align-items-center gap-2">
<div class="dropdown me-1 d-none d-md-block">
<button class="btn btn-outline-secondary btn-sm rounded-pill px-3 border-0 bg-light" type="button" data-bs-toggle="dropdown">
<i class="bi bi-shop me-1"></i> Switch
</button>
<ul class="dropdown-menu dropdown-menu-end shadow border-0 mt-2">
<?php foreach ($outlets as $o): ?>
<li>
<a class="dropdown-item <?= $o['id'] == $outlet_id ? 'active' : '' ?>" href="?outlet_id=<?= $o['id'] ?>">
<?= htmlspecialchars($o['name']) ?>
</a>
</li>
<li><a class="dropdown-item <?= $o['id'] == $outlet_id ? 'active' : '' ?>" href="?outlet_id=<?= $o['id'] ?>"><?= htmlspecialchars($o['name']) ?></a></li>
<?php endforeach; ?>
</ul>
</div>
<a href="kitchen.php" class="btn btn-outline-primary btn-sm rounded-pill px-2 px-sm-3 border-0"><i class="bi bi-fire me-1"></i> Kitchen</a>
<a href="admin/orders.php" class="btn btn-outline-secondary btn-sm rounded-pill px-2 px-sm-3 border-0"><i class="bi bi-receipt me-1"></i> Orders</a>
<button class="btn btn-outline-warning btn-sm rounded-pill px-2 px-sm-3 border-0" onclick="openRecallOrderModal()"><i class="bi bi-arrow-counterclockwise me-1"></i> Recall</button>
<a href="kitchen.php" class="btn btn-outline-primary btn-sm rounded-pill px-3">
<i class="bi bi-fire me-1"></i> Kitchen
</a>
<a href="admin/orders.php" class="btn btn-outline-secondary btn-sm rounded-pill px-3">
<i class="bi bi-receipt me-1"></i> Current Orders
</a>
<button class="btn btn-outline-warning btn-sm rounded-pill px-3" onclick="openRecallOrderModal()">
<i class="bi bi-arrow-counterclockwise me-1"></i> Recall Bill
</button>
<button class="btn btn-outline-info btn-sm rounded-pill px-3" onclick="showRatingQR()">
<i class="bi bi-qr-code me-1"></i> Rating QR
</button>
<div class="vr mx-2 h-25"></div>
<div class="vr mx-1 h-25 d-none d-sm-block"></div>
<div class="dropdown">
<button class="btn btn-light btn-sm rounded-circle p-1 border" type="button" data-bs-toggle="dropdown">
<img src="<?= !empty($currentUser['profile_pic']) ? htmlspecialchars($currentUser['profile_pic']) : 'https://ui-avatars.com/api/?name=' . urlencode($currentUser['username']) ?>" alt="User" width="30" height="30" class="rounded-circle">
<button class="btn btn-light btn-sm rounded-circle p-0 border" type="button" data-bs-toggle="dropdown" style="width: 32px; height: 32px;">
<img src="<?= !empty($currentUser['profile_pic']) ? htmlspecialchars($currentUser['profile_pic']) : 'https://ui-avatars.com/api/?name=' . urlencode($currentUser['username']) ?>" alt="User" width="32" height="32" class="rounded-circle">
</button>
<ul class="dropdown-menu dropdown-menu-end shadow border-0 mt-2">
<li class="px-3 py-2 border-bottom">
@ -175,355 +185,191 @@ if (!$loyalty_settings) {
</div>
</nav>
<div class="row g-0">
<div class="row g-0 pos-layout">
<!-- Left Sidebar: Categories -->
<div class="col-md-1 col-3 category-sidebar border-end scrollable-y p-2">
<button class="category-btn active mb-2" data-category="all">
<i class="bi bi-grid d-block fs-4 mb-1"></i>
<div class="col-md-2 col-auto pos-categories scrollable-y p-2" style="min-width: 120px;">
<button class="category-btn active mb-2 px-1 text-center" data-category="all">
<i class="bi bi-grid d-block fs-5 mb-1 text-inherit"></i>
<span style="font-size: 0.75rem;">All Items</span>
</button>
<?php foreach ($categories as $cat): ?>
<button class="category-btn mb-2" data-category="<?= $cat['id'] ?>">
<button class="category-btn mb-2 px-1 text-center" data-category="<?= $cat['id'] ?>">
<?php if (!empty($cat['image_url'])): ?>
<img src="<?= htmlspecialchars($cat['image_url']) ?>" alt="<?= htmlspecialchars($cat['name']) ?>" class="rounded d-block mb-1 mx-auto" style="width: 32px; height: 32px; object-fit: cover;">
<img src="<?= htmlspecialchars($cat['image_url']) ?>" alt="<?= htmlspecialchars($cat['name']) ?>" class="rounded-3 d-block mb-1 mx-auto" style="width: 32px; height: 32px; object-fit: cover;">
<?php else: ?>
<i class="bi bi-tag d-block fs-4 mb-1"></i>
<i class="bi bi-tag d-block fs-5 mb-1 text-inherit"></i>
<?php endif; ?>
<span class="d-block text-truncate text-center" style="font-size: 0.75rem;"><?= htmlspecialchars($cat['name']) ?></span>
<span class="d-block text-truncate" style="font-size: 0.75rem;"><?= htmlspecialchars($cat['name']) ?></span>
</button>
<?php endforeach; ?>
</div>
<!-- Center Area: Product Grid -->
<div class="col-md-8 col-9 product-area d-flex flex-column">
<div class="col pos-products">
<!-- Search Bar -->
<div class="p-3 border-bottom bg-light">
<div class="px-3 py-2 border-bottom bg-white">
<div class="position-relative">
<span class="position-absolute top-50 start-0 translate-middle-y ms-3 text-muted">
<i class="bi bi-search"></i>
<i class="bi bi-search small"></i>
</span>
<input type="text" id="product-search" class="form-control form-control-lg ps-5 border-0 shadow-sm rounded-pill" placeholder="Search products by name or SKU...">
<input type="text" id="product-search" class="form-control form-control-sm ps-5 border-0 bg-light rounded-3" placeholder="Search products by name or SKU...">
</div>
</div>
<!-- Grid Container -->
<div class="flex-grow-1 scrollable-y p-3">
<div class="row g-3" id="product-grid">
<div class="flex-grow-1 scrollable-y p-2">
<div class="row g-2 row-cols-3 row-cols-sm-4 row-cols-md-5 row-cols-lg-6 row-cols-xl-8 row-cols-xxl-10" id="product-grid">
<?php foreach ($all_products as $product): ?>
<?php $has_variants = !empty($variants_by_product[$product['id']]); ?>
<div class="col-xl-3 col-lg-4 col-md-6 col-6 product-item"
<div class="col product-item"
data-category="<?= $product['category_id'] ?>"
data-name="<?= strtolower($product['name']) ?>"
data-sku="<?= strtolower($product['sku'] ?? '') ?>"
onclick='handleProductClick(<?= json_encode($product) ?>, <?= json_encode($variants_by_product[$product['id']] ?? []) ?>)'>
<div class="card h-100 border-0 shadow-sm product-card rounded-4 overflow-hidden">
data-name="<?= htmlspecialchars(strtolower($product['name'])) ?>"
data-sku="<?= htmlspecialchars(strtolower($product['sku'] ?? '')) ?>"
onclick="handleProductClick(<?= htmlspecialchars(json_encode($product), ENT_QUOTES) ?>, <?= htmlspecialchars(json_encode($variants_by_product[$product['id']] ?? []), ENT_QUOTES) ?>)">
<div class="card h-100 border-0 shadow-sm product-card rounded-3 overflow-hidden">
<div class="card-img-container">
<?php if (!empty($product['image_url'])): ?>
<img src="<?= htmlspecialchars($product['image_url']) ?>" class="card-img-top" alt="<?= htmlspecialchars($product['name']) ?>" style="height: 120px; object-fit: cover;">
<img src="<?= htmlspecialchars($product['image_url']) ?>?v=<?= time() ?>" alt="<?= htmlspecialchars($product['name']) ?>">
<?php else: ?>
<div class="bg-light d-flex align-items-center justify-content-center" style="height: 120px;">
<i class="bi bi-image text-muted opacity-25 fs-1"></i>
<div class="d-flex align-items-center justify-content-center h-100">
<i class="bi bi-image text-muted opacity-25 fs-4"></i>
</div>
<?php endif; ?>
<div class="card-body p-2 text-center">
<h6 class="card-title fw-bold mb-1 text-truncate" style="font-size: 0.9rem;"><?= htmlspecialchars($product['name']) ?></h6>
<div class="text-primary fw-bold mb-1" style="font-size: 1rem;"><?= format_currency((float)$product['price']) ?></div>
<?php if (!empty($product['name_ar'])): ?>
<div class="text-primary small fw-semibold text-truncate mb-1" dir="rtl" style="font-size: 0.8rem;"><?= htmlspecialchars($product['name_ar']) ?></div>
<?php endif; ?>
<p class="card-text small text-muted text-truncate mb-0"><?= htmlspecialchars($product['category_name']) ?></p>
<?php if ($has_variants): ?>
<span class="badge bg-light text-secondary border mt-1">Options</span>
<div class="position-absolute top-0 end-0 p-1">
<span class="badge bg-warning text-dark p-0 rounded-circle d-flex align-items-center justify-content-center" style="width: 14px; height: 14px; font-size: 0.5rem;"><i class="bi bi-plus"></i></span>
</div>
<?php endif; ?>
</div>
<div class="card-body p-1 text-center d-flex flex-column justify-content-between">
<div>
<h6 class="card-title product-title mb-0"><?= htmlspecialchars($product['name']) ?></h6>
<?php if (!empty($product['name_ar'])): ?>
<div class="text-primary product-cat-name text-truncate" dir="rtl" style="margin-top: -2px;"><?= htmlspecialchars($product['name_ar']) ?></div>
<?php endif; ?>
</div>
<div class="product-price-tag mt-1"><?= format_currency((float)$product['price']) ?></div>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<!-- Right Sidebar: Cart & Order Info -->
<div class="col-md-3 col-12 cart-sidebar border-start p-0 d-flex flex-column">
<!-- Top Section: Customer & Type -->
<div class="p-3 border-bottom bg-white">
<!-- Order Type -->
<div class="btn-group w-100 mb-3" role="group">
<input type="radio" class="btn-check" name="order_type" id="ot-takeaway" value="takeaway" <?= $order_type === 'takeaway' ? 'checked' : '' ?>>
<label class="btn btn-outline-primary btn-sm" for="ot-takeaway">Takeaway</label>
<input type="radio" class="btn-check" name="order_type" id="ot-dine-in" value="dine-in" <?= $order_type === 'dine-in' ? 'checked' : '' ?>>
<label class="btn btn-outline-primary btn-sm" for="ot-dine-in">Dine-In</label>
<input type="radio" class="btn-check" name="order_type" id="ot-delivery" value="delivery" <?= $order_type === 'delivery' ? 'checked' : '' ?>>
<label class="btn btn-outline-primary btn-sm" for="ot-delivery">Delivery</label>
</div>
<!-- Customer Search -->
<!-- Right Sidebar: Cart -->
<div class="col-md-2 col-12 pos-cart shadow-sm">
<div class="p-2 border-bottom bg-white">
<div class="btn-group w-100 mb-2" role="group">
<input type="radio" class="btn-check" name="order_type" id="ot-takeaway" value="takeaway" <?= $order_type === 'takeaway' ? 'checked' : '' ?>>
<label class="btn btn-outline-primary btn-sm py-1 rounded-start-pill" for="ot-takeaway" style="font-size: 0.7rem;">Takeaway</label>
<input type="radio" class="btn-check" name="order_type" id="ot-dine-in" value="dine-in" <?= $order_type === 'dine-in' ? 'checked' : '' ?>>
<label class="btn btn-outline-primary btn-sm py-1" for="ot-dine-in" style="font-size: 0.7rem;">Dine-In</label>
<input type="radio" class="btn-check" name="order_type" id="ot-delivery" value="delivery" <?= $order_type === 'delivery' ? 'checked' : '' ?>>
<label class="btn btn-outline-primary btn-sm py-1 rounded-end-pill" for="ot-delivery" style="font-size: 0.7rem;">Delivery</label>
</div>
<div class="position-relative">
<div class="input-group input-group-sm">
<span class="input-group-text bg-white border-end-0"><i class="bi bi-person"></i></span>
<input type="text" class="form-control border-start-0 ps-0" id="customer-search" placeholder="Search Customer..." autocomplete="off">
<button class="btn btn-outline-secondary d-none" type="button" id="clear-customer"><i class="bi bi-x"></i></button>
<button class="btn btn-outline-primary" type="button" data-bs-toggle="modal" data-bs-target="#addCustomerModal" title="Add New Customer">
<i class="bi bi-plus-lg"></i>
</button>
<span class="input-group-text bg-light border-0 rounded-start-pill ps-3"><i class="bi bi-person text-muted"></i></span>
<input type="text" class="form-control border-0 bg-light ps-1" id="customer-search" placeholder="Customer Name/Phone" autocomplete="off">
<button class="btn btn-light border-0 d-none" type="button" id="clear-customer"><i class="bi bi-x"></i></button>
<button class="btn btn-light border-0 rounded-end-pill pe-3 text-primary" type="button" data-bs-toggle="modal" data-bs-target="#addCustomerModal"><i class="bi bi-plus-lg"></i></button>
</div>
<div class="list-group shadow-sm search-dropdown" id="customer-results"></div>
<div class="list-group shadow border-0 search-dropdown" id="customer-results" style="border-radius: 12px; margin-top: 5px;"></div>
<input type="hidden" id="selected-customer-id">
<div id="customer-info" class="small text-success mt-1 d-none">
<i class="bi bi-check-circle-fill me-1"></i> <span id="customer-name-display"></span>
</div>
<!-- Loyalty Section (Hidden if disabled) -->
<?php if ($loyalty_settings['is_enabled']): ?>
<div id="loyalty-section" class="d-none mt-2 p-2 bg-warning-subtle rounded border border-warning">
<div class="d-flex justify-content-between align-items-center">
<div>
<span class="d-block fw-bold small text-warning-emphasis">Loyalty Points</span>
<span id="loyalty-points-display" class="fw-bold fs-5">0</span>
</div>
<div class="d-flex flex-column gap-1">
<button id="redeem-loyalty-btn" class="btn btn-sm btn-success shadow-sm" disabled>
<i class="bi bi-gift-fill me-1"></i> Redeem
</button>
<button id="view-points-history-btn" class="btn btn-sm btn-outline-primary border-0 shadow-none p-0 text-decoration-underline" style="font-size: 0.7rem;">
<i class="bi bi-clock-history"></i> View History
</button>
</div>
</div>
<div id="loyalty-message" class="small text-muted mt-1 fst-italic" style="font-size: 0.75rem;"></div>
</div>
<?php endif; ?>
</div>
</div>
<!-- Cart Items (Flex Grow) -->
<div class="flex-grow-1 overflow-auto p-3 bg-white" id="cart-items">
<div class="text-center text-muted mt-5">
<i class="bi bi-basket3 fs-1 text-light"></i>
<p class="mt-2">Cart is empty</p>
<div class="flex-grow-1 overflow-auto p-2 bg-white" id="cart-items">
<div class="text-center text-muted mt-5 opacity-50">
<i class="bi bi-basket3 fs-1 d-block mb-2"></i>
<p class="small">Cart is empty</p>
</div>
</div>
<!-- Bottom: Totals & Action -->
<div class="p-3 border-top bg-light mt-auto">
<div class="d-flex justify-content-between mb-2">
<span class="text-muted">Subtotal</span>
<span class="fw-bold" id="cart-subtotal"><?= format_currency(0) ?></span>
<div class="p-3 border-top bg-light mt-auto rounded-top-4">
<div class="d-flex justify-content-between mb-1">
<span class="text-muted small">Subtotal</span>
<span class="fw-bold small" id="cart-subtotal"><?= format_currency(0) ?></span>
</div>
<!-- VAT Field -->
<div class="d-flex justify-content-between align-items-center mb-2">
<span class="text-muted">VAT (<?= htmlspecialchars((string)($settings['vat_rate'] ?? 0)) ?>%)</span>
<div class="input-group input-group-sm w-50">
<span class="input-group-text bg-white border-end-0 text-muted">+</span>
<input type="number" id="cart-vat-input" class="form-control border-start-0 text-end bg-white" value="0" step="0.01" readonly>
</div>
</div>
<div class="d-flex justify-content-between mb-3">
<span class="fs-5 fw-bold">Total</span>
<span class="fs-4 fw-bold text-primary" id="cart-total-price"><?= format_currency(0) ?></span>
<span class="fs-6 fw-bold">Total Payable</span>
<span class="fs-5 fw-bold text-primary" id="cart-total-price"><?= format_currency(0) ?></span>
</div>
<?php if (has_permission('pos_add')): ?>
<div class="mb-2">
<button class="btn btn-outline-danger w-100 py-2 fw-bold mb-2 btn-sm" onclick="clearCart()">
<i class="bi bi-trash me-1"></i> CLEAR CART
</button>
<button class="btn btn-link text-danger w-100 py-0 fw-semibold mb-3 btn-sm text-decoration-none" onclick="clearCart()" style="font-size: 0.75rem;">Empty Cart</button>
<div class="d-flex gap-2">
<button class="btn btn-primary w-50 btn-lg shadow-sm fw-bold" id="quick-order-btn" disabled>
QUICK ORDER <i class="bi bi-lightning-fill ms-1"></i>
</button>
<button class="btn btn-warning w-50 btn-lg shadow-sm text-white fw-bold" id="place-order-btn" disabled>
PLACE ORDER <i class="bi bi-clock ms-1"></i>
</button>
<button class="btn btn-primary w-50 btn-sm shadow-sm fw-bold py-2 rounded-3" id="quick-order-btn" disabled>QUICK PAY</button>
<button class="btn btn-outline-warning w-50 btn-sm shadow-sm fw-bold py-2 rounded-3" id="place-order-btn" disabled>SAVE BILL</button>
</div>
</div>
<?php else: ?>
<div class="alert alert-warning small py-2 mb-0 text-center">
<i class="bi bi-info-circle me-1"></i> View Only Mode
</div>
<?php endif; ?>
<div class="text-center mt-3 text-muted small" style="font-size: 0.7rem;">
Powered By Abidarcafe @2026
</div>
</div>
</div>
</div>
</div>
<!-- Modal components wrapped in no-print -->
<!-- Modals -->
<div class="no-print">
<!-- Toast Container -->
<div class="toast-container position-fixed bottom-0 start-50 translate-middle-x p-3" id="toast-container" style="z-index: 1060;"></div>
<!-- Recall Order Modal -->
<div class="modal fade" id="recallOrderModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title fw-bold">Recall Unpaid Bill</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body bg-light">
<div id="recall-orders-list" class="list-group">
<!-- Orders injected via JS -->
</div>
<div class="modal-content border-0 shadow-lg" style="border-radius: 20px;">
<div class="modal-header border-0 pb-0">
<h6 class="modal-title fw-bold">Recall Unpaid Bill</h6>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body p-3"><div id="recall-orders-list" class="list-group list-group-flush"></div></div>
</div>
</div>
</div>
<!-- Table Selection Modal -->
<div class="modal fade" id="tableSelectionModal" tabindex="-1" aria-hidden="true" data-bs-backdrop="static">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title fw-bold" id="tableSelectionModalLabel">Select Table</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" id="close-table-modal" style="display:none;"></button>
</div>
<div class="modal-body bg-light">
<div id="table-list-container" class="row g-3"></div>
</div>
</div>
</div>
</div>
<!-- Variant Selection Modal -->
<div class="modal fade" id="variantSelectionModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="variantModalTitle">Select Option</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div id="variant-list" class="list-group">
<!-- Variants injected by JS -->
</div>
<div class="modal-dialog modal-dialog-centered modal-sm">
<div class="modal-content border-0 shadow-lg" style="border-radius: 20px;">
<div class="modal-header border-0 pb-0">
<h6 class="modal-title fw-bold" id="variantModalTitle">Options</h6>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body p-3"><div id="variant-list" class="list-group list-group-flush"></div></div>
</div>
</div>
</div>
<!-- Add Customer Modal -->
<div class="modal fade" id="addCustomerModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-sm">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title fs-6 fw-bold">Add New Customer</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
<div class="modal-content border-0 shadow-lg" style="border-radius: 20px;">
<div class="modal-header border-0 pb-0">
<h6 class="modal-title fw-bold">New Customer</h6>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label for="new-customer-name" class="form-label small text-muted">Customer Name</label>
<input type="text" class="form-control form-control-sm" id="new-customer-name" placeholder="Enter name">
<div class="modal-body p-3">
<div class="mb-2">
<label class="small text-muted mb-1">Full Name</label>
<input type="text" class="form-control form-control-sm rounded-3" id="new-customer-name">
</div>
<div class="mb-3">
<label for="new-customer-phone" class="form-label small text-muted">Phone Number</label>
<input type="text" class="form-control form-control-sm" id="new-customer-phone" placeholder="Enter phone">
</div>
<div class="d-grid">
<button type="button" class="btn btn-primary btn-sm" id="save-new-customer">Save Customer</button>
<label class="small text-muted mb-1">Phone Number</label>
<input type="text" class="form-control form-control-sm rounded-3" id="new-customer-phone">
</div>
<button type="button" class="btn btn-primary btn-sm w-100 py-2 rounded-3" id="save-new-customer">Add Customer</button>
</div>
</div>
</div>
</div>
<!-- Points History Modal -->
<div class="modal fade" id="pointsHistoryModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title fw-bold">Points History</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body p-0">
<div class="table-responsive">
<table class="table table-sm table-hover mb-0">
<thead class="table-light">
<tr>
<th class="ps-3">Date</th>
<th>Action</th>
<th class="text-end pe-3">Points</th>
</tr>
</thead>
<tbody id="points-history-body">
<!-- History rows injected via JS -->
</tbody>
</table>
</div>
<div id="points-history-empty" class="text-center py-4 text-muted d-none">
<i class="bi bi-calendar-x fs-2"></i>
<p class="mt-2">No history found</p>
</div>
</div>
</div>
</div>
</div>
<!-- Payment Selection Modal -->
<div class="modal fade" id="paymentSelectionModal" tabindex="-1" aria-hidden="true" data-bs-backdrop="static">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title fw-bold">Select Payment Method</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="row g-3" id="payment-methods-container">
<!-- Injected via JS -->
</div>
</div>
</div>
</div>
</div>
<!-- Rating QR Modal -->
<div class="modal fade" id="ratingQRModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title fw-bold">Rating & Feedback QR</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body text-center p-4">
<p class="text-muted mb-4">Ask your customers to scan this QR code to rate your service and staff.</p>
<div id="rating-qr-container" class="mb-4">
<!-- QR Code will be generated here -->
<div class="bg-light p-4 rounded-4 d-inline-block shadow-sm">
<?php
$protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http";
$host = $_SERVER['HTTP_HOST'];
$ratingUrl = $protocol . "://" . $host . "/rate.php";
// Using a public QR generator for simplicity
$qrUrl = "https://api.qrserver.com/v1/create-qr-code/?size=250x250&data=" . urlencode($ratingUrl);
?>
<img src="<?= $qrUrl ?>" alt="Rating QR Code" class="img-fluid" style="width: 200px; height: 200px;">
</div>
</div>
<div class="alert alert-info small py-2">
<i class="bi bi-link-45deg me-1"></i> URL: <a href="<?= $ratingUrl ?>" target="_blank" class="text-decoration-none"><?= $ratingUrl ?></a>
</div>
<button class="btn btn-primary w-100 rounded-pill py-2 fw-bold" onclick="printQRCode('<?= $qrUrl ?>', 'Rating & Feedback QR')">
<i class="bi bi-printer me-2"></i> Print QR Code
</button>
<div class="modal fade" id="paymentSelectionModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-sm">
<div class="modal-content border-0 shadow-lg" style="border-radius: 20px;">
<div class="modal-header border-0 pb-0">
<h6 class="modal-title fw-bold">Select Payment</h6>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body p-3"><div class="row g-2" id="payment-methods-container"></div></div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<!-- Global POS Variables -->
<script>
const COMPANY_SETTINGS = <?= json_encode($settings) ?>;
const PRODUCT_VARIANTS = <?= json_encode($variants_by_product) ?>;
@ -533,44 +379,6 @@ if (!$loyalty_settings) {
const CURRENT_USER = { id: <?= $currentUser['id'] ?>, name: '<?= addslashes($currentUser['username']) ?>' };
const LOYALTY_SETTINGS = <?= json_encode($loyalty_settings) ?>;
</script>
<script src="assets/js/main.js?v=<?= time() ?>"></script>
<script>
function showRatingQR() {
const modal = new bootstrap.Modal(document.getElementById('ratingQRModal'));
modal.show();
}
function printQRCode(url, title) {
const win = window.open('', '_blank', 'width=600,height=600');
win.document.write(`
<html>
<head>
<title>${title}</title>
<style>
body { text-align: center; padding: 50px; font-family: sans-serif; }
img { width: 300px; height: 300px; margin-bottom: 20px; }
h2 { margin-bottom: 10px; }
@media print {
body { padding: 0; }
}
</style>
</head>
<body>
<h2>${title}</h2>
<img src="${url}" alt="QR Code">
<p>Scan to Rate Us</p>
<script>
window.onload = function() {
window.print();
setTimeout(function() { window.close(); }, 500);
}
<\/script>
</body>
</html>
`);
win.document.close();
}
</script>
</body>
</html>