lokesh341 commited on
Commit
a8784d0
·
verified ·
1 Parent(s): 46f28e7

Update templates/search.html

Browse files
Files changed (1) hide show
  1. templates/search.html +272 -353
templates/search.html CHANGED
@@ -3,7 +3,8 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Search - Menu</title>
 
7
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
8
  <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
9
  <style>
@@ -16,6 +17,98 @@
16
  flex-direction: column;
17
  padding-bottom: 70px;
18
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  .fixed-top-bar {
20
  position: relative;
21
  top: 0;
@@ -26,44 +119,20 @@
26
  color: white;
27
  padding: 15px;
28
  display: flex;
 
29
  align-items: center;
30
  z-index: 1000;
31
  }
32
- .orange-label {
33
- background-color: #FFA500;
34
- padding: 5px 10px;
35
- border-radius: 5px;
36
- display: flex;
37
- align-items: center;
38
  position: absolute;
39
- left: 10px;
40
  top: 50%;
41
  transform: translateY(-50%);
42
- }
43
- .back-button {
44
- background-color: black;
45
- color: white;
46
- border: none;
47
- border-radius: 50%;
48
- width: 25px;
49
- height: 25px;
50
- display: flex;
51
- align-items: center;
52
- justify-content: center;
53
- font-size: 16px;
54
- cursor: pointer;
55
- margin-right: 10px;
56
- }
57
- .search-bar-container {
58
- position: fixed;
59
- bottom: 10px;
60
- left: 50%;
61
- transform: translateX(-50%);
62
  display: flex;
63
  align-items: center;
64
  width: 300px;
65
  max-width: 90%;
66
- z-index: 1000;
67
  }
68
  .search-bar-container input {
69
  width: 100%;
@@ -75,370 +144,220 @@
75
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
76
  outline: none;
77
  }
78
- .search-icon {
79
- position: absolute;
80
- left: 15px;
81
- font-size: 18px;
82
  color: #888;
83
  }
84
- .mic-icon {
85
  position: absolute;
86
- right: 15px;
87
  font-size: 18px;
88
  color: #888;
89
- cursor: pointer;
90
  }
91
- .autocomplete-suggestions {
92
- position: absolute;
93
- bottom: 100%;
94
  left: 0;
95
- width: 100%;
96
- max-height: 200px;
97
- overflow-y: auto;
98
- background-color: #fff;
99
- border: 1px solid #ddd;
100
- border-radius: 5px;
101
- box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
102
  z-index: 1000;
103
- display: none;
 
104
  }
105
- .autocomplete-suggestions .suggestion-item {
106
- padding: 8px 15px;
107
- cursor: pointer;
108
- font-size: 14px;
109
- color: #333;
 
 
 
 
 
 
 
 
 
110
  }
111
- .autocomplete-suggestions .suggestion-item:hover {
112
- background-color: #f1f1f1;
 
113
  }
114
- .container {
115
- max-width: 900px;
116
- margin-top: 20px;
117
- margin-bottom: 70px;
118
  }
119
- .search-item {
120
- cursor: pointer;
 
121
  }
122
- .menu-card {
123
- max-width: 350px;
124
- border-radius: 15px;
125
- overflow: hidden;
126
- background-color: #fff;
127
- margin: auto;
128
- display: flex;
129
- flex-direction: column;
130
- box-shadow: 0 4px 8px rgba(0,0,0,0.1);
131
- transition: transform 0.2s;
132
- }
133
- .menu-card:hover {
134
- transform: scale(1.05);
135
  }
136
- .menu-video {
137
- height: 200px;
138
- width: 100%;
139
- object-fit: cover;
140
- border-radius: 15px 15px 0 0;
 
 
 
 
 
 
141
  }
