Swathi6 commited on
Commit
d77704f
·
verified ·
1 Parent(s): 22b080b

Update templates/menu.html

Browse files
Files changed (1) hide show
  1. templates/menu.html +135 -752
templates/menu.html CHANGED
@@ -8,780 +8,163 @@
8
  <!-- Bootstrap CSS -->
9
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
10
  <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
11
- <style>
12
- body {
13
- font-family: Arial, sans-serif;
14
- background-color: #fdf4e3; /* Updated background color */
15
- margin: 0;
16
- padding: 0;
17
- display: flex;
18
- flex-direction: column;
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
- }
32
- .menu-image {
33
- height: 200px; /* Fixed height */
34
- width: 100%; /* Full width of the card */
35
- object-fit: fill; /* Ensure the image covers the area and maintains the aspect ratio */
36
- border-radius: 15px 15px 0 0; /* Rounded top corners */
37
- }
38
- .card-title {
39
- font-size: 1.2rem;
40
- font-weight: bold;
41
- margin: 10px 0;
42
- }
43
- .card-text {
44
- font-size: 1rem;
45
- color: #6c757d;
46
- }
47
- .btn-primary {
48
- font-size: 13px;
49
- font-weight: bold;
50
- border-radius: 5px;
51
- width: 100px;
52
- background-color: #0FAA39; /* Updated button background color */
53
- border-color: #0FAA39;
54
- }
55
- .btn-primary:hover {
56
- background-color: #0FAA39;
57
- border-color: #0FAA39;
58
- }
59
- .btn-primary:active,
60
- .btn-primary:focus {
61
- background-color: #0FAA39;
62
- border-color: #ffffff;
63
- box-shadow: none;
64
- }
65
- .view-cart-container {
66
- position: fixed;
67
- bottom: 20px;
68
- right: 20px;
69
- z-index: 999;
70
- }
71
- .view-cart-button {
72
- background-color: #0FAA39; /* Updated View Cart button background color */
73
- color: #fff;
74
- padding: 10px 20px;
75
- border-radius: 30px;
76
- font-size: 1rem;
77
- font-weight: bold;
78
- text-decoration: none;
79
- box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
80
- display: flex;
81
- align-items: center;
82
- justify-content: center;
83
- }
84
- .view-cart-button:hover {
85
- background-color: #109835; /* Slightly darker shade for hover effect */
86
- text-decoration: none;
87
- }
88
- .avatar-dropdown-container {
89
- position: relative;
90
- }
91
- .avatar-icon {
92
- width: 40px;
93
- height: 40px;
94
- border-radius: 50%;
95
- background-color: #5bbfc1;
96
- cursor: pointer;
97
- display: flex;
98
- align-items: center;
99
- justify-content: center;
100
- color: white;
101
- font-size: 20px;
102
- font-weight: bold;
103
- }
104
- .dropdown-menu {
105
- position: absolute;
106
- right: 0;
107
- top: 100%;
108
- background-color: #fff;
109
- border-radius: 5px;
110
- width: 200px; /* Adjust width as needed */
111
- box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
112
- display: none;
113
- }
114
- .avatar-dropdown-container:hover .dropdown-menu {
115
- display: block;
116
- }
117
- .avatar-dropdown-container {
118
- position: absolute;
119
- right: 20px; /* Adjust the value as needed to position it properly */
120
- top: 50%; /* Adjust top to place it within the header */
121
- transform: translateY(-50%); /* Correct the alignment to be perfectly centered */
122
- display: flex;
123
- align-items: right;
124
- justify-content: center;
125
- }
126
-
127
- .dropdown-menu .dropdown-item {
128
- padding: 10px 15px;
129
- text-decoration: none;
130
- color: #333;
131
- border-bottom: 1px solid #ddd;
132
- display: block; /* Make each item stack vertically */
133
- }
134
- .dropdown-menu .dropdown-item:last-child {
135
- border-bottom: none; /* Remove the bottom border from the last item */
136
- }
137
- .dropdown-menu .dropdown-item:hover {
138
- background-color: #f1f1f1;
139
- }
140
- .fixed-search-container {
141
- position: absolute;
142
- top: 90px; /* Move it slightly lower */
143
- left: 50%;
144
- transform: translateX(-50%);
145
- width: 80%;
146
- max-width: 600px;
147
- z-index: 999; /* Keep it above content */
148
- background-color: white;
149
- padding: 10px;
150
- border-radius: 25px;
151
- box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);
152
- }
153
- /* Ensure the category filter dropdown does not overlap */
154
- form.text-center.mb-4 {
155
- margin-top: 10px; /* No margin at the top */
156
- margin-bottom: 0px; /* Small space at the bottom */
157
- }
158
- /* Ensure the container has enough margin so nothing is overlapped */
159
- .container {
160
- margin-top: 10px; /* Adjust spacing based on navbar and search bar */
161
- padding-top: 0 !important; /* Ensure no padding is added by default */
162
- }
163
- h1.text-center {
164
- margin-top: 10px; /* Reduced space above */
165
- padding-top: 0 !important; /* Removed padding */
166
- font-weight: semi-bold; /* Make the "Menu" text bold */
167
- }
168
- .fixed-top-bar {
169
- /* Remove the fixed positioning */
170
- position: relative; /* Change from fixed to relative */
171
- top: 0;
172
- left: 0;
173
- width: 100%;
174
- height: 54px;
175
- background-color: #FF6B35;
176
- color: white;
177
- padding: 15px;
178
- display: flex;
179
- justify-content: space-between;
180
- align-items: center; /* Vertically align items */
181
- z-index: 1000; /* Make sure it's still above other content */
182
- }
183
- .search-bar-container {
184
- padding: 10px;
185
- position: absolute;
186
- left: 20px;
187
- top: 50%;
188
- transform: translateY(-50%);
189
- display: flex;
190
- justify-content: flex-start;
191
- align-items: center;
192
- width: 300px; /* Adjust width as needed */
193
- }
194
- .search-bar-container input {
195
- width: 85%;
196
- padding: 8px 10px 8px 30px; /* Add padding for the icon */
197
- font-size: 16px;
198
- border-radius: 10px;
199
- border: none;
200
- }
201
- .search-icon {
202
- position: absolute;
203
- left: 15px; /* Position the icon inside the input box */
204
- font-size: 20px;
205
- color: #888; /* Icon color */
206
- }
207
- /* Style for customization sections */
208
- .addon-section {
209
- background-color: #fff; /* Light gray background */
210
- border: 2px solid #6c757d; /* Border color */
211
- border-radius: 8px;
212
- padding: 12px;
213
- margin-bottom: 10px; /* Spacing between sections */
214
- }
215
- /* Customization section title */
216
- .addon-section h6 {
217
- margin-bottom: 10px;
218
- font-size: 1.1rem;
219
- font-weight: bold;
220
- color: #343a40; /* Darker title text */
221
- }
222
- /* Style for add-on checkboxes */
223
- .addon-section .form-check {
224
- display: inline-flex; /* Display checkboxes horizontally */
225
- align-items: center; /* Align checkboxes and labels */
226
- margin-left: 10px; /* Space between checkboxes */
227
- color: #343a40; /* Darker text color */
228
- }
229
- /* Customize the default checkbox */
230
- .addon-section .form-check-input {
231
- -webkit-appearance: none; /* Remove default checkbox styling in Webkit browsers (e.g. Chrome, Safari) */
232
- -moz-appearance: none; /* Remove default checkbox styling in Firefox */
233
- appearance: none; /* Remove default checkbox styling in all browsers */
234
- width: 20px;
235
- height: 20px;
236
- border: 2px solid #343a40; /* Darker border color */
237
- border-radius: 5px; /* Rounded corners */
238
- background-color: #f0f0f0; /* Lighter gray background when unchecked */
239
- position: relative;
240
- margin-right: 10px; /* Add space between the checkbox and label */
241
- }
242
-
243
- /* Checked state for the custom checkbox */
244
- .addon-section .form-check-input:checked {
245
- background-color: #006400; /* Dark green background when checked */
246
- border-color: #006400; /* Dark green border when checked */
247
- }
248
- /* Add the check mark when checkbox is checked */
249
- .addon-section .form-check-input:checked::before {
250
- content: ''; /* Unicode check mark */
251
- font-size: 14px;
252
- position: absolute;
253
- top: 3px;
254
- left: 4px;
255
- color: white; /* White color for the check mark */
256
- }
257
- /* Hover effect for the checkboxes */
258
- .addon-section .form-check-input:hover {
259
- /* background-color: #006400; /* Slightly darker background on hover */
260
- }
261
- /* Focus effect on custom checkbox */
262
- .addon-section .form-check-input:focus {
263
- outline: none;
264
- box-shadow: 0 0 0 2px #006400; /* Green focus outline */
265
- }
266
- /* Custom checkbox label styles */
267
- .addon-section .form-check-label {
268
- font-size: 16px;
269
- margin-left: 5px;
270
- cursor: pointer;
271
- display: inline-block; /* Ensure label aligns correctly with checkbox */
272
- vertical-align: middle; /* Align text vertically with the checkbox */
273
- }
274
- /* Fix alignment of text and checkbox */
275
- .addon-section .form-check input[type="checkbox"],
276
- .addon-section .form-check label {
277
- display: inline-block;
278
- /* vertical-align: middle; /* Align text and checkboxes vertically */
279
- }
280
- /* Category Filter with Custom Radio Buttons */
281
- form.text-center.mb-4 {
282
- display: flex;
283
- flex-direction: column;
284
- align-items: center;
285
- justify-content: center;
286
- margin-bottom: 5px; /* Reduce bottom margin */
287
- }
288
- .form-check {
289
- display: inline-block;
290
- margin-right: 5px; /* Reduced space between radio button and label */
291
- margin-bottom: 0; /* Remove bottom margin */
292
- margin-top: 10px; /* Adds space between categories and Customized Dish */
293
- vertical-align: middle; /* Align radio buttons vertically */
294
- }
295
- .form-check-inline {
296
- display: inline-block;
297
- margin-right: 5px; /* Decrease space between each radio button */
298
- }
299
- .form-check-label {
300
- display: inline-block;
301
- font-size: 16px;
302
- margin-left: 5px; /* Spacing between radio button and label */
303
- vertical-align: middle; /* Align label vertically */
304
- }
305
- form-check-input addon-option{
306
- color: #333d47;
307
- }
308
- .custom-radio {
309
- appearance: none;
310
- -webkit-appearance: none;
311
- -moz-appearance: none;
312
- width: 20px;
313
- height: 20px;
314
- border: 3px solid #4CAF50; /* Green border */
315
- border-radius: 50%;
316
- margin-right: -5px; /* Reduced spacing between button and label */
317
- outline: none;
318
- cursor: pointer;
319
- position: relative;
320
- display: inline-block;
321
- vertical-align: middle; /* Align vertically with text */
322
- }
323
- .custom-radio:checked {
324
- background-color: #4CAF50; /* Green color when checked */
325
- border-color: #4CAF50; /* Matching border color */
326
- }
327
- .custom-radio:checked::after {
328
- content: '';
329
- position: relative;
330
- top: 5px;
331
- left: 5px;
332
- border-radius: 50%;
333
- }
334
- .custom-radio:hover {
335
- border-color: #388E3C;
336
- }
337
- /* Optional: Style the labels */
338
- .form-check-label {
339
- font-size: 16px;
340
- margin-left: 8px; /* Space between the radio button and the label */
341
- }
342
- .cart-container {
343
- display: flex;
344
- align-items: center;
345
- gap: 10px;
346
- }
347
- .modal-footer {
348
- display: flex;
349
- align-items: center;
350
- justify-content: space-between; /* Space between quantity and Add to Cart button */
351
- padding: 10px;
352
- }
353
- .modal-footer .d-flex {
354
- display: flex;
355
- align-items: center;
356
- gap: 10px; /* Space between quantity buttons */
357
- }
358
- .modal-footer .btn {
359
- height: 40px; /* Set consistent button height */
360
- padding: 0 15px; /* Adjust padding to fit inside the buttons */
361
- }
362
- .modal-footer .form-control {
363
- width: 50px; /* Fixed width for quantity input */
364
- height: 40px; /* Match the height of buttons */
365
- text-align: center; /* Center the value inside the input */
366
- }
367
- .modal-footer .btn-primary {
368
- background-color: #0FAA39; /* Green background for Add to Cart button */
369
- border-color: #0FAA39; /* Border color to match button background */
370
- font-weight: bold; /* Bold text */
371
- padding: 10px 20px; /* Adjust padding to make the button look better */
372
- height: 40px; /* Match the height with quantity buttons */
373
- display: flex;
374
- justify-content: center;
375
- align-items: center;
376
- width: auto; /* Auto width to adjust to button text */
377
- }
378
- .modal-footer .btn-outline-secondary {
379
- height: 40px; /* Ensure quantity buttons are the same size */
380
- width: 40px; /* Make sure the buttons are square */
381
- }
382
- @media (max-width: 576px) {
383
- /* Responsive adjustments for smaller screens */
384
- .modal-dialog {
385
- max-width: 98%; /* Adjust modal width for smaller screens */
386
- }
387
- .modal-footer .btn {
388
- height: 35px; /* Smaller buttons for small screens */
389
- }
390
- .modal-footer .form-control {
391
- width: 40px; /* Adjust input size for smaller screens */
392
- height: 35px;
393
- }
394
- }
395
- </style>
396
  </head>
