Spaces:
				
			
			
	
			
			
		Sleeping
		
	
	
	
			
			
	
	
	
	
		
		
		Sleeping
		
	| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Search Menu</title> | |
| <!-- Bootstrap CSS --> | |
| <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 () { | |
| // Avatar Dropdown | |
| 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'; | |
| }); | |
| }); | |
| // Search Bar Functionality | |
| 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); | |
| }); | |
| // Voice Recognition | |
| 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'; | |
| } | |
| // Lazy Loading for Cards | |
| 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 | |
| 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> | 