142
- .card-body {
143
- padding: 10px;
144
  text-align: center;
145
- }
146
- .card-title {
147
  font-size: 1.2rem;
148
- font-weight: 600;
149
- margin: 0;
150
- color: #333333;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  }
152
  </style>
153
  </head>
154
  <body>
155
  <div class="fixed-top-bar">
156
- <div class="orange-label">
157
- <button class="back-button" onclick="window.location.href='/menu'"><</button>
158
- <span>Search</span>
 
 
 
 
 
 
 
 
 
 
159
  </div>
160
  </div>
161
 
162
- <div class="container">
163
- <h2>Search Results</h2>
164
- <div id="searchResults" class="row">
165
- {% for item in all_items %}
166
- <div class="col-md-6 mb-4 search-item"
167
- data-name="{{ item.Name | lower }}"
168
- data-section="{{ item.Section__c | lower }}"
169
- data-price="{{ item.Price__c | default('0.00') }}"
170
- data-image="{{ item.Image2__c | default(item.Image1__c) | default('/static/placeholder.jpg') }}"
171
- data-description="{{ item.Description__c | default('No description') | e }}"
172
- data-ingredients="{{ item.IngredientsInfo__c | default('Not specified') | e }}"
173
- data-nutrition="{{ item.NutritionalInfo__c | default('Not available') | e }}"
174
- data-allergens="{{ item.Allergens__c | default('None listed') | e }}"
175
- data-category="{{ item.Category__c | default('') }}"
176
- onclick="triggerItemModal(this)">
177
- <div class="card menu-card">
178
- <img src="{{ item.Image2__c | default(item.Image1__c) | default('/static/placeholder.jpg') }}"
179
- class="card-img-top menu-video" alt="{{ item.Name }}" style="height: 200px; object-fit: cover;">
180
- <div class="card-body">
181
- <h5 class="card-title">{{ item.Name }}</h5>
182
  </div>
183
  </div>
184
- </div>
185
  {% endfor %}
186
  </div>
 
 
 
187
  </div>
188
 
189
- <div class="search-bar-container">
190
- <input type="text" id="searchBar" class="form-control" placeholder="Search items or sections..." autocomplete="off">
191
- <i class="bi bi-search search-icon"></i>
192
- <i class="bi bi-mic mic-icon" id="micIcon"></i>
193
- <div id="autocompleteSuggestions" class="autocomplete-suggestions"></div>
194
- </div>
195
-
196
- <!-- Include the Item Modal from Menu HTML -->
197
- <div class="modal fade" id="itemModal" tabindex="-1" aria-labelledby="itemModalLabel" aria-hidden="true">
198
- <div class="modal-dialog modal-dialog-centered">
199
- <div class="modal-content">
200
- <div class="modal-header">
201
- <h5 class="modal-title" id="itemModalLabel">Item Details</h5>
202
- <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
203
- </div>
204
- <div class="modal-body">
205
- <img id="modal-img" class="img-fluid rounded mb-3 d-block mx-auto" alt="Item Image" style="max-height: 200px; object-fit: cover;">
206
- <h5 id="modal-name" class="fw-bold text-center"></h5>
207
- <p id="modal-price" class="text-muted text-center"></p>
208
- <p id="modal-description" class="text-secondary"></p>
209
- <div class="nutritional-info">
210
- <strong>Ingredients:</strong> <span id="modal-ingredients"></span><br>
211
- <strong>Nutrition:</strong> <span id="modal-nutrition"></span><br>
212
- <strong>Allergens:</strong> <span id="modal-allergens"></span>
213
- </div>
214
- <div id="modal-addons" class="modal-addons mt-4">
215
- <h6>Customization Options</h6>
216
- <div id="addons-list" class="addons-container">Loading customization options...</div>
217
- </div>
218
- <div class="mt-4">
219
- <h6>Custom Request</h6>
220
- <textarea id="modal-instructions" class="form-control" placeholder="Enter any special instructions here..."></textarea>
221
- </div>
222
- <span id="modal-section" data-section="" data-category="" style="display: none;"></span>
223
- </div>
224
- <div class="modal-footer d-flex align-items-center justify-content-between">
225
- <div class="d-flex align-items-center gap-2">
226
- <button type="button" class="btn btn-outline-secondary" id="decreaseQuantity">-</button>
227
- <input type="text" class="form-control text-center" id="quantityInput" value="1" readonly style="width: 50px;"/>
228
- <button type="button" class="btn btn-outline-secondary" id="increaseQuantity">+</button>
229
- </div>
230
- <button type="button" class="btn btn-primary" onclick="addToCartFromModal()">Add to Cart</button>
231
- </div>
232
- </div>
233
- </div>
234
  </div>
235
 
236
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
237
  <script>
238
  const menuItems = [
239
- {% for item in all_items %}
240
- "{{ item.Name | e }}",
 
 
 
 
 
241
  {% endfor %}
242
  ];
243
 
244
- function sanitizeInput(input) {
245
- const div = document.createElement('div');
246
- div.textContent = input;
247
- return div.innerHTML;
248
- }
249
-
250
- document.addEventListener('DOMContentLoaded', function () {
251
- const searchBar = document.getElementById('searchBar');
252
- const suggestionsContainer = document.getElementById('autocompleteSuggestions');
253
- const searchResults = document.getElementById('searchResults');
254
-
255
- function filterSearch() {
256
- const input = sanitizeInput(searchBar.value.trim().toLowerCase());
257
- const items = document.querySelectorAll('.search-item');
258
-
259
- items.forEach(item => {
260
- const itemName = item.getAttribute('data-name');
261
- const itemSection = item.getAttribute('data-section');
262
- if (itemName.includes(input) || itemSection.includes(input)) {
263
- item.style.display = 'block';
264
- } else {
265
- item.style.display = 'none';
266
- }
267
- });
268
-
269
- if (!input) {
270
- items.forEach(item => item.style.display = 'block');
271
- }
272
  }
273
-
274
- searchBar.addEventListener('input', function () {
275
- const input = sanitizeInput(this.value.trim().toLowerCase());
276
- suggestionsContainer.innerHTML = '';
277
- suggestionsContainer.style.display = 'none';
278
-
279
- if (input) {
280
- const filteredItems = menuItems.filter(item =>
281
- item.toLowerCase().includes(input)
282
- );
283
- if (filteredItems.length > 0) {
284
- filteredItems.forEach(item => {
285
- const suggestionDiv = document.createElement('div');
286
- suggestionDiv.classList.add('suggestion-item');
287
- suggestionDiv.innerText = item;
288
- suggestionDiv.addEventListener('click', function () {
289
- searchBar.value = item;
290
- suggestionsContainer.style.display = 'none';
291
- filterSearch();
292
- });
293
- suggestionsContainer.appendChild(suggestionDiv);
294
- });
295
- suggestionsContainer.style.display = 'block';
296
- }
297
- }
298
- filterSearch();
299
- });
300
-
301
- document.addEventListener('click', function (event) {
302
- if (!searchBar.contains(event.target) && !suggestionsContainer.contains(event.target)) {
303
- suggestionsContainer.style.display = 'none';
304
- }
305
- });
306
-
307
- // Quantity controls for modal
308
- const decreaseBtn = document.getElementById('decreaseQuantity');
309
- const increaseBtn = document.getElementById('increaseQuantity');
310
- const quantityInput = document.getElementById('quantityInput');
311
- decreaseBtn.addEventListener('click', function () {
312
- let currentQuantity = parseInt(quantityInput.value);
313
- if (currentQuantity > 1) {
314
- currentQuantity--;
315
- quantityInput.value = currentQuantity;
316
- }
317
  });
318
- increaseBtn.addEventListener('click', function () {
319
- let currentQuantity = parseInt(quantityInput.value);
320
- currentQuantity++;
321
- quantityInput.value = currentQuantity;
322
- });
323
- });
324
-
325
- function triggerItemModal(element) {
326
- const name = element.querySelector('.card-title').innerText;
327
- const price = element.getAttribute('data-price');
328
- const image = element.getAttribute('data-image');
329
- const description = element.getAttribute('data-description');
330
- const ingredients = element.getAttribute('data-ingredients');
331
- const nutrition = element.getAttribute('data-nutrition');
332
- const allergens = element.getAttribute('data-allergens');
333
- const section = element.getAttribute('data-section');
334
- const selectedCategory = element.getAttribute('data-category');
335
-
336
- // Populate modal
337
- document.getElementById('modal-name').innerText = name;
338
- document.getElementById('modal-price').innerText = `$${price}`;
339
- document.getElementById('modal-img').src = image || '/static/placeholder.jpg';
340
- document.getElementById('modal-description').innerText = description || 'No description available.';
341
- document.getElementById('modal-ingredients').innerText = ingredients || 'Not specified';
342
- document.getElementById('modal-nutrition').innerText = nutrition || 'Not available';
343
- document.getElementById('modal-allergens').innerText = allergens || 'None listed';
344
- document.getElementById('modal-instructions').value = '';
345
- const modalSectionEl = document.getElementById('modal-section');
346
- modalSectionEl.setAttribute('data-section', section);
347
- modalSectionEl.setAttribute('data-category', selectedCategory);
348
- document.getElementById('quantityInput').value = 1;
349
-
350
- // Fetch addons (assuming this endpoint exists)
351
- fetch(`/api/addons?item_name=${encodeURIComponent(name)}&item_section=${encodeURIComponent(section)}`)
352
- .then(response => response.json())
353
- .then(data => {
354
- const addonsList = document.getElementById('addons-list');
355
- addonsList.innerHTML = '';
356
- if (!data.success || !data.addons || data.addons.length === 0) {
357
- addonsList.innerHTML = '<p>No customization options available.</p>';
358
- return;
359
- }
360
- data.addons.forEach(addon => {
361
- const sectionDiv = document.createElement('div');
362
- sectionDiv.classList.add('addon-section');
363
- const title = document.createElement('h6');
364
- title.innerText = addon.name;
365
- sectionDiv.appendChild(title);
366
- const optionsContainer = document.createElement('div');
367
- addon.options.forEach((option, index) => {
368
- const optionId = `addon-${addon.name.replace(/\s+/g, '')}-${index}`;
369
- const listItem = document.createElement('div');
370
- listItem.classList.add('form-check');
371
- listItem.innerHTML = `
372
- <input type="checkbox" class="form-check-input addon-option" id="${optionId}" value="${option}"
373
- data-name="${option}" data-group="${addon.name}" data-price="${addon.extra_charge ? addon.extra_charge_amount : 0}">
374
- <label class="form-check-label" for="${optionId}">
375
- ${option} ${addon.extra_charge ? `($${addon.extra_charge_amount})` : ''}
376
- </label>
377
- `;
378
- optionsContainer.appendChild(listItem);
379
- });
380
- sectionDiv.appendChild(optionsContainer);
381
- addonsList.appendChild(sectionDiv);
382
- });
383
- })
384
- .catch(err => {
385
- console.error('Error fetching add-ons:', err);
386
- document.getElementById('addons-list').innerHTML = '<p>Error loading customization options.</p>';
387
- });
388
-
389
- // Show modal
390
- const modal = new bootstrap.Modal(document.getElementById('itemModal'));
391
- modal.show();
392
  }
393
 
394
- function addToCartFromModal() {
395
- const itemName = document.getElementById('modal-name').innerText;
396
- const itemPrice = parseFloat(document.getElementById('modal-price').innerText.replace('$', ''));
397
- const itemImage = document.getElementById('modal-img').src;
398
- const instructions = document.getElementById('modal-instructions').value.trim();
399
- const quantity = parseInt(document.getElementById('quantityInput').value);
400
- const section = document.getElementById('modal-section').getAttribute('data-section');
401
- const selectedCategory = document.getElementById('modal-section').getAttribute('data-category');
402
- const addons = Array.from(document.querySelectorAll('.addon-option:checked')).map(cb => ({
403
- name: cb.getAttribute('data-name'),
404
- price: parseFloat(cb.getAttribute('data-price') || 0)
405
- }));
406
-
407
- const cartPayload = {
408
- itemName: itemName,
409
- itemPrice: itemPrice,
410
- itemImage: itemImage,
411
- section: section,
412
- category: selectedCategory,
413
- addons: addons,
414
- instructions: instructions,
415
- quantity: quantity
416
- };
417
-
418
- fetch('/cart/add', {
419
- method: 'POST',
420
- headers: {
421
- 'Content-Type': 'application/json',
422
- },
423
- body: JSON.stringify(cartPayload)
424
- })
425
- .then(response => response.json())
426
- .then(data => {
427
- if (data.success) {
428
- alert('Item added to cart successfully!');
429
- const modal = bootstrap.Modal.getInstance(document.getElementById('itemModal'));
430
- modal.hide();
431
- // Optionally update cart UI here if needed
432
- } else {
433
- console.error('Failed to add item to cart:', data.error);
434
- alert(data.error || 'Failed to add item to cart.');
435
- }
436
- })
437
- .catch(err => {
438
- console.error('Error adding item to cart:', err);
439
- alert('Error adding item to cart.');
440
- });
441
- }
442
- </script>
443
- </body>
444
- </html>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Search Menu</title>
7
+ <!-- Bootstrap CSS -->
8
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
9
  <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
10
  <style>
 
17
  flex-direction: column;
18
  padding-bottom: 70px;
19
  }