397
  <body>
398
 
399
- <div class="fixed-top-bar">
400
- <!-- Avatar and Dropdown -->
401
- <div class="avatar-dropdown-container">
402
- <div class="avatar-icon">
403
- <span>{{ first_letter }}</span> <!-- Display the first letter of the customer's name -->
404
- </div>
405
- <div class="dropdown-menu">
406
- <a href="{{ url_for('customer_details') }}" class="dropdown-item">View Profile</a>
407
- <a href="{{ url_for('order_history') }}" class="dropdown-item">Order History</a>
408
- <a href="{{ url_for('logout') }}" class="dropdown-item">Logout</a>
409
- </div>
410
- </div>
411
-
412
- <!-- Search Bar Section -->
413
- <div class="search-bar-container">
414
- <input type="text" id="searchBar" class="form-control" placeholder="Search items or sections..." onkeyup="filterMenu()">
415
- <i class="bi bi-search search-icon"></i> <!-- Search icon inside the input -->
416
- </div>
417
- </div>
418
 
419
- <!-- Category Filter with Custom Radio Buttons -->
420
- <form method="get" action="/menu" class="text-center mb-4">
421
- <label class="form-label fw-bold">Select a Category:</label>
422
- <div class="form-check form-check-inline">
423
- {% for category in categories %}
424
- <input type="radio" id="category-{{ category }}" name="category" value="{{ category }}" class="custom-radio"
425
- {% if selected_category == category %}checked{% endif %} onchange="this.form.submit()">
426
- <label class="form-check-label" for="category-{{ category }}">{{ category }}</label>
427
- {% endfor %}
428
- </div>
429
- <!-- Separate Customized Dish radio button in a new div to align it properly -->
430
- <div class="form-check">
431
- <input type="radio" id="category-CustomizedDish" name="category" value="Customized Dish" class="custom-radio"
432
- {% if selected_category == "Customized Dish" %}checked{% endif %} onchange="this.form.submit()">
433
- <label class="form-check-label" for="category-CustomizedDish">Customized Dish</label>
434
- </div>
435
- </form>
436
-
437
- <!-- Show menu items only when Customized Dish is not selected -->
438
- <div class="container mt-4">
439
- <h1 class="text-center">Menu</h1>
440
-
441
- <!-- Display text boxes for Customized Dish -->
442
- {% if selected_category == "Customized Dish" %}
443
- <div id="custom-dish-form" class="mt-4">
444
- <h3>Create Your Custom Dish</h3>
445
- <form method="POST" action="/generate_custom_dish">
446
- <div class="mb-3">
447
- <label for="custom-dish-name" class="form-label">Dish Name</label>
448
- <input type="text" class="form-control" id="custom-dish-name" name="name" required>
449
- </div>
450
- <div class="mb-3">
451
- <label for="custom-dish-description" class="form-label">Dish Description</label>
452
- <textarea class="form-control" id="custom-dish-description" name="description" required></textarea>
453
- </div>
454
- <button type="submit" class="btn btn-primary">Submit</button>
455
- </form>
456
- </div>
457
- {% else %}
458
-
459
- <!-- Menu Sections -->
460
- {% for section, items in ordered_menu.items() %}
461
- <h3>{{ section }}</h3>
462
- <div class="row">
463
- {% for item in items %}
464
- <div class="col-md-6 mb-4">
465
- <div class="card menu-card">
466
- <img src="{{ item.Image1__c }}" class="card-img-top menu-image" alt="{{ item.Name }}" onerror="this.src='/static/placeholder.jpg';">
467
- <div class="card-body">
468
- <h5 class="card-title">{{ item.Name }}</h5>
469
- <p class="card-text">${{ item.Price__c }}</p>
470
- <button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#itemModal"
471
- onclick="showItemDetails('{{ item.Name }}', '{{ item.Price__c }}', '{{ item.Image2__c }}', '{{ item.Description__c }}', '{{ item.Section__c }}','{{ selected_category }}')">
472
- Add
473
- </button>
474
- </div>
475
  </div>
