lokeshloki143 commited on
Commit
e04397b
·
verified ·
1 Parent(s): 20e3885

Update templates/menu.html

Browse files
Files changed (1) hide show
  1. templates/menu.html +219 -203
templates/menu.html CHANGED
@@ -520,7 +520,15 @@
520
  cursor: pointer;
521
  transition: background-color 0.3s ease;
522
  }
523
- .custom-toggle:checked {
 
 
 
 
 
 
 
 
524
  background: linear-gradient(45deg, #32CD32, #3CB371);
525
  }
526
  .custom-toggle::before {
@@ -852,12 +860,14 @@
852
  white-space: nowrap;
853
  }
854
  .bottom-action-bar .btn-order-history {
855
- background-color: #FFA07A;
856
- border-color: #FFA07A;
 
857
  }
858
  .bottom-action-bar .btn-order-history:hover {
859
- background-color: #FF8C61;
860
- border-color: #FF8C61;
 
861
  }
862
  .bottom-action-bar .btn-view-cart {
863
  background-color: #0FAA39;
@@ -1237,15 +1247,18 @@
1237
  class="menu-image"
1238
  src="{{ item.Image1__c | default('/static/placeholder.jpg') }}"
1239
  alt="{{ item.Name | default('Unnamed Item') }}"
1240
- loading="lazy">
 
 
1241
  <video
1242
  class="menu-video"
1243
  muted
1244
  loop
1245
- preload="auto"
1246
  width="350"
1247
  height="200"
1248
- loading="lazy"
 
1249
  onerror="this.classList.remove('active'); this.previousElementSibling.classList.remove('hidden');">
1250
  <source src="{{ item.Video1__c | default('/static/placeholder.mp4') }}" type="video/mp4">
1251
  Your browser does not support the video tag.
@@ -1324,7 +1337,7 @@
1324
  <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
1325
  </div>
1326
  <div class="modal-body">
1327
- <img id="modal-img" class="img-fluid rounded mb-3 d-block mx-auto" alt="Item Image" style="max-height: 200px; object-fit: cover;" loading="lazy">
1328
  <h5 id="modal-name" class="fw-bold text-center"></h5>
1329
  <p id="modal-price" class="text-muted text-center"></p>
1330
  <p id="modal-description" class="text-secondary"></p>
@@ -1359,7 +1372,7 @@
1359
  <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
1360
  </div>
1361
  <div class="modal-body">
1362
- <img id="soft-drink-image" class="img-fluid rounded mb-3 d-block mx-auto" alt="Soft Drink Image" loading="lazy">
1363
  <div class="text-center mb-3">
1364
  <h5 id="soft-drink-name"></h5>
1365
  <p id="soft-drink-price"></p>
@@ -1392,7 +1405,7 @@
1392
  <i class="bi bi-mic" id="mic-icon-animation"></i>
1393
  <p id="mic-status" class="mt-3">Say the name of a menu item...</p>
1394
  <div id="mic-item-details" style="display: none;">
1395
- <img id="mic-item-image" class="img-fluid rounded mb-3 d-block mx-auto" alt="Spoken Item Image" loading="lazy">
1396
  <h5 id="mic-item-name" class="fw-bold text-center"></h5>
1397
  </div>
1398
  </div>
@@ -1831,240 +1844,243 @@
1831
  if (toggleLink) {
1832
  toggleLink.click();
1833
  }
1834
- }
1835
- });
1836
- if (buttonContainer) {
1837
- if (section === 'Soft Drinks') {
1838
- showSoftDrinkModal(buttonContainer.querySelector('.add-to-cart-btn'));
1839
- } else {
1840
  const name = buttonContainer.getAttribute('data-item-name');
1841
  const price = buttonContainer.getAttribute('data-item-price');
1842
  const image = buttonContainer.getAttribute('data-item-image2');
1843
  const description = buttonContainer.getAttribute('data-item-description');
1844
  const category = buttonContainer.getAttribute('data-item-category');
1845
- showItemDetails(name, price, image, description, section, category);
1846
- const modal = new bootstrap.Modal(document.getElementById('item itemModal'));
1847
- modal.show();
 
 
 
 
 
 
1848
  }
 
 
 
 
1849
  }