20
+ .container {
21
+ max-width: 900px;
22
+ }
23
+ .menu-card {
24
+ max-width: 350px;
25
+ border-radius: 15px;
26
+ overflow: hidden;
27
+ background-color: #fff;
28
+ margin: auto;
29
+ display: flex;
30
+ flex-direction: column;
31
+ opacity: 0;
32
+ transition: opacity 0.3s ease-in-out;
33
+ box-shadow: 0 4px 8px rgba(0,0,0,0.1);
34
+ cursor: pointer;
35
+ }
36
+ .menu-card.visible {
37
+ opacity: 1;
38
+ }
39
+ .menu-card:hover {
40
+ transform: scale(1.05);
41
+ box-shadow: 0 6px 12px rgba(0,0,0,0.2);
42
+ }
43
+ .menu-card img {
44
+ height: 200px;
45
+ width: 100%;
46
+ object-fit: cover;
47
+ border-radius: 15px 15px 0 0;
48
+ background-color: #000;
49
+ }
50
+ .menu-card .card-body .card-title {
51
+ font-size: 1.2rem;
52
+ font-weight: 600;
53
+ margin: 10px 0;
54
+ color: #333333;
55
+ text-align: center;
56
+ }
57
+ .menu-card .card-body .card-text.section {
58
+ font-size: 0.9rem;
59
+ color: #6c757d;
60
+ text-align: center;
61
+ margin-bottom: 10px;
62
+ }
63
+ .avatar-dropdown-container {
64
+ position: absolute;
65
+ right: 10px;
66
+ top: 50%;
67
+ transform: translateY(-50%);
68
+ display: flex;
69
+ align-items: right;
70
+ justify-content: center;
71
+ }
72
+ .avatar-icon {
73
+ width: 40px;
74
+ height: 40px;
75
+ border-radius: 50%;
76
+ background-color: #007bff;
77
+ cursor: pointer;
78
+ display: flex;
79
+ align-items: center;
80
+ justify-content: center;
81
+ color: white;
82
+ font-size: 20px;
83
+ font-weight: bold;
84
+ }
85
+ .dropdown-menu {
86
+ position: absolute;
87
+ right: 0;
88
+ top: 100%;
89
+ background-color: #fff8f0;
90
+ border-radius: 5px;
91
+ width: 220px;
92
+ box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
93
+ display: none;
94
+ border: 1px solid #ffd8b1;
95
+ }
96
+ .dropdown-menu .dropdown-item {
97
+ padding: 12px 16px;
98
+ text-decoration: none;
99
+ color: #333;
100
+ border-bottom: 1px solid #ffd8b1;
101
+ display: block;
102
+ font-size: 15px;
103
+ transition: background-color 0.2s ease;
104
+ }
105
+ .dropdown-menu .dropdown-item:last-child {
106
+ border-bottom: none;
107
+ }
108
+ .dropdown-menu .dropdown-item:hover {
109
+ background-color: #ffe4c4;
110
+ color: #333;
111
+ }
112
  .fixed-top-bar {
113
  position: relative;
114
  top: 0;
 
119
  color: white;
120
  padding: 15px;
121
  display: flex;
122
+ justify-content: space-between;
123
  align-items: center;
124
  z-index: 1000;
125
  }