476
  </div>
477
- {% endfor %}
478
- </div>
479
- {% endfor %}
480
- </div>
481
- {% endif %}
482
-
483
- </div>
484
 
485
- <!-- View Cart Button -->
486
- <div class="view-cart-container">
487
- <a href="/cart" class="view-cart-button">
488
- View Cart
489
- </a>
490
- </div>
491
 
492
- <!-- Modal for Item Details -->
493
- <div class="modal fade" id="itemModal" tabindex="-1" aria-labelledby="itemModalLabel" aria-hidden="true">
494
  <div class="modal-dialog modal-dialog-centered">
495
  <div class="modal-content">
496
  <div class="modal-header">
497
- <h5 class="modal-title" id="itemModalLabel">Item Details</h5>
498
  <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
499
  </div>
500
  <div class="modal-body">
501
- <!-- Item Image -->
502
- <img id="modal-img" class="img-fluid rounded mb-3 d-block mx-auto" alt="Item Image" style="max-height: 200px; object-fit: cover;">
503
- <!-- Item Name -->
504
- <h5 id="modal-name" class="fw-bold text-center"></h5>
505
- <!-- Item Price -->
506
- <p id="modal-price" class="text-muted text-center"></p>
507
- <!-- Item Description -->
508
- <p id="modal-description" class="text-secondary"></p>
509
- <!-- Add-ons -->
510
- <div id="modal-addons" class="modal-addons mt-4">
511
- <h6>Customization Options</h6>
512
- <div id="addons-list" class="addons-container">Loading customization options...</div>
513
- </div>
514
- <div class="mt-4">
515
- <h6>Custom Request</h6>
516
- <textarea id="modal-instructions" class="form-control" placeholder="Enter any special instructions here..."></textarea>
517
- </div>
518
- <span id="modal-section" data-section="" data-category="" style="display: none;"></span>
519
- </div>
520
- <!-- Quantity Controls and Add to Cart Button -->
521
- <div class="modal-footer d-flex align-items-center justify-content-between">
522
- <!-- Quantity Controls -->
523
- <div class="d-flex align-items-center gap-2">
524
- <button type="button" class="btn btn-outline-secondary" id="decreaseQuantity">-</button>
525
- <input type="text" class="form-control text-center" id="quantityInput" value="1" readonly style="width: 50px;"/>
526
- <button type="button" class="btn btn-outline-secondary" id="increaseQuantity">+</button>
527
- </div>
528
- <!-- Add to Cart Button -->
529
- <button type="button" class="btn btn-primary" onclick="addToCartFromModal()">Add to Cart</button>
530
  </div>