1850
- localStorage.removeItem('selectedItem');
1851
- } catch (e) {
1852
- console.error('Error parsing selectedItem:', e);
1853
- localStorage.removeItem('selectedItem');
1854
  }
1855
- }
1856
 
1857
- // Image-to-Video hover/touch functionality
1858
- const mediaWrappers = document.querySelectorAll('.media-wrapper');
1859
- mediaWrappers.forEach(wrapper => {
1860
- const video = wrapper.querySelector('.menu-video');
1861
- const image = wrapper.querySelector('.menu-image');
1862
 
1863
- // Hover events for desktop
1864
- wrapper.addEventListener('mouseenter', () => {
1865
- image.classList.add('hidden');
1866
- video.classList.add('active');
1867
- video.play().catch(err => console.error('Video play error:', err));
1868
- });
1869
 
1870
- wrapper.addEventListener('mouseleave', () => {
1871
- video.classList.remove('active');
1872
- image.classList.remove('hidden');
1873
- video.pause();
1874
- video.currentTime = 0;
1875
- });
 
 
 
 
 
 
 
 
 
1876
 
1877
- // Touch events for mobile
1878
- wrapper.addEventListener('touchstart', (e) => {
1879
- e.preventDefault();
1880
- wrapper.classList.add('touched');
1881
- image.classList.add('hidden');
1882
- video.classList.add('active');
1883
- video.play().catch(err => console.error('Video play error:', err));
1884
  });
1885
 
1886
- wrapper.addEventListener('touchend', () => {
1887
- wrapper.classList.remove('touched');
1888
- video.classList.remove('active');
1889
- image.classList.remove('hidden');
1890
- video.pause();
1891
- video.currentTime = 0;
 
 
 
 
 
 
 
1892
  });
1893
- });
1894
 
1895
- // IntersectionObserver for lazy-loaded videos
1896
- const videoObserver = new IntersectionObserver((entries, observer) => {
1897
- entries.forEach(entry => {
1898
- if (entry.isIntersecting) {
1899
- const video = entry.target;
1900
- video.load();
1901
- observer.unobserve(video);
1902
- }
 
1903
  });
1904
- }, { threshold: 0.2 });
1905
 
1906
- document.querySelectorAll('.menu-video').forEach(video => {
1907
- videoObserver.observe(video);
1908
- });
 
 
 
1909
 
1910
- // Toggle item details
1911
- document.querySelectorAll('.toggle-details').forEach(toggle => {
1912
- toggle.addEventListener('click', function () {
1913
- const details = document.getElementById(`details-${this.getAttribute('data-item-name').replace(/\s+/g, '-')}`);
1914
- if (details) {
1915
- details.classList.toggle('show');
1916
- this.textContent = details.classList.contains('show') ? 'Hide Details' : 'Show Details';
1917
  }
1918
  });
1919
- });
1920
-
1921
- document.getElementById('increaseQuantity').addEventListener('click', function () {
1922
- let quantity = parseInt(document.getElementById('quantityInput').value) || 1;
1923
- document.getElementById('quantityInput').value = quantity + 1;
1924
- updateModalPrice();
1925
- });
1926
-
1927
- document.getElementById('decreaseQuantity').addEventListener('click', function () {
1928
- let quantity = parseInt(document.getElementById('quantityInput').value) || 1;
1929
- if (quantity > 1) {
1930
- document.getElementById('quantityInput').value = quantity - 1;
1931
- updateModalPrice();
1932
- }
1933
- });
1934
 
