Update templates/menu.html
Browse files- templates/menu.html +171 -29
templates/menu.html
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
<!DOCTYPE html>
|
| 2 |
<html lang="en">
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8">
|
|
@@ -189,7 +189,8 @@
|
|
| 189 |
}
|
| 190 |
.upload-item,
|
| 191 |
.delete-item,
|
| 192 |
-
.view-item
|
|
|
|
| 193 |
padding: 10px 16px;
|
| 194 |
text-decoration: none;
|
| 195 |
color: #333;
|
|
@@ -199,7 +200,8 @@
|
|
| 199 |
}
|
| 200 |
.upload-item:hover,
|
| 201 |
.delete-item:hover,
|
| 202 |
-
.view-item:hover
|
|
|
|
| 203 |
background-color: #ffe4c4;
|
| 204 |
color: #2c2c2c;
|
| 205 |
}
|
|
@@ -367,9 +369,10 @@
|
|
| 367 |
max-width: 100%;
|
| 368 |
max-height: 400px;
|
| 369 |
object-fit: contain;
|
| 370 |
-
border-radius:
|
| 371 |
margin: 0 auto;
|
| 372 |
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
|
|
| 373 |
}
|
| 374 |
.modal-body #modal-img {
|
| 375 |
max-height: 200px;
|
|
@@ -717,7 +720,8 @@
|
|
| 717 |
}
|
| 718 |
.upload-item,
|
| 719 |
.delete-item,
|
| 720 |
-
.view-item
|
|
|
|
| 721 |
padding: 8px 12px;
|
| 722 |
font-size: 13px;
|
| 723 |
}
|
|
@@ -889,6 +893,7 @@
|
|
| 889 |
{% if user_image %}
|
| 890 |
<div class="dropdown-item delete-item" id="deleteAvatar">Delete Image</div>
|
| 891 |
<div class="dropdown-item view-item" id="viewAvatar">View Avatar</div>
|
|
|
|
| 892 |
{% endif %}
|
| 893 |
<a href="{{ url_for('orderhistory.order_history') }}" class="dropdown-item">Order History</a>
|
| 894 |
<div class="dropdown-item upload-item">
|
|
@@ -1075,7 +1080,29 @@
|
|
| 1075 |
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
| 1076 |
</div>
|
| 1077 |
<div class="modal-body">
|
| 1078 |
-
<img id="avatar-modal-img" class="img-fluid rounded mx-auto d-block" alt="Avatar Image" style="max-height: 400px; object-fit: contain;">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1079 |
</div>
|
| 1080 |
<div class="modal-footer">
|
| 1081 |
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
|
@@ -1302,6 +1329,7 @@
|
|
| 1302 |
const avatarUpload = document.getElementById('avatarUpload');
|
| 1303 |
const deleteAvatar = document.getElementById('deleteAvatar');
|
| 1304 |
const viewAvatar = document.getElementById('viewAvatar');
|
|
|
|
| 1305 |
|
| 1306 |
// Load avatar from localStorage if available
|
| 1307 |
function loadAvatar() {
|
|
@@ -1322,7 +1350,7 @@
|
|
| 1322 |
}
|
| 1323 |
}
|
| 1324 |
|
| 1325 |
-
// Ensure avatar options (Delete
|
| 1326 |
function ensureAvatarOptions() {
|
| 1327 |
if (!document.querySelector('#deleteAvatar')) {
|
| 1328 |
const deleteItem = document.createElement('div');
|
|
@@ -1341,19 +1369,57 @@
|
|
| 1341 |
if (firstChild) dropdownMenu.insertBefore(viewItem, firstChild.nextSibling);
|
| 1342 |
addViewListener(viewItem);
|
| 1343 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1344 |
}
|
| 1345 |
|
| 1346 |
// Remove avatar options
|
| 1347 |
function removeAvatarOptions() {
|
| 1348 |
const deleteItem = document.getElementById('deleteAvatar');
|
| 1349 |
const viewItem = document.getElementById('viewAvatar');
|
|
|
|
| 1350 |
if (deleteItem) deleteItem.remove();
|
| 1351 |
if (viewItem) viewItem.remove();
|
|
|
|
| 1352 |
}
|
| 1353 |
|
| 1354 |
-
// Save avatar to localStorage
|
| 1355 |
function saveAvatar(imageUrl) {
|
| 1356 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1357 |
}
|
| 1358 |
|
| 1359 |
// Clear avatar from localStorage
|
|
@@ -1369,14 +1435,14 @@
|
|
| 1369 |
dropdownMenu.style.display = dropdownMenu.style.display === 'block' ? 'none' : 'block';
|
| 1370 |
});
|
| 1371 |
|
| 1372 |
-
// Handle image upload with
|
| 1373 |
avatarUpload.addEventListener('change', function(event) {
|
| 1374 |
const file = event.target.files[0];
|
| 1375 |
if (file) {
|
| 1376 |
-
const maxSize =
|
| 1377 |
if (file.size > maxSize) {
|
| 1378 |
-
alert('Image size must not exceed
|
| 1379 |
-
|
| 1380 |
return;
|
| 1381 |
}
|
| 1382 |
const reader = new FileReader();
|
|
@@ -1451,6 +1517,87 @@
|
|
| 1451 |
}
|
| 1452 |
});
|
| 1453 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1454 |
// Handle image deletion
|
| 1455 |
function addDeleteListener(deleteElement) {
|
| 1456 |
deleteElement.addEventListener('click', function() {
|
|
@@ -1495,9 +1642,19 @@
|
|
| 1495 |
});
|
| 1496 |
}
|
| 1497 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1498 |
// Add listeners if elements exist
|
| 1499 |
if (deleteAvatar) addDeleteListener(deleteAvatar);
|
| 1500 |
if (viewAvatar) addViewListener(viewAvatar);
|
|
|
|
| 1501 |
|
| 1502 |
// Load avatar on page load
|
| 1503 |
loadAvatar();
|
|
@@ -1786,7 +1943,7 @@
|
|
| 1786 |
const micPopupText = document.getElementById('micPopupText');
|
| 1787 |
const micPopupCancel = document.getElementById('micPopupCancel');
|
| 1788 |
|
| 1789 |
-
|
| 1790 |
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
|
| 1791 |
const recognition = new SpeechRecognition();
|
| 1792 |
recognition.continuous = false;
|
|
@@ -1863,7 +2020,6 @@
|
|
| 1863 |
micUnsupported.style.display = 'block';
|
| 1864 |
}
|
| 1865 |
});
|
| 1866 |
-
|
| 1867 |
function filterMenu() {
|
| 1868 |
const input = sanitizeInput(document.getElementById('searchBar').value.trim().toLowerCase());
|
| 1869 |
const sections = document.querySelectorAll('h3');
|
|
@@ -1901,7 +2057,6 @@
|
|
| 1901 |
});
|
| 1902 |
}
|
| 1903 |
}
|
| 1904 |
-
|
| 1905 |
function showItemDetails(name, price, image, description, ingredients, nutrition, allergens, section, selectedCategory) {
|
| 1906 |
document.getElementById('modal-name').innerText = name;
|
| 1907 |
document.getElementById('modal-price').innerText = `$${price}`;
|
|
@@ -1917,7 +2072,6 @@
|
|
| 1917 |
modalSectionEl.setAttribute('data-section', section);
|
| 1918 |
modalSectionEl.setAttribute('data-category', selectedCategory);
|
| 1919 |
document.getElementById('quantityInput').value = 1;
|
| 1920 |
-
|
| 1921 |
fetch(`/api/addons?item_name=${encodeURIComponent(name)}&item_section=${encodeURIComponent(section)}`)
|
| 1922 |
.then(response => response.json())
|
| 1923 |
.then(data => {
|
|
@@ -1956,13 +2110,11 @@
|
|
| 1956 |
document.getElementById('addons-list').innerHTML = '<p>Error loading customization options.</p>';
|
| 1957 |
});
|
| 1958 |
}
|
| 1959 |
-
|
| 1960 |
document.addEventListener('click', function(event) {
|
| 1961 |
if (event.target.classList.contains('addon-option')) {
|
| 1962 |
handleAddonClick(event.target);
|
| 1963 |
}
|
| 1964 |
});
|
| 1965 |
-
|
| 1966 |
function handleAddonClick(checkbox) {
|
| 1967 |
const groupName = checkbox.getAttribute('data-group');
|
| 1968 |
const isMultiSelectGroup = ["Extra Toppings", "Choose Raita/Sides", "Select Dip/Sauce", "Extra Add-ons", "Make it"].includes(groupName);
|
|
@@ -1973,7 +2125,6 @@
|
|
| 1973 |
});
|
| 1974 |
}
|
| 1975 |
}
|
| 1976 |
-
|
| 1977 |
function addToCartFromModal() {
|
| 1978 |
const itemName = document.getElementById('modal-name').innerText;
|
| 1979 |
const itemPrice = parseFloat(document.getElementById('modal-price').innerText.replace('$', ''));
|
|
@@ -1986,7 +2137,6 @@
|
|
| 1986 |
name: cb.getAttribute('data-name'),
|
| 1987 |
price: parseFloat(cb.getAttribute('data-price') || 0)
|
| 1988 |
}));
|
| 1989 |
-
|
| 1990 |
const cartPayload = {
|
| 1991 |
itemName: itemName,
|
| 1992 |
itemPrice: itemPrice,
|
|
@@ -1997,7 +2147,6 @@
|
|
| 1997 |
instructions: instructions,
|
| 1998 |
quantity: quantity
|
| 1999 |
};
|
| 2000 |
-
|
| 2001 |
fetch('/cart/add', {
|
| 2002 |
method: 'POST',
|
| 2003 |
headers: {
|
|
@@ -2036,10 +2185,3 @@
|
|
| 2036 |
</body>
|
| 2037 |
</html>
|
| 2038 |
|
| 2039 |
-
|
| 2040 |
-
|
| 2041 |
-
|
| 2042 |
-
|
| 2043 |
-
|
| 2044 |
-
|
| 2045 |
-
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
<html lang="en">
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8">
|
|
|
|
| 189 |
}
|
| 190 |
.upload-item,
|
| 191 |
.delete-item,
|
| 192 |
+
.view-item,
|
| 193 |
+
.profile-item {
|
| 194 |
padding: 10px 16px;
|
| 195 |
text-decoration: none;
|
| 196 |
color: #333;
|
|
|
|
| 200 |
}
|
| 201 |
.upload-item:hover,
|
| 202 |
.delete-item:hover,
|
| 203 |
+
.view-item:hover,
|
| 204 |
+
.profile-item:hover {
|
| 205 |
background-color: #ffe4c4;
|
| 206 |
color: #2c2c2c;
|
| 207 |
}
|
|
|
|
| 369 |
max-width: 100%;
|
| 370 |
max-height: 400px;
|
| 371 |
object-fit: contain;
|
| 372 |
+
border-radius: 50%; /* Make the avatar image round */
|
| 373 |
margin: 0 auto;
|
| 374 |
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
| 375 |
+
border: 2px solid #0FAA39; /* Optional: Add a border for style */
|
| 376 |
}
|
| 377 |
.modal-body #modal-img {
|
| 378 |
max-height: 200px;
|
|
|
|
| 720 |
}
|
| 721 |
.upload-item,
|
| 722 |
.delete-item,
|
| 723 |
+
.view-item,
|
| 724 |
+
.profile-item {
|
| 725 |
padding: 8px 12px;
|
| 726 |
font-size: 13px;
|
| 727 |
}
|
|
|
|
| 893 |
{% if user_image %}
|
| 894 |
<div class="dropdown-item delete-item" id="deleteAvatar">Delete Image</div>
|
| 895 |
<div class="dropdown-item view-item" id="viewAvatar">View Avatar</div>
|
| 896 |
+
<div class="dropdown-item profile-item" id="viewProfile">View Profile Customer Details</div>
|
| 897 |
{% endif %}
|
| 898 |
<a href="{{ url_for('orderhistory.order_history') }}" class="dropdown-item">Order History</a>
|
| 899 |
<div class="dropdown-item upload-item">
|
|
|
|
| 1080 |
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
| 1081 |
</div>
|
| 1082 |
<div class="modal-body">
|
| 1083 |
+
<img id="avatar-modal-img" class="img-fluid rounded mx-auto d-block" alt="Avatar Image" style="max-height: 400px; object-fit: contain; border-radius: 50%; border: 2px solid #0FAA39;">
|
| 1084 |
+
</div>
|
| 1085 |
+
<div class="modal-footer">
|
| 1086 |
+
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
| 1087 |
+
</div>
|
| 1088 |
+
</div>
|
| 1089 |
+
</div>
|
| 1090 |
+
</div>
|
| 1091 |
+
|
| 1092 |
+
<!-- Modal for Profile Customer Details -->
|
| 1093 |
+
<div class="modal fade" id="profileModal" tabindex="-1" aria-labelledby="profileModalLabel" aria-hidden="true">
|
| 1094 |
+
<div class="modal-dialog modal-dialog-centered modal-lg">
|
| 1095 |
+
<div class="modal-content">
|
| 1096 |
+
<div class="modal-header">
|
| 1097 |
+
<h5 class="modal-title" id="profileModalLabel">Customer Profile Details</h5>
|
| 1098 |
+
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
| 1099 |
+
</div>
|
| 1100 |
+
<div class="modal-body">
|
| 1101 |
+
<p><strong>Name:</strong> {{ user_name | default('Not specified') }}</p>
|
| 1102 |
+
<p><strong>Email:</strong> {{ user_email | default('Not specified') }}</p>
|
| 1103 |
+
<p><strong>Joined Date:</strong> {{ user_joined_date | default('Not specified') }}</p>
|
| 1104 |
+
<p><strong>Total Orders:</strong> {{ total_orders | default('0') }}</p>
|
| 1105 |
+
<!-- Add more profile details as needed -->
|
| 1106 |
</div>
|
| 1107 |
<div class="modal-footer">
|
| 1108 |
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
|
|
|
| 1329 |
const avatarUpload = document.getElementById('avatarUpload');
|
| 1330 |
const deleteAvatar = document.getElementById('deleteAvatar');
|
| 1331 |
const viewAvatar = document.getElementById('viewAvatar');
|
| 1332 |
+
const viewProfile = document.getElementById('viewProfile');
|
| 1333 |
|
| 1334 |
// Load avatar from localStorage if available
|
| 1335 |
function loadAvatar() {
|
|
|
|
| 1350 |
}
|
| 1351 |
}
|
| 1352 |
|
| 1353 |
+
// Ensure avatar options (Delete, View, Profile) are present only once
|
| 1354 |
function ensureAvatarOptions() {
|
| 1355 |
if (!document.querySelector('#deleteAvatar')) {
|
| 1356 |
const deleteItem = document.createElement('div');
|
|
|
|
| 1369 |
if (firstChild) dropdownMenu.insertBefore(viewItem, firstChild.nextSibling);
|
| 1370 |
addViewListener(viewItem);
|
| 1371 |
}
|
| 1372 |
+
if (!document.querySelector('#viewProfile')) {
|
| 1373 |
+
const profileItem = document.createElement('div');
|
| 1374 |
+
profileItem.className = 'dropdown-item profile-item';
|
| 1375 |
+
profileItem.id = 'viewProfile';
|
| 1376 |
+
profileItem.innerText = 'View Profile Customer Details';
|
| 1377 |
+
const viewItem = document.getElementById('viewAvatar');
|
| 1378 |
+
if (viewItem) dropdownMenu.insertBefore(profileItem, viewItem.nextSibling);
|
| 1379 |
+
addProfileListener(profileItem);
|
| 1380 |
+
}
|
| 1381 |
}
|
| 1382 |
|
| 1383 |
// Remove avatar options
|
| 1384 |
function removeAvatarOptions() {
|
| 1385 |
const deleteItem = document.getElementById('deleteAvatar');
|
| 1386 |
const viewItem = document.getElementById('viewAvatar');
|
| 1387 |
+
const profileItem = document.getElementById('viewProfile');
|
| 1388 |
if (deleteItem) deleteItem.remove();
|
| 1389 |
if (viewItem) viewItem.remove();
|
| 1390 |
+
if (profileItem) profileItem.remove();
|
| 1391 |
}
|
| 1392 |
|
| 1393 |
+
// Save avatar to localStorage with size check and compression
|
| 1394 |
function saveAvatar(imageUrl) {
|
| 1395 |
+
const img = new Image();
|
| 1396 |
+
img.src = imageUrl;
|
| 1397 |
+
img.onload = function() {
|
| 1398 |
+
const maxSize = 50 * 1024 * 1024; // 50MB in bytes
|
| 1399 |
+
const canvas = document.createElement('canvas');
|
| 1400 |
+
const ctx = canvas.getContext('2d');
|
| 1401 |
+
let width = img.width;
|
| 1402 |
+
let height = img.height;
|
| 1403 |
+
|
| 1404 |
+
// Resize if larger than 50MB (approximate based on pixel data)
|
| 1405 |
+
if (img.size > maxSize || (width * height * 4) > maxSize) {
|
| 1406 |
+
const aspectRatio = width / height;
|
| 1407 |
+
if (width > height) {
|
| 1408 |
+
width = 800; // Reduce to a reasonable size
|
| 1409 |
+
height = width / aspectRatio;
|
| 1410 |
+
} else {
|
| 1411 |
+
height = 800;
|
| 1412 |
+
width = height * aspectRatio;
|
| 1413 |
+
}
|
| 1414 |
+
canvas.width = width;
|
| 1415 |
+
canvas.height = height;
|
| 1416 |
+
ctx.drawImage(img, 0, 0, width, height);
|
| 1417 |
+
const compressedDataUrl = canvas.toDataURL('image/jpeg', 0.7); // Compress to JPEG
|
| 1418 |
+
localStorage.setItem('userAvatar', compressedDataUrl);
|
| 1419 |
+
} else {
|
| 1420 |
+
localStorage.setItem('userAvatar', imageUrl);
|
| 1421 |
+
}
|
| 1422 |
+
};
|
| 1423 |
}
|
| 1424 |
|
| 1425 |
// Clear avatar from localStorage
|
|
|
|
| 1435 |
dropdownMenu.style.display = dropdownMenu.style.display === 'block' ? 'none' : 'block';
|
| 1436 |
});
|
| 1437 |
|
| 1438 |
+
// Handle image upload with 50MB limit and compression
|
| 1439 |
avatarUpload.addEventListener('change', function(event) {
|
| 1440 |
const file = event.target.files[0];
|
| 1441 |
if (file) {
|
| 1442 |
+
const maxSize = 50 * 1024 * 1024; // 50MB in bytes
|
| 1443 |
if (file.size > maxSize) {
|
| 1444 |
+
alert('Image size must not exceed 50MB. Compressing and resizing...');
|
| 1445 |
+
compressImage(file);
|
| 1446 |
return;
|
| 1447 |
}
|
| 1448 |
const reader = new FileReader();
|
|
|
|
| 1517 |
}
|
| 1518 |
});
|
| 1519 |
|
| 1520 |
+
// Compress image if it exceeds 50MB
|
| 1521 |
+
function compressImage(file) {
|
| 1522 |
+
const reader = new FileReader();
|
| 1523 |
+
reader.onload = function(e) {
|
| 1524 |
+
const img = new Image();
|
| 1525 |
+
img.src = e.target.result;
|
| 1526 |
+
img.onload = function() {
|
| 1527 |
+
const canvas = document.createElement('canvas');
|
| 1528 |
+
const ctx = canvas.getContext('2d');
|
| 1529 |
+
let width = img.width;
|
| 1530 |
+
let height = img.height;
|
| 1531 |
+
const maxWidth = 800; // Max width for compression
|
| 1532 |
+
const maxHeight = 800; // Max height for compression
|
| 1533 |
+
|
| 1534 |
+
if (width > height) {
|
| 1535 |
+
if (width > maxWidth) {
|
| 1536 |
+
height *= maxWidth / width;
|
| 1537 |
+
width = maxWidth;
|
| 1538 |
+
}
|
| 1539 |
+
} else {
|
| 1540 |
+
if (height > maxHeight) {
|
| 1541 |
+
width *= maxHeight / height;
|
| 1542 |
+
height = maxHeight;
|
| 1543 |
+
}
|
| 1544 |
+
}
|
| 1545 |
+
|
| 1546 |
+
canvas.width = width;
|
| 1547 |
+
canvas.height = height;
|
| 1548 |
+
ctx.drawImage(img, 0, 0, width, height);
|
| 1549 |
+
const compressedDataUrl = canvas.toDataURL('image/jpeg', 0.7); // Compress to 70% quality
|
| 1550 |
+
fetch('/upload_avatar', {
|
| 1551 |
+
method: 'POST',
|
| 1552 |
+
headers: { 'Content-Type': 'application/json' },
|
| 1553 |
+
body: JSON.stringify({ image: compressedDataUrl })
|
| 1554 |
+
})
|
| 1555 |
+
.then(response => response.json())
|
| 1556 |
+
.then(data => {
|
| 1557 |
+
if (data.success) {
|
| 1558 |
+
const imgElement = document.createElement('img');
|
| 1559 |
+
imgElement.src = data.image || '/static/default-avatar.jpg';
|
| 1560 |
+
imgElement.alt = 'User Avatar';
|
| 1561 |
+
imgElement.className = 'avatar-image';
|
| 1562 |
+
imgElement.style.cssText = 'width: 100%; height: 100%; object-fit: cover; border-radius: 50%;';
|
| 1563 |
+
avatarIcon.innerHTML = '';
|
| 1564 |
+
avatarIcon.appendChild(imgElement);
|
| 1565 |
+
saveAvatar(data.image);
|
| 1566 |
+
ensureAvatarOptions();
|
| 1567 |
+
dropdownMenu.style.display = 'none';
|
| 1568 |
+
} else {
|
| 1569 |
+
alert('Failed to upload compressed image: ' + (data.error || 'Unknown error'));
|
| 1570 |
+
const img = document.createElement('img');
|
| 1571 |
+
img.src = '/static/default-avatar.jpg';
|
| 1572 |
+
img.alt = 'User Avatar';
|
| 1573 |
+
img.className = 'avatar-image';
|
| 1574 |
+
img.style.cssText = 'width: 100%; height: 100%; object-fit: cover; border-radius: 50%;';
|
| 1575 |
+
avatarIcon.innerHTML = '';
|
| 1576 |
+
avatarIcon.appendChild(img);
|
| 1577 |
+
saveAvatar('/static/default-avatar.jpg');
|
| 1578 |
+
ensureAvatarOptions();
|
| 1579 |
+
dropdownMenu.style.display = 'none';
|
| 1580 |
+
}
|
| 1581 |
+
})
|
| 1582 |
+
.catch(error => {
|
| 1583 |
+
console.error('Upload error:', error);
|
| 1584 |
+
alert('Error uploading compressed image. Using default image.');
|
| 1585 |
+
const img = document.createElement('img');
|
| 1586 |
+
img.src = '/static/default-avatar.jpg';
|
| 1587 |
+
img.alt = 'User Avatar';
|
| 1588 |
+
img.className = 'avatar-image';
|
| 1589 |
+
img.style.cssText = 'width: 100%; height: 100%; object-fit: cover; border-radius: 50%;';
|
| 1590 |
+
avatarIcon.innerHTML = '';
|
| 1591 |
+
avatarIcon.appendChild(img);
|
| 1592 |
+
saveAvatar('/static/default-avatar.jpg');
|
| 1593 |
+
ensureAvatarOptions();
|
| 1594 |
+
dropdownMenu.style.display = 'none';
|
| 1595 |
+
});
|
| 1596 |
+
};
|
| 1597 |
+
};
|
| 1598 |
+
reader.readAsDataURL(file);
|
| 1599 |
+
}
|
| 1600 |
+
|
| 1601 |
// Handle image deletion
|
| 1602 |
function addDeleteListener(deleteElement) {
|
| 1603 |
deleteElement.addEventListener('click', function() {
|
|
|
|
| 1642 |
});
|
| 1643 |
}
|
| 1644 |
|
| 1645 |
+
// Handle profile view
|
| 1646 |
+
function addProfileListener(profileElement) {
|
| 1647 |
+
profileElement.addEventListener('click', function() {
|
| 1648 |
+
const modal = new bootstrap.Modal(document.getElementById('profileModal'));
|
| 1649 |
+
modal.show();
|
| 1650 |
+
dropdownMenu.style.display = 'none';
|
| 1651 |
+
});
|
| 1652 |
+
}
|
| 1653 |
+
|
| 1654 |
// Add listeners if elements exist
|
| 1655 |
if (deleteAvatar) addDeleteListener(deleteAvatar);
|
| 1656 |
if (viewAvatar) addViewListener(viewAvatar);
|
| 1657 |
+
if (viewProfile) addProfileListener(viewProfile);
|
| 1658 |
|
| 1659 |
// Load avatar on page load
|
| 1660 |
loadAvatar();
|
|
|
|
| 1943 |
const micPopupText = document.getElementById('micPopupText');
|
| 1944 |
const micPopupCancel = document.getElementById('micPopupCancel');
|
| 1945 |
|
| 1946 |
+
if ('SpeechRecognition' in window || 'webkitSpeechRecognition' in window) {
|
| 1947 |
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
|
| 1948 |
const recognition = new SpeechRecognition();
|
| 1949 |
recognition.continuous = false;
|
|
|
|
| 2020 |
micUnsupported.style.display = 'block';
|
| 2021 |
}
|
| 2022 |
});
|
|
|
|
| 2023 |
function filterMenu() {
|
| 2024 |
const input = sanitizeInput(document.getElementById('searchBar').value.trim().toLowerCase());
|
| 2025 |
const sections = document.querySelectorAll('h3');
|
|
|
|
| 2057 |
});
|
| 2058 |
}
|
| 2059 |
}
|
|
|
|
| 2060 |
function showItemDetails(name, price, image, description, ingredients, nutrition, allergens, section, selectedCategory) {
|
| 2061 |
document.getElementById('modal-name').innerText = name;
|
| 2062 |
document.getElementById('modal-price').innerText = `$${price}`;
|
|
|
|
| 2072 |
modalSectionEl.setAttribute('data-section', section);
|
| 2073 |
modalSectionEl.setAttribute('data-category', selectedCategory);
|
| 2074 |
document.getElementById('quantityInput').value = 1;
|
|
|
|
| 2075 |
fetch(`/api/addons?item_name=${encodeURIComponent(name)}&item_section=${encodeURIComponent(section)}`)
|
| 2076 |
.then(response => response.json())
|
| 2077 |
.then(data => {
|
|
|
|
| 2110 |
document.getElementById('addons-list').innerHTML = '<p>Error loading customization options.</p>';
|
| 2111 |
});
|
| 2112 |
}
|
|
|
|
| 2113 |
document.addEventListener('click', function(event) {
|
| 2114 |
if (event.target.classList.contains('addon-option')) {
|
| 2115 |
handleAddonClick(event.target);
|
| 2116 |
}
|
| 2117 |
});
|
|
|
|
| 2118 |
function handleAddonClick(checkbox) {
|
| 2119 |
const groupName = checkbox.getAttribute('data-group');
|
| 2120 |
const isMultiSelectGroup = ["Extra Toppings", "Choose Raita/Sides", "Select Dip/Sauce", "Extra Add-ons", "Make it"].includes(groupName);
|
|
|
|
| 2125 |
});
|
| 2126 |
}
|
| 2127 |
}
|
|
|
|
| 2128 |
function addToCartFromModal() {
|
| 2129 |
const itemName = document.getElementById('modal-name').innerText;
|
| 2130 |
const itemPrice = parseFloat(document.getElementById('modal-price').innerText.replace('$', ''));
|
|
|
|
| 2137 |
name: cb.getAttribute('data-name'),
|
| 2138 |
price: parseFloat(cb.getAttribute('data-price') || 0)
|
| 2139 |
}));
|
|
|
|
| 2140 |
const cartPayload = {
|
| 2141 |
itemName: itemName,
|
| 2142 |
itemPrice: itemPrice,
|
|
|
|
| 2147 |
instructions: instructions,
|
| 2148 |
quantity: quantity
|
| 2149 |
};
|
|
|
|
| 2150 |
fetch('/cart/add', {
|
| 2151 |
method: 'POST',
|
| 2152 |
headers: {
|
|
|
|
| 2185 |
</body>
|
| 2186 |
</html>
|
| 2187 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|