531
  </div>
532
  </div>
533
  </div>
534
 
535
- <!-- JavaScript -->
536
  <script>
537
- // Show item details and fetch customization options
538
- function showItemDetails(name, price, image, description, section, selectedCategory) {
539
- document.getElementById('modal-name').innerText = name;
540
- document.getElementById('modal-price').innerText = `$${price}`;
541
- document.getElementById('modal-img').src = image || '/static/placeholder.jpg';
542
- document.getElementById('modal-description').innerText = description || 'No description available.';
543
- document.getElementById('addons-list').innerHTML = 'Loading customization options...';
544
- document.getElementById('modal-instructions').value = '';
545
- const modalSectionEl = document.getElementById('modal-section');
546
- modalSectionEl.setAttribute('data-section', section);
547
- modalSectionEl.setAttribute('data-category', selectedCategory);
548
- // Set the default quantity to 1
549
- document.getElementById('quantityInput').value = 1;
550
-
551
- // Fetch customization options based on the section
552
- fetch(`/api/addons?item_name=${encodeURIComponent(name)}&item_section=${encodeURIComponent(section)}`)
553
- .then(response => response.json())
554
- .then(data => {
555
- const addonsList = document.getElementById('addons-list');
556
- addonsList.innerHTML = ''; // Clear previous content
557
- if (!data.success || !data.addons || data.addons.length === 0) {
558
- addonsList.innerHTML = '<p>No customization options available.</p>';
559
- return;
560
- }
561
-
562
- // Display customization options inside styled divs
563
- data.addons.forEach(addon => {
564
- const sectionDiv = document.createElement('div');
565
- sectionDiv.classList.add('addon-section'); // Add styling class
566
-
567
- // Add section title
568
- const title = document.createElement('h6');
569
- title.innerText = addon.name;
570
- sectionDiv.appendChild(title);
571
-
572
- // Create options list
573
- const optionsContainer = document.createElement('div');
574
- addon.options.forEach((option, index) => {
575
- const optionId = `addon-${addon.name.replace(/\s+/g, '')}-${index}`;
576
- const listItem = document.createElement('div');
577
- listItem.classList.add('form-check');
578
- listItem.innerHTML = `
579
- <input type="checkbox" class="form-check-input addon-option" id="${optionId}" value="${option}"
580
- data-name="${option}" data-group="${addon.name}" data-price="${addon.extra_charge ? addon.extra_charge_amount : 0}">
581
- <label class="form-check-label" for="${optionId}">
582
- ${option} ${addon.extra_charge ? `($${addon.extra_charge_amount})` : ''}
583
- </label>
584
- `;
585
- optionsContainer.appendChild(listItem);
586
- });
587
- sectionDiv.appendChild(optionsContainer);
588
- addonsList.appendChild(sectionDiv);
589
- });
590
- })
591
- .catch(err => {
592
- console.error('Error fetching add-ons:', err);
593
- document.getElementById('addons-list').innerHTML = '<p>Error loading customization options.</p>';
594
- });
595
  }
