geethareddy commited on
Commit
8e8e0f8
·
verified ·
1 Parent(s): 480cb3f

Update templates/menu.html

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