1935
- // Initialize cart UI
1936
- fetch('/cart')
1937
- .then(response => response.json())
1938
- .then(data => {
1939
- if (data.success && data.cart) {
1940
- updateCartUI(data.cart);
1941
- } else {
1942
- console.warn('No cart data found, checking localStorage');
 
 
 
 
 
 
1943
  const localCart = getCartLocalStorage();
1944
  updateCartUI(localCart);
1945
- }
1946
- })
1947
- .catch(err => {
1948
- console.error('Error fetching cart:', err);
1949
- const localCart = getCartLocalStorage();
1950
- updateCartUI(localCart);
1951
- });
1952
 
1953
- // Microphone functionality
1954
- const micIcon = document.getElementById('micIcon');
1955
- micIcon.addEventListener('click', function () {
1956
- if (!('webkitSpeechRecognition' in window) && !('SpeechRecognition' in window)) {
1957
- alert('Sorry, your browser does not support speech recognition.');
1958
- return;
1959
- }
1960
 
1961
- recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition)();
1962
- recognition.lang = 'en-US';
1963
- recognition.interimResults = true;
1964
- recognition.maxAlternatives = 1;
1965
 
1966
- const micModal = new bootstrap.Modal(document.getElementById('micModal'));
1967
- micModal.show();
1968
- micIcon.classList.add('active');
1969
 
1970
- recognition.start();
1971
 
1972
- recognition.onresult = function (event) {
1973
- const transcript = event.results[0][0].transcript.toLowerCase().trim();
1974
- document.getElementById('mic-status').textContent = `Heard: "${transcript}"`;
1975
 
1976
- const matchedItem = menuItems.find(item =>
1977
- item.name.toLowerCase().includes(transcript) ||
1978
- transcript.includes(item.name.toLowerCase())
1979
- );
1980
 
1981
- if (matchedItem && event.results[0].isFinal) {
1982
- document.getElementById('mic-status').style.display = 'none';
1983
- document.getElementById('mic-item-details').style.display = 'block';
1984
- document.getElementById('mic-item-name').textContent = matchedItem.name;
1985
- document.getElementById('mic-item-image').src = matchedItem.image || '/static/placeholder.jpg';
1986
- document.getElementById('mic-item-details').classList.add('show');
1987
 
1988
- const menuCard = document.querySelector(`.menu-card[data-item-name="${matchedItem.name}"][data-item-section="${matchedItem.section}"]`);
1989
- if (menuCard) {
1990
- menuCard.classList.add('highlighted');
1991
- menuCard.scrollIntoView({ behavior: 'smooth', block: 'center' });
1992
 
1993
- const buttonContainer = menuCard.querySelector('.button-container');
1994
- if (buttonContainer) {
1995
- if (matchedItem.section === 'Soft Drinks') {
1996
- setTimeout(() => {
1997
- showSoftDrinkModal(buttonContainer.querySelector('.add-to-cart-btn'));
1998
- stopSpeechRecognition();
1999
- }, 1000);
2000
- } else {
2001
- const name = buttonContainer.getAttribute('data-item-name');
2002
- const price = buttonContainer.getAttribute('data-item-price');
2003
- const image = buttonContainer.getAttribute('data-item-image2');
2004
- const description = buttonContainer.getAttribute('data-item-description');
2005
- const category = buttonContainer.getAttribute('data-item-category');
2006
- setTimeout(() => {
2007
- showItemDetails(name, price, image, description, matchedItem.section, category);
2008
- const itemModal = new bootstrap.Modal(document.getElementById('itemModal'));
2009
- itemModal.show();
2010
- stopSpeechRecognition();
2011
- }, 1000);
 
2012
  }
2013
  }
2014
  }
2015
- }
2016
- };
2017
 
2018
- recognition.onend = function () {
2019
- if (micIcon.classList.contains('active')) {
2020
- recognition.start();
2021
- }
2022
- };
2023
 
2024
- recognition.onerror = function (event) {
2025
- console.error('Speech recognition error:', event.error);
2026
- document.getElementById('mic-status').textContent = 'Error occurred. Please try again.';
2027
- stopSpeechRecognition();
2028
- };
2029
- });
2030
 
