Update templates/menu.html
Browse files- templates/menu.html +172 -45
templates/menu.html
CHANGED
|
@@ -15,7 +15,6 @@
|
|
| 15 |
{% endfor %}
|
| 16 |
{% endfor %}
|
| 17 |
<style>
|
| 18 |
-
/* Existing styles remain unchanged */
|
| 19 |
body {
|
| 20 |
font-family: Arial, sans-serif;
|
| 21 |
background-color: #fdf4e3;
|
|
@@ -1001,7 +1000,9 @@
|
|
| 1001 |
<div>
|
| 1002 |
<h5 class="card-title">{{ item.Name | default('Unnamed Item') }}</h5>
|
| 1003 |
<p class="card-text price">${{ item.Price__c | default('0.00') }}</p>
|
| 1004 |
-
|
|
|
|
|
|
|
| 1005 |
</div>
|
| 1006 |
<div class="d-flex flex-column align-item-center justify-content-center">
|
| 1007 |
<div class="button-container"
|
|
@@ -1010,12 +1011,16 @@
|
|
| 1010 |
data-item-image="{{ item.Image2__c | default(item.Image1__c) | default('/static/placeholder.jpg') }}"
|
| 1011 |
data-item-section="{{ item.Section__c | default(section) }}"
|
| 1012 |
data-item-category="{{ selected_category }}">
|
| 1013 |
-
|
| 1014 |
-
|
| 1015 |
-
|
| 1016 |
-
|
| 1017 |
-
|
| 1018 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1019 |
{% if item.Section__c != 'Apetizer' and item.Section__c != 'Customized dish' and item.Section__c != 'Soft Drinks' %}
|
| 1020 |
<span class="customisable-text">Customisable</span>
|
| 1021 |
{% endif %}
|
|
@@ -1023,16 +1028,18 @@
|
|
| 1023 |
</div>
|
| 1024 |
</div>
|
| 1025 |
</div>
|
| 1026 |
-
|
| 1027 |
-
<
|
| 1028 |
-
|
| 1029 |
-
|
| 1030 |
-
|
| 1031 |
-
|
| 1032 |
-
|
| 1033 |
-
|
| 1034 |
-
|
| 1035 |
-
|
|
|
|
|
|
|
| 1036 |
</div>
|
| 1037 |
</div>
|
| 1038 |
{% endfor %}
|
|
@@ -1110,6 +1117,35 @@
|
|
| 1110 |
</div>
|
| 1111 |
</div>
|
| 1112 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1113 |
<!-- Mic Popup -->
|
| 1114 |
<div class="mic-popup" id="micPopup">
|
| 1115 |
<div class="mic-popup-icon">
|
|
@@ -1127,6 +1163,7 @@
|
|
| 1127 |
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
|
| 1128 |
<script>
|
| 1129 |
let isProcessingRequest = false;
|
|
|
|
| 1130 |
|
| 1131 |
const menuItems = [
|
| 1132 |
{% for section, items in ordered_menu.items() %}
|
|
@@ -1204,6 +1241,79 @@
|
|
| 1204 |
};
|
| 1205 |
}
|
| 1206 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1207 |
function updateCartUI(cart) {
|
| 1208 |
if (!Array.isArray(cart)) {
|
| 1209 |
console.error('Invalid cart data:', cart);
|
|
@@ -1242,31 +1352,36 @@
|
|
| 1242 |
|
| 1243 |
const addButton = itemElement.querySelector('.btn-primary');
|
| 1244 |
const buttonContainer = addButton.closest('.button-container');
|
| 1245 |
-
const name = buttonContainer.getAttribute('data-item-name');
|
| 1246 |
-
const price = buttonContainer.getAttribute('data-item-price');
|
| 1247 |
-
const image = buttonContainer.getAttribute('data-item-image');
|
| 1248 |
-
const category = buttonContainer.getAttribute('data-item-category');
|
| 1249 |
const section = buttonContainer.getAttribute('data-item-section');
|
| 1250 |
-
|
| 1251 |
-
|
| 1252 |
-
|
| 1253 |
-
|
| 1254 |
-
|
| 1255 |
-
|
| 1256 |
-
|
| 1257 |
-
|
| 1258 |
-
|
| 1259 |
-
|
| 1260 |
-
|
| 1261 |
-
|
| 1262 |
-
|
| 1263 |
-
|
| 1264 |
-
|
| 1265 |
-
|
| 1266 |
-
|
| 1267 |
-
|
| 1268 |
-
|
| 1269 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1270 |
}
|
| 1271 |
|
| 1272 |
sessionStorage.removeItem('highlightItem');
|
|
@@ -1657,6 +1772,18 @@
|
|
| 1657 |
quantityInput.value = qty + 1;
|
| 1658 |
});
|
| 1659 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1660 |
const micIcon = document.getElementById('micIcon');
|
| 1661 |
const micUnsupported = document.getElementById('micUnsupported');
|
| 1662 |
const micPopup = document.getElementById('micPopup');
|
|
@@ -1826,8 +1953,7 @@
|
|
| 1826 |
handleAddonClick(event.target);
|
| 1827 |
}
|
| 1828 |
});
|
| 1829 |
-
|
| 1830 |
-
function handleAddonClick(checkbox) {
|
| 1831 |
const groupName = checkbox.getAttribute('data-group');
|
| 1832 |
const isMultiSelectGroup = ["Extra Toppings", "Choose Raita/Sides", "Select Dip/Sauce", "Extra Add-ons", "Make it"].includes(groupName);
|
| 1833 |
const checkboxes = document.querySelectorAll(`.addon-option[data-group="${groupName}"]`);
|
|
@@ -1898,4 +2024,5 @@
|
|
| 1898 |
}
|
| 1899 |
</script>
|
| 1900 |
</body>
|
| 1901 |
-
</html>
|
|
|
|
|
|
| 15 |
{% endfor %}
|
| 16 |
{% endfor %}
|
| 17 |
<style>
|
|
|
|
| 18 |
body {
|
| 19 |
font-family: Arial, sans-serif;
|
| 20 |
background-color: #fdf4e3;
|
|
|
|
| 1000 |
<div>
|
| 1001 |
<h5 class="card-title">{{ item.Name | default('Unnamed Item') }}</h5>
|
| 1002 |
<p class="card-text price">${{ item.Price__c | default('0.00') }}</p>
|
| 1003 |
+
{% if item.Section__c != 'Soft Drinks' %}
|
| 1004 |
+
<div class="toggle-details" data-item-name="{{ item.Name | default('Unnamed Item') }}">Show Details</div>
|
| 1005 |
+
{% endif %}
|
| 1006 |
</div>
|
| 1007 |
<div class="d-flex flex-column align-item-center justify-content-center">
|
| 1008 |
<div class="button-container"
|
|
|
|
| 1011 |
data-item-image="{{ item.Image2__c | default(item.Image1__c) | default('/static/placeholder.jpg') }}"
|
| 1012 |
data-item-section="{{ item.Section__c | default(section) }}"
|
| 1013 |
data-item-category="{{ selected_category }}">
|
| 1014 |
+
{% if item.Section__c == 'Soft Drinks' %}
|
| 1015 |
+
<button class="btn btn-primary add-to-cart-btn" onclick="showSoftDrinkModal(this)">ADD</button>
|
| 1016 |
+
{% else %}
|
| 1017 |
+
<button class="btn btn-primary"
|
| 1018 |
+
data-bs-toggle="modal"
|
| 1019 |
+
data-bs-target="#itemModal"
|
| 1020 |
+
onclick="showItemDetails('{{ item.Name | default('Unnamed Item') | e }}', '{{ item.Price__c | default('0.00') }}', '{{ item.Image2__c | default(item.Image1__c) | default('/static/placeholder.jpg') }}', '{{ item.Description__c | default('No description') | e }}', '{{ item.IngredientsInfo__c | default('Not specified') | e }}', '{{ item.NutritionalInfo__c | default('Not available') | e }}', '{{ item.Allergens__c | default('None listed') | e }}', '{{ item.Section__c | default(section) | e }}', '{{ selected_category | e }}')">
|
| 1021 |
+
ADD
|
| 1022 |
+
</button>
|
| 1023 |
+
{% endif %}
|
| 1024 |
{% if item.Section__c != 'Apetizer' and item.Section__c != 'Customized dish' and item.Section__c != 'Soft Drinks' %}
|
| 1025 |
<span class="customisable-text">Customisable</span>
|
| 1026 |
{% endif %}
|
|
|
|
| 1028 |
</div>
|
| 1029 |
</div>
|
| 1030 |
</div>
|
| 1031 |
+
{% if item.Section__c != 'Soft Drinks' %}
|
| 1032 |
+
<div class="item-details" id="details-{{ item.Name | default('unnamed-item') | replace(' ', '-') }}">
|
| 1033 |
+
<h6>Description</h6>
|
| 1034 |
+
<p>{{ item.Description__c | default('No description available') }}</p>
|
| 1035 |
+
<h6>Ingredients Info</h6>
|
| 1036 |
+
<p>{{ item.IngredientsInfo__c | default('Not specified') }}</p>
|
| 1037 |
+
<h6>Nutritional Info</h6>
|
| 1038 |
+
север <p>{{ item.NutritionalInfo__c | default('Not available') }}</p>
|
| 1039 |
+
<h6>Allergens</h6>
|
| 1040 |
+
<p>{{ item.Allergens__c | default('None listed') }}</p>
|
| 1041 |
+
</div>
|
| 1042 |
+
{% endif %}
|
| 1043 |
</div>
|
| 1044 |
</div>
|
| 1045 |
{% endfor %}
|
|
|
|
| 1117 |
</div>
|
| 1118 |
</div>
|
| 1119 |
|
| 1120 |
+
<!-- Modal for Soft Drinks Quantity Selection -->
|
| 1121 |
+
<div class="modal fade" id="softDrinkModal" tabindex="-1" aria-labelledby="softDrinkModalLabel" aria-hidden="true">
|
| 1122 |
+
<div class="modal-dialog modal-dialog-centered">
|
| 1123 |
+
<div class="modal-content" style="border-radius: 15px; box-shadow: 0 4px 15px rgba(0,0,0,0.2);">
|
| 1124 |
+
<div class="modal-header" style="background: linear-gradient(45deg, #0FAA39, #0D9232); color: white; border-radius: 15px 15px 0 0;">
|
| 1125 |
+
<h5 class="modal-title" id="softDrinkModalLabel">Select Your Drink</h5>
|
| 1126 |
+
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
| 1127 |
+
</div>
|
| 1128 |
+
<div class="modal-body" style="padding: 20px;">
|
| 1129 |
+
<div class="text-center mb-4">
|
| 1130 |
+
<img id="soft-drink-image" class="img-fluid rounded mb-3" alt="Soft Drink Image" style="max-height: 150px; width: auto; object-fit: contain;">
|
| 1131 |
+
<h5 id="soft-drink-name" class="fw-bold" style="color: #333;"></h5>
|
| 1132 |
+
<p id="soft-drink-price" class="text-muted" style="font-size: 1.1rem;"></p>
|
| 1133 |
+
</div>
|
| 1134 |
+
<div class="d-flex justify-content-center align-items-center mb-4">
|
| 1135 |
+
<div class="quantity-selector" style="background-color: #f8f9fa; padding: 10px; border-radius: 10px;">
|
| 1136 |
+
<button type="button" class="btn btn-outline-secondary" id="soft-drink-decrease" style="width: 40px; height: 40px;">-</button>
|
| 1137 |
+
<input type="text" class="form-control text-center mx-2" id="soft-drink-quantity" value="1" readonly style="width: 60px; font-weight: bold; font-size: 1.1rem;">
|
| 1138 |
+
<button type="button" class="btn btn-outline-secondary" id="soft-drink-increase" style="width: 40px; height: 40px;">+</button>
|
| 1139 |
+
</div>
|
| 1140 |
+
</div>
|
| 1141 |
+
</div>
|
| 1142 |
+
<div class="modal-footer" style="border-top: none; padding: 0 20px 20px 20px; justify-content: center;">
|
| 1143 |
+
<button type="button" class="btn btn-primary" onclick="addSoftDrinkToCart()" style="width: 200px; padding: 12px; font-size: 1.1rem; background-color: #0FAA39; border-color: #0FAA39;">Add to Cart</button>
|
| 1144 |
+
</div>
|
| 1145 |
+
</div>
|
| 1146 |
+
</div>
|
| 1147 |
+
</div>
|
| 1148 |
+
|
| 1149 |
<!-- Mic Popup -->
|
| 1150 |
<div class="mic-popup" id="micPopup">
|
| 1151 |
<div class="mic-popup-icon">
|
|
|
|
| 1163 |
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
|
| 1164 |
<script>
|
| 1165 |
let isProcessingRequest = false;
|
| 1166 |
+
let currentSoftDrinkButton = null;
|
| 1167 |
|
| 1168 |
const menuItems = [
|
| 1169 |
{% for section, items in ordered_menu.items() %}
|
|
|
|
| 1241 |
};
|
| 1242 |
}
|
| 1243 |
|
| 1244 |
+
function showSoftDrinkModal(button) {
|
| 1245 |
+
currentSoftDrinkButton = button;
|
| 1246 |
+
const buttonContainer = button.closest('.button-container');
|
| 1247 |
+
const itemName = sanitizeInput(buttonContainer.getAttribute('data-item-name'));
|
| 1248 |
+
const itemPrice = buttonContainer.getAttribute('data-item-price');
|
| 1249 |
+
const itemImage = buttonContainer.getAttribute('data-item-image');
|
| 1250 |
+
|
| 1251 |
+
document.getElementById('soft-drink-name').textContent = itemName;
|
| 1252 |
+
document.getElementById('soft-drink-price').textContent = `$${itemPrice}`;
|
| 1253 |
+
document.getElementById('soft-drink-quantity').value = '1';
|
| 1254 |
+
const softDrinkImage = document.getElementById('soft-drink-image');
|
| 1255 |
+
softDrinkImage.src = itemImage || '/static/placeholder.jpg';
|
| 1256 |
+
|
| 1257 |
+
const modal = new bootstrap.Modal(document.getElementById('softDrinkModal'));
|
| 1258 |
+
modal.show();
|
| 1259 |
+
}
|
| 1260 |
+
|
| 1261 |
+
function addSoftDrinkToCart() {
|
| 1262 |
+
if (!currentSoftDrinkButton) return;
|
| 1263 |
+
|
| 1264 |
+
const buttonContainer = currentSoftDrinkButton.closest('.button-container');
|
| 1265 |
+
const quantity = parseInt(document.getElementById('soft-drink-quantity').value) || 1;
|
| 1266 |
+
|
| 1267 |
+
const itemName = sanitizeInput(buttonContainer.getAttribute('data-item-name'));
|
| 1268 |
+
const itemPrice = parseFloat(buttonContainer.getAttribute('data-item-price'));
|
| 1269 |
+
const itemImage = buttonContainer.getAttribute('data-item-image');
|
| 1270 |
+
const section = sanitizeInput(buttonContainer.getAttribute('data-item-section'));
|
| 1271 |
+
const selectedCategory = sanitizeInput(buttonContainer.getAttribute('data-item-category'));
|
| 1272 |
+
|
| 1273 |
+
const cartPayload = {
|
| 1274 |
+
itemName: itemName,
|
| 1275 |
+
itemPrice: itemPrice,
|
| 1276 |
+
itemImage: itemImage,
|
| 1277 |
+
section: section,
|
| 1278 |
+
category: selectedCategory,
|
| 1279 |
+
addons: [],
|
| 1280 |
+
instructions: '',
|
| 1281 |
+
quantity: quantity
|
| 1282 |
+
};
|
| 1283 |
+
|
| 1284 |
+
fetch('/cart/add', {
|
| 1285 |
+
method: 'POST',
|
| 1286 |
+
headers: {
|
| 1287 |
+
'Content-Type': 'application/json',
|
| 1288 |
+
},
|
| 1289 |
+
body: JSON.stringify(cartPayload)
|
| 1290 |
+
})
|
| 1291 |
+
.then(response => response.json())
|
| 1292 |
+
.then(data => {
|
| 1293 |
+
if (data.success) {
|
| 1294 |
+
alert('Item added to cart successfully!');
|
| 1295 |
+
updateCartUI(data.cart);
|
| 1296 |
+
const modal = bootstrap.Modal.getInstance(document.getElementById('softDrinkModal'));
|
| 1297 |
+
modal.hide();
|
| 1298 |
+
} else {
|
| 1299 |
+
console.error('Failed to add item to cart:', data.error);
|
| 1300 |
+
alert(data.error || 'Failed to add item to cart. Using local storage as fallback.');
|
| 1301 |
+
const cart = addToCartLocalStorage(cartPayload);
|
| 1302 |
+
updateCartUI(cart);
|
| 1303 |
+
const modal = bootstrap.Modal.getInstance(document.getElementById('softDrinkModal'));
|
| 1304 |
+
modal.hide();
|
| 1305 |
+
}
|
| 1306 |
+
})
|
| 1307 |
+
.catch(err => {
|
| 1308 |
+
console.error('Error adding item to cart:', err);
|
| 1309 |
+
alert('Error adding item to cart. Using local storage as fallback.');
|
| 1310 |
+
const cart = addToCartLocalStorage(cartPayload);
|
| 1311 |
+
updateCartUI(cart);
|
| 1312 |
+
const modal = bootstrap.Modal.getInstance(document.getElementById('softDrinkModal'));
|
| 1313 |
+
modal.hide();
|
| 1314 |
+
});
|
| 1315 |
+
}
|
| 1316 |
+
|
| 1317 |
function updateCartUI(cart) {
|
| 1318 |
if (!Array.isArray(cart)) {
|
| 1319 |
console.error('Invalid cart data:', cart);
|
|
|
|
| 1352 |
|
| 1353 |
const addButton = itemElement.querySelector('.btn-primary');
|
| 1354 |
const buttonContainer = addButton.closest('.button-container');
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1355 |
const section = buttonContainer.getAttribute('data-item-section');
|
| 1356 |
+
|
| 1357 |
+
if (section === 'Soft Drinks') {
|
| 1358 |
+
showSoftDrinkModal(addButton);
|
| 1359 |
+
} else {
|
| 1360 |
+
const name = buttonContainer.getAttribute('data-item-name');
|
| 1361 |
+
const price = buttonContainer.getAttribute('data-item-price');
|
| 1362 |
+
const image = buttonContainer.getAttribute('data-item-image');
|
| 1363 |
+
const category = buttonContainer.getAttribute('data-item-category');
|
| 1364 |
+
|
| 1365 |
+
const description = itemElement.querySelector('.item-details h6:contains("Description") + p')?.textContent || 'No description available';
|
| 1366 |
+
const ingredients = itemElement.querySelector('.item-details h6:contains("Ingredients Info") + p')?.textContent || 'Not specified';
|
| 1367 |
+
const nutrition = itemElement.querySelector('.item-details h6:contains("Nutritional Info") + p')?.textContent || 'Not available';
|
| 1368 |
+
const allergens = itemElement.querySelector('.item-details h6:contains("Allergens") + p')?.textContent || 'None listed';
|
| 1369 |
+
|
| 1370 |
+
showItemDetails(
|
| 1371 |
+
name,
|
| 1372 |
+
price,
|
| 1373 |
+
image,
|
| 1374 |
+
description,
|
| 1375 |
+
ingredients,
|
| 1376 |
+
nutrition,
|
| 1377 |
+
allergens,
|
| 1378 |
+
section,
|
| 1379 |
+
category
|
| 1380 |
+
);
|
| 1381 |
+
|
| 1382 |
+
const modal = new bootstrap.Modal(document.getElementById('itemModal'));
|
| 1383 |
+
modal.show();
|
| 1384 |
+
}
|
| 1385 |
}
|
| 1386 |
|
| 1387 |
sessionStorage.removeItem('highlightItem');
|
|
|
|
| 1772 |
quantityInput.value = qty + 1;
|
| 1773 |
});
|
| 1774 |
|
| 1775 |
+
const softDrinkDecreaseBtn = document.getElementById('soft-drink-decrease');
|
| 1776 |
+
const softDrinkIncreaseBtn = document.getElementById('soft-drink-increase');
|
| 1777 |
+
const softDrinkQuantityInput = document.getElementById('soft-drink-quantity');
|
| 1778 |
+
softDrinkDecreaseBtn.addEventListener('click', function() {
|
| 1779 |
+
let qty = parseInt(softDrinkQuantityInput.value);
|
| 1780 |
+
if (qty > 1) softDrinkQuantityInput.value = qty - 1;
|
| 1781 |
+
});
|
| 1782 |
+
softDrinkIncreaseBtn.addEventListener('click', function() {
|
| 1783 |
+
let qty = parseInt(softDrinkQuantityInput.value);
|
| 1784 |
+
if (qty < 1000) softDrinkQuantityInput.value = qty + 1;
|
| 1785 |
+
});
|
| 1786 |
+
|
| 1787 |
const micIcon = document.getElementById('micIcon');
|
| 1788 |
const micUnsupported = document.getElementById('micUnsupported');
|
| 1789 |
const micPopup = document.getElementById('micPopup');
|
|
|
|
| 1953 |
handleAddonClick(event.target);
|
| 1954 |
}
|
| 1955 |
});
|
| 1956 |
+
function handleAddonClick(checkbox) {
|
|
|
|
| 1957 |
const groupName = checkbox.getAttribute('data-group');
|
| 1958 |
const isMultiSelectGroup = ["Extra Toppings", "Choose Raita/Sides", "Select Dip/Sauce", "Extra Add-ons", "Make it"].includes(groupName);
|
| 1959 |
const checkboxes = document.querySelectorAll(`.addon-option[data-group="${groupName}"]`);
|
|
|
|
| 2024 |
}
|
| 2025 |
</script>
|
| 2026 |
</body>
|
| 2027 |
+
</html>
|
| 2028 |
+
|