126
+ .search-bar-container {
 
 
 
 
 
127
  position: absolute;
128
+ left: 20px;
129
  top: 50%;
130
  transform: translateY(-50%);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  display: flex;
132
  align-items: center;
133
  width: 300px;
134
  max-width: 90%;
135
+ position: relative;
136
  }
137
  .search-bar-container input {
138
  width: 100%;
 
144
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
145
  outline: none;
146
  }
147
+ .search-bar-container input::placeholder {
 
 
 
148
  color: #888;
149
  }
150
+ .search-icon {
151
  position: absolute;
152
+ left: 15px;
153
  font-size: 18px;
154
  color: #888;
 
155
  }
156
+ .bottom-action-bar {
157
+ position: fixed;
158
+ bottom: 0;
159
  left: 0;
160
+ right: 0;
161
+ background-color: white;
162
+ padding: 10px 20px;
163
+ display: flex;
164
+ justify-content: space-between;
165
+ align-items: center;
166
+ box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
167
  z-index: 1000;
168
+ max-width: 900px;
169
+ margin: 0 auto;
170
  }
171
+ .bottom-action-bar .btn {
172
+ flex: 1;
173
+ margin: 0 5px;
174
+ padding: 10px 15px;
175
+ border-radius: 8px;
176
+ font-weight: bold;
177
+ font-size: 16px;
178
+ color: white;
179
+ display: flex;
180
+ align-items: center;
181
+ justify-content: center;
182
+ text-align: center;
183
+ min-width: 0;
184
+ white-space: nowrap;
185
  }