2031
- // Autocomplete for custom dish description
2032
- const descriptionInput = document.getElementById('custom-dish-description');
2033
- const suggestionsContainer = document.getElementById('descriptionSuggestions');
2034
 
2035
- if (descriptionInput && suggestionsContainer) {
2036
- descriptionInput.addEventListener('input', debounce(function () {
2037
- const query = this.value.toLowerCase();
2038
- suggestionsContainer.innerHTML = '';
2039
- if (query.length < 2) return;
2040
 
2041
- const filteredIngredients = ingredientsList.filter(ingredient =>
2042
- ingredient.toLowerCase().includes(query)
2043
- );
2044
 
2045
- filteredIngredients.forEach(ingredient => {
2046
- const suggestion = document.createElement('div');
2047
- suggestion.classList.add('suggestion-item');
2048
- suggestion.textContent = ingredient;
2049
- suggestion.style.padding = '8px';
2050
- suggestion.style.cursor = 'pointer';
2051
- suggestion.style.backgroundColor = '#fff';
2052
- suggestion.style.borderBottom = '1px solid #ddd';
2053
- suggestion.addEventListener('click', () => {
2054
- descriptionInput.value = ingredient;
2055
- suggestionsContainer.innerHTML = '';
 
 
2056
  });
2057
- suggestionsContainer.appendChild(suggestion);
2058
- });
2059
- }, 300));
2060
 
2061
- document.addEventListener('click', function (event) {
2062
- if (!suggestionsContainer.contains(event.target) && event.target !== descriptionInput) {
2063
- suggestionsContainer.innerHTML = '';
2064
- }
2065
- });
2066
- }
2067
- });
2068
- </script>
2069
- </body>
2070
  </html>
 
520
  cursor: pointer;
521
  transition: background-color 0.3s ease;
522
  }
523
+ /* Vegetarian Toggle Specific Styling */
524
+ #veg-toggle {
525
+ background-color: #DC3545; /* Red when off */
526
+ }
527
+ #veg-toggle:checked {
528
+ background-color: #0FAA39; /* Green when on */
529
+ }
530
+ /* Customized Dish Toggle Retains Original Styling */
531
+ #category-CustomizedDish:checked {
532
  background: linear-gradient(45deg, #32CD32, #3CB371);
533
  }
534
  .custom-toggle::before {
 
860
  white-space: nowrap;
861
  }
