Spaces:
Runtime error
Runtime error
<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/bootstrap@5.3.0-alpha1/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; | |
} | |
.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; | |
align-items: center; | |
z-index: 1000; | |
} | |
.orange-label { | |
background-color: #FFA500; | |
padding: 5px 10px; | |
border-radius: 5px; | |
display: flex; | |
align-items: center; | |
position: absolute; | |
left: 10px; | |
top: 50%; | |
transform: translateY(-50%); | |
} | |
.back-button { | |
background-color: black; | |
color: white; | |
border: none; | |
border-radius: 50%; | |
width: 25px; | |
height: 25px; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
font-size: 16px; | |
cursor: pointer; | |
margin-right: 10px; | |
} | |
.search-bar-container { | |
position: fixed; | |
bottom: 10px; | |
left: 50%; | |
transform: translateX(-50%); | |
display: flex; | |
align-items: center; | |
width: 300px; | |
max-width: 90%; | |
z-index: 1000; | |
} | |
.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; | |
} | |
.search-icon { | |
position: absolute; | |
left: 15px; | |
font-size: 18px; | |
color: #888; | |
} | |
.mic-icon { | |
position: absolute; | |
right: 15px; | |
font-size: 18px; | |
color: #888; | |
cursor: pointer; | |
} | |
.autocomplete-suggestions { | |
position: absolute; | |
bottom: 100%; | |
left: 0; | |
width: 100%; | |
max-height: 200px; | |
overflow-y: auto; | |
background-color: #fff; | |
border: 1px solid #ddd; | |
border-radius: 5px; | |
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); | |
z-index: 1000; | |
display: none; | |
} | |
.autocomplete-suggestions .suggestion-item { | |
padding: 8px 15px; | |
cursor: pointer; | |
font-size: 14px; | |
color: #333; | |
} | |
.autocomplete-suggestions .suggestion-item:hover { | |
background-color: #f1f1f1; | |
} | |
.container { | |
max-width: 900px; | |
margin-top: 20px; | |
margin-bottom: 70px; | |
} | |
.search-item { | |
cursor: pointer; | |
} | |
.menu-card { | |
max-width: 350px; | |
border-radius: 15px; | |
overflow: hidden; | |
background-color: #fff; | |
margin: auto; | |
display: flex; | |
flex-direction: column; | |
box-shadow: 0 4px 8px rgba(0,0,0,0.1); | |
transition: transform 0.2s; | |
} | |
.menu-card:hover { | |
transform: scale(1.05); | |
} | |
.menu-video { | |
height: 200px; | |
width: 100%; | |
object-fit: cover; | |
border-radius: 15px 15px 0 0; | |
} | |
.card-body { | |
padding: 10px; | |
text-align: center; | |
} | |
.card-title { | |
font-size: 1.2rem; | |
font-weight: 600; | |
margin: 0; | |
color: #333333; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="fixed-top-bar"> | |
<div class="orange-label"> | |
<button class="back-button" onclick="window.location.href='/menu'"><</button> | |
<span>Search</span> | |
</div> | |
</div> | |
<div class="container"> | |
<h2>Search Results</h2> | |
<div id="searchResults" class="row"> | |
{% for item in all_items %} | |
<div class="col-md-6 mb-4 search-item" data-name="{{ item.Name | lower }}" data-section="{{ item.Section__c | lower }}" | |
onclick="window.location.href='/menu?highlight={{ item.Name | urlencode }}'"> | |
<div class="card menu-card"> | |
<img src="{{ item.Image2__c | default(item.Image1__c) | default('/static/placeholder.jpg') }}" | |
class="card-img-top menu-video" alt="{{ item.Name }}" style="height: 200px; object-fit: cover;"> | |
<div class="card-body"> | |
<h5 class="card-title">{{ item.Name }}</h5> | |
</div> | |
</div> | |
</div> | |
{% endfor %} | |
</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 id="autocompleteSuggestions" class="autocomplete-suggestions"></div> | |
</div> | |
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script> | |
<script> | |
const menuItems = [ | |
{% for item in all_items %} | |
"{{ item.Name | e }}", | |
{% endfor %} | |
]; | |
function sanitizeInput(input) { | |
const div = document.createElement('div'); | |
div.textContent = input; | |
return div.innerHTML; | |
} | |
document.addEventListener('DOMContentLoaded', function () { | |
const searchBar = document.getElementById('searchBar'); | |
const suggestionsContainer = document.getElementById('autocompleteSuggestions'); | |
const searchResults = document.getElementById('searchResults'); | |
function filterSearch() { | |
const input = sanitizeInput(searchBar.value.trim().toLowerCase()); | |
const items = document.querySelectorAll('.search-item'); | |
items.forEach(item => { | |
const itemName = item.getAttribute('data-name'); | |
const itemSection = item.getAttribute('data-section'); | |
if (itemName.includes(input) || itemSection.includes(input)) { | |
item.style.display = 'block'; | |
} else { | |
item.style.display = 'none'; | |
} | |
}); | |
if (!input) { | |
items.forEach(item => item.style.display = 'block'); | |
} | |
} | |
searchBar.addEventListener('input', function () { | |
const input = sanitizeInput(this.value.trim().toLowerCase()); | |
suggestionsContainer.innerHTML = ''; | |
suggestionsContainer.style.display = 'none'; | |
if (input) { | |
const filteredItems = menuItems.filter(item => | |
item.toLowerCase().includes(input) | |
); | |
if (filteredItems.length > 0) { | |
filteredItems.forEach(item => { | |
const suggestionDiv = document.createElement('div'); | |
suggestionDiv.classList.add('suggestion-item'); | |
suggestionDiv.innerText = item; | |
suggestionDiv.addEventListener('click', function () { | |
searchBar.value = item; | |
suggestionsContainer.style.display = 'none'; | |
filterSearch(); | |
}); | |
suggestionsContainer.appendChild(suggestionDiv); | |
}); | |
suggestionsContainer.style.display = 'block'; | |
} | |
} | |
filterSearch(); | |
}); | |
document.addEventListener('click', function (event) { | |
if (!searchBar.contains(event.target) && !suggestionsContainer.contains(event.target)) { | |
suggestionsContainer.style.display = 'none'; | |
} | |
}); | |
}); | |
</script> | |
</body> | |
</html> |