596
- // Handle single-select/deselect logic for checkbox groups in all modals
597
- document.addEventListener('click', function(event) {
598
- if (event.target.classList.contains('addon-option')) {
599
- handleAddonClick(event.target);
600
- }
601
- });
602
- // Handle checkbox selection logic
603
- function handleAddonClick(checkbox) {
604
- const groupName = checkbox.getAttribute('data-group');
605
- const isMultiSelectGroup = ["Extra Toppings", "Choose Raita/Sides","Select Dip/Sauce","Extra Add-ons","Make it a Combo"].includes(groupName);
606
-
607
- // If it's not multi-select, uncheck all other checkboxes in the same group
608
- if (!isMultiSelectGroup) {
609
- const checkboxes = document.querySelectorAll(`.addon-option[data-group="${groupName}"]`);
610
- checkboxes.forEach(otherCheckbox => {
611
- if (otherCheckbox !== checkbox) {
612
- otherCheckbox.checked = false;
613
- }
614
- });
615
- }
616
- }
617
- function filterMenu() {
618
- let input = document.getElementById('searchBar').value.toLowerCase(); // Get the value from search bar
619
- let sections = document.querySelectorAll('h3'); // Select section headers
620
- let items = document.querySelectorAll('.menu-card'); // Select all items
621
- let matchedSections = new Set(); // Store matched sections
622
-
623
- // Hide all items initially
624
- items.forEach(item => {
625
- let itemName = item.querySelector('.card-title').innerText.toLowerCase(); // Get item name
626
- let itemSection = item.closest('.row').previousElementSibling.innerText.toLowerCase(); // Get section name
627
-
628
- // If the search matches item name or section, show the item
629
- if (itemName.includes(input) || (itemSection && itemSection.includes(input))) {
630
- item.style.display = 'block'; // Show item if it matches search
631
- matchedSections.add(item.closest('.row')); // Add section to matched list
632
- } else {
633
- item.style.display = 'none'; // Hide item if not matched
634
- }
635
- });
636
-
637
- // Show or hide sections based on matched items
638
- sections.forEach(section => {
639
- let sectionRow = section.nextElementSibling; // The row containing items
640
- if (matchedSections.has(sectionRow)) {
641
- section.style.display = 'block'; // Show section header
642
- sectionRow.style.display = 'flex'; // Show section items
643
- } else {
644
- section.style.display = 'none'; // Hide section header
645
- sectionRow.style.display = 'none'; // Hide section items
646
- }
647
- });
648
- }
649
- function addToCartFromModal() {
650
- const itemName = document.getElementById('modal-name').innerText;
651
- let itemPrice = parseFloat(document.getElementById('modal-price').innerText.replace('$', ''));
652
- // Validate item price
653
- if (isNaN(itemPrice)) {
654
- alert('Invalid price for the item. Please check the item details.');
655
- return;
656
- }
657
- const itemImage = document.getElementById('modal-img').src;
658
- console.log(itemName, itemPrice, itemImage); // Log values for debugging
659
- const modalSectionEl = document.getElementById('modal-section');
660
- const section = modalSectionEl.getAttribute('data-section');
661
- const selectedCategory = modalSectionEl.getAttribute('data-category');
662
- if (!itemName || !itemPrice || !section || !itemImage) {
663
- console.error('Missing data for cart item:', { itemName, itemPrice, section, itemImage});
664
- return;
665
- }
666
-
667
- // Collect selected add-ons
668
- let selectedAddOns = Array.from(
669
- document.querySelectorAll('#addons-list input[type="checkbox"]:checked')
670
- ).map(addon => ({
671
- name: addon.getAttribute('data-name') || 'Default Name', // Fallback Name
672
- price: parseFloat(addon.getAttribute('data-price') || 0)
673
- }));
674
- // Get the selected quantity
675
- const quantity = parseInt(document.getElementById('quantityInput').value) || 1; // Default to 1 if invalid
676
- const instructions = document.getElementById('modal-instructions').value;
677
- // Prepare data for the cart
678
- const cartPayload = {
679
- itemName: itemName,
680
- itemPrice: itemPrice,
681
- itemImage: itemImage,
682
- section: section,
683
- category: selectedCategory,
684
- addons: selectedAddOns,
685
- instructions: instructions,
686
- quantity: quantity // Include the quantity
687
- };
688
- // Send the cart data to the server
689
- fetch('/cart/add', {
690
- method: 'POST',
691
- headers: {
692
- 'Content-Type': 'application/json',
693
- },
694
- body: JSON.stringify(cartPayload)
695
- })
696
- .then(response => response.json())
697
- .then(data => {
698
- if (data.success) {
699
- alert('Item added to cart successfully!');
700
- updateCartUI(data.cart); // Update cart UI after adding an item
701
- const modal = document.getElementById('itemModal');
702
- const modalInstance = bootstrap.Modal.getInstance(modal);
703
- modalInstance.hide();
704
- } else {
705
- alert(data.error || 'Failed to add item to cart.');
706
- }
707
- })
708
- .catch(err => {
709
- console.error('Error adding item to cart:', err);
710
- alert('An error occurred while adding the item to the cart.');
711
- });
712
- }
713
- function updateCartUI(cart) {
714
- if (!Array.isArray(cart)) {
715
- console.error('Invalid cart data:', cart);
716
- return;
717
- }
718
- const cartIcon = document.getElementById('cart-icon');
719
- cartIcon.innerText = cart.length; // Assuming cart is an array of items
720
- }
721
- function updateCartDisplay(cart) {
722
- if (!Array.isArray(cart)) {
723
- console.error('Invalid cart data:', cart);
724
- return;
725
- }
726
- // Optional: Update quantity on the cart page
727
- const cartCountElement = document.getElementById('cart-count');
728
- cartCountElement.innerText = cart.reduce((total, item)=> total+item.quantity,0); // Update cart item count //Sum of all quantities
729
-
730
- // Optionally, show a small success notification that the item was added
731
- const successNotification = document.createElement('div');
732
- successNotification.classList.add('success-notification');
733
- successNotification.innerText = 'Item added to cart!';
734
- document.body.appendChild(successNotification);
735
- setTimeout(() => {
736
- successNotification.remove(); // Remove success notification after a few seconds
737
- }, 2000);
738
- }
739
-
740
- document.addEventListener('DOMContentLoaded', function () {
741
- // Get references to the quantity buttons and the input field
742
- const decreaseBtn = document.getElementById('decreaseQuantity');
743
- const increaseBtn = document.getElementById('increaseQuantity');
744
- const quantityInput = document.getElementById('quantityInput');
745
- // Add event listener to decrease button
746
- decreaseBtn.addEventListener('click', function () {
747
- let currentQuantity = parseInt(quantityInput.value);
748
- if (currentQuantity > 1) {
749
- currentQuantity--;
750
- quantityInput.value = currentQuantity;
751
- }
752
- });
753
- // Add event listener to increase button
754
- increaseBtn.addEventListener('click', function () {
755
- let currentQuantity = parseInt(quantityInput.value);
756
- currentQuantity++;
757
- quantityInput.value = currentQuantity;
758
  });
759
- });
760
- // Function to round reward points to a single digit
761
- function roundRewardPoints() {
762
- // Get the reward points element
763
- let rewardPointsElement = document.getElementById('reward-points');
764
- // Check if the element exists in the DOM
765
- if (rewardPointsElement) {
766
- let rewardPointsText = rewardPointsElement.innerText.trim(); // Get and trim the value to remove any extra spaces
767
- // Check if the innerText is a valid number
768
- let rewardPoints = parseFloat(rewardPointsText);
769
- // If it's a valid number, round it to 1 decimal place
770
- if (!isNaN(rewardPoints)) {
771
- rewardPointsElement.innerText = rewardPoints.toFixed(1); // Round to 1 decimal place
772
- } else {
773
- console.error("Reward points value is not a valid number:", rewardPointsText);
774
- }
775
- } else {
776
- console.error("Reward points element is missing.");
777
- }
778
- }
779
- // Run the function when the page loads
780
- window.onload = roundRewardPoints;
781
-
782
- </script>
783
 