862
  .bottom-action-bar .btn-order-history {
863
+ background: linear-gradient(45deg, #FFA07A, #FF69B4, #0FAA39);
864
+ border-color: transparent;
865
+ color: #000000; /* Black text */
866
  }
867
  .bottom-action-bar .btn-order-history:hover {
868
+ background: linear-gradient(45deg, #FF8C61, #FF1493, #0D9232);
869
+ border-color: transparent;
870
+ color: #000000; /* Black text on hover */
871
  }
872
  .bottom-action-bar .btn-view-cart {
873
  background-color: #0FAA39;
 
1247
  class="menu-image"
1248
  src="{{ item.Image1__c | default('/static/placeholder.jpg') }}"
1249
  alt="{{ item.Name | default('Unnamed Item') }}"
1250
+ loading="lazy"
1251
+ decoding="async"
1252
+ fetchpriority="low">
1253
  <video
1254
  class="menu-video"
1255
  muted
1256
  loop
1257
+ preload="metadata"
1258
  width="350"
1259
  height="200"
1260
+ loading="lazy"
1261
+ fetchpriority="low"
1262
  onerror="this.classList.remove('active'); this.previousElementSibling.classList.remove('hidden');">
1263
  <source src="{{ item.Video1__c | default('/static/placeholder.mp4') }}" type="video/mp4">
1264
  Your browser does not support the video tag.
 
1337
  <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
1338
  </div>
1339
  <div class="modal-body">
1340
+ <img id="modal-img" class="img-fluid rounded mb-3 d-block mx-auto" alt="Item Image" style="max-height: 200px; object-fit: cover;" loading="lazy" decoding="async">
1341
  <h5 id="modal-name" class="fw-bold text-center"></h5>
1342
  <p id="modal-price" class="text-muted text-center"></p>
1343
  <p id="modal-description" class="text-secondary"></p>
 
1372
  <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
1373
  </div>
1374
  <div class="modal-body">
1375
+ <img id="soft-drink-image" class="img-fluid rounded mb-3 d-block mx-auto" alt="Soft Drink Image" loading="lazy" decoding="async">
1376
  <div class="text-center mb-3">
1377
  <h5 id="soft-drink-name"></h5>
1378
  <p id="soft-drink-price"></p>
 
1405
  <i class="bi bi-mic" id="mic-icon-animation"></i>
1406
  <p id="mic-status" class="mt-3">Say the name of a menu item...</p>
1407
  <div id="mic-item-details" style="display: none;">
1408
+ <img id="mic-item-image" class="img-fluid rounded mb-3 d-block mx-auto" alt="Spoken Item Image" loading="lazy" decoding="async">
1409
  <h5 id="mic-item-name" class="fw-bold text-center"></h5>
1410
  </div>
1411
  </div>
 
1844
  if (toggleLink) {
1845
  toggleLink.click();
1846
  }
1847
+ }
1848
+ });
1849
+ if (targetCard && buttonContainer) {
 
 
 
1850
  const name = buttonContainer.getAttribute('data-item-name');
1851
  const price = buttonContainer.getAttribute('data-item-price');
1852
  const image = buttonContainer.getAttribute('data-item-image2');
1853
  const description = buttonContainer.getAttribute('data-item-description');
1854
  const category = buttonContainer.getAttribute('data-item-category');
1855
+ setTimeout(() => {
1856
+ if (section === 'Soft Drinks') {
1857
+ showSoftDrinkModal(buttonContainer.querySelector('.add-to-cart-btn'));
1858
+ } else {
1859
+ showItemDetails(name, price, image, description, section, category);
1860
+ const modal = new bootstrap.Modal(document.getElementById('itemModal'));
1861
+ modal.show();
1862
+ }
1863
+ }, 1000);
1864
  }
1865
+ } catch (e) {
1866
+ console.error('Error parsing selectedItem:', e);
1867
+ } finally {
1868
+ localStorage.removeItem('selectedItem');
1869
  }
 
 
 
 
1870
  }
 
1871
 
1872
+ // Image-to-Video hover/touch functionality
1873
+ const mediaWrappers = document.querySelectorAll('.media-wrapper');
1874
+ mediaWrappers.forEach(wrapper => {
1875
+ const video = wrapper.querySelector('.menu-video');
1876
+ const image = wrapper.querySelector('.menu-image');
1877
 
1878
+ // Hover events for desktop
1879
+ wrapper.addEventListener('mouseenter', () => {
1880
+ image.classList.add('hidden');
1881
+ video.classList.add('active');
1882
+ video.play().catch(err => console.error('Video play error:', err));
1883
+ });
1884
 
1885
+ wrapper.addEventListener('mouseleave', () => {
1886
+ video.classList.remove('active');
1887
+ image.classList.remove('hidden');
1888
+ video.pause();
1889
+ video.currentTime = 0;
1890
+ });
1891
+
1892
+ // Touch events for mobile
1893
+ wrapper.addEventListener('touchstart', (e) => {
1894
+ e.preventDefault();
1895
+ wrapper.classList.add('touched');
1896
+ image.classList.add('hidden');
1897
+ video.classList.add('active');
1898
+ video.play().catch(err => console.error('Video play error:', err));
1899
+ });
1900
 
1901
+ wrapper.addEventListener('touchend', () => {
1902
+ wrapper.classList.remove('touched');
1903
+ video.classList.remove('active');
1904
+ image.classList.remove('hidden');
1905
+ video.pause();
1906
+ video.currentTime = 0;
1907
+ });
1908
  });
1909
 
