|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>Search Menu</title> |
|
|
|
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"> |
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet"> |
|
<style> |
|
body { |
|
font-family: Arial, sans-serif; |
|
background-color: #fdf4e3; |
|
margin: 0; |
|
padding: 0; |
|
display: flex; |
|
flex-direction: column; |
|
padding-bottom: 70px; |
|
} |
|
.container { |
|
max-width: 900px; |
|
} |
|
.menu-card { |
|
max-width: 350px; |
|
border-radius: 15px; |
|
overflow: hidden; |
|
background-color: #fff; |
|
margin: auto; |
|
display: flex; |
|
flex-direction: column; |
|
opacity: 0; |
|
transition: opacity 0.3s ease-in-out; |
|
box-shadow: 0 4px 8px rgba(0,0,0,0.1); |
|
cursor: pointer; |
|
} |
|
.menu-card.visible { |
|
opacity: 1; |
|
} |
|
.menu-card:hover { |
|
transform: scale(1.05); |
|
box-shadow: 0 6px 12px rgba(0,0,0,0.2); |
|
} |
|
.menu-card img { |
|
height: 200px; |
|
width: 100%; |
|
object-fit: cover; |
|
border-radius: 15px 15px 0 0; |
|
background-color: #000; |
|
} |
|
.menu-card .card-body .card-title { |
|
font-size: 1.2rem; |
|
font-weight: 600; |
|
margin: 10px 0; |
|
color: #333333; |
|
text-align: center; |
|
} |
|
.menu-card .card-body .card-text.section { |
|
font-size: 0.9rem; |
|
color: #6c757d; |
|
text-align: center; |
|
margin-bottom: 10px; |
|
} |
|
.avatar-dropdown-container { |
|
position: absolute; |
|
right: 10px; |
|
top: 50%; |
|
transform: translateY(-50%); |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
} |
|
.avatar-icon { |
|
width: 40px; |
|
height: 40px; |
|
border-radius: 50%; |
|
background-color: #007bff; |
|
cursor: pointer; |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
color: white; |
|
font-size: 20px; |
|
font-weight: bold; |
|
} |
|
.dropdown-menu { |
|
position: absolute; |
|
right: 0; |
|
top: 100%; |
|
background-color: #fff8f0; |
|
border-radius: 5px; |
|
width: 220px; |
|
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); |
|
display: none; |
|
border: 1px solid #ffd8b1; |
|
} |
|
.dropdown-menu .dropdown-item { |
|
padding: 12px 16px; |
|
text-decoration: none; |
|
color: #333; |
|
border-bottom: 1px solid #ffd8b1; |
|
display: block; |
|
font-size: 15px; |
|
transition: background-color 0.2s ease; |
|
} |
|
.dropdown-menu .dropdown-item:last-child { |
|
border-bottom: none; |
|
} |
|
.dropdown-menu .dropdown-item:hover { |
|
background-color: #ffe4c4; |
|
color: #333; |
|
} |
|
.fixed-top-bar { |
|
position: relative; |
|
top: 0; |
|
left: 0; |
|
width: 100%; |
|
height: 54px; |
|
background: linear-gradient(45deg, #FFA07A, #FFB347); |
|
color: white; |
|
padding: 15px; |
|
display: flex; |
|
justify-content: space-between; |
|
align-items: center; |
|
z-index: 1000; |
|
} |
|
.back-arrow-container { |
|
position: absolute; |
|
left: 10px; |
|
top: 50%; |
|
transform: translateY(-50%); |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
} |
|
.back-arrow { |
|
width: 36px; |
|
height: 36px; |
|
border-radius: 50%; |
|
background: linear-gradient(45deg, #FFA07A, #FFB347); |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
color: white; |
|
font-size: 20px; |
|
cursor: pointer; |
|
transition: transform 0.2s ease, background-color 0.2s ease; |
|
text-decoration: none; |
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); |
|
} |
|
.back-arrow:hover { |
|
background: linear-gradient(45deg, #FF8C61, #FF9E2C); |
|
transform: scale(1.1); |
|
} |
|
.back-arrow:active { |
|
transform: scale(0.95); |
|
} |
|
.search-bar-container { |
|
position: absolute; |
|
left: 60px; |
|
top: 50%; |
|
transform: translateY(-50%); |
|
display: flex; |
|
align-items: center; |
|
width: 300px; |
|
max-width: calc(90% - 60px); |
|
} |
|
.search-bar-container input { |
|
width: 100%; |
|
padding: 8px 40px 8px 40px; |
|
font-size: 16px; |
|
border-radius: 25px; |
|
border: none; |
|
background-color: #fff; |
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); |
|
outline: none; |
|
transition: border-bottom 0.3s ease; |
|
} |
|
.search-bar-container input:focus { |
|
border-bottom: 2px solid #FFA07A; |
|
} |
|
.search-bar-container input::placeholder { |
|
color: #888; |
|
} |
|
.search-icon { |
|
position: absolute; |
|
left: 15px; |
|
font-size: 18px; |
|
color: #888; |
|
} |
|
.mic-icon { |
|
position: absolute; |
|
right: 15px; |
|
font-size: 18px; |
|
color: #888; |
|
cursor: pointer; |
|
transition: color 0.3s ease; |
|
} |
|
.mic-icon.active { |
|
color: #007bff; |
|
} |
|
.bottom-action-bar { |
|
position: fixed; |
|
bottom: 0; |
|
left: 0; |
|
right: 0; |
|
background-color: white; |
|
padding: 10px 20px; |
|
display: flex; |
|
justify-content: space-between; |
|
align-items: center; |
|
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1); |
|
z-index: 1000; |
|
max-width: 900px; |
|
margin: 0 auto; |
|
} |
|
.bottom-action-bar .btn { |
|
flex: 1; |
|
margin: 0 5px; |
|
padding: 10px 15px; |
|
border-radius: 8px; |
|
font-weight: bold; |
|
font-size: 16px; |
|
color: white; |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
text-align: center; |
|
min-width: 0; |
|
white-space: nowrap; |
|
} |
|
.bottom-action-bar .btn-order-history { |
|
background-color: #FFA07A; |
|
border-color: #FFA07A; |
|
} |
|
.bottom-action-bar .btn-order-history:hover { |
|
background-color: #FF8C61; |
|
border-color: #FF8C61; |
|
} |
|
.bottom-action-bar .btn-view-cart { |
|
background-color: #0FAA39; |
|
border-color: #0FAA39; |
|
} |
|
.bottom-action-bar .btn-view-cart:hover { |
|
background-color: #0D9232; |
|
border-color: #0D9232; |
|
} |
|
.cart-icon-badge { |
|
background-color: white; |
|
color: #0FAA39; |
|
border-radius: 50%; |
|
width: 20px; |
|
height: 20px; |
|
display: inline-flex; |
|
align-items: center; |
|
justify-content: center; |
|
font-size: 12px; |
|
margin-left: 8px; |
|
} |
|
.no-results { |
|
text-align: center; |
|
font-size: 1.2rem; |
|
color: #6c757d; |
|
margin-top: 20px; |
|
} |
|
@media (max-width: 576px) { |
|
.fixed-top-bar { |
|
height: 60px; |
|
padding: 10px; |
|
} |
|
.back-arrow-container { |
|
left: 8px; |
|
} |
|
.back-arrow { |
|
width: 32px; |
|
height: 32px; |
|
font-size: 18px; |
|
} |
|
.search-bar-container { |
|
width: calc(80% - 50px); |
|
max-width: calc(100% - 50px); |
|
left: 50px; |
|
} |
|
.search-bar-container input { |
|
padding: 6px 35px 6px 35px; |
|
font-size: 14px; |
|
border-radius: 20px; |
|
} |
|
.search-icon { |
|
left: 12px; |
|
font-size: 16px; |
|
} |
|
.mic-icon { |
|
right: 12px; |
|
font-size: 16px; |
|
} |
|
.avatar-dropdown-container { |
|
right: 10px; |
|
} |
|
.avatar-icon { |
|
width: 40px; |
|
height: 40px; |
|
font-size: 20px; |
|
} |
|
.dropdown-menu { |
|
width: 220px; |
|
} |
|
.dropdown-menu .dropdown-item { |
|
padding: 12px 16px; |
|
font-size: 15px; |
|
} |
|
.menu-card { |
|
max-width: 100%; |
|
} |
|
.menu-card img { |
|
height: 150px; |
|
} |
|
.menu-card .card-body .card-title { |
|
font-size: 1rem; |
|
} |
|
.menu-card .card-body .card-text.section { |
|
font-size: 0.8rem; |
|
} |
|
.bottom-action-bar { |
|
padding: 8px 10px; |
|
} |
|
.bottom-action-bar .btn { |
|
padding: 8px 10px; |
|
font-size: 14px; |
|
} |
|
.cart-icon-badge { |
|
width: 18px; |
|
height: 18px; |
|
font-size: 10px; |
|
margin-left: 5px; |
|
} |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
<div class="fixed-top-bar"> |
|
<div class="back-arrow-container"> |
|
<a href="{{ url_for('menu.menu') }}" class="back-arrow" aria-label="Back to Menu"> |
|
<i class="bi bi-arrow-left"></i> |
|
</a> |
|
</div> |
|
<div class="avatar-dropdown-container"> |
|
<div class="avatar-icon"> |
|
<span>{{ first_letter }}</span> |
|
</div> |
|
<div class="dropdown-menu"> |
|
<a href="{{ url_for('user_details.customer_details') }}" class="dropdown-item">View Profile</a> |
|
<a href="{{ url_for('orderhistory.order_history') }}" class="dropdown-item">Order History</a> |
|
<a href="{{ url_for('combined_summary.combined_summary') }}" class="dropdown-item">MY Summary</a> |
|
|
|
<a href="{{ url_for('logout') }}" class="dropdown-item">Logout</a> |
|
</div> |
|
</div> |
|
<div class="search-bar-container"> |
|
<input type="text" id="searchBar" class="form-control" placeholder="Search items or sections..." autocomplete="off"> |
|
<i class="bi bi-search search-icon"></i> |
|
<i class="bi bi-mic mic-icon" id="micIcon"></i> |
|
</div> |
|
</div> |
|
|
|
<div class="container mt-4"> |
|
<div class="row" id="menuItems"> |
|
{% for section, items in ordered_menu.items() %} |
|
{% for item in items %} |
|
<div class="col-md-6 mb-4 menu-item" data-name="{{ item.Name | default('Unnamed Item') }}" data-section="{{ item.Section__c | default(section) }}"> |
|
<div class="card menu-card" onclick="selectItem('{{ item.Name | default('Unnamed Item') }}', '{{ item.Section__c | default(section) }}')"> |
|
<img src="{{ item.Image1__c | default('/static/placeholder.jpg') }}" alt="{{ item.Name | default('Unnamed Item') }}" class="card-img-top"> |
|
<div class="card-body"> |
|
<h5 class="card-title">{{ item.Name | default('Unnamed Item') }}</h5> |
|
<p class="card-text section">{{ item.Section__c | default(section) }}</p> |
|
</div> |
|
</div> |
|
</div> |
|
{% endfor %} |
|
{% endfor %} |
|
</div> |
|
<div class="no-results" id="noResults" style="display: none;"> |
|
No items found matching your search. |
|
</div> |
|
</div> |
|
|
|
<div class="bottom-action-bar"> |
|
<a href="{{ url_for('orderhistory.order_history') }}" class="btn btn-order-history"> |
|
<i class="bi bi-clock-history"></i> Order History |
|
</a> |
|
<a href="{{ url_for('cart.cart') }}" class="btn btn-view-cart"> |
|
<i class="bi bi-cart"></i> View Cart |
|
<span id="cart-item-count" class="cart-icon-badge" style="display: none;">0</span> |
|
</a> |
|
</div> |
|
|
|
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script> |
|
<script> |
|
const menuItems = [ |
|
{% for section, items in ordered_menu.items() %} |
|
{% for item in items %} |
|
{ |
|
name: "{{ item.Name | default('Unnamed Item') }}", |
|
section: "{{ item.Section__c | default(section) }}" |
|
}, |
|
{% endfor %} |
|
{% endfor %} |
|
]; |
|
|
|
function updateCartUI(cart) { |
|
if (!Array.isArray(cart)) { |
|
console.error('Invalid cart data:', cart); |
|
return; |
|
} |
|
let totalQuantity = 0; |
|
cart.forEach(item => { |
|
totalQuantity += item.quantity; |
|
}); |
|
const cartItemCount = document.getElementById('cart-item-count'); |
|
if (cartItemCount) { |
|
cartItemCount.innerText = totalQuantity; |
|
cartItemCount.style.display = totalQuantity > 0 ? 'inline-flex' : 'none'; |
|
} |
|
} |
|
|
|
function getCartLocalStorage() { |
|
return JSON.parse(localStorage.getItem('cart')) || []; |
|
} |
|
|
|
function selectItem(itemName, section) { |
|
localStorage.setItem('selectedItem', JSON.stringify({ name: itemName, section: section })); |
|
window.location.href = '/menu'; |
|
} |
|
|
|
function filterMenuItems(query) { |
|
const menuItemElements = document.querySelectorAll('.menu-item'); |
|
const noResults = document.getElementById('noResults'); |
|
let hasResults = false; |
|
|
|
menuItemElements.forEach(item => { |
|
const name = item.getAttribute('data-name').toLowerCase(); |
|
const section = item.getAttribute('data-section').toLowerCase(); |
|
const matches = name.includes(query.toLowerCase()) || section.includes(query.toLowerCase()); |
|
item.style.display = matches ? '' : 'none'; |
|
if (matches) hasResults = true; |
|
}); |
|
|
|
noResults.style.display = hasResults ? 'none' : 'block'; |
|
} |
|
|
|
document.addEventListener('DOMContentLoaded', function () { |
|
|
|
const avatarContainer = document.querySelector('.avatar-dropdown-container'); |
|
const dropdownMenu = document.querySelector('.dropdown-menu'); |
|
avatarContainer.addEventListener('click', function (event) { |
|
event.stopPropagation(); |
|
dropdownMenu.style.display = dropdownMenu.style.display === 'block' ? 'none' : 'block'; |
|
}); |
|
document.addEventListener('click', function (event) { |
|
if (!avatarContainer.contains(event.target)) { |
|
dropdownMenu.style.display = 'none'; |
|
} |
|
}); |
|
const dropdownItems = document.querySelectorAll('.dropdown-item'); |
|
dropdownItems.forEach(item => { |
|
item.addEventListener('click', function () { |
|
dropdownMenu.style.display = 'none'; |
|
}); |
|
}); |
|
|
|
|
|
const searchBar = document.getElementById('searchBar'); |
|
const searchQuery = localStorage.getItem('searchQuery'); |
|
if (searchQuery) { |
|
searchBar.value = searchQuery; |
|
filterMenuItems(searchQuery); |
|
localStorage.removeItem('searchQuery'); |
|
} |
|
searchBar.addEventListener('input', function () { |
|
filterMenuItems(this.value); |
|
}); |
|
|
|
|
|
const micIcon = document.getElementById('micIcon'); |
|
if ('SpeechRecognition' in window || 'webkitSpeechRecognition' in window) { |
|
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; |
|
const recognition = new SpeechRecognition(); |
|
recognition.lang = 'en-US'; |
|
recognition.onstart = () => micIcon.classList.add('active'); |
|
recognition.onresult = (event) => { |
|
const query = event.results[0][0].transcript.trim(); |
|
searchBar.value = query; |
|
filterMenuItems(query); |
|
}; |
|
recognition.onend = () => micIcon.classList.remove('active'); |
|
recognition.onerror = (event) => { |
|
micIcon.classList.remove('active'); |
|
console.error('Speech error:', event.error); |
|
}; |
|
micIcon.addEventListener('click', () => { |
|
recognition.start(); |
|
}); |
|
} else { |
|
micIcon.style.display = 'none'; |
|
} |
|
|
|
|
|
const menuCards = document.querySelectorAll('.menu-card'); |
|
const cardObserver = new IntersectionObserver((entries, observer) => { |
|
entries.forEach(entry => { |
|
if (entry.isIntersecting) { |
|
entry.target.classList.add('visible'); |
|
observer.unobserve(entry.target); |
|
} |
|
}); |
|
}, { |
|
root: null, |
|
rootMargin: '0px', |
|
threshold: 0.1 |
|
}); |
|
menuCards.forEach(card => cardObserver.observe(card)); |
|
|
|
|
|
fetch('/cart/get') |
|
.then(response => { |
|
if (!response.ok) { |
|
throw new Error(`HTTP error! Status: ${response.status}`); |
|
} |
|
return response.json(); |
|
}) |
|
.then(data => { |
|
if (data.success) { |
|
updateCartUI(data.cart); |
|
} else { |
|
console.error('Failed to fetch cart:', data.error); |
|
const cart = getCartLocalStorage(); |
|
updateCartUI(cart); |
|
} |
|
}) |
|
.catch(err => { |
|
console.error('Error fetching cart:', err); |
|
const cart = getCartLocalStorage(); |
|
updateCartUI(cart); |
|
}); |
|
}); |
|
</script> |
|
</body> |
|
</html> |