geethareddy commited on
Commit
e92b578
·
verified ·
1 Parent(s): 3f75263

Update templates/menu.html

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