1910
+ // IntersectionObserver for lazy-loaded videos
1911
+ const videoObserver = new IntersectionObserver((entries, observer) => {
1912
+ entries.forEach(entry => {
1913
+ if (entry.isIntersecting) {
1914
+ const video = entry.target;
1915
+ video.load();
1916
+ observer.unobserve(video);
1917
+ }
1918
+ });
1919
+ }, { threshold: 0.2 });
1920
+
1921
+ document.querySelectorAll('.menu-video').forEach(video => {
1922
+ videoObserver.observe(video);
1923
  });
 
1924
 
1925
+ // Toggle item details
1926
+ document.querySelectorAll('.toggle-details').forEach(toggle => {
1927
+ toggle.addEventListener('click', function () {
1928
+ const details = document.getElementById(`details-${this.getAttribute('data-item-name').replace(/\s+/g, '-')}`);
1929
+ if (details) {
1930
+ details.classList.toggle('show');
1931
+ this.textContent = details.classList.contains('show') ? 'Hide Details' : 'Show Details';
1932
+ }
1933
+ });
1934
  });
 
1935
 
1936
+ // Quantity controls
1937
+ document.getElementById('increaseQuantity').addEventListener('click', function () {
1938
+ let quantity = parseInt(document.getElementById('quantityInput').value) || 1;
1939
+ document.getElementById('quantityInput').value = quantity + 1;
1940
+ updateModalPrice();
1941
+ });
1942
 