186
+ .bottom-action-bar .btn-order-history {
187
+ background-color: #FFA07A;
188
+ border-color: #FFA07A;
189
  }
190
+ .bottom-action-bar .btn-order-history:hover {
191
+ background-color: #FF8C61;
192
+ border-color: #FF8C61;
 
193
  }
194
+ .bottom-action-bar .btn-view-cart {
195
+ background-color: #0FAA39;
196
+ border-color: #0FAA39;
197
  }
198
+ .bottom-action-bar .btn-view-cart:hover {
199
+ background-color: #0D9232;
200
+ border-color: #0D9232;
 
 
 
 
 
 
 
 
 
 
201
  }
202
+ .cart-icon-badge {
203
+ background-color: white;
204
+ color: #0FAA39;
205
+ border-radius: 50%;
206
+ width: 20px;
207
+ height: 20px;
208
+ display: inline-flex;
209
+ align-items: center;
210
+ justify-content: center;
211
+ font-size: 12px;
212
+ margin-left: 8px;
213
  }
214
+ .no-results {
 
215
  text-align: center;
 
 
216
  font-size: 1.2rem;
217
+ color: #6c757d;
218
+ margin-top: 20px;
219
+ }
220
+ @media (max-width: 576px) {
221
+ .fixed-top-bar {
222
+ height: 60px;
223
+ padding: 10px;
224
+ }
225
+ .search-bar-container {
226
+ width: 80%;
227
+ max-width: 100%;
228
+ left: 10px;
229
+ top: 50%;
230
+ transform: translateY(-50%);
231
+ }
232
+ .search-bar-container input {
233
+ padding: 6px 35px 6px 35px;
234
+ font-size: 14px;
235
+ border-radius: 20px;
236
+ }
237
+ .search-icon {
238
+ left: 12px;
239
+ font-size: 16px;
240
+ }
241
+ .avatar-dropdown-container {
242
+ right: 10px;
243
+ }
244
+ .avatar-icon {
245
+ width: 40px;
246
+ height: 40px;
247
+ font-size: 20px;
248
+ }
249
+ .dropdown-menu {
250
+ width: 220px;
251
+ }
252
+ .dropdown-menu .dropdown-item {
253
+ padding: 12px 16px;
254
+ font-size: 15px;
255
+ }
256
+ .menu-card {
257
+ max-width: 100%;
258
+ }
259
+ .menu-card img {
260
+ height: 150px;
261
+ }
262
+ .menu-card .card-body .card-title {
263
+ font-size: 1rem;
264
+ }
265
+ .menu-card .card-body .card-text.section {
266
+ font-size: 0.8rem;
267
+ }
268
+ .bottom-action-bar {
269
+ padding: 8px 10px;
270
+ }
271
+ .bottom-action-bar .btn {
272
+ padding: 8px 10px;
273
+ font-size: 14px;
274
+ }
275
+ .cart-icon-badge {
276
+ width: 18px;
277
+ height: 18px;
278
+ font-size: 10px;
279
+ margin-left: 5px;
280
+ }
281
  }
