Update templates/menu.html
Browse files- templates/menu.html +191 -190
templates/menu.html
CHANGED
|
@@ -157,7 +157,7 @@
|
|
| 157 |
width: 40px;
|
| 158 |
height: 40px;
|
| 159 |
border-radius: 50%;
|
| 160 |
-
background:
|
| 161 |
cursor: pointer;
|
| 162 |
display: flex;
|
| 163 |
align-items: center;
|
|
@@ -165,47 +165,34 @@
|
|
| 165 |
color: white;
|
| 166 |
font-size: 20px;
|
| 167 |
font-weight: bold;
|
| 168 |
-
transition: transform 0.3s ease;
|
| 169 |
-
}
|
| 170 |
-
.avatar-icon:hover {
|
| 171 |
-
transform: scale(1.1);
|
| 172 |
}
|
| 173 |
.dropdown-menu {
|
| 174 |
position: absolute;
|
| 175 |
right: 0;
|
| 176 |
top: 100%;
|
| 177 |
-
background:
|
| 178 |
-
border-radius:
|
| 179 |
-
width:
|
| 180 |
-
box-shadow:
|
| 181 |
display: none;
|
| 182 |
-
border:
|
| 183 |
-
padding: 10px 0;
|
| 184 |
-
z-index: 1000;
|
| 185 |
-
overflow: hidden;
|
| 186 |
}
|
| 187 |
.dropdown-menu .dropdown-item {
|
| 188 |
-
padding: 12px
|
| 189 |
text-decoration: none;
|
| 190 |
color: #333;
|
| 191 |
-
|
| 192 |
-
|
| 193 |
font-size: 15px;
|
| 194 |
-
transition:
|
| 195 |
-
}
|
| 196 |
-
.dropdown-menu .dropdown-item i {
|
| 197 |
-
margin-right: 10px;
|
| 198 |
-
font-size: 18px;
|
| 199 |
-
color: #FF4500;
|
| 200 |
-
}
|
| 201 |
-
.dropdown-menu .dropdown-item:hover {
|
| 202 |
-
background: linear-gradient(45deg, #FFE4B5, #FFDAB9);
|
| 203 |
-
color: #000;
|
| 204 |
-
transform: translateX(5px);
|
| 205 |
}
|
| 206 |
.dropdown-menu .dropdown-item:last-child {
|
| 207 |
border-bottom: none;
|
| 208 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 209 |
.fixed-top-bar {
|
| 210 |
position: relative;
|
| 211 |
top: 0;
|
|
@@ -975,7 +962,19 @@
|
|
| 975 |
max-width: 150px;
|
| 976 |
margin: 0 auto 8px;
|
| 977 |
display: block;
|
| 978 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 979 |
.modal-body .nutritional-info {
|
| 980 |
font-size: 10px;
|
| 981 |
margin-bottom: 5px;
|
|
@@ -1205,10 +1204,10 @@
|
|
| 1205 |
<span>{{ first_letter }}</span>
|
| 1206 |
</div>
|
| 1207 |
<div class="dropdown-menu">
|
| 1208 |
-
<a href="{{ url_for('user_details.customer_details') }}" class="dropdown-item"
|
| 1209 |
-
<a href="{{ url_for('orderhistory.order_history') }}" class="dropdown-item"
|
| 1210 |
-
<a href="{{ url_for('combined_summary.combined_summary') }}" class="dropdown-item"
|
| 1211 |
-
<a href="{{ url_for('logout') }}" class="dropdown-item"
|
| 1212 |
</div>
|
| 1213 |
</div>
|
| 1214 |
<div class="search-bar-container">
|
|
@@ -1415,7 +1414,7 @@
|
|
| 1415 |
|
| 1416 |
<!-- Microphone Modal -->
|
| 1417 |
<div class="modal fade" id="micModal" tabindex="-1" aria-labelledby="micModalLabel" aria-hidden="true">
|
| 1418 |
-
<div class
|
| 1419 |
<div class="modal-content">
|
| 1420 |
<div class="modal-header">
|
| 1421 |
<h5 class="modal-title" id="micModalLabel">Speak Now</h5>
|
|
@@ -1896,24 +1895,16 @@
|
|
| 1896 |
|
| 1897 |
// Hover events for desktop
|
| 1898 |
wrapper.addEventListener('mouseenter', () => {
|
| 1899 |
-
|
| 1900 |
-
|
| 1901 |
-
|
| 1902 |
-
video.play().catch(err => {
|
| 1903 |
-
console.error('Video play error:', err);
|
| 1904 |
-
video.classList.remove('active');
|
| 1905 |
-
image.classList.remove('hidden');
|
| 1906 |
-
});
|
| 1907 |
-
}
|
| 1908 |
});
|
| 1909 |
|
| 1910 |
wrapper.addEventListener('mouseleave', () => {
|
| 1911 |
-
|
| 1912 |
-
|
| 1913 |
-
|
| 1914 |
-
|
| 1915 |
-
video.currentTime = 0;
|
| 1916 |
-
}
|
| 1917 |
});
|
| 1918 |
|
| 1919 |
// Touch events for mobile
|
|
@@ -1922,163 +1913,167 @@
|
|
| 1922 |
wrapper.classList.add('touched');
|
| 1923 |
image.classList.add('hidden');
|
| 1924 |
video.classList.add('active');
|
| 1925 |
-
video.play().catch(err =>
|
| 1926 |
-
console.error('Video play error:', err);
|
| 1927 |
-
video.classList.remove('active');
|
| 1928 |
-
image.classList.remove('hidden');
|
| 1929 |
-
});
|
| 1930 |
});
|
| 1931 |
|
| 1932 |
wrapper.addEventListener('touchend', () => {
|
| 1933 |
wrapper.classList.remove('touched');
|
| 1934 |
video.classList.remove('active');
|
| 1935 |
-
image.classList.remove('
|
| 1936 |
video.pause();
|
| 1937 |
video.currentTime = 0;
|
| 1938 |
});
|
| 1939 |
});
|
| 1940 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1941 |
// Quantity controls for item modal
|
| 1942 |
const decreaseBtn = document.getElementById('decreaseQuantity');
|
| 1943 |
const increaseBtn = document.getElementById('increaseQuantity');
|
| 1944 |
const quantityInput = document.getElementById('quantityInput');
|
| 1945 |
|
| 1946 |
decreaseBtn.addEventListener('click', () => {
|
| 1947 |
-
let
|
| 1948 |
-
if (
|
| 1949 |
-
quantityInput.value =
|
| 1950 |
updateModalPrice();
|
| 1951 |
}
|
| 1952 |
});
|
| 1953 |
|
| 1954 |
increaseBtn.addEventListener('click', () => {
|
| 1955 |
-
let
|
| 1956 |
-
quantityInput.value =
|
| 1957 |
updateModalPrice();
|
| 1958 |
});
|
| 1959 |
|
| 1960 |
-
//
|
| 1961 |
-
|
| 1962 |
-
toggle.addEventListener('click', () => {
|
| 1963 |
-
const itemName = toggle.getAttribute('data-item-name').replace(/\s+/g, '-');
|
| 1964 |
-
const details = document.getElementById(`details-${itemName}`);
|
| 1965 |
-
if (details) {
|
| 1966 |
-
details.classList.toggle('show');
|
| 1967 |
-
toggle.textContent = details.classList.contains('show') ? 'Hide Details' : 'Show Details';
|
| 1968 |
-
}
|
| 1969 |
-
});
|
| 1970 |
-
});
|
| 1971 |
-
|
| 1972 |
-
// Initialize cart UI
|
| 1973 |
-
fetch('/cart')
|
| 1974 |
-
.then(response => response.json())
|
| 1975 |
-
.then(data => {
|
| 1976 |
-
if (data.success) {
|
| 1977 |
-
updateCartUI(data.cart);
|
| 1978 |
-
} else {
|
| 1979 |
-
updateCartUI(getCartLocalStorage());
|
| 1980 |
-
}
|
| 1981 |
-
})
|
| 1982 |
-
.catch(err => {
|
| 1983 |
-
console.error('Error fetching cart:', err);
|
| 1984 |
-
updateCartUI(getCartLocalStorage());
|
| 1985 |
-
});
|
| 1986 |
|
| 1987 |
// Speech recognition setup
|
| 1988 |
-
|
| 1989 |
-
|
| 1990 |
-
|
| 1991 |
-
|
| 1992 |
-
|
| 1993 |
-
|
| 1994 |
-
|
| 1995 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1996 |
|
| 1997 |
-
|
| 1998 |
-
|
| 1999 |
-
|
| 2000 |
-
|
| 2001 |
-
|
| 2002 |
-
|
|
|
|
|
|
|
| 2003 |
|
| 2004 |
-
|
| 2005 |
-
micIcon.classList.add('active');
|
| 2006 |
-
document.getElementById('mic-status').textContent = 'Listening...';
|
| 2007 |
-
const micModal = new bootstrap.Modal(document.getElementById('micModal'));
|
| 2008 |
-
micModal.show();
|
| 2009 |
-
};
|
| 2010 |
|
| 2011 |
-
|
| 2012 |
-
const
|
| 2013 |
-
|
| 2014 |
-
const matchedItem = menuItems.find(item =>
|
| 2015 |
-
item.name.toLowerCase().includes(transcript) ||
|
| 2016 |
-
item.section.toLowerCase().includes(transcript)
|
| 2017 |
);
|
| 2018 |
|
| 2019 |
-
if (
|
| 2020 |
-
recognition.stop();
|
| 2021 |
document.getElementById('mic-status').style.display = 'none';
|
| 2022 |
document.getElementById('mic-item-details').style.display = 'block';
|
| 2023 |
-
document.getElementById('mic-item-name').textContent =
|
| 2024 |
-
document.getElementById('mic-item-image').src =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2025 |
|
| 2026 |
-
|
| 2027 |
-
const
|
| 2028 |
-
|
| 2029 |
-
|
|
|
|
|
|
|
|
|
|
| 2030 |
|
| 2031 |
-
|
| 2032 |
-
|
| 2033 |
-
|
| 2034 |
-
|
| 2035 |
-
const buttonContainer = menuCard.querySelector('.button-container');
|
| 2036 |
-
if (buttonContainer) {
|
| 2037 |
-
const name = buttonContainer.getAttribute('data-item-name');
|
| 2038 |
-
const price = buttonContainer.getAttribute('data-item-price');
|
| 2039 |
-
const image = buttonContainer.getAttribute('data-item-image2');
|
| 2040 |
-
const description = buttonContainer.getAttribute('data-item-description');
|
| 2041 |
-
const section = buttonContainer.getAttribute('data-item-section');
|
| 2042 |
-
const category = buttonContainer.getAttribute('data-item-category');
|
| 2043 |
|
| 2044 |
-
|
| 2045 |
-
|
| 2046 |
-
|
| 2047 |
-
|
| 2048 |
-
|
| 2049 |
-
|
| 2050 |
-
}
|
| 2051 |
}
|
| 2052 |
-
}
|
| 2053 |
-
}
|
| 2054 |
-
} else {
|
| 2055 |
-
document.getElementById('mic-status').textContent = 'No matching item found. Try again.';
|
| 2056 |
}
|
| 2057 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2058 |
|
| 2059 |
-
|
| 2060 |
-
|
| 2061 |
-
|
|
|
|
| 2062 |
stopSpeechRecognition();
|
| 2063 |
-
};
|
|
|
|
| 2064 |
|
| 2065 |
-
|
| 2066 |
-
|
| 2067 |
-
if (document.getElementById('mic-item-details').style.display !== 'block') {
|
| 2068 |
-
setTimeout(() => {
|
| 2069 |
-
const micModal = bootstrap.Modal.getInstance(document.getElementById('micModal'));
|
| 2070 |
-
if (micModal) {
|
| 2071 |
-
micModal.hide();
|
| 2072 |
-
resetMicModal();
|
| 2073 |
-
}
|
| 2074 |
-
}, 1000);
|
| 2075 |
-
}
|
| 2076 |
-
};
|
| 2077 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2078 |
recognition.start();
|
| 2079 |
-
}
|
| 2080 |
-
|
| 2081 |
-
|
|
|
|
| 2082 |
}
|
| 2083 |
|
| 2084 |
// Autocomplete for custom dish description
|
|
@@ -2086,41 +2081,46 @@
|
|
| 2086 |
const suggestionsContainer = document.getElementById('descriptionSuggestions');
|
| 2087 |
|
| 2088 |
if (descriptionInput && suggestionsContainer) {
|
| 2089 |
-
|
| 2090 |
-
const query = this.value.trim();
|
| 2091 |
suggestionsContainer.innerHTML = '';
|
| 2092 |
-
|
| 2093 |
-
|
| 2094 |
-
|
| 2095 |
-
|
| 2096 |
-
|
| 2097 |
-
|
| 2098 |
-
|
| 2099 |
-
|
| 2100 |
-
|
| 2101 |
-
|
| 2102 |
-
|
| 2103 |
-
suggestionDiv.style.cursor = 'pointer';
|
| 2104 |
-
suggestionDiv.style.backgroundColor = '#fff';
|
| 2105 |
-
suggestionDiv.style.borderBottom = '1px solid #eee';
|
| 2106 |
-
|
| 2107 |
-
suggestionDiv.addEventListener('click', () => {
|
| 2108 |
-
descriptionInput.value = descriptionInput.value + ' ' + ingredient;
|
| 2109 |
-
suggestionsContainer.innerHTML = '';
|
| 2110 |
-
});
|
| 2111 |
-
|
| 2112 |
-
suggestionsContainer.appendChild(suggestionDiv);
|
| 2113 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2114 |
|
| 2115 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2116 |
} else {
|
| 2117 |
suggestionsContainer.style.display = 'none';
|
| 2118 |
}
|
| 2119 |
}, 300));
|
| 2120 |
|
| 2121 |
-
document.addEventListener('click', (
|
| 2122 |
-
if (!descriptionInput.contains(
|
| 2123 |
-
suggestionsContainer.innerHTML = '';
|
| 2124 |
suggestionsContainer.style.display = 'none';
|
| 2125 |
}
|
| 2126 |
});
|
|
@@ -2128,4 +2128,5 @@
|
|
| 2128 |
});
|
| 2129 |
</script>
|
| 2130 |
</body>
|
| 2131 |
-
</html>
|
|
|
|
|
|
| 157 |
width: 40px;
|
| 158 |
height: 40px;
|
| 159 |
border-radius: 50%;
|
| 160 |
+
background-color: #007bff;
|
| 161 |
cursor: pointer;
|
| 162 |
display: flex;
|
| 163 |
align-items: center;
|
|
|
|
| 165 |
color: white;
|
| 166 |
font-size: 20px;
|
| 167 |
font-weight: bold;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 168 |
}
|
| 169 |
.dropdown-menu {
|
| 170 |
position: absolute;
|
| 171 |
right: 0;
|
| 172 |
top: 100%;
|
| 173 |
+
background-color: #fff8f0;
|
| 174 |
+
border-radius: 5px;
|
| 175 |
+
width: 220px;
|
| 176 |
+
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
|
| 177 |
display: none;
|
| 178 |
+
border: 1px solid #ffd8b1;
|
|
|
|
|
|
|
|
|
|
| 179 |
}
|
| 180 |
.dropdown-menu .dropdown-item {
|
| 181 |
+
padding: 12px 16px;
|
| 182 |
text-decoration: none;
|
| 183 |
color: #333;
|
| 184 |
+
border-bottom: 1px solid #ffd8b1;
|
| 185 |
+
display: block;
|
| 186 |
font-size: 15px;
|
| 187 |
+
transition: background-color 0.2s ease;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 188 |
}
|
| 189 |
.dropdown-menu .dropdown-item:last-child {
|
| 190 |
border-bottom: none;
|
| 191 |
}
|
| 192 |
+
.dropdown-menu .dropdown-item:hover {
|
| 193 |
+
background-color: #ffe4c4;
|
| 194 |
+
color: #333;
|
| 195 |
+
}
|
| 196 |
.fixed-top-bar {
|
| 197 |
position: relative;
|
| 198 |
top: 0;
|
|
|
|
| 962 |
max-width: 150px;
|
| 963 |
margin: 0 auto 8px;
|
| 964 |
display: block;
|
| 965 |
+
}
|
| 966 |
+
.modal-body #modal-name {
|
| 967 |
+
font-size: 18px;
|
| 968 |
+
margin-bottom: 5px;
|
| 969 |
+
}
|
| 970 |
+
.modal-body #modal-price {
|
| 971 |
+
font-size: 14px;
|
| 972 |
+
margin-bottom: 8px;
|
| 973 |
+
}
|
| 974 |
+
.modal-body #modal-description {
|
| 975 |
+
font-size: 12px;
|
| 976 |
+
margin-bottom: 10px;
|
| 977 |
+
}
|
| 978 |
.modal-body .nutritional-info {
|
| 979 |
font-size: 10px;
|
| 980 |
margin-bottom: 5px;
|
|
|
|
| 1204 |
<span>{{ first_letter }}</span>
|
| 1205 |
</div>
|
| 1206 |
<div class="dropdown-menu">
|
| 1207 |
+
<a href="{{ url_for('user_details.customer_details') }}" class="dropdown-item">View Profile</a>
|
| 1208 |
+
<a href="{{ url_for('orderhistory.order_history') }}" class="dropdown-item">Order History</a>
|
| 1209 |
+
<a href="{{ url_for('combined_summary.combined_summary') }}" class="dropdown-item">MY Summary</a>
|
| 1210 |
+
<a href="{{ url_for('logout') }}" class="dropdown-item">Logout</a>
|
| 1211 |
</div>
|
| 1212 |
</div>
|
| 1213 |
<div class="search-bar-container">
|
|
|
|
| 1414 |
|
| 1415 |
<!-- Microphone Modal -->
|
| 1416 |
<div class="modal fade" id="micModal" tabindex="-1" aria-labelledby="micModalLabel" aria-hidden="true">
|
| 1417 |
+
<div class="modal-dialog modal-dialog-centered">
|
| 1418 |
<div class="modal-content">
|
| 1419 |
<div class="modal-header">
|
| 1420 |
<h5 class="modal-title" id="micModalLabel">Speak Now</h5>
|
|
|
|
| 1895 |
|
| 1896 |
// Hover events for desktop
|
| 1897 |
wrapper.addEventListener('mouseenter', () => {
|
| 1898 |
+
image.classList.add('hidden');
|
| 1899 |
+
video.classList.add('active');
|
| 1900 |
+
video.play().catch(err => console.error('Video play error:', err));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1901 |
});
|
| 1902 |
|
| 1903 |
wrapper.addEventListener('mouseleave', () => {
|
| 1904 |
+
video.classList.remove('active');
|
| 1905 |
+
image.classList.remove('hidden');
|
| 1906 |
+
video.pause();
|
| 1907 |
+
video.currentTime = 0;
|
|
|
|
|
|
|
| 1908 |
});
|
| 1909 |
|
| 1910 |
// Touch events for mobile
|
|
|
|
| 1913 |
wrapper.classList.add('touched');
|
| 1914 |
image.classList.add('hidden');
|
| 1915 |
video.classList.add('active');
|
| 1916 |
+
video.play().catch(err => console.error('Video play error:', err));
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1917 |
});
|
| 1918 |
|
| 1919 |
wrapper.addEventListener('touchend', () => {
|
| 1920 |
wrapper.classList.remove('touched');
|
| 1921 |
video.classList.remove('active');
|
| 1922 |
+
image.classList.remove('hidden');
|
| 1923 |
video.pause();
|
| 1924 |
video.currentTime = 0;
|
| 1925 |
});
|
| 1926 |
});
|
| 1927 |
|
| 1928 |
+
// IntersectionObserver for lazy-loaded videos
|
| 1929 |
+
const videoObserver = new IntersectionObserver((entries, observer) => {
|
| 1930 |
+
entries.forEach(entry => {
|
| 1931 |
+
if (entry.isIntersecting) {
|
| 1932 |
+
const video = entry.target;
|
| 1933 |
+
video.load();
|
| 1934 |
+
observer.unobserve(video);
|
| 1935 |
+
}
|
| 1936 |
+
});
|
| 1937 |
+
}, { threshold: 0.2 });
|
| 1938 |
+
|
| 1939 |
+
document.querySelectorAll('.menu-video').forEach(video => {
|
| 1940 |
+
videoObserver.observe(video);
|
| 1941 |
+
});
|
| 1942 |
+
|
| 1943 |
+
// Toggle item details
|
| 1944 |
+
document.querySelectorAll('.toggle-details').forEach(toggle => {
|
| 1945 |
+
toggle.addEventListener('click', function () {
|
| 1946 |
+
const details = document.getElementById(`details-${this.getAttribute('data-item-name').replace(/\s+/g, '-')}`);
|
| 1947 |
+
if (details) {
|
| 1948 |
+
details.classList.toggle('show');
|
| 1949 |
+
this.textContent = details.classList.contains('show') ? 'Hide Details' : 'Show Details';
|
| 1950 |
+
}
|
| 1951 |
+
});
|
| 1952 |
+
});
|
| 1953 |
+
|
| 1954 |
// Quantity controls for item modal
|
| 1955 |
const decreaseBtn = document.getElementById('decreaseQuantity');
|
| 1956 |
const increaseBtn = document.getElementById('increaseQuantity');
|
| 1957 |
const quantityInput = document.getElementById('quantityInput');
|
| 1958 |
|
| 1959 |
decreaseBtn.addEventListener('click', () => {
|
| 1960 |
+
let value = parseInt(quantityInput.value) || 1;
|
| 1961 |
+
if (value > 1) {
|
| 1962 |
+
quantityInput.value = value - 1;
|
| 1963 |
updateModalPrice();
|
| 1964 |
}
|
| 1965 |
});
|
| 1966 |
|
| 1967 |
increaseBtn.addEventListener('click', () => {
|
| 1968 |
+
let value = parseInt(quantityInput.value) || 1;
|
| 1969 |
+
quantityInput.value = value + 1;
|
| 1970 |
updateModalPrice();
|
| 1971 |
});
|
| 1972 |
|
| 1973 |
+
// Initialize cart UI from local storage
|
| 1974 |
+
updateCartUI(getCartLocalStorage());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1975 |
|
| 1976 |
// Speech recognition setup
|
| 1977 |
+
if ('webkitSpeechRecognition' in window || 'SpeechRecognition' in window) {
|
| 1978 |
+
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
|
| 1979 |
+
recognition = new SpeechRecognition();
|
| 1980 |
+
recognition.continuous = false;
|
| 1981 |
+
recognition.interimResults = true;
|
| 1982 |
+
recognition.lang = 'en-US';
|
| 1983 |
+
|
| 1984 |
+
recognition.onstart = () => {
|
| 1985 |
+
document.getElementById('mic-status').textContent = 'Listening...';
|
| 1986 |
+
document.getElementById('mic-icon-animation').classList.add('bi-mic-fill');
|
| 1987 |
+
document.getElementById('mic-icon-animation').classList.remove('bi-mic');
|
| 1988 |
+
};
|
| 1989 |
+
|
| 1990 |
+
recognition.onresult = (event) => {
|
| 1991 |
+
let interimTranscript = '';
|
| 1992 |
+
let finalTranscript = '';
|
| 1993 |
|
| 1994 |
+
for (let i = event.resultIndex; i < event.results.length; i++) {
|
| 1995 |
+
const transcript = event.results[i][0].transcript;
|
| 1996 |
+
if (event.results[i].isFinal) {
|
| 1997 |
+
finalTranscript += transcript;
|
| 1998 |
+
} else {
|
| 1999 |
+
interimTranscript += transcript;
|
| 2000 |
+
}
|
| 2001 |
+
}
|
| 2002 |
|
| 2003 |
+
document.getElementById('mic-status').textContent = interimTranscript || finalTranscript;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2004 |
|
| 2005 |
+
if (finalTranscript) {
|
| 2006 |
+
const spokenItem = menuItems.find(item =>
|
| 2007 |
+
item.name.toLowerCase().includes(finalTranscript.toLowerCase())
|
|
|
|
|
|
|
|
|
|
| 2008 |
);
|
| 2009 |
|
| 2010 |
+
if (spokenItem) {
|
|
|
|
| 2011 |
document.getElementById('mic-status').style.display = 'none';
|
| 2012 |
document.getElementById('mic-item-details').style.display = 'block';
|
| 2013 |
+
document.getElementById('mic-item-name').textContent = spokenItem.name;
|
| 2014 |
+
document.getElementById('mic-item-image').src = spokenItem.image || '/static/placeholder.jpg';
|
| 2015 |
+
|
| 2016 |
+
const menuCards = document.querySelectorAll('.menu-card');
|
| 2017 |
+
let targetButton = null;
|
| 2018 |
+
menuCards.forEach(card => {
|
| 2019 |
+
if (card.getAttribute('data-item-name') === spokenItem.name &&
|
| 2020 |
+
card.getAttribute('data-item-section') === spokenItem.section) {
|
| 2021 |
+
targetButton = card.querySelector('.button-container');
|
| 2022 |
+
}
|
| 2023 |
+
});
|
| 2024 |
|
| 2025 |
+
if (targetButton) {
|
| 2026 |
+
const name = targetButton.getAttribute('data-item-name');
|
| 2027 |
+
const price = targetButton.getAttribute('data-item-price');
|
| 2028 |
+
const image = targetButton.getAttribute('data-item-image2');
|
| 2029 |
+
const description = targetButton.getAttribute('data-item-description');
|
| 2030 |
+
const section = targetButton.getAttribute('data-item-section');
|
| 2031 |
+
const category = targetButton.getAttribute('data-item-category');
|
| 2032 |
|
| 2033 |
+
setTimeout(() => {
|
| 2034 |
+
recognition.stop();
|
| 2035 |
+
const micModal = bootstrap.Modal.getInstance(document.getElementById('micModal'));
|
| 2036 |
+
micModal.hide();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2037 |
|
| 2038 |
+
if (section === 'Soft Drinks') {
|
| 2039 |
+
showSoftDrinkModal(targetButton.querySelector('.add-to-cart-btn'));
|
| 2040 |
+
} else {
|
| 2041 |
+
showItemDetails(name, price, image, description, section, category);
|
| 2042 |
+
const modal = new bootstrap.Modal(document.getElementById('itemModal'));
|
| 2043 |
+
modal.show();
|
|
|
|
| 2044 |
}
|
| 2045 |
+
}, 500);
|
| 2046 |
+
}
|
|
|
|
|
|
|
| 2047 |
}
|
| 2048 |
+
}
|
| 2049 |
+
};
|
| 2050 |
+
|
| 2051 |
+
recognition.onend = () => {
|
| 2052 |
+
document.getElementById('mic-icon-animation').classList.remove('bi-mic-fill');
|
| 2053 |
+
document.getElementById('mic-icon-animation').classList.add('bi-mic');
|
| 2054 |
+
document.getElementById('micIcon').classList.remove('active');
|
| 2055 |
+
};
|
| 2056 |
|
| 2057 |
+
recognition.onerror = (event) => {
|
| 2058 |
+
console.error('Speech recognition error:', event.error);
|
| 2059 |
+
document.getElementById('mic-status').textContent = 'Error occurred. Please try again.';
|
| 2060 |
+
setTimeout(() => {
|
| 2061 |
stopSpeechRecognition();
|
| 2062 |
+
}, 2000);
|
| 2063 |
+
};
|
| 2064 |
|
| 2065 |
+
document.getElementById('micIcon').addEventListener('click', () => {
|
| 2066 |
+
if (!recognition) return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2067 |
|
| 2068 |
+
document.getElementById('micIcon').classList.add('active');
|
| 2069 |
+
const micModal = new bootstrap.Modal(document.getElementById('micModal'));
|
| 2070 |
+
micModal.show();
|
| 2071 |
+
resetMicModal();
|
| 2072 |
recognition.start();
|
| 2073 |
+
});
|
| 2074 |
+
} else {
|
| 2075 |
+
document.getElementById('micIcon').style.display = 'none';
|
| 2076 |
+
console.warn('Speech recognition not supported in this browser.');
|
| 2077 |
}
|
| 2078 |
|
| 2079 |
// Autocomplete for custom dish description
|
|
|
|
| 2081 |
const suggestionsContainer = document.getElementById('descriptionSuggestions');
|
| 2082 |
|
| 2083 |
if (descriptionInput && suggestionsContainer) {
|
| 2084 |
+
const showSuggestions = (suggestions) => {
|
|
|
|
| 2085 |
suggestionsContainer.innerHTML = '';
|
| 2086 |
+
if (suggestions.length === 0) {
|
| 2087 |
+
suggestionsContainer.style.display = 'none';
|
| 2088 |
+
return;
|
| 2089 |
+
}
|
| 2090 |
+
suggestions.forEach(suggestion => {
|
| 2091 |
+
const div = document.createElement('div');
|
| 2092 |
+
div.classList.add('suggestion-item');
|
| 2093 |
+
div.textContent = suggestion;
|
| 2094 |
+
div.addEventListener('click', () => {
|
| 2095 |
+
descriptionInput.value = suggestion;
|
| 2096 |
+
suggestionsContainer.style.display = 'none';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2097 |
});
|
| 2098 |
+
suggestionsContainer.appendChild(div);
|
| 2099 |
+
});
|
| 2100 |
+
suggestionsContainer.style.display = 'block';
|
| 2101 |
+
};
|
| 2102 |
+
|
| 2103 |
+
const filterSuggestions = (input) => {
|
| 2104 |
+
const inputWords = input.toLowerCase().split(/\s+/);
|
| 2105 |
+
return ingredientsList.filter(ingredient =>
|
| 2106 |
+
inputWords.every(word =>
|
| 2107 |
+
ingredient.toLowerCase().includes(word)
|
| 2108 |
+
)
|
| 2109 |
+
).slice(0, 5);
|
| 2110 |
+
};
|
| 2111 |
|
| 2112 |
+
descriptionInput.addEventListener('input', debounce(() => {
|
| 2113 |
+
const input = descriptionInput.value.trim();
|
| 2114 |
+
if (input) {
|
| 2115 |
+
const suggestions = filterSuggestions(input);
|
| 2116 |
+
showSuggestions(suggestions);
|
| 2117 |
} else {
|
| 2118 |
suggestionsContainer.style.display = 'none';
|
| 2119 |
}
|
| 2120 |
}, 300));
|
| 2121 |
|
| 2122 |
+
document.addEventListener('click', (event) => {
|
| 2123 |
+
if (!descriptionInput.contains(event.target) && !suggestionsContainer.contains(event.target)) {
|
|
|
|
| 2124 |
suggestionsContainer.style.display = 'none';
|
| 2125 |
}
|
| 2126 |
});
|
|
|
|
| 2128 |
});
|
| 2129 |
</script>
|
| 2130 |
</body>
|
| 2131 |
+
</html>
|
| 2132 |
+
</xaiArtifact>
|