784
- <!-- Bootstrap JS -->
785
- <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
786
  </body>
787
  </html>
 
8
  <!-- Bootstrap CSS -->
9
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
10
  <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
11
+ <style>
12
+ /* Custom Styling */
13
+ body {
14
+ font-family: Arial, sans-serif;
15
+ background-color: #fdf4e3; /* Background color */
16
+ margin: 0;
17
+ padding: 0;
18
+ display: flex;
19
+ flex-direction: column;
20
+ }
21
+ .container {
22
+ max-width: 900px;
23
+ }
24
+ .menu-card {
25
+ max-width: 350px;
26
+ border-radius: 15px;
27
+ overflow: hidden;
28
+ background-color: #fff;
29
+ margin: auto;
30
+ display: flex;
31
+ flex-direction: column;
32
+ }
33
+ .menu-image {
34
+ height: 200px;
35
+ width: 100%;
36
+ object-fit: fill;
37
+ border-radius: 15px 15px 0 0;
38
+ cursor: pointer;
39
+ }
40
+ .card-title {
41
+ font-size: 1.2rem;
42
+ font-weight: bold;
43
+ margin: 10px 0;
44
+ }
45
+ .card-text {
46
+ font-size: 1rem;
47
+ color: #6c757d;
48
+ }
49
+ .btn-primary {
50
+ font-size: 13px;
51
+ font-weight: bold;
52
+ border-radius: 5px;
53
+ width: 100px;
54
+ background-color: #0FAA39;
55
+ border-color: #0FAA39;
56
+ }
57
+ .btn-primary:hover {
58
+ background-color: #0FAA39;
59
+ border-color: #0FAA39;
60
+ }
61
+ .btn-primary:active,
62
+ .btn-primary:focus {
63
+ background-color: #0FAA39;
64
+ border-color: #ffffff;
65
+ box-shadow: none;
66
+ }
67
+ /* Video Modal Styling */
68
+ .modal-content {
69
+ background-color: #fff;
70
+ border-radius: 10px;
71
+ padding: 20px;
72
+ }
73
+ #modal-video {
74
+ width: 100%;
75
+ height: auto;
76
+ }
77
+ /* Modal Header Styling */
78
+ .modal-header {
79
+ border-bottom: none;
80
+ }
81
+ .modal-title {
82
+ font-size: 1.5rem;
83
+ font-weight: bold;
84
+ }
85
+ </style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  </head>
87
  <body>
