Spaces:
Runtime error
Runtime error
Update templates/menu.html
Browse files- templates/menu.html +36 -86
templates/menu.html
CHANGED
@@ -49,14 +49,14 @@
|
|
49 |
border-radius: 15px 15px 0 0;
|
50 |
opacity: 0;
|
51 |
transition: opacity 0.5s ease-in-out;
|
52 |
-
background-color: #000;
|
53 |
}
|
54 |
.menu-video.loaded {
|
55 |
opacity: 1;
|
56 |
}
|
57 |
.menu-card:hover .menu-video {
|
58 |
opacity: 1;
|
59 |
-
transform: scale(1.05);
|
60 |
}
|
61 |
.menu-card .card-body .card-title {
|
62 |
font-size: 1.2rem;
|
@@ -174,8 +174,8 @@
|
|
174 |
font-size: 15px;
|
175 |
transition: background-color 0.2s ease;
|
176 |
}
|
177 |
-
.dropdown-menu .dropdown-item:
|
178 |
-
border-
|
179 |
}
|
180 |
.dropdown-menu .dropdown-item:hover {
|
181 |
background-color: #ffe4c4;
|
@@ -660,17 +660,6 @@
|
|
660 |
50% { transform: scale(1.1); }
|
661 |
100% { transform: scale(1); }
|
662 |
}
|
663 |
-
.avatar-modal .modal-content {
|
664 |
-
border-radius: 15px;
|
665 |
-
box-shadow: 0 4px 15px rgba(0,0,0,0.2);
|
666 |
-
}
|
667 |
-
.avatar-modal .modal-body img {
|
668 |
-
max-width: 100%;
|
669 |
-
max-height: 80vh;
|
670 |
-
border-radius: 10px;
|
671 |
-
margin: 0 auto;
|
672 |
-
display: block;
|
673 |
-
}
|
674 |
@media (max-width: 576px) {
|
675 |
.fixed-top-bar {
|
676 |
height: 60px;
|
@@ -873,7 +862,9 @@
|
|
873 |
{% endif %}
|
874 |
</div>
|
875 |
<div class="dropdown-menu" id="avatarDropdown">
|
876 |
-
|
|
|
|
|
877 |
<a href="{{ url_for('orderhistory.order_history') }}" class="dropdown-item">Order History</a>
|
878 |
<div class="dropdown-item upload-item">
|
879 |
<label for="avatarUpload" style="cursor: pointer; margin: 0; width: 100%;">
|
@@ -881,9 +872,6 @@
|
|
881 |
</label>
|
882 |
<input type="file" id="avatarUpload" accept="image/*" style="display: none;">
|
883 |
</div>
|
884 |
-
{% if user_image %}
|
885 |
-
<div class="dropdown-item delete-item" id="deleteAvatar">Delete Image</div>
|
886 |
-
{% endif %}
|
887 |
<a href="{{ url_for('logout') }}" class="dropdown-item">Logout</a>
|
888 |
</div>
|
889 |
</div>
|
@@ -896,24 +884,6 @@
|
|
896 |
</div>
|
897 |
</div>
|
898 |
|
899 |
-
<!-- Avatar View Modal (Triggered Directly from Avatar Icon) -->
|
900 |
-
<div class="modal fade avatar-modal" id="avatarViewModal" tabindex="-1" aria-labelledby="avatarViewModalLabel" aria-hidden="true">
|
901 |
-
<div class="modal-dialog modal-dialog-centered">
|
902 |
-
<div class="modal-content">
|
903 |
-
<div class="modal-header">
|
904 |
-
<h5 class="modal-title" id="avatarViewModalLabel">View Avatar</h5>
|
905 |
-
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
906 |
-
</div>
|
907 |
-
<div class="modal-body">
|
908 |
-
<img id="avatarModalImage" src="" alt="Avatar Image" class="img-fluid">
|
909 |
-
</div>
|
910 |
-
<div class="modal-footer">
|
911 |
-
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
912 |
-
</div>
|
913 |
-
</div>
|
914 |
-
</div>
|
915 |
-
</div>
|
916 |
-
|
917 |
<form method="get" action="/menu" class="text-center mb-4" id="categoryForm">
|
918 |
<label class="form-label fw-bold">Select a Category:</label>
|
919 |
<div class="category-buttons">
|
@@ -1288,7 +1258,6 @@
|
|
1288 |
const avatarIcon = document.getElementById('avatarIcon');
|
1289 |
const avatarUpload = document.getElementById('avatarUpload');
|
1290 |
const deleteAvatar = document.getElementById('deleteAvatar');
|
1291 |
-
const avatarModalImage = document.getElementById('avatarModalImage');
|
1292 |
|
1293 |
// Load avatar from localStorage if available
|
1294 |
function loadAvatar() {
|
@@ -1306,7 +1275,7 @@
|
|
1306 |
deleteItem.className = 'dropdown-item delete-item';
|
1307 |
deleteItem.id = 'deleteAvatar';
|
1308 |
deleteItem.innerText = 'Delete Image';
|
1309 |
-
dropdownMenu.insertBefore(deleteItem, dropdownMenu.
|
1310 |
addDeleteListener(deleteItem);
|
1311 |
}
|
1312 |
}
|
@@ -1324,16 +1293,10 @@
|
|
1324 |
if (deleteAvatar) deleteAvatar.remove();
|
1325 |
}
|
1326 |
|
1327 |
-
// Avatar click handler
|
1328 |
avatarIcon.addEventListener('click', function(event) {
|
1329 |
event.stopPropagation();
|
1330 |
-
|
1331 |
-
if (avatarImg) {
|
1332 |
-
avatarModalImage.src = avatarImg.src || '/static/default-avatar.jpg'; // Fallback image
|
1333 |
-
new bootstrap.Modal(document.getElementById('avatarViewModal')).show();
|
1334 |
-
} else {
|
1335 |
-
dropdownMenu.style.display = dropdownMenu.style.display === 'block' ? 'none' : 'block';
|
1336 |
-
}
|
1337 |
});
|
1338 |
|
1339 |
// Handle image upload with 15MB limit and error handling
|
@@ -1363,7 +1326,7 @@
|
|
1363 |
.then(data => {
|
1364 |
if (data.success) {
|
1365 |
const img = document.createElement('img');
|
1366 |
-
img.src = data.image || '/static/default-avatar.jpg';
|
1367 |
img.alt = 'User Avatar';
|
1368 |
img.className = 'avatar-image';
|
1369 |
img.style.cssText = 'width: 100%; height: 100%; object-fit: cover; border-radius: 50%;';
|
@@ -1375,14 +1338,14 @@
|
|
1375 |
deleteItem.className = 'dropdown-item delete-item';
|
1376 |
deleteItem.id = 'deleteAvatar';
|
1377 |
deleteItem.innerText = 'Delete Image';
|
1378 |
-
dropdownMenu.insertBefore(deleteItem, dropdownMenu.
|
1379 |
addDeleteListener(deleteItem);
|
1380 |
}
|
1381 |
dropdownMenu.style.display = 'none';
|
1382 |
} else {
|
1383 |
alert('Failed to upload image: ' + (data.error || 'Unknown error. Using default image.'));
|
1384 |
const img = document.createElement('img');
|
1385 |
-
img.src = '/static/default-avatar.jpg';
|
1386 |
img.alt = 'User Avatar';
|
1387 |
img.className = 'avatar-image';
|
1388 |
img.style.cssText = 'width: 100%; height: 100%; object-fit: cover; border-radius: 50%;';
|
@@ -1394,7 +1357,7 @@
|
|
1394 |
deleteItem.className = 'dropdown-item delete-item';
|
1395 |
deleteItem.id = 'deleteAvatar';
|
1396 |
deleteItem.innerText = 'Delete Image';
|
1397 |
-
dropdownMenu.insertBefore(deleteItem, dropdownMenu.
|
1398 |
addDeleteListener(deleteItem);
|
1399 |
}
|
1400 |
dropdownMenu.style.display = 'none';
|
@@ -1404,7 +1367,7 @@
|
|
1404 |
console.error('Upload error:', error);
|
1405 |
alert('Error uploading image. Using default image as fallback.');
|
1406 |
const img = document.createElement('img');
|
1407 |
-
img.src = '/static/default-avatar.jpg';
|
1408 |
img.alt = 'User Avatar';
|
1409 |
img.className = 'avatar-image';
|
1410 |
img.style.cssText = 'width: 100%; height: 100%; object-fit: cover; border-radius: 50%;';
|
@@ -1416,7 +1379,7 @@
|
|
1416 |
deleteItem.className = 'dropdown-item delete-item';
|
1417 |
deleteItem.id = 'deleteAvatar';
|
1418 |
deleteItem.innerText = 'Delete Image';
|
1419 |
-
dropdownMenu.insertBefore(deleteItem, dropdownMenu.
|
1420 |
addDeleteListener(deleteItem);
|
1421 |
}
|
1422 |
dropdownMenu.style.display = 'none';
|
@@ -1425,7 +1388,7 @@
|
|
1425 |
reader.onerror = function() {
|
1426 |
alert('Error reading the image file. Using default image as fallback.');
|
1427 |
const img = document.createElement('img');
|
1428 |
-
img.src = '/static/default-avatar.jpg';
|
1429 |
img.alt = 'User Avatar';
|
1430 |
img.className = 'avatar-image';
|
1431 |
img.style.cssText = 'width: 100%; height: 100%; object-fit: cover; border-radius: 50%;';
|
@@ -1437,7 +1400,7 @@
|
|
1437 |
deleteItem.className = 'dropdown-item delete-item';
|
1438 |
deleteItem.id = 'deleteAvatar';
|
1439 |
deleteItem.innerText = 'Delete Image';
|
1440 |
-
dropdownMenu.insertBefore(deleteItem, dropdownMenu.
|
1441 |
addDeleteListener(deleteItem);
|
1442 |
}
|
1443 |
dropdownMenu.style.display = 'none';
|
@@ -1945,51 +1908,39 @@
|
|
1945 |
|
1946 |
function handleAddonClick(checkbox) {
|
1947 |
const groupName = checkbox.getAttribute('data-group');
|
1948 |
-
const isMultiSelectGroup = ["Extra Toppings", "Choose Raita/Sides", "Select Dip/Sauce", "Extra Add-ons", "Make it
|
|
|
1949 |
if (!isMultiSelectGroup) {
|
1950 |
-
|
1951 |
-
|
1952 |
-
if (otherCheckbox !== checkbox) {
|
1953 |
-
otherCheckbox.checked = false;
|
1954 |
-
}
|
1955 |
});
|
1956 |
}
|
1957 |
}
|
1958 |
|
1959 |
function addToCartFromModal() {
|
1960 |
const itemName = document.getElementById('modal-name').innerText;
|
1961 |
-
|
1962 |
-
if (isNaN(itemPrice)) {
|
1963 |
-
alert('Invalid price for the item. Please check the item details.');
|
1964 |
-
return;
|
1965 |
-
}
|
1966 |
const itemImage = document.getElementById('modal-img').src;
|
1967 |
-
const
|
1968 |
-
const
|
1969 |
-
const
|
1970 |
-
|
1971 |
-
|
1972 |
-
|
1973 |
-
|
1974 |
-
const selectedAddOns = Array.from(
|
1975 |
-
document.querySelectorAll('#addons-list input[type="checkbox"]:checked')
|
1976 |
-
).map(addon => ({
|
1977 |
-
name: addon.getAttribute('data-name') || 'Default Name',
|
1978 |
-
price: parseFloat(addon.getAttribute('data-price') || 0)
|
1979 |
}));
|
1980 |
-
|
1981 |
-
const instructions = document.getElementById('modal-instructions').value;
|
1982 |
const cartPayload = {
|
1983 |
itemName: itemName,
|
1984 |
itemPrice: itemPrice,
|
1985 |
itemImage: itemImage,
|
1986 |
section: section,
|
1987 |
category: selectedCategory,
|
1988 |
-
addons:
|
1989 |
instructions: instructions,
|
1990 |
quantity: quantity
|
1991 |
};
|
1992 |
-
|
1993 |
fetch('/cart/add', {
|
1994 |
method: 'POST',
|
1995 |
headers: {
|
@@ -2002,12 +1953,11 @@
|
|
2002 |
if (data.success) {
|
2003 |
alert('Item added to cart successfully!');
|
2004 |
updateCartUI(data.cart);
|
2005 |
-
const modal = document.getElementById('itemModal');
|
2006 |
-
|
2007 |
-
modalInstance.hide();
|
2008 |
} else {
|
2009 |
console.error('Failed to add item to cart:', data.error);
|
2010 |
-
alert(data.error || 'Failed to add item to cart.');
|
2011 |
const cart = addToCartLocalStorage(cartPayload);
|
2012 |
updateCartUI(cart);
|
2013 |
const modal = document.getElementById('itemModal');
|
|
|
49 |
border-radius: 15px 15px 0 0;
|
50 |
opacity: 0;
|
51 |
transition: opacity 0.5s ease-in-out;
|
52 |
+
background-color: #000;
|
53 |
}
|
54 |
.menu-video.loaded {
|
55 |
opacity: 1;
|
56 |
}
|
57 |
.menu-card:hover .menu-video {
|
58 |
opacity: 1;
|
59 |
+
transform: scale(1.05);
|
60 |
}
|
61 |
.menu-card .card-body .card-title {
|
62 |
font-size: 1.2rem;
|
|
|
174 |
font-size: 15px;
|
175 |
transition: background-color 0.2s ease;
|
176 |
}
|
177 |
+
.dropdown-menu .dropdown-item:first-child {
|
178 |
+
border-top: none;
|
179 |
}
|
180 |
.dropdown-menu .dropdown-item:hover {
|
181 |
background-color: #ffe4c4;
|
|
|
660 |
50% { transform: scale(1.1); }
|
661 |
100% { transform: scale(1); }
|
662 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
663 |
@media (max-width: 576px) {
|
664 |
.fixed-top-bar {
|
665 |
height: 60px;
|
|
|
862 |
{% endif %}
|
863 |
</div>
|
864 |
<div class="dropdown-menu" id="avatarDropdown">
|
865 |
+
{% if user_image %}
|
866 |
+
<div class="dropdown-item delete-item" id="deleteAvatar">Delete Image</div>
|
867 |
+
{% endif %}
|
868 |
<a href="{{ url_for('orderhistory.order_history') }}" class="dropdown-item">Order History</a>
|
869 |
<div class="dropdown-item upload-item">
|
870 |
<label for="avatarUpload" style="cursor: pointer; margin: 0; width: 100%;">
|
|
|
872 |
</label>
|
873 |
<input type="file" id="avatarUpload" accept="image/*" style="display: none;">
|
874 |
</div>
|
|
|
|
|
|
|
875 |
<a href="{{ url_for('logout') }}" class="dropdown-item">Logout</a>
|
876 |
</div>
|
877 |
</div>
|
|
|
884 |
</div>
|
885 |
</div>
|
886 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
887 |
<form method="get" action="/menu" class="text-center mb-4" id="categoryForm">
|
888 |
<label class="form-label fw-bold">Select a Category:</label>
|
889 |
<div class="category-buttons">
|
|
|
1258 |
const avatarIcon = document.getElementById('avatarIcon');
|
1259 |
const avatarUpload = document.getElementById('avatarUpload');
|
1260 |
const deleteAvatar = document.getElementById('deleteAvatar');
|
|
|
1261 |
|
1262 |
// Load avatar from localStorage if available
|
1263 |
function loadAvatar() {
|
|
|
1275 |
deleteItem.className = 'dropdown-item delete-item';
|
1276 |
deleteItem.id = 'deleteAvatar';
|
1277 |
deleteItem.innerText = 'Delete Image';
|
1278 |
+
dropdownMenu.insertBefore(deleteItem, dropdownMenu.firstChild);
|
1279 |
addDeleteListener(deleteItem);
|
1280 |
}
|
1281 |
}
|
|
|
1293 |
if (deleteAvatar) deleteAvatar.remove();
|
1294 |
}
|
1295 |
|
1296 |
+
// Avatar click handler
|
1297 |
avatarIcon.addEventListener('click', function(event) {
|
1298 |
event.stopPropagation();
|
1299 |
+
dropdownMenu.style.display = dropdownMenu.style.display === 'block' ? 'none' : 'block';
|
|
|
|
|
|
|
|
|
|
|
|
|
1300 |
});
|
1301 |
|
1302 |
// Handle image upload with 15MB limit and error handling
|
|
|
1326 |
.then(data => {
|
1327 |
if (data.success) {
|
1328 |
const img = document.createElement('img');
|
1329 |
+
img.src = data.image || '/static/default-avatar.jpg';
|
1330 |
img.alt = 'User Avatar';
|
1331 |
img.className = 'avatar-image';
|
1332 |
img.style.cssText = 'width: 100%; height: 100%; object-fit: cover; border-radius: 50%;';
|
|
|
1338 |
deleteItem.className = 'dropdown-item delete-item';
|
1339 |
deleteItem.id = 'deleteAvatar';
|
1340 |
deleteItem.innerText = 'Delete Image';
|
1341 |
+
dropdownMenu.insertBefore(deleteItem, dropdownMenu.firstChild);
|
1342 |
addDeleteListener(deleteItem);
|
1343 |
}
|
1344 |
dropdownMenu.style.display = 'none';
|
1345 |
} else {
|
1346 |
alert('Failed to upload image: ' + (data.error || 'Unknown error. Using default image.'));
|
1347 |
const img = document.createElement('img');
|
1348 |
+
img.src = '/static/default-avatar.jpg';
|
1349 |
img.alt = 'User Avatar';
|
1350 |
img.className = 'avatar-image';
|
1351 |
img.style.cssText = 'width: 100%; height: 100%; object-fit: cover; border-radius: 50%;';
|
|
|
1357 |
deleteItem.className = 'dropdown-item delete-item';
|
1358 |
deleteItem.id = 'deleteAvatar';
|
1359 |
deleteItem.innerText = 'Delete Image';
|
1360 |
+
dropdownMenu.insertBefore(deleteItem, dropdownMenu.firstChild);
|
1361 |
addDeleteListener(deleteItem);
|
1362 |
}
|
1363 |
dropdownMenu.style.display = 'none';
|
|
|
1367 |
console.error('Upload error:', error);
|
1368 |
alert('Error uploading image. Using default image as fallback.');
|
1369 |
const img = document.createElement('img');
|
1370 |
+
img.src = '/static/default-avatar.jpg';
|
1371 |
img.alt = 'User Avatar';
|
1372 |
img.className = 'avatar-image';
|
1373 |
img.style.cssText = 'width: 100%; height: 100%; object-fit: cover; border-radius: 50%;';
|
|
|
1379 |
deleteItem.className = 'dropdown-item delete-item';
|
1380 |
deleteItem.id = 'deleteAvatar';
|
1381 |
deleteItem.innerText = 'Delete Image';
|
1382 |
+
dropdownMenu.insertBefore(deleteItem, dropdownMenu.firstChild);
|
1383 |
addDeleteListener(deleteItem);
|
1384 |
}
|
1385 |
dropdownMenu.style.display = 'none';
|
|
|
1388 |
reader.onerror = function() {
|
1389 |
alert('Error reading the image file. Using default image as fallback.');
|
1390 |
const img = document.createElement('img');
|
1391 |
+
img.src = '/static/default-avatar.jpg';
|
1392 |
img.alt = 'User Avatar';
|
1393 |
img.className = 'avatar-image';
|
1394 |
img.style.cssText = 'width: 100%; height: 100%; object-fit: cover; border-radius: 50%;';
|
|
|
1400 |
deleteItem.className = 'dropdown-item delete-item';
|
1401 |
deleteItem.id = 'deleteAvatar';
|
1402 |
deleteItem.innerText = 'Delete Image';
|
1403 |
+
dropdownMenu.insertBefore(deleteItem, dropdownMenu.firstChild);
|
1404 |
addDeleteListener(deleteItem);
|
1405 |
}
|
1406 |
dropdownMenu.style.display = 'none';
|
|
|
1908 |
|
1909 |
function handleAddonClick(checkbox) {
|
1910 |
const groupName = checkbox.getAttribute('data-group');
|
1911 |
+
const isMultiSelectGroup = ["Extra Toppings", "Choose Raita/Sides", "Select Dip/Sauce", "Extra Add-ons", "Make it"].includes(groupName);
|
1912 |
+
const checkboxes = document.querySelectorAll(`.addon-option[data-group="${groupName}"]`);
|
1913 |
if (!isMultiSelectGroup) {
|
1914 |
+
checkboxes.forEach(cb => {
|
1915 |
+
if (cb !== checkbox) cb.checked = false;
|
|
|
|
|
|
|
1916 |
});
|
1917 |
}
|
1918 |
}
|
1919 |
|
1920 |
function addToCartFromModal() {
|
1921 |
const itemName = document.getElementById('modal-name').innerText;
|
1922 |
+
const itemPrice = parseFloat(document.getElementById('modal-price').innerText.replace('$', ''));
|
|
|
|
|
|
|
|
|
1923 |
const itemImage = document.getElementById('modal-img').src;
|
1924 |
+
const instructions = document.getElementById('modal-instructions').value.trim();
|
1925 |
+
const quantity = parseInt(document.getElementById('quantityInput').value);
|
1926 |
+
const section = document.getElementById('modal-section').getAttribute('data-section');
|
1927 |
+
const selectedCategory = document.getElementById('modal-section').getAttribute('data-category');
|
1928 |
+
const addons = Array.from(document.querySelectorAll('.addon-option:checked')).map(cb => ({
|
1929 |
+
name: cb.getAttribute('data-name'),
|
1930 |
+
price: parseFloat(cb.getAttribute('data-price') || 0)
|
|
|
|
|
|
|
|
|
|
|
1931 |
}));
|
1932 |
+
|
|
|
1933 |
const cartPayload = {
|
1934 |
itemName: itemName,
|
1935 |
itemPrice: itemPrice,
|
1936 |
itemImage: itemImage,
|
1937 |
section: section,
|
1938 |
category: selectedCategory,
|
1939 |
+
addons: addons,
|
1940 |
instructions: instructions,
|
1941 |
quantity: quantity
|
1942 |
};
|
1943 |
+
|
1944 |
fetch('/cart/add', {
|
1945 |
method: 'POST',
|
1946 |
headers: {
|
|
|
1953 |
if (data.success) {
|
1954 |
alert('Item added to cart successfully!');
|
1955 |
updateCartUI(data.cart);
|
1956 |
+
const modal = bootstrap.Modal.getInstance(document.getElementById('itemModal'));
|
1957 |
+
modal.hide();
|
|
|
1958 |
} else {
|
1959 |
console.error('Failed to add item to cart:', data.error);
|
1960 |
+
alert(data.error || 'Failed to add item to cart. Using local storage as fallback.');
|
1961 |
const cart = addToCartLocalStorage(cartPayload);
|
1962 |
updateCartUI(cart);
|
1963 |
const modal = document.getElementById('itemModal');
|