Update templates/menu.html
Browse files- templates/menu.html +88 -31
templates/menu.html
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<!DOCTYPE html>
|
2 |
<html lang="en">
|
3 |
<head>
|
4 |
<meta charset="UTF-8">
|
@@ -174,7 +174,6 @@
|
|
174 |
background-color: #ffe4c4;
|
175 |
color: #333;
|
176 |
}
|
177 |
-
/* Added styles for upload/delete options */
|
178 |
.upload-item:hover,
|
179 |
.delete-item:hover {
|
180 |
background-color: #ffe4c4;
|
@@ -246,6 +245,17 @@
|
|
246 |
.mic-icon.active {
|
247 |
color: #007bff;
|
248 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
249 |
.autocomplete-suggestions {
|
250 |
position: absolute;
|
251 |
top: 100%;
|
@@ -599,8 +609,6 @@
|
|
599 |
font-size: 12px;
|
600 |
margin-left: 8px;
|
601 |
}
|
602 |
-
|
603 |
-
/* Mic Popup Styles */
|
604 |
.mic-popup {
|
605 |
position: fixed;
|
606 |
top: 50%;
|
@@ -617,24 +625,20 @@
|
|
617 |
max-width: 90%;
|
618 |
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
|
619 |
}
|
620 |
-
|
621 |
.mic-popup.active {
|
622 |
display: block;
|
623 |
}
|
624 |
-
|
625 |
.mic-popup-icon {
|
626 |
font-size: 48px;
|
627 |
margin-bottom: 20px;
|
628 |
color: #ff4444;
|
629 |
animation: pulse 1.5s infinite;
|
630 |
}
|
631 |
-
|
632 |
.mic-popup-text {
|
633 |
font-size: 18px;
|
634 |
margin-bottom: 15px;
|
635 |
min-height: 24px;
|
636 |
}
|
637 |
-
|
638 |
.mic-popup-cancel {
|
639 |
background-color: #ff4444;
|
640 |
color: white;
|
@@ -644,13 +648,11 @@
|
|
644 |
cursor: pointer;
|
645 |
font-weight: bold;
|
646 |
}
|
647 |
-
|
648 |
@keyframes pulse {
|
649 |
0% { transform: scale(1); }
|
650 |
50% { transform: scale(1.1); }
|
651 |
100% { transform: scale(1); }
|
652 |
}
|
653 |
-
|
654 |
@media (max-width: 576px) {
|
655 |
.fixed-top-bar {
|
656 |
height: 60px;
|
@@ -824,7 +826,6 @@
|
|
824 |
.toggle-details {
|
825 |
font-size: 0.8rem;
|
826 |
}
|
827 |
-
/* Mic Popup Mobile Styles */
|
828 |
.mic-popup {
|
829 |
padding: 20px;
|
830 |
width: 280px;
|
@@ -874,6 +875,7 @@
|
|
874 |
<input type="text" id="searchBar" class="form-control" placeholder="Search items or sections..." autocomplete="off">
|
875 |
<i class="bi bi-search search-icon"></i>
|
876 |
<i class="bi bi-mic mic-icon" id="micIcon"></i>
|
|
|
877 |
<div id="autocompleteSuggestions" class="autocomplete-suggestions"></div>
|
878 |
</div>
|
879 |
</div>
|
@@ -893,7 +895,7 @@
|
|
893 |
{% if selected_category == "Customized Dish" %}
|
894 |
<div id="custom-dish-form" class="mt-4">
|
895 |
<h3>Create Your Custom Dish</h3>
|
896 |
-
<form method="POST" action="/customdish/generate_custom_dish">
|
897 |
<div class="mb-3">
|
898 |
<label for="custom-dish-name" class="form-label">Dish Name</label>
|
899 |
<input type="text" class="form-control" id="custom-dish-name" name="name" required>
|
@@ -953,7 +955,7 @@
|
|
953 |
<button class="btn btn-primary"
|
954 |
data-bs-toggle="modal"
|
955 |
data-bs-target="#itemModal"
|
956 |
-
onclick="showItemDetails('{{ item.Name | default('Unnamed Item') }}', '{{ item.Price__c | default('0.00') }}', '{{ item.Image2__c | default(item.Image1__c) }}', '{{ item.Description__c | default('No description') }}', '{{ item.IngredientsInfo__c | default('Not specified') }}', '{{ item.NutritionalInfo__c | default('Not available') }}', '{{ item.Allergens__c | default('None listed') }}', '{{ item.Section__c | default(section) }}', '{{ selected_category }}')">
|
957 |
ADD
|
958 |
</button>
|
959 |
{% endif %}
|
@@ -968,8 +970,8 @@
|
|
968 |
<div class="item-details" id="details-{{ item.Name | default('unnamed-item') | replace(' ', '-') }}">
|
969 |
<h6>Description</h6>
|
970 |
<p>{{ item.Description__c | default('No description available') }}</p>
|
971 |
-
<h6>
|
972 |
-
<p>{{ item.
|
973 |
<h6>Nutritional Info</h6>
|
974 |
<p>{{ item.NutritionalInfo__c | default('Not available') }}</p>
|
975 |
<h6>Allergens</h6>
|
@@ -1081,7 +1083,7 @@
|
|
1081 |
const menuItems = [
|
1082 |
{% for section, items in ordered_menu.items() %}
|
1083 |
{% for item in items %}
|
1084 |
-
"{{ item.Name | default('Unnamed Item') }}",
|
1085 |
{% endfor %}
|
1086 |
{% endfor %}
|
1087 |
];
|
@@ -1102,6 +1104,13 @@
|
|
1102 |
"Whole Wheat Flour", "Yogurt (Curd)"
|
1103 |
];
|
1104 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1105 |
function addToCartLocalStorage(payload) {
|
1106 |
let cart = JSON.parse(localStorage.getItem('cart')) || [];
|
1107 |
const existingItem = cart.find(item =>
|
@@ -1151,7 +1160,7 @@
|
|
1151 |
function showSoftDrinkModal(button) {
|
1152 |
currentSoftDrinkButton = button;
|
1153 |
const buttonContainer = button.closest('.button-container');
|
1154 |
-
const itemName = buttonContainer.getAttribute('data-item-name');
|
1155 |
const itemPrice = buttonContainer.getAttribute('data-item-price');
|
1156 |
const itemImage = buttonContainer.getAttribute('data-item-image');
|
1157 |
|
@@ -1171,11 +1180,11 @@
|
|
1171 |
const buttonContainer = currentSoftDrinkButton.closest('.button-container');
|
1172 |
const quantity = parseInt(document.getElementById('soft-drink-quantity').value) || 1;
|
1173 |
|
1174 |
-
const itemName = buttonContainer.getAttribute('data-item-name');
|
1175 |
const itemPrice = parseFloat(buttonContainer.getAttribute('data-item-price'));
|
1176 |
const itemImage = buttonContainer.getAttribute('data-item-image');
|
1177 |
-
const section = buttonContainer.getAttribute('data-item-section');
|
1178 |
-
const selectedCategory = buttonContainer.getAttribute('data-item-category');
|
1179 |
|
1180 |
const cartPayload = {
|
1181 |
itemName: itemName,
|
@@ -1198,11 +1207,13 @@
|
|
1198 |
.then(response => response.json())
|
1199 |
.then(data => {
|
1200 |
if (data.success) {
|
|
|
1201 |
updateCartUI(data.cart);
|
1202 |
const modal = bootstrap.Modal.getInstance(document.getElementById('softDrinkModal'));
|
1203 |
modal.hide();
|
1204 |
} else {
|
1205 |
console.error('Failed to add item to cart:', data.error);
|
|
|
1206 |
const cart = addToCartLocalStorage(cartPayload);
|
1207 |
updateCartUI(cart);
|
1208 |
const modal = bootstrap.Modal.getInstance(document.getElementById('softDrinkModal'));
|
@@ -1211,6 +1222,7 @@
|
|
1211 |
})
|
1212 |
.catch(err => {
|
1213 |
console.error('Error adding item to cart:', err);
|
|
|
1214 |
const cart = addToCartLocalStorage(cartPayload);
|
1215 |
updateCartUI(cart);
|
1216 |
const modal = bootstrap.Modal.getInstance(document.getElementById('softDrinkModal'));
|
@@ -1422,10 +1434,12 @@
|
|
1422 |
categoryForm.submit();
|
1423 |
});
|
1424 |
});
|
|
|
1425 |
const searchBar = document.getElementById('searchBar');
|
1426 |
const suggestionsContainer = document.getElementById('autocompleteSuggestions');
|
|
|
1427 |
searchBar.addEventListener('input', function () {
|
1428 |
-
const input = this.value.trim().toLowerCase();
|
1429 |
suggestionsContainer.innerHTML = '';
|
1430 |
suggestionsContainer.style.display = 'none';
|
1431 |
if (input) {
|
@@ -1440,20 +1454,21 @@
|
|
1440 |
suggestionDiv.addEventListener('click', function () {
|
1441 |
searchBar.value = item;
|
1442 |
suggestionsContainer.style.display = 'none';
|
1443 |
-
|
1444 |
});
|
1445 |
suggestionsContainer.appendChild(suggestionDiv);
|
1446 |
});
|
1447 |
suggestionsContainer.style.display = 'block';
|
1448 |
}
|
1449 |
}
|
1450 |
-
|
1451 |
});
|
1452 |
document.addEventListener('click', function (event) {
|
1453 |
if (!searchBar.contains(event.target) && !suggestionsContainer.contains(event.target)) {
|
1454 |
suggestionsContainer.style.display = 'none';
|
1455 |
}
|
1456 |
});
|
|
|
1457 |
const descriptionTextarea = document.getElementById('custom-dish-description');
|
1458 |
const descriptionSuggestions = document.getElementById('descriptionSuggestions');
|
1459 |
if (descriptionTextarea && descriptionSuggestions) {
|
@@ -1507,6 +1522,46 @@
|
|
1507 |
}
|
1508 |
});
|
1509 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1510 |
fetch('/cart/get')
|
1511 |
.then(response => {
|
1512 |
if (!response.ok) {
|
@@ -1528,12 +1583,14 @@
|
|
1528 |
const cart = getCartLocalStorage();
|
1529 |
updateCartUI(cart);
|
1530 |
});
|
|
|
1531 |
const preloadedVideos = document.querySelectorAll('link[rel="preload"][as="video"]');
|
1532 |
preloadedVideos.forEach(link => {
|
1533 |
const video = document.createElement('video');
|
1534 |
video.src = link.href;
|
1535 |
video.preload = 'auto';
|
1536 |
});
|
|
|
1537 |
const decreaseBtn = document.getElementById('decreaseQuantity');
|
1538 |
const increaseBtn = document.getElementById('increaseQuantity');
|
1539 |
const quantityInput = document.getElementById('quantityInput');
|
@@ -1572,6 +1629,7 @@
|
|
1572 |
|
1573 |
// Mic Popup Functionality
|
1574 |
const micIcon = document.getElementById('micIcon');
|
|
|
1575 |
const micPopup = document.getElementById('micPopup');
|
1576 |
const micPopupText = document.getElementById('micPopupText');
|
1577 |
const micPopupCancel = document.getElementById('micPopupCancel');
|
@@ -1602,15 +1660,13 @@
|
|
1602 |
}
|
1603 |
}
|
1604 |
|
1605 |
-
// Display interim results
|
1606 |
if (interimTranscript) {
|
1607 |
micPopupText.textContent = interimTranscript;
|
1608 |
}
|
1609 |
|
1610 |
-
// When we have a final result
|
1611 |
if (finalTranscript) {
|
1612 |
-
searchBar.value = finalTranscript.trim();
|
1613 |
-
|
1614 |
micPopup.classList.remove('active');
|
1615 |
}
|
1616 |
};
|
@@ -1618,7 +1674,6 @@
|
|
1618 |
recognition.onend = () => {
|
1619 |
micIcon.classList.remove('active');
|
1620 |
if (micPopup.classList.contains('active')) {
|
1621 |
-
// If still active, it means it ended unexpectedly
|
1622 |
setTimeout(() => {
|
1623 |
micPopup.classList.remove('active');
|
1624 |
}, 1000);
|
@@ -1653,11 +1708,12 @@
|
|
1653 |
});
|
1654 |
} else {
|
1655 |
micIcon.style.display = 'none';
|
|
|
1656 |
}
|
1657 |
});
|
1658 |
|
1659 |
function filterMenu() {
|
1660 |
-
const input = document.getElementById('searchBar').value.trim().toLowerCase();
|
1661 |
const sections = document.querySelectorAll('h3');
|
1662 |
const items = document.querySelectorAll('.menu-card');
|
1663 |
let matchedSections = new Set();
|
@@ -1757,7 +1813,7 @@
|
|
1757 |
|
1758 |
function handleAddonClick(checkbox) {
|
1759 |
const groupName = checkbox.getAttribute('data-group');
|
1760 |
-
const isMultiSelectGroup = ["Extra Toppings", "Choose Raita/Sides", "Select Dip/Sauce", "Extra Add-ons", "Make it a Combo","Beverages","Sauces"].includes(groupName);
|
1761 |
if (!isMultiSelectGroup) {
|
1762 |
const checkboxes = document.querySelectorAll(`.addon-option[data-group="${groupName}"]`);
|
1763 |
checkboxes.forEach(otherCheckbox => {
|
@@ -1797,7 +1853,8 @@
|
|
1797 |
itemImage: itemImage,
|
1798 |
section: section,
|
1799 |
category: selectedCategory,
|
1800 |
-
|
|
|
1801 |
instructions: instructions,
|
1802 |
quantity: quantity
|
1803 |
};
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
<html lang="en">
|
3 |
<head>
|
4 |
<meta charset="UTF-8">
|
|
|
174 |
background-color: #ffe4c4;
|
175 |
color: #333;
|
176 |
}
|
|
|
177 |
.upload-item:hover,
|
178 |
.delete-item:hover {
|
179 |
background-color: #ffe4c4;
|
|
|
245 |
.mic-icon.active {
|
246 |
color: #007bff;
|
247 |
}
|
248 |
+
.mic-unsupported {
|
249 |
+
display: none;
|
250 |
+
position: absolute;
|
251 |
+
right: 15px;
|
252 |
+
font-size: 14px;
|
253 |
+
color: #888;
|
254 |
+
background-color: #fff;
|
255 |
+
padding: 2px 8px;
|
256 |
+
border-radius: 10px;
|
257 |
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
258 |
+
}
|
259 |
.autocomplete-suggestions {
|
260 |
position: absolute;
|
261 |
top: 100%;
|
|
|
609 |
font-size: 12px;
|
610 |
margin-left: 8px;
|
611 |
}
|
|
|
|
|
612 |
.mic-popup {
|
613 |
position: fixed;
|
614 |
top: 50%;
|
|
|
625 |
max-width: 90%;
|
626 |
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
|
627 |
}
|
|
|
628 |
.mic-popup.active {
|
629 |
display: block;
|
630 |
}
|
|
|
631 |
.mic-popup-icon {
|
632 |
font-size: 48px;
|
633 |
margin-bottom: 20px;
|
634 |
color: #ff4444;
|
635 |
animation: pulse 1.5s infinite;
|
636 |
}
|
|
|
637 |
.mic-popup-text {
|
638 |
font-size: 18px;
|
639 |
margin-bottom: 15px;
|
640 |
min-height: 24px;
|
641 |
}
|
|
|
642 |
.mic-popup-cancel {
|
643 |
background-color: #ff4444;
|
644 |
color: white;
|
|
|
648 |
cursor: pointer;
|
649 |
font-weight: bold;
|
650 |
}
|
|
|
651 |
@keyframes pulse {
|
652 |
0% { transform: scale(1); }
|
653 |
50% { transform: scale(1.1); }
|
654 |
100% { transform: scale(1); }
|
655 |
}
|
|
|
656 |
@media (max-width: 576px) {
|
657 |
.fixed-top-bar {
|
658 |
height: 60px;
|
|
|
826 |
.toggle-details {
|
827 |
font-size: 0.8rem;
|
828 |
}
|
|
|
829 |
.mic-popup {
|
830 |
padding: 20px;
|
831 |
width: 280px;
|
|
|
875 |
<input type="text" id="searchBar" class="form-control" placeholder="Search items or sections..." autocomplete="off">
|
876 |
<i class="bi bi-search search-icon"></i>
|
877 |
<i class="bi bi-mic mic-icon" id="micIcon"></i>
|
878 |
+
<span class="mic-unsupported" id="micUnsupported">Mic not supported</span>
|
879 |
<div id="autocompleteSuggestions" class="autocomplete-suggestions"></div>
|
880 |
</div>
|
881 |
</div>
|
|
|
895 |
{% if selected_category == "Customized Dish" %}
|
896 |
<div id="custom-dish-form" class="mt-4">
|
897 |
<h3>Create Your Custom Dish</h3>
|
898 |
+
<form method="POST" action="/customdish/generate_custom_dish" id="customDishForm">
|
899 |
<div class="mb-3">
|
900 |
<label for="custom-dish-name" class="form-label">Dish Name</label>
|
901 |
<input type="text" class="form-control" id="custom-dish-name" name="name" required>
|
|
|
955 |
<button class="btn btn-primary"
|
956 |
data-bs-toggle="modal"
|
957 |
data-bs-target="#itemModal"
|
958 |
+
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 }}')">
|
959 |
ADD
|
960 |
</button>
|
961 |
{% endif %}
|
|
|
970 |
<div class="item-details" id="details-{{ item.Name | default('unnamed-item') | replace(' ', '-') }}">
|
971 |
<h6>Description</h6>
|
972 |
<p>{{ item.Description__c | default('No description available') }}</p>
|
973 |
+
<h6>Ingredients Info</h6>
|
974 |
+
<p>{{ item.IngredientsInfo__c | default('Not specified') }}</p>
|
975 |
<h6>Nutritional Info</h6>
|
976 |
<p>{{ item.NutritionalInfo__c | default('Not available') }}</p>
|
977 |
<h6>Allergens</h6>
|
|
|
1083 |
const menuItems = [
|
1084 |
{% for section, items in ordered_menu.items() %}
|
1085 |
{% for item in items %}
|
1086 |
+
"{{ item.Name | default('Unnamed Item') | e }}",
|
1087 |
{% endfor %}
|
1088 |
{% endfor %}
|
1089 |
];
|
|
|
1104 |
"Whole Wheat Flour", "Yogurt (Curd)"
|
1105 |
];
|
1106 |
|
1107 |
+
// Utility function to sanitize input to prevent XSS
|
1108 |
+
function sanitizeInput(input) {
|
1109 |
+
const div = document.createElement('div');
|
1110 |
+
div.textContent = input;
|
1111 |
+
return div.innerHTML;
|
1112 |
+
}
|
1113 |
+
|
1114 |
function addToCartLocalStorage(payload) {
|
1115 |
let cart = JSON.parse(localStorage.getItem('cart')) || [];
|
1116 |
const existingItem = cart.find(item =>
|
|
|
1160 |
function showSoftDrinkModal(button) {
|
1161 |
currentSoftDrinkButton = button;
|
1162 |
const buttonContainer = button.closest('.button-container');
|
1163 |
+
const itemName = sanitizeInput(buttonContainer.getAttribute('data-item-name'));
|
1164 |
const itemPrice = buttonContainer.getAttribute('data-item-price');
|
1165 |
const itemImage = buttonContainer.getAttribute('data-item-image');
|
1166 |
|
|
|
1180 |
const buttonContainer = currentSoftDrinkButton.closest('.button-container');
|
1181 |
const quantity = parseInt(document.getElementById('soft-drink-quantity').value) || 1;
|
1182 |
|
1183 |
+
const itemName = sanitizeInput(buttonContainer.getAttribute('data-item-name'));
|
1184 |
const itemPrice = parseFloat(buttonContainer.getAttribute('data-item-price'));
|
1185 |
const itemImage = buttonContainer.getAttribute('data-item-image');
|
1186 |
+
const section = sanitizeInput(buttonContainer.getAttribute('data-item-section'));
|
1187 |
+
const selectedCategory = sanitizeInput(buttonContainer.getAttribute('data-item-category'));
|
1188 |
|
1189 |
const cartPayload = {
|
1190 |
itemName: itemName,
|
|
|
1207 |
.then(response => response.json())
|
1208 |
.then(data => {
|
1209 |
if (data.success) {
|
1210 |
+
alert('Item added to cart successfully!');
|
1211 |
updateCartUI(data.cart);
|
1212 |
const modal = bootstrap.Modal.getInstance(document.getElementById('softDrinkModal'));
|
1213 |
modal.hide();
|
1214 |
} else {
|
1215 |
console.error('Failed to add item to cart:', data.error);
|
1216 |
+
alert(data.error || 'Failed to add item to cart. Using local storage as fallback.');
|
1217 |
const cart = addToCartLocalStorage(cartPayload);
|
1218 |
updateCartUI(cart);
|
1219 |
const modal = bootstrap.Modal.getInstance(document.getElementById('softDrinkModal'));
|
|
|
1222 |
})
|
1223 |
.catch(err => {
|
1224 |
console.error('Error adding item to cart:', err);
|
1225 |
+
alert('Error adding item to cart. Using local storage as fallback.');
|
1226 |
const cart = addToCartLocalStorage(cartPayload);
|
1227 |
updateCartUI(cart);
|
1228 |
const modal = bootstrap.Modal.getInstance(document.getElementById('softDrinkModal'));
|
|
|
1434 |
categoryForm.submit();
|
1435 |
});
|
1436 |
});
|
1437 |
+
|
1438 |
const searchBar = document.getElementById('searchBar');
|
1439 |
const suggestionsContainer = document.getElementById('autocompleteSuggestions');
|
1440 |
+
const debouncedFilterMenu = debounce(filterMenu, 300);
|
1441 |
searchBar.addEventListener('input', function () {
|
1442 |
+
const input = sanitizeInput(this.value.trim().toLowerCase());
|
1443 |
suggestionsContainer.innerHTML = '';
|
1444 |
suggestionsContainer.style.display = 'none';
|
1445 |
if (input) {
|
|
|
1454 |
suggestionDiv.addEventListener('click', function () {
|
1455 |
searchBar.value = item;
|
1456 |
suggestionsContainer.style.display = 'none';
|
1457 |
+
debouncedFilterMenu();
|
1458 |
});
|
1459 |
suggestionsContainer.appendChild(suggestionDiv);
|
1460 |
});
|
1461 |
suggestionsContainer.style.display = 'block';
|
1462 |
}
|
1463 |
}
|
1464 |
+
debouncedFilterMenu();
|
1465 |
});
|
1466 |
document.addEventListener('click', function (event) {
|
1467 |
if (!searchBar.contains(event.target) && !suggestionsContainer.contains(event.target)) {
|
1468 |
suggestionsContainer.style.display = 'none';
|
1469 |
}
|
1470 |
});
|
1471 |
+
|
1472 |
const descriptionTextarea = document.getElementById('custom-dish-description');
|
1473 |
const descriptionSuggestions = document.getElementById('descriptionSuggestions');
|
1474 |
if (descriptionTextarea && descriptionSuggestions) {
|
|
|
1522 |
}
|
1523 |
});
|
1524 |
}
|
1525 |
+
|
1526 |
+
// Custom Dish Form Validation
|
1527 |
+
const customDishForm = document.getElementById('customDishForm');
|
1528 |
+
if (customDishForm) {
|
1529 |
+
customDishForm.addEventListener('submit', function(event) {
|
1530 |
+
const dishName = document.getElementById('custom-dish-name').value.trim();
|
1531 |
+
const description = document.getElementById('custom-dish-description').value.trim();
|
1532 |
+
if (!dishName || !description) {
|
1533 |
+
event.preventDefault();
|
1534 |
+
alert('Please fill in both the dish name and description.');
|
1535 |
+
return;
|
1536 |
+
}
|
1537 |
+
// Optional: Add AJAX submission to provide feedback
|
1538 |
+
event.preventDefault();
|
1539 |
+
fetch('/customdish/generate_custom_dish', {
|
1540 |
+
method: 'POST',
|
1541 |
+
headers: {
|
1542 |
+
'Content-Type': 'application/x-www-form-urlencoded',
|
1543 |
+
},
|
1544 |
+
body: new URLSearchParams({
|
1545 |
+
'name': dishName,
|
1546 |
+
'description': description
|
1547 |
+
})
|
1548 |
+
})
|
1549 |
+
.then(response => response.json())
|
1550 |
+
.then(data => {
|
1551 |
+
if (data.success) {
|
1552 |
+
alert('Custom dish submitted successfully!');
|
1553 |
+
window.location.reload();
|
1554 |
+
} else {
|
1555 |
+
alert('Failed to submit custom dish: ' + (data.error || 'Unknown error'));
|
1556 |
+
}
|
1557 |
+
})
|
1558 |
+
.catch(error => {
|
1559 |
+
console.error('Error submitting custom dish:', error);
|
1560 |
+
alert('Error submitting custom dish. Please try again.');
|
1561 |
+
});
|
1562 |
+
});
|
1563 |
+
}
|
1564 |
+
|
1565 |
fetch('/cart/get')
|
1566 |
.then(response => {
|
1567 |
if (!response.ok) {
|
|
|
1583 |
const cart = getCartLocalStorage();
|
1584 |
updateCartUI(cart);
|
1585 |
});
|
1586 |
+
|
1587 |
const preloadedVideos = document.querySelectorAll('link[rel="preload"][as="video"]');
|
1588 |
preloadedVideos.forEach(link => {
|
1589 |
const video = document.createElement('video');
|
1590 |
video.src = link.href;
|
1591 |
video.preload = 'auto';
|
1592 |
});
|
1593 |
+
|
1594 |
const decreaseBtn = document.getElementById('decreaseQuantity');
|
1595 |
const increaseBtn = document.getElementById('increaseQuantity');
|
1596 |
const quantityInput = document.getElementById('quantityInput');
|
|
|
1629 |
|
1630 |
// Mic Popup Functionality
|
1631 |
const micIcon = document.getElementById('micIcon');
|
1632 |
+
const micUnsupported = document.getElementById('micUnsupported');
|
1633 |
const micPopup = document.getElementById('micPopup');
|
1634 |
const micPopupText = document.getElementById('micPopupText');
|
1635 |
const micPopupCancel = document.getElementById('micPopupCancel');
|
|
|
1660 |
}
|
1661 |
}
|
1662 |
|
|
|
1663 |
if (interimTranscript) {
|
1664 |
micPopupText.textContent = interimTranscript;
|
1665 |
}
|
1666 |
|
|
|
1667 |
if (finalTranscript) {
|
1668 |
+
searchBar.value = sanitizeInput(finalTranscript.trim());
|
1669 |
+
debouncedFilterMenu();
|
1670 |
micPopup.classList.remove('active');
|
1671 |
}
|
1672 |
};
|
|
|
1674 |
recognition.onend = () => {
|
1675 |
micIcon.classList.remove('active');
|
1676 |
if (micPopup.classList.contains('active')) {
|
|
|
1677 |
setTimeout(() => {
|
1678 |
micPopup.classList.remove('active');
|
1679 |
}, 1000);
|
|
|
1708 |
});
|
1709 |
} else {
|
1710 |
micIcon.style.display = 'none';
|
1711 |
+
micUnsupported.style.display = 'block';
|
1712 |
}
|
1713 |
});
|
1714 |
|
1715 |
function filterMenu() {
|
1716 |
+
const input = sanitizeInput(document.getElementById('searchBar').value.trim().toLowerCase());
|
1717 |
const sections = document.querySelectorAll('h3');
|
1718 |
const items = document.querySelectorAll('.menu-card');
|
1719 |
let matchedSections = new Set();
|
|
|
1813 |
|
1814 |
function handleAddonClick(checkbox) {
|
1815 |
const groupName = checkbox.getAttribute('data-group');
|
1816 |
+
const isMultiSelectGroup = ["Extra Toppings", "Choose Raita/Sides", "Select Dip/Sauce", "Extra Add-ons", "Make it a Combo", "Beverages", "Sauces"].includes(groupName);
|
1817 |
if (!isMultiSelectGroup) {
|
1818 |
const checkboxes = document.querySelectorAll(`.addon-option[data-group="${groupName}"]`);
|
1819 |
checkboxes.forEach(otherCheckbox => {
|
|
|
1853 |
itemImage: itemImage,
|
1854 |
section: section,
|
1855 |
category: selectedCategory,
|
1856 |
+
|
1857 |
+
addons: selectedAddOns,
|
1858 |
instructions: instructions,
|
1859 |
quantity: quantity
|
1860 |
};
|