88
 
89
+ <!-- Main Content: Menu Items -->
90
+ <div class="container mt-4">
91
+ <h1 class="text-center">Menu</h1>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
+ <!-- Looping over menu items (Dynamically rendered) -->
94
+ {% for section, items in ordered_menu.items() %}
95
+ <h3>{{ section }}</h3>
96
+ <div class="row">
97
+ {% for item in items %}
98
+ <div class="col-md-6 mb-4">
99
+ <div class="card menu-card">
100
+ <!-- Image with video URL -->
101
+ <img src="{{ item.Image1__c }}" class="card-img-top menu-image" alt="{{ item.Name }}"
102
+ data-video-url="{{ item.Video_Url__c }}" onerror="this.src='/static/placeholder.jpg';">
103
+ <div class="card-body">
104
+ <h5 class="card-title">{{ item.Name }}</h5>
105
+ <p class="card-text">${{ item.Price__c }}</p>
106
+ <button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#itemModal"
107
+ onclick="showItemDetails('{{ item.Name }}', '{{ item.Price__c }}', '{{ item.Image2__c }}', '{{ item.Description__c }}', '{{ item.Section__c }}', '{{ selected_category }}')">
108
+ Add
109
+ </button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  </div>
111
  </div>
112
+ </div>
113
+ {% endfor %}
114
+ </div>
115
+ {% endfor %}
116
+ </div>
 
 
117
 