282
  </style>
283
  </head>
284
  <body>
285
  <div class="fixed-top-bar">
286
+ <div class="avatar-dropdown-container">
287
+ <div class="avatar-icon">
288
+ <span>{{ first_letter }}</span>
289
+ </div>
290
+ <div class="dropdown-menu">
291
+ <a href="{{ url_for('user_details.customer_details') }}" class="dropdown-item">View Profile</a>
292
+ <a href="{{ url_for('orderhistory.order_history') }}" class="dropdown-item">Order History</a>
293
+ <a href="{{ url_for('logout') }}" class="dropdown-item">Logout</a>
294
+ </div>
295
+ </div>
296
+ <div class="search-bar-container">
297
+ <input type="text" id="searchBar" class="form-control" placeholder="Search items or sections..." autocomplete="off">
298
+ <i class="bi bi-search search-icon"></i>
299
  </div>
300
  </div>
301
 
302
+ <div class="container mt-4">
303
+ <div class="row" id="menuItems">
304
+ {% for section, items in ordered_menu.items() %}
305
+ {% for item in items %}
306
+ <div class="col-md-6 mb-4 menu-item" data-name="{{ item.Name | default('Unnamed Item') }}" data-section="{{ item.Section__c | default(section) }}">
307
+ <div class="card menu-card" onclick="selectItem('{{ item.Name | default('Unnamed Item') }}')">
308
+ <img src="{{ item.Image1__c | default('/static/placeholder.jpg') }}" alt="{{ item.Name | default('Unnamed Item') }}" class="card-img-top">
309
+ <div class="card-body">
310
+ <h5 class="card-title">{{ item.Name | default('Unnamed Item') }}</h5>
311
+ <p class="card-text section">{{ item.Section__c | default(section) }}</p>
312
+ </div>
 
 
 
 
 
 
 
 
 
