551 lines
22 KiB
PHP
551 lines
22 KiB
PHP
<?php
|
||
require_once __DIR__ . '/includes/app.php';
|
||
|
||
$forcePublic = true;
|
||
$pageTitle = tr('الطلب عبر الإنترنت', 'Online Ordering');
|
||
|
||
require __DIR__ . '/includes/header.php';
|
||
|
||
$db = db();
|
||
$stmt = $db->query("
|
||
SELECT i.*, c.name_ar as cat_ar, c.name_en as cat_en
|
||
FROM items i
|
||
LEFT JOIN categories c ON i.category_id = c.id
|
||
WHERE i.in_catalog = 1
|
||
ORDER BY c.id, i.name
|
||
");
|
||
$items = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||
|
||
$catalog = [];
|
||
foreach ($items as $item) {
|
||
$catName = current_lang() === 'ar' ? ($item['cat_ar'] ?? 'عام') : ($item['cat_en'] ?? 'General');
|
||
$catalog[$catName][] = $item;
|
||
}
|
||
?>
|
||
<style>
|
||
.shop-item-card {
|
||
transition: transform 0.2s, box-shadow 0.2s;
|
||
border-radius: 12px;
|
||
border: none;
|
||
box-shadow: 0 4px 12px rgba(0,0,0,0.05);
|
||
height: 100%;
|
||
}
|
||
.shop-item-card:hover {
|
||
transform: translateY(-5px);
|
||
box-shadow: 0 12px 24px rgba(0,0,0,0.1);
|
||
}
|
||
.shop-item-img {
|
||
height: 200px;
|
||
object-fit: cover;
|
||
border-top-left-radius: 12px;
|
||
border-top-right-radius: 12px;
|
||
}
|
||
.cart-floating-btn {
|
||
position: fixed;
|
||
bottom: 30px;
|
||
right: 30px;
|
||
border-radius: 50%;
|
||
width: 60px;
|
||
height: 60px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 24px;
|
||
box-shadow: 0 4px 15px rgba(13,110,253,0.4);
|
||
z-index: 1000;
|
||
}
|
||
.cart-badge {
|
||
position: absolute;
|
||
top: 0;
|
||
right: 0;
|
||
transform: translate(30%, -30%);
|
||
}
|
||
body { background-color: #f8f9fa; }
|
||
|
||
/* Hide scrollbar for category filter */
|
||
.category-filter-container::-webkit-scrollbar {
|
||
display: none;
|
||
}
|
||
.category-filter-container {
|
||
-ms-overflow-style: none;
|
||
scrollbar-width: none;
|
||
}
|
||
.shop-pagination-wrap {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: 12px;
|
||
}
|
||
.shop-pagination-status {
|
||
color: #6c757d;
|
||
font-weight: 600;
|
||
}
|
||
.shop-pagination .page-link {
|
||
border-radius: 999px !important;
|
||
margin: 0 4px;
|
||
border: 0;
|
||
box-shadow: 0 3px 10px rgba(0,0,0,0.06);
|
||
color: #0d6efd;
|
||
}
|
||
.shop-pagination .page-item.active .page-link {
|
||
background: #0d6efd;
|
||
color: #fff;
|
||
}
|
||
.shop-pagination .page-item.disabled .page-link {
|
||
color: #adb5bd;
|
||
box-shadow: none;
|
||
}
|
||
</style>
|
||
|
||
<div class="container py-5">
|
||
<div class="d-flex justify-content-between align-items-center mb-5 bg-white p-4 rounded-4 shadow-sm">
|
||
<div>
|
||
<h1 class="fw-bold text-primary mb-1"><i class="bi bi-shop me-2"></i><?= h(get_setting('company_name_' . current_lang(), app_name())) ?></h1>
|
||
<p class="text-muted mb-0"><?= h(tr('اطلب الآن وسنقوم بتجهيز طلبك', 'Order now and we will prepare your request')) ?></p>
|
||
</div>
|
||
<div class="language-switcher">
|
||
<a class="btn btn-sm <?= current_lang() === 'ar' ? 'btn-primary' : 'btn-light text-dark' ?> rounded-pill px-3" href="shop.php?lang=ar">AR</a>
|
||
<a class="btn btn-sm <?= current_lang() === 'en' ? 'btn-primary' : 'btn-light text-dark' ?> rounded-pill px-3" href="shop.php?lang=en">EN</a>
|
||
</div>
|
||
</div>
|
||
|
||
<?php if (!empty($catalog)): ?>
|
||
<!-- Search and Filter -->
|
||
<div class="row mb-4">
|
||
<div class="col-md-6 mb-3 mb-md-0">
|
||
<div class="input-group input-group-lg shadow-sm rounded-pill overflow-hidden">
|
||
<span class="input-group-text bg-white border-0 ps-4"><i class="bi bi-search text-muted"></i></span>
|
||
<input type="text" id="searchInput" class="form-control border-0 px-3" placeholder="<?= h(tr('ابحث عن منتج...', 'Search for a product...')) ?>" onkeyup="filterProducts()">
|
||
</div>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<div class="d-flex gap-2 overflow-auto py-2 px-1 category-filter-container" style="white-space: nowrap;" id="categoryFilters">
|
||
<button class="btn btn-primary rounded-pill px-4 active" data-filter="all" onclick="setCategoryFilter('all', this)"><?= h(tr('الكل', 'All')) ?></button>
|
||
<?php foreach (array_keys($catalog) as $catName): ?>
|
||
<button class="btn btn-light rounded-pill px-4 text-dark shadow-sm border" data-filter="<?= htmlspecialchars($catName) ?>" onclick="setCategoryFilter(this.getAttribute('data-filter'), this)"><?= h($catName) ?></button>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="shop-pagination-wrap bg-white p-3 rounded-4 shadow-sm mb-4">
|
||
<div class="shop-pagination-status" id="paginationStatus">
|
||
<?= h(tr('جارٍ تحميل المنتجات...', 'Loading products...')) ?>
|
||
</div>
|
||
<nav aria-label="<?= h(tr('تنقل الصفحات', 'Product pagination')) ?>">
|
||
<ul class="pagination pagination-sm mb-0 shop-pagination" id="paginationTop"></ul>
|
||
</nav>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<?php if (empty($catalog)): ?>
|
||
<div class="text-center py-5">
|
||
<i class="bi bi-box-seam display-1 text-muted opacity-50 mb-3 d-block"></i>
|
||
<h3 class="text-muted"><?= h(tr('لا توجد منتجات متاحة حالياً', 'No products available currently')) ?></h3>
|
||
</div>
|
||
<?php else: ?>
|
||
<?php foreach ($catalog as $category => $catItems): ?>
|
||
<h3 class="fw-bold mb-4 mt-5 border-bottom pb-2 category-title" data-category="<?= htmlspecialchars($category) ?>"><?= h($category) ?></h3>
|
||
<div class="row g-4 category-row" data-category="<?= htmlspecialchars($category) ?>">
|
||
<?php foreach ($catItems as $item): ?>
|
||
<div class="col-sm-6 col-md-4 col-lg-3 product-item" data-name="<?= htmlspecialchars(strtolower($item['name'])) ?>">
|
||
<div class="card shop-item-card">
|
||
<?php if (!empty($item['image_url'])): ?>
|
||
<img src="<?= h($item['image_url']) ?>" class="card-img-top shop-item-img" alt="<?= h($item['name']) ?>">
|
||
<?php else: ?>
|
||
<div class="bg-light d-flex align-items-center justify-content-center shop-item-img text-muted">
|
||
<i class="bi bi-image" style="font-size: 3rem;"></i>
|
||
</div>
|
||
<?php endif; ?>
|
||
<div class="card-body d-flex flex-column">
|
||
<h5 class="card-title fw-bold mb-1"><?= h($item['name']) ?></h5>
|
||
<p class="text-primary fw-bold fs-5 mb-3"><?= h(currency($item['price'])) ?></p>
|
||
<button class="btn btn-outline-primary mt-auto rounded-pill fw-bold" onclick="addToCart(<?= htmlspecialchars(json_encode([
|
||
'id' => $item['id'],
|
||
'sku' => $item['sku'],
|
||
'name' => $item['name'],
|
||
'price' => $item['price'], 'vat' => $item['vat'] ?? 0
|
||
]), ENT_QUOTES, 'UTF-8') ?>)">
|
||
<i class="bi bi-cart-plus me-1"></i> <?= h(tr('إضافة للسلة', 'Add to Cart')) ?>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
|
||
<!-- No results message -->
|
||
<div id="noResultsMsg" class="text-center py-5" style="display: none;">
|
||
<i class="bi bi-search display-1 text-muted opacity-50 mb-3 d-block"></i>
|
||
<h3 class="text-muted"><?= h(tr('لم يتم العثور على نتائج', 'No results found')) ?></h3>
|
||
</div>
|
||
|
||
<div class="shop-pagination-wrap bg-white p-3 rounded-4 shadow-sm mt-4" id="paginationFooter">
|
||
<div class="shop-pagination-status" id="paginationStatusBottom"></div>
|
||
<nav aria-label="<?= h(tr('تنقل الصفحات', 'Product pagination')) ?>">
|
||
<ul class="pagination pagination-sm mb-0 shop-pagination" id="paginationBottom"></ul>
|
||
</nav>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<button class="btn btn-primary cart-floating-btn position-relative" onclick="openCart()">
|
||
<i class="bi bi-cart3"></i>
|
||
<span class="position-absolute badge rounded-pill bg-danger cart-badge border border-light" id="cartCount">
|
||
0
|
||
</span>
|
||
</button>
|
||
|
||
<!-- Cart Modal -->
|
||
<div class="modal fade" id="cartModal" tabindex="-1" aria-hidden="true">
|
||
<div class="modal-dialog modal-dialog-centered modal-lg">
|
||
<div class="modal-content border-0 shadow-lg rounded-4">
|
||
<div class="modal-header border-bottom-0 pb-0 pt-4 px-4">
|
||
<h5 class="modal-title fw-bold"><i class="bi bi-cart-check me-2 text-primary"></i><?= h(tr('سلة المشتريات', 'Shopping Cart')) ?></h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||
</div>
|
||
<div class="modal-body px-4 py-4">
|
||
<div id="cartItemsList" class="mb-4">
|
||
<!-- Items will be rendered here -->
|
||
</div>
|
||
<!-- cart summary -->
|
||
<div class="bg-light p-3 rounded-3 mb-4">
|
||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||
<span class="text-muted"><?= h(tr("المجموع الفرعي", "Subtotal")) ?></span>
|
||
<span class="fw-bold" id="cartSubtotal">0.00</span>
|
||
</div>
|
||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||
<span class="text-muted"><?= h(tr("الضريبة", "VAT")) ?></span>
|
||
<span class="fw-bold" id="cartVat">0.00</span>
|
||
</div>
|
||
<hr>
|
||
<div class="d-flex justify-content-between align-items-center">
|
||
<h5 class="mb-0 fw-bold"><?= h(tr("المجموع الإجمالي", "Total Amount")) ?></h5>
|
||
<h4 class="mb-0 fw-bold text-primary" id="cartTotal">0.00</h4>
|
||
</div>
|
||
</div>
|
||
|
||
<h5 class="fw-bold mb-3 border-bottom pb-2"><?= h(tr('بيانات العميل', 'Customer Details')) ?></h5>
|
||
<form id="checkoutForm">
|
||
<div class="mb-3">
|
||
<label class="form-label fw-semibold"><?= h(tr('الاسم', 'Name')) ?> *</label>
|
||
<input type="text" class="form-control form-control-lg rounded-3" id="customerName" required>
|
||
</div>
|
||
<div class="mb-3">
|
||
<label class="form-label fw-semibold"><?= h(tr('رقم الهاتف', 'Telephone')) ?> *</label>
|
||
<input type="tel" class="form-control form-control-lg rounded-3" id="customerPhone" required>
|
||
</div>
|
||
<div class="mb-3">
|
||
<label class="form-label fw-semibold"><?= h(tr('العنوان', 'Address')) ?> *</label>
|
||
<textarea class="form-control form-control-lg rounded-3" id="customerAddress" rows="2" required></textarea>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
<div class="modal-footer border-top-0 pt-0 pb-4 px-4 d-flex justify-content-between">
|
||
<button type="button" class="btn btn-light rounded-pill px-4" data-bs-dismiss="modal"><?= h(tr('إكمال التسوق', 'Continue Shopping')) ?></button>
|
||
<button type="button" class="btn btn-success rounded-pill px-5 fw-bold shadow-sm" id="submitOrderBtn" onclick="submitOrder()">
|
||
<i class="bi bi-check2-circle me-1"></i> <?= h(tr('تأكيد الطلب', 'Confirm Order')) ?>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||
<script>
|
||
let cart = JSON.parse(localStorage.getItem('shop_cart')) || {};
|
||
let cartModalInstance = null;
|
||
|
||
function saveCart() {
|
||
localStorage.setItem('shop_cart', JSON.stringify(cart));
|
||
updateCartBadge();
|
||
}
|
||
|
||
function updateCartBadge() {
|
||
let count = 0;
|
||
for (let id in cart) {
|
||
count += cart[id].qty;
|
||
}
|
||
document.getElementById('cartCount').innerText = count;
|
||
}
|
||
|
||
function addToCart(item) {
|
||
if (cart[item.id]) {
|
||
cart[item.id].qty += 1;
|
||
} else {
|
||
cart[item.id] = { ...item, qty: 1 };
|
||
}
|
||
saveCart();
|
||
|
||
Swal.fire({
|
||
title: '<?= h(tr('تمت الإضافة', 'Added')) ?>',
|
||
text: item.name,
|
||
icon: 'success',
|
||
toast: true,
|
||
position: 'top-end',
|
||
showConfirmButton: false,
|
||
timer: 1500
|
||
});
|
||
}
|
||
|
||
function changeQty(id, delta) {
|
||
if (cart[id]) {
|
||
cart[id].qty += delta;
|
||
if (cart[id].qty <= 0) {
|
||
delete cart[id];
|
||
}
|
||
saveCart();
|
||
renderCart();
|
||
}
|
||
}
|
||
|
||
function renderCart() {
|
||
const list = document.getElementById('cartItemsList');
|
||
let html = '';
|
||
let total = 0;
|
||
let totalVat = 0;
|
||
|
||
if (Object.keys(cart).length === 0) {
|
||
html = '<div class="text-center text-muted py-4"><?= h(tr('السلة فارغة', 'Cart is empty')) ?></div>';
|
||
} else {
|
||
html = '<div class="list-group list-group-flush">';
|
||
for (let id in cart) {
|
||
const item = cart[id];
|
||
const subtotal = item.price * item.qty;
|
||
const itemVat = subtotal * ((item.vat || 0) / 100);
|
||
totalVat += itemVat;
|
||
total += subtotal;
|
||
html += `
|
||
<div class="list-group-item d-flex justify-content-between align-items-center py-3 px-0 border-bottom-dashed">
|
||
<div>
|
||
<h6 class="mb-1 fw-bold">${item.name}</h6>
|
||
<small class="text-muted">${Number(item.price).toFixed(2)}</small>
|
||
</div>
|
||
<div class="d-flex align-items-center">
|
||
<button class="btn btn-sm btn-outline-secondary rounded-circle px-2 me-2" onclick="changeQty(${id}, -1)"><i class="bi bi-dash"></i></button>
|
||
<span class="fw-bold px-2">${item.qty}</span>
|
||
<button class="btn btn-sm btn-outline-secondary rounded-circle px-2 ms-2 me-4" onclick="changeQty(${id}, 1)"><i class="bi bi-plus"></i></button>
|
||
<span class="fw-bold text-primary" style="width: 70px; text-align:right;">${subtotal.toFixed(2)}</span>
|
||
</div>
|
||
</div>`;
|
||
}
|
||
html += '</div>';
|
||
}
|
||
|
||
list.innerHTML = html;
|
||
document.getElementById('cartSubtotal').innerText = total.toFixed(2);
|
||
document.getElementById('cartVat').innerText = totalVat.toFixed(2);
|
||
document.getElementById('cartTotal').innerText = (total + totalVat).toFixed(2);
|
||
}
|
||
|
||
function openCart() {
|
||
if (!cartModalInstance && typeof bootstrap !== 'undefined') {
|
||
cartModalInstance = new bootstrap.Modal(document.getElementById('cartModal'));
|
||
}
|
||
|
||
if (cartModalInstance) {
|
||
renderCart();
|
||
cartModalInstance.show();
|
||
} else {
|
||
console.error("Bootstrap is not loaded yet.");
|
||
}
|
||
}
|
||
|
||
async function submitOrder() {
|
||
if (Object.keys(cart).length === 0) {
|
||
Swal.fire('<?= h(tr('تنبيه', 'Warning')) ?>', '<?= h(tr('السلة فارغة', 'Cart is empty')) ?>', 'warning');
|
||
return;
|
||
}
|
||
|
||
const form = document.getElementById('checkoutForm');
|
||
if (!form.reportValidity()) return;
|
||
|
||
const btn = document.getElementById('submitOrderBtn');
|
||
const origText = btn.innerHTML;
|
||
btn.innerHTML = '<span class="spinner-border spinner-border-sm"></span>';
|
||
btn.disabled = true;
|
||
|
||
const data = {
|
||
name: document.getElementById('customerName').value,
|
||
phone: document.getElementById('customerPhone').value,
|
||
address: document.getElementById('customerAddress').value,
|
||
items: cart
|
||
};
|
||
|
||
try {
|
||
const res = await fetch('api/place_order.php', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify(data)
|
||
});
|
||
const json = await res.json();
|
||
|
||
if (json.success) {
|
||
cart = {};
|
||
saveCart();
|
||
if (cartModalInstance) cartModalInstance.hide();
|
||
Swal.fire({
|
||
title: '<?= h(tr('تم إرسال الطلب بنجاح!', 'Order submitted successfully!')) ?>',
|
||
text: '<?= h(tr('سنتواصل معك قريباً لتأكيد الطلب.', 'We will contact you shortly to confirm the order.')) ?>',
|
||
icon: 'success',
|
||
confirmButtonText: '<?= h(tr('حسناً', 'OK')) ?>'
|
||
});
|
||
form.reset();
|
||
} else {
|
||
Swal.fire('<?= h(tr('خطأ', 'Error')) ?>', json.error || '<?= h(tr('فشل إرسال الطلب', 'Failed to submit order')) ?>', 'error');
|
||
}
|
||
} catch (e) {
|
||
Swal.fire('<?= h(tr('خطأ', 'Error')) ?>', '<?= h(tr('حدث خطأ في الاتصال', 'Network error')) ?>', 'error');
|
||
} finally {
|
||
btn.innerHTML = origText;
|
||
btn.disabled = false;
|
||
}
|
||
}
|
||
|
||
// Filtering + Pagination Logic
|
||
let currentCategory = 'all';
|
||
let currentPage = 1;
|
||
const itemsPerPage = 24;
|
||
|
||
function setCategoryFilter(cat, btn) {
|
||
currentCategory = cat;
|
||
currentPage = 1;
|
||
|
||
document.querySelectorAll('#categoryFilters button').forEach(b => {
|
||
b.classList.remove('btn-primary', 'active');
|
||
b.classList.add('btn-light', 'text-dark');
|
||
});
|
||
btn.classList.remove('btn-light', 'text-dark');
|
||
btn.classList.add('btn-primary', 'active');
|
||
|
||
filterProducts();
|
||
}
|
||
|
||
function getFilteredItems() {
|
||
const searchInput = document.getElementById('searchInput');
|
||
const searchVal = searchInput ? searchInput.value.toLowerCase().trim() : '';
|
||
|
||
return Array.from(document.querySelectorAll('.product-item')).filter(item => {
|
||
const itemName = (item.getAttribute('data-name') || '').toLowerCase();
|
||
const itemCategory = item.closest('.category-row')?.getAttribute('data-category') || '';
|
||
const matchesSearch = itemName.includes(searchVal);
|
||
const matchesCategory = currentCategory === 'all' || currentCategory === itemCategory;
|
||
return matchesSearch && matchesCategory;
|
||
});
|
||
}
|
||
|
||
function renderPagination(totalItems) {
|
||
const top = document.getElementById('paginationTop');
|
||
const bottom = document.getElementById('paginationBottom');
|
||
const statusTop = document.getElementById('paginationStatus');
|
||
const statusBottom = document.getElementById('paginationStatusBottom');
|
||
const footerWrap = document.getElementById('paginationFooter');
|
||
|
||
if (!top || !bottom || !statusTop || !statusBottom) return;
|
||
|
||
const totalPages = Math.max(1, Math.ceil(totalItems / itemsPerPage));
|
||
if (currentPage > totalPages) currentPage = totalPages;
|
||
|
||
if (totalItems === 0) {
|
||
statusTop.textContent = <?= json_encode(tr('0 منتج', '0 products')) ?>;
|
||
statusBottom.textContent = statusTop.textContent;
|
||
top.innerHTML = '';
|
||
bottom.innerHTML = '';
|
||
if (footerWrap) footerWrap.style.display = 'none';
|
||
return;
|
||
}
|
||
|
||
const start = ((currentPage - 1) * itemsPerPage) + 1;
|
||
const end = Math.min(totalItems, currentPage * itemsPerPage);
|
||
const statusText = `<?= h(tr('عرض', 'Showing')) ?> ${start}-${end} <?= h(tr('من', 'of')) ?> ${totalItems}`;
|
||
statusTop.textContent = statusText;
|
||
statusBottom.textContent = statusText;
|
||
if (footerWrap) footerWrap.style.display = '';
|
||
|
||
if (totalPages <= 1) {
|
||
top.innerHTML = '';
|
||
bottom.innerHTML = '';
|
||
return;
|
||
}
|
||
|
||
const pages = [];
|
||
pages.push(1);
|
||
for (let p = Math.max(2, currentPage - 1); p <= Math.min(totalPages - 1, currentPage + 1); p++) {
|
||
pages.push(p);
|
||
}
|
||
if (totalPages > 1) pages.push(totalPages);
|
||
|
||
const uniquePages = [...new Set(pages)].sort((a, b) => a - b);
|
||
const parts = [];
|
||
|
||
const addControl = (label, page, disabled = false, active = false) => {
|
||
parts.push(`<li class="page-item${disabled ? ' disabled' : ''}${active ? ' active' : ''}"><button class="page-link" type="button" ${disabled ? 'disabled' : ''} onclick="goToPage(${page})">${label}</button></li>`);
|
||
};
|
||
|
||
addControl('‹', Math.max(1, currentPage - 1), currentPage === 1);
|
||
|
||
let lastPage = 0;
|
||
uniquePages.forEach(page => {
|
||
if (lastPage && page > lastPage + 1) {
|
||
parts.push('<li class="page-item disabled"><span class="page-link">…</span></li>');
|
||
}
|
||
addControl(page, page, false, page === currentPage);
|
||
lastPage = page;
|
||
});
|
||
|
||
addControl('›', Math.min(totalPages, currentPage + 1), currentPage === totalPages);
|
||
|
||
const html = parts.join('');
|
||
top.innerHTML = html;
|
||
bottom.innerHTML = html;
|
||
}
|
||
|
||
function goToPage(page) {
|
||
currentPage = page;
|
||
filterProducts(false);
|
||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||
}
|
||
|
||
function filterProducts(resetPage = true) {
|
||
if (resetPage) currentPage = 1;
|
||
|
||
const filteredItems = getFilteredItems();
|
||
const totalVisible = filteredItems.length;
|
||
const startIndex = (currentPage - 1) * itemsPerPage;
|
||
const endIndex = startIndex + itemsPerPage;
|
||
const visibleOnPage = new Set(filteredItems.slice(startIndex, endIndex));
|
||
|
||
document.querySelectorAll('.category-row').forEach(row => {
|
||
let hasVisibleItems = false;
|
||
|
||
row.querySelectorAll('.product-item').forEach(item => {
|
||
if (visibleOnPage.has(item)) {
|
||
item.style.display = '';
|
||
hasVisibleItems = true;
|
||
} else {
|
||
item.style.display = 'none';
|
||
}
|
||
});
|
||
|
||
const title = row.previousElementSibling;
|
||
if (title && title.classList.contains('category-title')) {
|
||
title.style.display = hasVisibleItems ? '' : 'none';
|
||
row.style.display = hasVisibleItems ? '' : 'none';
|
||
}
|
||
});
|
||
|
||
const noResultsMsg = document.getElementById('noResultsMsg');
|
||
if (noResultsMsg) {
|
||
noResultsMsg.style.display = totalVisible === 0 ? 'block' : 'none';
|
||
}
|
||
|
||
renderPagination(totalVisible);
|
||
}
|
||
|
||
// init
|
||
updateCartBadge();
|
||
filterProducts();
|
||
</script>
|
||
|
||
<?php require __DIR__ . '/includes/footer.php'; ?>
|