1943
+ document.getElementById('decreaseQuantity').addEventListener('click', function () {
1944
+ let quantity = parseInt(document.getElementById('quantityInput').value) || 1;
1945
+ if (quantity > 1) {
1946
+ document.getElementById('quantityInput').value = quantity - 1;
1947
+ updateModalPrice();
 
 
1948
  }
1949
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1950
 
1951
+ // Initialize cart UI
1952
+ fetch('/cart')
1953
+ .then(response => response.json())
1954
+ .then(data => {
1955
+ if (data.success && data.cart) {
1956
+ updateCartUI(data.cart);
1957
+ } else {
1958
+ console.warn('No cart data found, checking localStorage');
1959
+ const localCart = getCartLocalStorage();
1960
+ updateCartUI(localCart);
1961
+ }
1962
+ })
1963
+ .catch(err => {
1964
+ console.error('Error fetching cart:', err);
1965
  const localCart = getCartLocalStorage();
1966
  updateCartUI(localCart);
1967
+ });
 
 
 
 
 
 
1968
 
1969
+ // Microphone functionality
1970
+ const micIcon = document.getElementById('micIcon');
1971
+ micIcon.addEventListener('click', function () {
1972
+ if (!('webkitSpeechRecognition' in window) && !('SpeechRecognition' in window)) {
1973
+ alert('Sorry, your browser does not support speech recognition.');
1974
+ return;
1975
+ }
1976
 
1977
+ recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition)();
1978
+ recognition.lang = 'en-US';
1979
+ recognition.interimResults = true;
1980
+ recognition.maxAlternatives = 1;
1981
 
1982
+ const micModal = new bootstrap.Modal(document.getElementById('micModal'));
1983
+ micModal.show();
1984
+ micIcon.classList.add('active');
1985
 
1986
+ recognition.start();
1987
 
1988
+ recognition.onresult = function (event) {
1989
+ const transcript = event.results[0][0].transcript.toLowerCase().trim();
1990
+ document.getElementById('mic-status').textContent = `Heard: "${transcript}"`;
1991
 
1992
+ const matchedItem = menuItems.find(item =>
1993
+ item.name.toLowerCase().includes(transcript) ||
1994
+ transcript.includes(item.name.toLowerCase())
1995
+ );
1996
 
1997
+ if (matchedItem && event.results[0].isFinal) {
1998
+ document.getElementById('mic-status').style.display = 'none';
1999
+ document.getElementById('mic-item-details').style.display = 'block';
2000
+ document.getElementById('mic-item-name').textContent = matchedItem.name;
2001
+ document.getElementById('mic-item-image').src = matchedItem.image || '/static/placeholder.jpg';
2002
+ document.getElementById('mic-item-details').classList.add('show');
2003
 
2004
+ const menuCard = document.querySelector(`.menu-card[data-item-name="${matchedItem.name}"][data-item-section="${matchedItem.section}"]`);
2005
+ if (menuCard) {
2006
+ menuCard.classList.add('highlighted');
2007
+ menuCard.scrollIntoView({ behavior: 'smooth', block: 'center' });
2008
 
2009
+ const buttonContainer = menuCard.querySelector('.button-container');
2010
+ if (buttonContainer) {
2011
+ if (matchedItem.section === 'Soft Drinks') {
2012
+ setTimeout(() => {
2013
+ showSoftDrinkModal(buttonContainer.querySelector('.add-to-cart-btn'));
2014
+ stopSpeechRecognition();
2015
+ }, 1000);
2016
+ } else {
2017
+ const name = buttonContainer.getAttribute('data-item-name');
2018
+ const price = buttonContainer.getAttribute('data-item-price');
2019
+ const image = buttonContainer.getAttribute('data-item-image2');
2020
+ const description = buttonContainer.getAttribute('data-item-description');
2021
+ const category = buttonContainer.getAttribute('data-item-category');
2022
+ setTimeout(() => {
2023
+ showItemDetails(name, price, image, description, matchedItem.section, category);
2024
+ const itemModal = new bootstrap.Modal(document.getElementById('itemModal'));
2025
+ itemModal.show();
2026
+ stopSpeechRecognition();
2027
+ }, 1000);
2028
+ }
2029
  }
2030
  }
2031
  }
2032
+ };
 
2033
 
2034
+ recognition.onend = function () {
2035
+ if (micIcon.classList.contains('active')) {
2036
+ recognition.start();
2037
+ }
2038
+ };
2039
 
2040
+ recognition.onerror = function (event) {
2041
+ console.error('Speech recognition error:', event.error);
2042
+ document.getElementById('mic-status').textContent = 'Error occurred. Please try again.';
2043
+ stopSpeechRecognition();
2044
+ };
2045
+ });
2046
 
2047
+ // Autocomplete for custom dish description
2048
+ const descriptionInput = document.getElementById('custom-dish-description');
2049
+ const suggestionsContainer = document.getElementById('descriptionSuggestions');
2050
 
2051
+ if (descriptionInput && suggestionsContainer) {
2052
+ descriptionInput.addEventListener('input', debounce(function () {
2053
+ const query = this.value.toLowerCase();
2054
+ suggestionsContainer.innerHTML = '';
2055
+ if (query.length < 2) return;
2056
 
2057
+ const filteredIngredients = ingredientsList.filter(ingredient =>
2058
+ ingredient.toLowerCase().includes(query)
2059
+ );
2060
 
2061
+ filteredIngredients.forEach(ingredient => {
2062
+ const suggestion = document.createElement('div');
2063
+ suggestion.classList.add('suggestion-item');
2064
+ suggestion.textContent = ingredient;
2065
+ suggestion.style.padding = '8px';
2066
+ suggestion.style.cursor = 'pointer';
2067
+ suggestion.style.backgroundColor = '#fff';
2068
+ suggestion.style.borderBottom = '1px solid #ddd';
2069
+ suggestion.addEventListener('click', () => {
2070
+ descriptionInput.value = ingredient;
2071
+ suggestionsContainer.innerHTML = '';
2072
+ });
2073
+ suggestionsContainer.appendChild(suggestion);
2074
  });
2075
+ }, 300));
 
 
2076
 
2077
+ document.addEventListener('click', function (event) {
2078
+ if (!suggestionsContainer.contains(event.target) && event.target !== descriptionInput) {
2079
+ suggestionsContainer.innerHTML = '';
2080
+ }
2081
+ });
2082
+ }
2083
+ });
2084
+ </script>
2085
+ </body>
2086
  </html>