Spaces:
Sleeping
Sleeping
Update templates/menu.html
Browse files- templates/menu.html +122 -99
templates/menu.html
CHANGED
|
@@ -463,117 +463,140 @@ form.text-center.mb-4 {
|
|
| 463 |
|
| 464 |
|
| 465 |
|
| 466 |
-
<!-- Modal
|
| 467 |
-
<div class="modal fade" id="itemModal" tabindex="-1" aria-labelledby="itemModalLabel" aria-hidden="true">
|
| 468 |
-
|
| 469 |
-
|
| 470 |
-
|
| 471 |
-
|
| 472 |
-
|
| 473 |
-
</div>
|
| 474 |
-
<div class="modal-body">
|
| 475 |
-
<img id="modal-img" class="img-fluid rounded mb-3 d-block mx-auto" alt="Item Image" style="max-height: 200px; object-fit: cover;">
|
| 476 |
-
<h5 id="modal-name" class="fw-bold text-center"></h5>
|
| 477 |
-
<p id="modal-price" class="text-muted text-center"></p>
|
| 478 |
-
<p id="modal-description" class="text-secondary"></p>
|
| 479 |
-
|
| 480 |
-
<div id="modal-addons" class="mt-4">
|
| 481 |
-
<h6>Customization Options</h6>
|
| 482 |
-
<div id="addons-list">Loading customization options...</div>
|
| 483 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 484 |
|
| 485 |
-
<div class="mt-4">
|
| 486 |
-
<h6>Custom Request</h6>
|
| 487 |
-
<textarea id="modal-instructions" class="form-control" placeholder="Enter any special instructions here..."></textarea>
|
| 488 |
</div>
|
| 489 |
-
<
|
| 490 |
-
|
| 491 |
-
|
| 492 |
-
|
| 493 |
-
|
| 494 |
-
|
| 495 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 496 |
</div>
|
| 497 |
-
<button class="add-to-cart-btn" onclick="addToCartFromModal()">
|
| 498 |
-
Add items $<span id="totalAmountDisplay">0.00</span>
|
| 499 |
-
</button>
|
| 500 |
</div>
|
| 501 |
</div>
|
| 502 |
</div>
|
| 503 |
|
|
|
|
| 504 |
<script>
|
| 505 |
-
|
| 506 |
-
|
| 507 |
-
if (e.target.matches('.addon-option')) {
|
| 508 |
-
const multiSelectGroups = ['ExtraAdd-ons']; // Sections allowing multiple selections
|
| 509 |
-
if (!multiSelectGroups.includes(e.target.name)) {
|
| 510 |
-
document.querySelectorAll(`input[name="${e.target.name}"]`).forEach(checkbox => {
|
| 511 |
-
if (checkbox !== e.target) checkbox.checked = false;
|
| 512 |
-
});
|
| 513 |
-
}
|
| 514 |
-
}
|
| 515 |
-
});
|
| 516 |
-
|
| 517 |
-
// Quantity management
|
| 518 |
-
const decreaseBtn = document.getElementById('decreaseQuantity');
|
| 519 |
-
const increaseBtn = document.getElementById('increaseQuantity');
|
| 520 |
-
const quantityInput = document.getElementById('quantityInput');
|
| 521 |
-
|
| 522 |
-
decreaseBtn.addEventListener('click', () => {
|
| 523 |
let currentQuantity = parseInt(quantityInput.value);
|
| 524 |
-
|
| 525 |
-
});
|
| 526 |
-
|
| 527 |
-
increaseBtn.addEventListener('click', () => {
|
| 528 |
-
quantityInput.value = parseInt(quantityInput.value) + 1;
|
| 529 |
-
});
|
| 530 |
-
|
| 531 |
-
// Add to Cart logic
|
| 532 |
-
function addToCartFromModal() {
|
| 533 |
-
const cartPayload = {
|
| 534 |
-
itemName: document.getElementById('modal-name').innerText,
|
| 535 |
-
itemPrice: parseFloat(document.getElementById('modal-price').innerText.replace('$', '')),
|
| 536 |
-
itemImage: document.getElementById('modal-img').src,
|
| 537 |
-
section: document.getElementById('modal-section').getAttribute('data-section'),
|
| 538 |
-
category: document.getElementById('modal-section').getAttribute('data-category'),
|
| 539 |
-
addons: Array.from(document.querySelectorAll('#addons-list input:checked')).map(addon => ({
|
| 540 |
-
name: addon.getAttribute('data-name'),
|
| 541 |
-
price: parseFloat(addon.getAttribute('data-price')) || 0
|
| 542 |
-
})),
|
| 543 |
-
instructions: document.getElementById('modal-instructions').value,
|
| 544 |
-
quantity: parseInt(document.getElementById('quantityInput').value) || 1
|
| 545 |
-
};
|
| 546 |
|
| 547 |
-
|
| 548 |
-
|
| 549 |
-
|
| 550 |
-
body: JSON.stringify(cartPayload)
|
| 551 |
-
})
|
| 552 |
-
.then(response => response.json())
|
| 553 |
-
.then(data => {
|
| 554 |
-
if (data.success) {
|
| 555 |
-
alert('Item added to cart successfully!');
|
| 556 |
-
bootstrap.Modal.getInstance(document.getElementById('itemModal')).hide();
|
| 557 |
-
} else {
|
| 558 |
-
alert('Failed to add item to cart.');
|
| 559 |
-
}
|
| 560 |
-
})
|
| 561 |
-
.catch(err => {
|
| 562 |
-
console.error('Error:', err);
|
| 563 |
-
alert('An error occurred.');
|
| 564 |
-
});
|
| 565 |
-
}
|
| 566 |
-
|
| 567 |
-
// Reward points rounding
|
| 568 |
-
function roundRewardPoints() {
|
| 569 |
-
const rewardPointsElement = document.getElementById('reward-points');
|
| 570 |
-
if (rewardPointsElement) {
|
| 571 |
-
const points = parseFloat(rewardPointsElement.innerText.trim());
|
| 572 |
-
if (!isNaN(points)) rewardPointsElement.innerText = points.toFixed(1);
|
| 573 |
}
|
| 574 |
}
|
| 575 |
-
|
| 576 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 577 |
|
| 578 |
function filterMenu() {
|
| 579 |
let input = document.getElementById('searchBar').value.toLowerCase(); // Get the value from search bar
|
|
@@ -757,4 +780,4 @@ function roundRewardPoints() {
|
|
| 757 |
<!-- Bootstrap JS -->
|
| 758 |
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
|
| 759 |
</body>
|
| 760 |
-
</html>
|
|
|
|
| 463 |
|
| 464 |
|
| 465 |
|
| 466 |
+
<!-- Modal for Item Details -->
|
| 467 |
+
<div class="modal fade" id="itemModal" tabindex="-1" aria-labelledby="itemModalLabel" aria-hidden="true">
|
| 468 |
+
<div class="modal-dialog modal-dialog-centered">
|
| 469 |
+
<div class="modal-content">
|
| 470 |
+
<div class="modal-header">
|
| 471 |
+
<h5 class="modal-title" id="itemModalLabel">Item Details</h5>
|
| 472 |
+
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 473 |
</div>
|
| 474 |
+
<div class="modal-body">
|
| 475 |
+
<!-- Item Image -->
|
| 476 |
+
<img id="modal-img" class="img-fluid rounded mb-3 d-block mx-auto" alt="Item Image" style="max-height: 200px; object-fit: cover;">
|
| 477 |
+
<!-- Item Name -->
|
| 478 |
+
<h5 id="modal-name" class="fw-bold text-center"></h5>
|
| 479 |
+
<!-- Item Price -->
|
| 480 |
+
<p id="modal-price" class="text-muted text-center"></p>
|
| 481 |
+
<!-- Item Description -->
|
| 482 |
+
<p id="modal-description" class="text-secondary"></p>
|
| 483 |
+
<!-- Add-ons -->
|
| 484 |
+
<div id="modal-addons" class="modal-addons mt-4">
|
| 485 |
+
<h6>Customization Options</h6>
|
| 486 |
+
<div id="addons-list" class="addons-container">Loading customization options...</div>
|
| 487 |
+
</div>
|
| 488 |
+
|
| 489 |
+
|
| 490 |
+
<div class="mt-4">
|
| 491 |
+
<h6>Custom Request</h6>
|
| 492 |
+
<textarea id="modal-instructions" class="form-control" placeholder="Enter any special instructions here..."></textarea>
|
| 493 |
+
</div>
|
| 494 |
+
<span id="modal-section" data-section="" data-category="" style="display: none;"></span>
|
| 495 |
|
|
|
|
|
|
|
|
|
|
| 496 |
</div>
|
| 497 |
+
<div class="modal-footer">
|
| 498 |
+
<div class="d-flex align-items-center">
|
| 499 |
+
<button type="button" class="btn btn-outline-secondary" id="decreaseQuantity">-</button>
|
| 500 |
+
<input type="text" class="form-control text-center" id="quantityInput" value="1" readonly style="width: 50px;"/>
|
| 501 |
+
<button type="button" class="btn btn-outline-secondary" id="increaseQuantity">+</button>
|
| 502 |
+
</div>
|
| 503 |
+
|
| 504 |
+
<div>
|
| 505 |
+
<button class="add-to-cart-btn" onclick="addToCartFromModal()">Add items $<span id="totalAmountDisplay">0.00</span></button>
|
| 506 |
+
</div>
|
| 507 |
+
|
| 508 |
</div>
|
|
|
|
|
|
|
|
|
|
| 509 |
</div>
|
| 510 |
</div>
|
| 511 |
</div>
|
| 512 |
|
| 513 |
+
<!-- JavaScript -->
|
| 514 |
<script>
|
| 515 |
+
function changeQuantity(amount, itemId) {
|
| 516 |
+
let quantityInput = document.getElementById("quantity-" + itemId);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 517 |
let currentQuantity = parseInt(quantityInput.value);
|
| 518 |
+
let newQuantity = currentQuantity + amount;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 519 |
|
| 520 |
+
if (newQuantity >= 1) {
|
| 521 |
+
quantityInput.value = newQuantity;
|
| 522 |
+
updateTotalAmount(itemId);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 523 |
}
|
| 524 |
}
|
| 525 |
+
|
| 526 |
+
function updateTotalAmount(itemId) {
|
| 527 |
+
let quantity = parseInt(document.getElementById("quantity-" + itemId).value);
|
| 528 |
+
let price = parseFloat(document.getElementById("price-" + itemId).innerText); // Get price dynamically
|
| 529 |
+
let totalAmount = price * quantity;
|
| 530 |
+
|
| 531 |
+
// Update the individual total amount display
|
| 532 |
+
document.getElementById("totalAmountDisplay-" + itemId).innerText = $${totalAmount.toFixed(2)};
|
| 533 |
+
}
|
| 534 |
+
|
| 535 |
+
function addToCartFromModal(itemId) {
|
| 536 |
+
let quantity = parseInt(document.getElementById("quantity-" + itemId).value);
|
| 537 |
+
let itemName = document.getElementById("name-" + itemId).innerText; // Get item name dynamically
|
| 538 |
+
let price = parseFloat(document.getElementById("price-" + itemId).innerText); // Get price dynamically
|
| 539 |
+
let totalAmount = price * quantity;
|
| 540 |
+
|
| 541 |
+
// Update the "Add to Cart" button with the correct total amount
|
| 542 |
+
document.getElementById("addToCartBtn-" + itemId).innerHTML = Add to Cart $${totalAmount.toFixed(2)};
|
| 543 |
+
|
| 544 |
+
alert(Added ${quantity} x ${itemName} ($${totalAmount.toFixed(2)}) to cart!);
|
| 545 |
+
}
|
| 546 |
+
function showItemDetails(name, price, image, description, section, selectedCategory) {
|
| 547 |
+
document.getElementById('modal-name').innerText = name;
|
| 548 |
+
document.getElementById('modal-price').innerText = $${price};
|
| 549 |
+
document.getElementById('modal-img').src = image || '/static/placeholder.jpg';
|
| 550 |
+
document.getElementById('modal-description').innerText = description || 'No description available.';
|
| 551 |
+
document.getElementById('addons-list').innerHTML = 'Loading customization options...';
|
| 552 |
+
document.getElementById('modal-instructions').value = '';
|
| 553 |
+
// Set section and category for reference
|
| 554 |
+
const modalSectionEl = document.getElementById('modal-section');
|
| 555 |
+
modalSectionEl.setAttribute('data-section', section);
|
| 556 |
+
modalSectionEl.setAttribute('data-category', selectedCategory);
|
| 557 |
+
// Fetch customization options based on the section
|
| 558 |
+
fetch(/api/addons?item_name=${encodeURIComponent(name)}&item_section=${encodeURIComponent(section)})
|
| 559 |
+
.then(response => response.json())
|
| 560 |
+
.then(data => {
|
| 561 |
+
const addonsList = document.getElementById('addons-list');
|
| 562 |
+
addonsList.innerHTML = ''; // Clear previous content
|
| 563 |
+
|
| 564 |
+
if (!data.success || !data.addons || data.addons.length === 0) {
|
| 565 |
+
addonsList.innerHTML = '<p>No customization options available.</p>';
|
| 566 |
+
return;
|
| 567 |
+
}
|
| 568 |
+
// Display customization options inside styled divs
|
| 569 |
+
data.addons.forEach(addon => {
|
| 570 |
+
const sectionDiv = document.createElement('div');
|
| 571 |
+
sectionDiv.classList.add('addon-section'); // Add styling class
|
| 572 |
+
// Add section title
|
| 573 |
+
const title = document.createElement('h6');
|
| 574 |
+
title.innerText = addon.name;
|
| 575 |
+
sectionDiv.appendChild(title);
|
| 576 |
+
// Create options list
|
| 577 |
+
const optionsContainer = document.createElement('div');
|
| 578 |
+
addon.options.forEach((option, index) => {
|
| 579 |
+
const optionId = addon-${addon.name.replace(/\s+/g, '')}-${index};
|
| 580 |
+
const listItem = document.createElement('div');
|
| 581 |
+
listItem.classList.add('form-check');
|
| 582 |
+
listItem.innerHTML =
|
| 583 |
+
<input type="checkbox" class="form-check-input addon-option" id="${optionId}" value="${option}"
|
| 584 |
+
data-name="${option}" data-price="${addon.extra_charge ? addon.extra_charge_amount : 0}">
|
| 585 |
+
<label class="form-check-label" for="${optionId}">
|
| 586 |
+
${option} ${addon.extra_charge ? ($${addon.extra_charge_amount}) : ''}
|
| 587 |
+
</label>
|
| 588 |
+
;
|
| 589 |
+
optionsContainer.appendChild(listItem);
|
| 590 |
+
});
|
| 591 |
+
sectionDiv.appendChild(optionsContainer);
|
| 592 |
+
addonsList.appendChild(sectionDiv);
|
| 593 |
+
});
|
| 594 |
+
})
|
| 595 |
+
.catch(err => {
|
| 596 |
+
console.error('Error fetching add-ons:', err);
|
| 597 |
+
document.getElementById('addons-list').innerHTML = '<p>Error loading customization options.</p>';
|
| 598 |
+
});
|
| 599 |
+
}
|
| 600 |
|
| 601 |
function filterMenu() {
|
| 602 |
let input = document.getElementById('searchBar').value.toLowerCase(); // Get the value from search bar
|
|
|
|
| 780 |
<!-- Bootstrap JS -->
|
| 781 |
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
|
| 782 |
</body>
|
| 783 |
+
</html>
|