313
  </div>
314
  </div>
315
+ {% endfor %}
316
  {% endfor %}
317
  </div>
318
+ <div class="no-results" id="noResults" style="display: none;">
319
+ No items found matching your search.
320
+ </div>
321
  </div>
322
 
323
+ <div class="bottom-action-bar">
324
+ <a href="{{ url_for('orderhistory.order_history') }}" class="btn btn-order-history">
325
+ <i class="bi bi-clock-history"></i> Order History
326
+ </a>
327
+ <a href="{{ url_for('cart.cart') }}" class="btn btn-view-cart">
328
+ <i class="bi bi-cart"></i> View Cart
329
+ <span id="cart-item-count" class="cart-icon-badge" style="display: none;">0</span>
330
+ </a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
331
  </div>
332
 
333
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
334
  <script>
335
  const menuItems = [
336
+ {% for section, items in ordered_menu.items() %}
337
+ {% for item in items %}
338
+ {
339
+ name: "{{ item.Name | default('Unnamed Item') }}",
340
+ section: "{{ item.Section__c | default(section) }}"
341
+ },
342
+ {% endfor %}
343
  {% endfor %}
344
  ];
345
 
346
+ function updateCartUI(cart) {
347
+ if (!Array.isArray(cart)) {
348
+ console.error('Invalid cart data:', cart);
349
+ return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
350
  }
351
+ let totalQuantity = 0;
352
+ cart.forEach(item => {
353
+ totalQuantity += item.quantity;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
354
  });
355
+ const cartItemCount = document.getElementById('cart-item-count');
356
+ if (cartItemCount) {
357
+ cartItemCount.innerText = totalQuantity;
358
+ cartItemCount.style.display = totalQuantity > 0 ? 'inline-flex' : 'none';
359
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
360
  }
361
 
362
+ function getCartLocalStorage() {
363
+ return JSON.parse(localStorage.getItem('