118
+ <!-- View Cart Button -->
119
+ <div class="view-cart-container">
120
+ <a href="/cart" class="view-cart-button">
121
+ View Cart
122
+ </a>
123
+ </div>
124
 
125
+ <!-- Video Modal (for displaying video when an image is clicked) -->
126
+ <div class="modal fade" id="videoModal" tabindex="-1" aria-labelledby="videoModalLabel" aria-hidden="true">
127
  <div class="modal-dialog modal-dialog-centered">
128
  <div class="modal-content">
129
  <div class="modal-header">
130
+ <h5 class="modal-title" id="videoModalLabel">Video</h5>
131
  <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
132
  </div>
133
  <div class="modal-body">
134
+ <!-- Video Player -->
135
+ <video id="modal-video" class="embed-responsive-item" controls>
136
+ <source id="video-source" src="" type="video/mp4">
137
+ Your browser does not support the video tag.
138
+ </video>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  </div>
140
  </div>
141
  </div>
142
  </div>
143
 
144
+ <!-- JavaScript for Handling Video Display on Image Click -->
145
  <script>
146
+ function showVideo(videoUrl) {
147
+ const videoElement = document.getElementById('modal-video');
148
+ const videoSource = document.getElementById('video-source');
149
+ videoSource.src = videoUrl;
150
+ videoElement.load(); // Reload the video element to apply the new source
151
+ const videoModal = new bootstrap.Modal(document.getElementById('videoModal'));
152
+ videoModal.show();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
  }
154
+
155
+ document.querySelectorAll('.menu-image').forEach((image) => {
156
+ image.addEventListener('click', function () {
157
+ const videoUrl = image.getAttribute('data-video-url');
158
+ if (videoUrl) {
159
+ showVideo(videoUrl); // Open the video modal
160
+ } else {
161
+ alert("No video associated with this image.");
162
+ }
163
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  });
165
+ </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
 
167
+ <!-- Bootstrap JS -->
168
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
169
  </body>
170
  </html>