lokesh341 commited on
Commit
4fb1436
·
verified ·
1 Parent(s): 30de228

Update templates/menu.html

Browse files
Files changed (1) hide show
  1. 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: 8px;
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 and View) are present only once
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
- localStorage.setItem('userAvatar', imageUrl);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 15MB limit and error handling
1373
  avatarUpload.addEventListener('change', function(event) {
1374
  const file = event.target.files[0];
1375
  if (file) {
1376
- const maxSize = 15 * 1024 * 1024; // 15MB in bytes
1377
  if (file.size > maxSize) {
1378
- alert('Image size must not exceed 15MB.');
1379
- this.value = '';
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
- if ('SpeechRecognition' in window || 'webkitSpeechRecognition' in window) {
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