lokeshloki143 commited on
Commit
76f3266
·
verified ·
1 Parent(s): 375fc97

Update templates/menu.html

Browse files
Files changed (1) hide show
  1. templates/menu.html +592 -671
templates/menu.html CHANGED
@@ -36,10 +36,6 @@
36
  display: flex;
37
  flex-direction: column;
38
  box-shadow: 0 4px 8px rgba(0,0,0,0.1);
39
- transition: transform 0.2s ease;
40
- }
41
- .menu-card:hover {
42
- transform: translateY(-5px);
43
  }
44
  .menu-card.highlighted {
45
  border: 3px solid #0FAA39;
@@ -77,7 +73,6 @@
77
  width: 100%;
78
  height: 100%;
79
  object-fit: cover;
80
- aspect-ratio: 16/9;
81
  opacity: 1;
82
  transition: opacity 0.3s ease;
83
  }
@@ -97,19 +92,18 @@
97
  margin-bottom: 5px;
98
  }
99
  .addbutton .btn {
100
- background-color: #0FAA39;
101
  color: white;
102
  padding: 10px 20px;
103
  font-size: 16px;
104
  font-weight: bold;
105
- border-radius: 8px;
106
  border: none;
107
- transition: background-color 0.3s ease, transform 0.2s ease;
108
  margin-left: 13px;
109
  }
110
  .addbutton .btn:hover {
111
- background-color: #0D9232;
112
- transform: scale(1.05);
113
  }
114
  .button-container {
115
  display: flex;
@@ -138,12 +132,11 @@
138
  align-items: center;
139
  justify-content: center;
140
  padding: 0;
141
- transition: background-color 0.3s ease, transform 0.2s ease;
142
  }
143
  .btn-primary:hover {
144
  background-color: #0D9232;
145
  border-color: #0D9232;
146
- transform: scale(1.05);
147
  }
148
  .btn-primary:active,
149
  .btn-primary:focus {
@@ -164,7 +157,7 @@
164
  width: 40px;
165
  height: 40px;
166
  border-radius: 50%;
167
- background: linear-gradient(45deg, #FFA500, #000000, #0000FF);
168
  cursor: pointer;
169
  display: flex;
170
  align-items: center;
@@ -176,22 +169,22 @@
176
  }
177
  .avatar-icon:hover {
178
  transform: scale(1.1);
179
- box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
180
  }
181
  .dropdown-menu {
182
  position: absolute;
183
  right: 0;
184
  top: 100%;
185
- background: linear-gradient(180deg, #ffffff, #f8f9fa);
186
  border-radius: 12px;
187
  width: 240px;
188
  box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
189
  display: none;
190
- border: none;
191
  padding: 12px 0;
192
  animation: slideDown 0.3s ease-out;
193
  z-index: 1000;
194
- overflow: hidden;
195
  }
196
  .dropdown-menu.show {
197
  display: block;
@@ -199,30 +192,36 @@
199
  .dropdown-menu .dropdown-item {
200
  padding: 12px 18px;
201
  text-decoration: none;
202
- color: #333;
203
  display: flex;
204
  align-items: center;
205
  font-size: 15px;
206
  font-weight: 500;
207
- transition: background-color 0.2s ease, color 0.2s ease, transform 0.2s ease;
 
 
208
  }
209
  .dropdown-menu .dropdown-item i {
210
  margin-right: 12px;
211
  font-size: 18px;
212
  color: #0FAA39;
 
213
  }
214
  .dropdown-menu .dropdown-item:hover {
215
  background-color: #e6f4ea;
216
- color: #0D9232;
217
  transform: translateX(5px);
218
  }
219
  .dropdown-menu .dropdown-item:hover i {
220
  color: #0D9232;
221
  }
 
 
 
222
  @keyframes slideDown {
223
  from {
224
  opacity: 0;
225
- transform: translateY(-10px);
226
  }
227
  to {
228
  opacity: 1;
@@ -242,7 +241,6 @@
242
  justify-content: space-between;
243
  align-items: center;
244
  z-index: 1000;
245
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
246
  }
247
  .search-bar-container {
248
  position: absolute;
@@ -264,14 +262,13 @@
264
  background-color: #fff;
265
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
266
  outline: none;
267
- transition: box-shadow 0.2s ease;
268
- }
269
- .search-bar-container input:focus {
270
- box-shadow: 0 0 0 3px rgba(255, 160, 122, 0.3);
271
  }
272
  .search-bar-container input::placeholder {
273
  color: #888;
274
  }
 
 
 
275
  .search-icon {
276
  position: absolute;
277
  left: 15px;
@@ -284,15 +281,10 @@
284
  font-size: 18px;
285
  color: #888;
286
  cursor: pointer;
287
- transition: color 0.3s ease, transform 0.2s ease;
288
- }
289
- .mic-icon:hover {
290
- color: #DC3545;
291
- transform: scale(1.1);
292
  }
293
  .mic-icon.active {
294
- color: #DC3545;
295
- animation: pulseMic 1.5s infinite;
296
  }
297
  /* Addon Section */
298
  .addon-section {
@@ -414,7 +406,7 @@
414
  #softDrinkModal .modal-content {
415
  border-radius: 12px;
416
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
417
- background: linear-gradient(180deg, #ffffff, #f8f9fa);
418
  overflow: hidden;
419
  }
420
  #softDrinkModal .modal-header {
@@ -434,17 +426,12 @@
434
  text-align: center;
435
  }
436
  #softDrinkModal .modal-body img {
437
- width: 160px;
438
- height: 160px;
439
  object-fit: cover;
440
- aspect-ratio: 1/1;
441
  border-radius: 8px;
442
  margin-bottom: 15px;
443
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
444
- transition: transform 0.3s ease;
445
- }
446
- #softDrinkModal .modal-body img:hover {
447
- transform: scale(1.05);
448
  }
449
  #softDrinkModal .modal-body h5 {
450
  font-size: 1.4rem;
@@ -472,27 +459,26 @@
472
  margin-bottom: 20px;
473
  }
474
  #softDrinkModal .quantity-controls .btn {
475
- width: 48px;
476
- height: 48px;
477
  border-radius: 50%;
478
  padding: 0;
479
- font-size: 1.4rem;
480
- line-height: 48px;
481
  text-align: center;
482
  background-color: #e9ecef;
483
  border: none;
484
  color: #333;
485
- transition: background-color 0.2s ease, transform 0.2s ease;
486
  }
487
  #softDrinkModal .quantity-controls .btn:hover {
488
  background-color: #d1d4d7;
489
- transform: scale(1.1);
490
  }
491
  #softDrinkModal .quantity-controls input {
492
  width: 60px;
493
- height: 48px;
494
  text-align: center;
495
- font-size: 1.2rem;
496
  font-weight: 600;
497
  border: 1px solid #ced4da;
498
  border-radius: 6px;
@@ -507,59 +493,18 @@
507
  #softDrinkModal .modal-footer .btn-primary {
508
  background-color: #0FAA39;
509
  border-color: #0FAA39;
510
- padding: 12px 40px;
511
  text-align: center;
512
- font-size: 1.1rem;
513
  font-weight: 600;
514
  border-radius: 8px;
515
- transition: background-color 0.2s ease, transform 0.2s ease;
516
  width: auto;
517
  }
518
  #softDrinkModal .modal-footer .btn-primary:hover {
519
  background-color: #0D9232;
520
- transform: scale(1.05);
521
- }
522
- /* Item Modal Styling */
523
- #itemModal .modal-dialog {
524
- max-width: 500px;
525
- margin: 1.75rem auto;
526
- animation: fadeInModal 0.3s ease-out;
527
- }
528
- #itemModal .modal-content {
529
- border-radius: 12px;
530
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
531
- background: linear-gradient(180deg, #ffffff, #f8f9fa);
532
- overflow: hidden;
533
- }
534
- #itemModal .modal-header {
535
- background: linear-gradient(45deg, #FFA07A, #FFB347);
536
- border-top-left-radius: 12px;
537
- border-top-right-radius: 12px;
538
- padding: 12px 15px;
539
- border-bottom: none;
540
- }
541
- #itemModal .modal-title {
542
- font-size: 1.3rem;
543
- font-weight: 600;
544
- color: #fff;
545
- }
546
- #itemModal .modal-body {
547
- padding: 20px;
548
- }
549
- #itemModal .modal-body img {
550
- width: 200px;
551
- height: 200px;
552
- object-fit: cover;
553
- aspect-ratio: 1/1;
554
- border-radius: 8px;
555
- margin: 0 auto 15px;
556
- display: block;
557
- box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
558
- transition: transform 0.3s ease;
559
- }
560
- #itemModal .modal-body img:hover {
561
- transform: scale(1.05);
562
  }
 
563
  #itemModal .quantity-controls {
564
  display: flex;
565
  justify-content: center;
@@ -568,45 +513,31 @@
568
  margin-bottom: 20px;
569
  }
570
  #itemModal .quantity-controls .btn {
571
- width: 48px;
572
- height: 48px;
573
  border-radius: 50%;
574
  padding: 0;
575
- font-size: 1.4rem;
576
- line-height: 48px;
577
  text-align: center;
578
  background-color: #e9ecef;
579
  border: none;
580
  color: #333;
581
- transition: background-color 0.2s ease, transform 0.2s ease;
582
  }
583
  #itemModal .quantity-controls .btn:hover {
584
  background-color: #d1d4d7;
585
- transform: scale(1.1);
586
  }
587
  #itemModal .quantity-controls input {
588
  width: 60px;
589
- height: 48px;
590
  text-align: center;
591
- font-size: 1.2rem;
592
  font-weight: 600;
593
  border: 1px solid #ced4da;
594
  border-radius: 6px;
595
  background-color: #f8f9fa;
596
  }
597
- #itemModal .modal-footer .btn-primary {
598
- background-color: #0FAA39;
599
- border-color: #0FAA39;
600
- padding: 12px 40px;
601
- font-size: 1.1rem;
602
- font-weight: 600;
603
- border-radius: 8px;
604
- transition: background-color 0.2s ease, transform 0.2s ease;
605
- }
606
- #itemModal .modal-footer .btn-primary:hover {
607
- background-color: #0D9232;
608
- transform: scale(1.05);
609
- }
610
  /* Filter Form Styling */
611
  #filter-form {
612
  display: flex;
@@ -675,7 +606,7 @@
675
  #micModal .modal-content {
676
  border-radius: 12px;
677
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
678
- background: linear-gradient(180deg, #ffffff, #f8f9fa);
679
  text-align: center;
680
  }
681
  #micModal .modal-header {
@@ -698,47 +629,24 @@
698
  align-items: center;
699
  gap: 15px;
700
  min-height: 200px;
701
- position: relative;
702
  }
703
  #micModal .modal-body i#mic-icon-animation {
704
  font-size: 2.5rem;
705
- color: #DC3545;
706
- position: relative;
707
  animation: pulse 2s infinite;
708
  }
709
- #micModal .modal-body i#mic-icon-animation::before {
710
- content: '';
711
- position: absolute;
712
- top: -10px;
713
- left: -10px;
714
- right: -10px;
715
- bottom: -10px;
716
- border: 2px solid #DC3545;
717
- border-radius: 50%;
718
- opacity: 0.5;
719
- animation: ripple 2s infinite;
720
- }
721
  #micModal .modal-body p#mic-status {
722
  font-size: 1.1rem;
723
  color: #333;
724
  margin: 0;
725
  }
726
  #micModal .modal-body #mic-item-image {
727
- width: 150px;
728
- height: 150px;
729
  object-fit: cover;
730
- aspect-ratio: 1/1;
731
  border-radius: 8px;
732
  margin-bottom: 10px;
733
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
734
- animation: fadeIn 0.3s ease;
735
- }
736
- #micModal .modal-body #mic-item-name {
737
- font-size: 1.2rem;
738
- font-weight: 600;
739
- color: #333;
740
- margin-bottom: 10px;
741
- animation: fadeIn 0.3s ease;
742
  }
743
  #micModal .modal-body #mic-item-details.show {
744
  animation: fadeIn 0.3s ease;
@@ -754,63 +662,11 @@
754
  padding: 10px 20px;
755
  font-size: 1rem;
756
  border-radius: 8px;
757
- transition: background-color 0.2s ease, transform 0.2s ease;
758
  }
759
  #micModal .modal-footer .btn-secondary:hover {
760
  background-color: #5a6268;
761
- transform: scale(1.05);
762
- }
763
- /* Search Suggestions Styling */
764
- .autocomplete-suggestions {
765
- position: absolute;
766
- top: 100%;
767
- left: 0;
768
- right: 0;
769
- background-color: #fff;
770
- border: 1px solid #ced4da;
771
- border-radius: 8px;
772
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
773
- max-height: 200px;
774
- overflow-y: auto;
775
- z-index: 1000;
776
- display: none;
777
- animation: slideDown 0.3s ease-out;
778
- }
779
- .autocomplete-suggestion {
780
- display: flex;
781
- align-items: center;
782
- padding: 8px 12px;
783
- cursor: pointer;
784
- font-size: 0.9rem;
785
- color: #333;
786
- transition: background-color 0.2s ease, transform 0.2s ease;
787
- }
788
- .autocomplete-suggestion:hover {
789
- background-color: #e6f4ea;
790
- transform: translateX(5px);
791
- }
792
- .autocomplete-suggestion img {
793
- width: 40px;
794
- height: 40px;
795
- object-fit: cover;
796
- border-radius: 4px;
797
- margin-right: 10px;
798
  }
799
- .autocomplete-suggestions::-webkit-scrollbar {
800
- width: 6px;
801
- }
802
- .autocomplete-suggestions::-webkit-scrollbar-track {
803
- background: #f1f1f1;
804
- border-radius: 10px;
805
- }
806
- .autocomplete-suggestions::-webkit-scrollbar-thumb {
807
- background: #0FAA39;
808
- border-radius: 10px;
809
- }
810
- .autocomplete-suggestions::-webkit-scrollbar-thumb:hover {
811
- background: #0D9232;
812
- }
813
- /* Animations */
814
  @keyframes checkmark {
815
  from { transform: scale(0); }
816
  to { transform: scale(1); }
@@ -832,17 +688,6 @@
832
  50% { transform: scale(1.2); }
833
  100% { transform: scale(1); }
834
  }
835
- @keyframes pulseMic {
836
- 0% { transform: scale(1); }
837
- 50% { transform: scale(1.15); }
838
- 100% { transform: scale(1); }
839
- }
840
- @keyframes ripple {
841
- 0% { transform: scale(0.8); opacity: 0.5; }
842
- 50% { transform: scale(1.2); opacity: 0.2; }
843
- 100% { transform: scale(1.6); opacity: 0; }
844
- }
845
- /* Modal General Styles */
846
  .modal-header {
847
  padding: 10px 15px;
848
  }
@@ -856,15 +701,11 @@
856
  padding: 15px;
857
  }
858
  .modal-body #modal-img {
859
- width: 200px;
860
- height: 200px;
861
  object-fit: cover;
862
- aspect-ratio: 1/1;
863
  border-radius: 8px;
864
  margin-bottom: 10px;
865
- display: block;
866
- margin-left: auto;
867
- margin-right: auto;
868
  }
869
  .modal-body #modal-name {
870
  font-size: 20px;
@@ -1063,10 +904,6 @@
1063
  text-align: center;
1064
  min-width: 0;
1065
  white-space: nowrap;
1066
- transition: transform 0.2s ease;
1067
- }
1068
- .bottom-action-bar .btn:hover {
1069
- transform: scale(1.05);
1070
  }
1071
  .bottom-action-bar .btn-order-history {
1072
  background: linear-gradient(45deg, #FF8C00, #32CD32);
@@ -1075,6 +912,7 @@
1075
  }
1076
  .bottom-action-bar .btn-order-history:hover {
1077
  background: linear-gradient(45deg, #FF4500, #228B22);
 
1078
  color: #000000;
1079
  }
1080
  .bottom-action-bar .btn-view-cart {
@@ -1084,6 +922,7 @@
1084
  }
1085
  .bottom-action-bar .btn-view-cart:hover {
1086
  background-color: #0D9232;
 
1087
  color: white;
1088
  }
1089
  .cart-icon-badge {
@@ -1097,7 +936,6 @@
1097
  justify-content: center;
1098
  font-size: 12px;
1099
  margin-left: 8px;
1100
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
1101
  }
1102
  /* Mobile-Specific Styles */
1103
  @media (max-width: 576px) {
@@ -1135,16 +973,16 @@
1135
  }
1136
  .dropdown-menu {
1137
  width: 200px;
1138
- border-radius: 10px;
1139
- padding: 10px 0;
1140
  }
1141
  .dropdown-menu .dropdown-item {
1142
- padding: 10px 15px;
1143
- font-size: 14px;
1144
  }
1145
  .dropdown-menu .dropdown-item i {
1146
- font-size: 16px;
1147
- margin-right: 10px;
1148
  }
1149
  .modal-dialog {
1150
  max-width: 90%;
@@ -1161,8 +999,9 @@
1161
  padding: 12px;
1162
  }
1163
  .modal-body #modal-img {
1164
- width: 150px;
1165
- height: 150px;
 
1166
  margin: 0 auto 8px;
1167
  display: block;
1168
  }
@@ -1304,8 +1143,7 @@
1304
  padding: 15px;
1305
  }
1306
  #softDrinkModal .modal-body img {
1307
- width: 130px;
1308
- height: 130px;
1309
  margin-bottom: 12px;
1310
  }
1311
  #softDrinkModal .modal-body h5 {
@@ -1317,45 +1155,38 @@
1317
  margin-bottom: 15px;
1318
  }
1319
  #softDrinkModal .quantity-controls .btn {
1320
- width: 40px;
1321
- height: 40px;
1322
- font-size: 1.2rem;
1323
- line-height: 40px;
1324
  }
1325
  #softDrinkModal .quantity-controls input {
1326
  width: 50px;
1327
- height: 40px;
1328
- font-size: 1rem;
1329
  }
1330
  #softDrinkModal .modal-footer {
1331
  padding: 10px;
1332
  }
1333
  #softDrinkModal .modal-footer .btn-primary {
1334
- padding: 10px 30px;
1335
- font-size: 1rem;
1336
  }
1337
  /* Mobile-Specific Item Modal Styles */
1338
- #itemModal .modal-dialog {
1339
- max-width: 90%;
1340
- }
1341
- #itemModal .modal-body img {
1342
- width: 150px;
1343
- height: 150px;
1344
- }
1345
  #itemModal .quantity-controls .btn {
1346
- width: 40px;
1347
- height: 40px;
1348
- font-size: 1.2rem;
1349
- line-height: 40px;
1350
  }
1351
  #itemModal .quantity-controls input {
1352
  width: 50px;
1353
- height: 40px;
1354
- font-size: 1rem;
1355
  }
1356
  #itemModal .modal-footer .btn-primary {
1357
- padding: 10px 30px;
1358
- font-size: 1rem;
1359
  }
1360
  /* Mobile-Specific Filter Form Styles */
1361
  #filter-form {
@@ -1394,8 +1225,7 @@
1394
  font-size: 1rem;
1395
  }
1396
  #micModal .modal-body #mic-item-image {
1397
- width: 120px;
1398
- height: 120px;
1399
  margin-bottom: 8px;
1400
  }
1401
  #micModal .modal-body #mic-item-name {
@@ -1406,10 +1236,43 @@
1406
  padding: 8px 15px;
1407
  font-size: 0.9rem;
1408
  }
1409
- .autocomplete-suggestion img {
1410
- width: 32px;
1411
- height: 32px;
1412
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1413
  }
1414
  </style>
1415
  </head>
@@ -1430,7 +1293,6 @@
1430
  <input type="text" id="searchBar" class="form-control" placeholder="Search items or sections..." autocomplete="off">
1431
  <i class="bi bi-search search-icon"></i>
1432
  <i class="bi bi-mic mic-icon" id="micIcon"></i>
1433
- <div id="searchSuggestions" class="autocomplete-suggestions"></div>
1434
  </div>
1435
  </div>
1436
 
@@ -1439,7 +1301,7 @@
1439
  <div class="toggle-container">
1440
  <!-- Veg Only Toggle -->
1441
  <input type="checkbox" id="veg-toggle" name="veg"
1442
- {% if veg == "Veg" %}checked{% endif %}
1443
  class="custom-toggle" onchange="handleToggle('veg')"
1444
  aria-label="Toggle Vegetarian filter">
1445
  <label for="veg-toggle">Veg</label>
@@ -1463,9 +1325,10 @@
1463
  <label for="custom-dish-name" class="form-label">Dish Name</label>
1464
  <input type="text" class="form-control" id="custom-dish-name" name="name" required>
1465
  </div>
1466
- <div class="mb-3">
1467
  <label for="custom-dish-description" class="form-label">Dish Description</label>
1468
  <textarea class="form-control" id="custom-dish-description" name="description" required></textarea>
 
1469
  </div>
1470
  <button type="submit" class="btn btn-primary">Submit Custom Dish</button>
1471
  </form>
@@ -1516,14 +1379,14 @@
1516
  data-item-section="{{ item.Section__c | default(section) }}"
1517
  data-item-category="{{ selected_category }}"
1518
  data-item-description="{{ item.Description__c | default('No description') }}"
1519
- data-item-image2="{{ item.Image2__c | default(item.Image1__c) | default('/static/placeholder.jpg') }}">
1520
  {% if item.Section__c == 'Soft Drinks' %}
1521
  <button class="btn btn-primary add-to-cart-btn" onclick="showSoftDrinkModal(this)">ADD</button>
1522
  {% else %}
1523
  <button class="btn btn-primary"
1524
  data-bs-toggle="modal"
1525
  data-bs-target="#itemModal"
1526
- onclick="showItemDetails('{{ item.Name | default('Unnamed Item') }}', '{{ item.Price__c | default('0.00') }}', '{{ item.Image2__c if item.Image2__c else item.Image1__c | default('/static/placeholder.jpg') }}', '{{ item.Description__c | default('No description') }}', '{{ item.Section__c | default(section) }}', '{{ selected_category }}')">
1527
  ADD
1528
  </button>
1529
  {% if item.Section__c != 'Apetizer' and item.Section__c != 'Customized dish' %}
@@ -1575,7 +1438,7 @@
1575
  <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
1576
  </div>
1577
  <div class="modal-body">
1578
- <img id="modal-img" class="img-fluid rounded mb-3 d-block mx-auto" alt="Item Image" loading="lazy" decoding="async">
1579
  <h5 id="modal-name" class="fw-bold text-center"></h5>
1580
  <p id="modal-price" class="text-muted text-center"></p>
1581
  <p id="modal-description" class="text-secondary"></p>
@@ -1662,15 +1525,26 @@
1662
  {
1663
  name: "{{ item.Name | default('Unnamed Item') }}",
1664
  section: "{{ item.Section__c | default(section) }}",
1665
- image: "{{ item.Image1__c | default('/static/placeholder.jpg') }}",
1666
- price: "{{ item.Price__c | default('0.00') }}",
1667
- image2: "{{ item.Image2__c if item.Image2__c else item.Image1__c | default('/static/placeholder.jpg') }}",
1668
- description: "{{ item.Description__c | default('No description') }}",
1669
- category: "{{ selected_category }}"
1670
  },
1671
  {% endfor %}
1672
  {% endfor %}
1673
  ];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1674
  function addToCartLocalStorage(payload) {
1675
  let cart = JSON.parse(localStorage.getItem('cart')) || [];
1676
  const existingItem = cart.find(item =>
@@ -1825,426 +1699,473 @@
1825
  modalSectionEl.setAttribute('data-section', section);
1826
  modalSectionEl.setAttribute('data-category', selectedCategory);
1827
  document.getElementById('quantityInput').value = 1;
1828
- const isVegFilter = document.getElementById('veg-toggle').checked;
1829
- const vegParam = isVegFilter ? '&veg=Veg' : '';
1830
- fetch(`/api/addons?item_name=${encodeURIComponent(name)}&item_section=${encodeURIComponent(section)}${vegParam}`)
1831
  .then(response => response.json())
1832
  .then(data => {
1833
  const addonsList = document.getElementById('addons-list');
1834
  addonsList.classList.remove('addon-loading');
1835
  addonsList.innerHTML = '';
1836
  if (!data.success || !data.addons || data.addons.length === 0) {
1837
- const noAddonsMessage = document.createElement('p');
1838
- noAddonsMessage.textContent = 'No add-ons available for this item.';
1839
- noAddonsMessage.className = 'text-muted';
1840
- addonsList.appendChild(noAddonsMessage);
1841
- } else {
1842
- data.addons.forEach(addon => {
1843
- const addonSection = document.createElement('div');
1844
- addonSection.className = 'addon-section';
1845
- const addonHeader = document.createElement('h6');
1846
- addonHeader.textContent = addon.section;
1847
- addonHeader.setAttribute('data-bs-toggle', 'collapse');
1848
- addonHeader.setAttribute('data-bs-target', `#addon-collapse-${addon.section.replace(/\s+/g, '-')}`);
1849
- addonHeader.setAttribute('aria-expanded', 'true');
1850
- addonHeader.setAttribute('aria-controls', `addon-collapse-${addon.section.replace(/\s+/g, '-')}`);
1851
- addonSection.appendChild(addonHeader);
1852
- const addonCollapse = document.createElement('div');
1853
- addonCollapse.id = `addon-collapse-${addon.section.replace(/\s+/g, '-')}`;
1854
- addonCollapse.className = 'addon-options collapse show';
1855
- addon.items.forEach(item => {
1856
- const addonItem = document.createElement('div');
1857
- addonItem.className = 'form-check';
1858
- const input = document.createElement('input');
1859
- input.type = 'checkbox';
1860
- input.className = 'form-check-input';
1861
- input.id = `addon-${item.name.replace(/\s+/g, '-')}`;
1862
- input.setAttribute('data-price', item.price || 0);
1863
- input.setAttribute('data-name', item.name);
1864
- input.setAttribute('data-section', addon.section);
1865
- input.addEventListener('change', updateModalPrice);
1866
- const label = document.createElement('label');
1867
- label.className = 'form-check-label';
1868
- label.htmlFor = `addon-${item.name.replace(/\s+/g, '-')}`;
1869
- label.textContent = item.name;
1870
- if (item.price > 0) {
1871
- const priceSpan = document.createElement('span');
1872
- priceSpan.className = 'extra-charge';
1873
- priceSpan.textContent = `+$${parseFloat(item.price).toFixed(2)}`;
1874
- label.appendChild(priceSpan);
1875
- }
1876
- addonItem.appendChild(input);
1877
- addonItem.appendChild(label);
1878
- addonCollapse.appendChild(addonItem);
1879
- });
1880
- addonSection.appendChild(addonCollapse);
1881
- addonsList.appendChild(addonSection);
1882
- });
1883
- }
1884
- })
1885
- .catch(err => {
1886
- console.error('Error fetching addons:', err);
1887
- const addonsList = document.getElementById('addons-list');
1888
- addonsList.classList.remove('addon-loading');
1889
- addonsList.innerHTML = '<p class="text-muted">Failed to load add-ons.</p>';
1890
- });
1891
- }
1892
- function addToCartFromModal() {
1893
- if (isProcessingRequest) return;
1894
- isProcessingRequest = true;
1895
- const itemName = document.getElementById('modal-name').innerText;
1896
- const quantity = parseInt(document.getElementById('quantityInput').value) || 1;
1897
- const instructions = document.getElementById('modal-instructions').value;
1898
- const selectedAddOns = Array.from(
1899
- document.querySelectorAll('#addons-list input[type="checkbox"]:checked')
1900
- ).map(addon => ({
1901
- section: addon.getAttribute('data-section'),
1902
- name: addon.getAttribute('data-name'),
1903
- price: parseFloat(addon.getAttribute('data-price')) || 0
1904
- }));
1905
- const modalSectionEl = document.getElementById('modal-section');
1906
- const section = modalSectionEl.getAttribute('data-section');
1907
- const selectedCategory = modalSectionEl.getAttribute('data-category');
1908
- const totalAddOnPrice = selectedAddOns.reduce((sum, addon) => sum + addon.price, 0);
1909
- const totalPrice = (baseItemPrice + totalAddOnPrice);
1910
- const modalImg = document.getElementById('modal-img').src;
1911
- const cartPayload = {
1912
- itemName: itemName,
1913
- itemPrice: totalPrice,
1914
- itemImage: modalImg,
1915
- section: section,
1916
- category: selectedCategory,
1917
- addons: selectedAddOns,
1918
- instructions: instructions,
1919
- quantity: quantity
1920
- };
1921
- fetch('/cart/add', {
1922
- method: 'POST',
1923
- headers: {
1924
- 'Content-Type': 'application/json',
1925
- },
1926
- body: JSON.stringify(cartPayload)
1927
- })
1928
- .then(response => response.json())
1929
- .then(data => {
1930
- isProcessingRequest = false;
1931
- if (data.success) {
1932
- updateCartUI(data.cart);
1933
- const modal = bootstrap.Modal.getInstance(document.getElementById('itemModal'));
1934
- modal.hide();
1935
- } else {
1936
- console.error('Failed to add item to cart:', data.error);
1937
- const cart = addToCartLocalStorage(cartPayload);
1938
- updateCartUI(cart);
1939
- const modal = bootstrap.Modal.getInstance(document.getElementById('itemModal'));
1940
- modal.hide();
1941
- }
1942
- })
1943
- .catch(err => {
1944
- isProcessingRequest = false;
1945
- console.error('Error adding item to cart:', err);
1946
- const cart = addToCartLocalStorage(cartPayload);
1947
- updateCartUI(cart);
1948
- const modal = bootstrap.Modal.getInstance(document.getElementById('itemModal'));
1949
- modal.hide();
1950
- });
1951
- }
1952
- function resetMicModal() {
1953
- const micStatus = document.getElementById('mic-status');
1954
- const micItemDetails = document.getElementById('mic-item-details');
1955
- const micItemName = document.getElementById('mic-item-name');
1956
- const micItemImage = document.getElementById('mic-item-image');
1957
- micStatus.textContent = 'Say the name of a menu item...';
1958
- micStatus.style.display = 'block';
1959
- micItemDetails.style.display = 'none';
1960
- micItemName.textContent = '';
1961
- micItemImage.src = '/static/placeholder.jpg';
1962
- }
1963
- function stopSpeechRecognition() {
1964
- if (recognition) {
1965
- recognition.stop();
1966
- const micModal = bootstrap.Modal.getInstance(document.getElementById('micModal'));
1967
- if (micModal) {
1968
- micModal.hide();
1969
- resetMicModal();
1970
- }
1971
- }
1972
- }
1973
- function handleToggle(toggleType) {
1974
- const vegToggle = document.getElementById('veg-toggle');
1975
- const customToggle = document.getElementById('category-CustomizedDish');
1976
- let url = '/menu?';
1977
- const params = [];
1978
- if (toggleType === 'veg' && vegToggle.checked) {
1979
- params.push('veg=Veg');
1980
- customToggle.checked = false;
1981
- } else if (toggleType === 'custom' && customToggle.checked) {
1982
- params.push('category=Customized+Dish');
1983
- vegToggle.checked = false;
1984
- }
1985
- url += params.join('&');
1986
- window.location.href = url;
1987
- }
1988
- document.addEventListener('DOMContentLoaded', function () {
1989
- const avatarIcon = document.querySelector('.avatar-icon');
1990
- const dropdownMenu = document.querySelector('.dropdown-menu');
1991
- avatarIcon.addEventListener('click', function () {
1992
- dropdownMenu.classList.toggle('show');
1993
- });
1994
- document.addEventListener('click', function (event) {
1995
- if (!avatarIcon.contains(event.target) && !dropdownMenu.contains(event.target)) {
1996
- dropdownMenu.classList.remove('show');
1997
- }
1998
- });
1999
- const searchBar = document.getElementById('searchBar');
2000
- const searchSuggestions = document.getElementById('searchSuggestions');
2001
- searchBar.addEventListener('input', debounce(function () {
2002
- const query = searchBar.value.trim().toLowerCase();
2003
- searchSuggestions.innerHTML = '';
2004
- if (query.length < 2) {
2005
- searchSuggestions.style.display = 'none';
2006
- return;
2007
- }
2008
- const filteredItems = menuItems.filter(item =>
2009
- item.name.toLowerCase().includes(query) || item.section.toLowerCase().includes(query)
2010
- );
2011
- if (filteredItems.length === 0) {
2012
- searchSuggestions.style.display = 'none';
2013
- return;
2014
- }
2015
- filteredItems.forEach(item => {
2016
- const suggestion = document.createElement('div');
2017
- suggestion.classList.add('autocomplete-suggestion');
2018
- const img = document.createElement('img');
2019
- img.src = item.image || '/static/placeholder.jpg';
2020
- img.alt = item.name;
2021
- suggestion.appendChild(img);
2022
- const text = document.createElement('span');
2023
- text.textContent = item.name;
2024
- suggestion.appendChild(text);
2025
- suggestion.addEventListener('click', () => {
2026
- const card = document.querySelector(`.menu-card[data-item-name="${item.name}"]`);
2027
- if (card) {
2028
- card.scrollIntoView({ behavior: 'smooth', block: 'center' });
2029
- card.classList.add('highlighted');
2030
- setTimeout(() => card.classList.remove('highlighted'), 2000);
2031
- const buttonContainer = card.querySelector('.button-container');
2032
- if (item.section === 'Soft Drinks') {
2033
- showSoftDrinkModal(buttonContainer.querySelector('.add-to-cart-btn'));
2034
- } else {
2035
- showItemDetails(
2036
- item.name,
2037
- item.price,
2038
- item.image2 || item.image,
2039
- item.description,
2040
- item.section,
2041
- item.category
2042
- );
2043
- const modal = new bootstrap.Modal(document.getElementById('itemModal'));
2044
- modal.show();
2045
  }
2046
- searchBar.value = '';
2047
- searchSuggestions.innerHTML = '';
2048
- searchSuggestions.style.display = 'none';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2049
  }
 
 
 
 
 
 
 
 
 
 
2050
  });
2051
- searchSuggestions.appendChild(suggestion);
2052
- });
2053
- searchSuggestions.style.display = 'block';
2054
- }, 300));
2055
- document.addEventListener('click', function (event) {
2056
- if (!searchBar.contains(event.target) && !searchSuggestions.contains(event.target)) {
2057
- searchSuggestions.style.display = 'none';
2058
- }
2059
- });
2060
- if (localStorage.getItem('selectedItem')) {
2061
- try {
2062
- const selectedItem = JSON.parse(localStorage.getItem('selectedItem'));
2063
- const card = document.querySelector(`.menu-card[data-item-name="${selectedItem.name}"]`);
2064
- if (card) {
2065
- card.scrollIntoView({ behavior: 'smooth', block: 'center' });
2066
- card.classList.add('highlighted');
2067
- setTimeout(() => card.classList.remove('highlighted'), 2000);
2068
- const buttonContainer = card.querySelector('.button-container');
2069
- if (selectedItem.section === 'Soft Drinks') {
2070
- showSoftDrinkModal(buttonContainer.querySelector('.add-to-cart-btn'));
2071
- } else {
2072
- showItemDetails(
2073
- selectedItem.name,
2074
- selectedItem.price,
2075
- selectedItem.image2 || selectedItem.image,
2076
- selectedItem.description,
2077
- selectedItem.section,
2078
- selectedItem.category
2079
- );
2080
- const modal = new bootstrap.Modal(document.getElementById('itemModal'));
2081
- modal.show();
2082
  }
2083
  }
2084
- localStorage.removeItem('selectedItem');
2085
- } catch (err) {
2086
- console.error('Error processing selected item:', err);
2087
- localStorage.removeItem('selectedItem');
2088
- }
2089
- }
2090
- document.querySelectorAll('.media-wrapper').forEach(wrapper => {
2091
- const video = wrapper.querySelector('.menu-video');
2092
- const image = wrapper.querySelector('.menu-image');
2093
- wrapper.addEventListener('mouseenter', () => {
2094
- image.classList.add('hidden');
2095
- video.classList.add('active');
2096
- video.play().catch(err => {
2097
- console.error('Video playback failed:', err);
2098
- image.classList.remove('hidden');
2099
- video.classList.remove('active');
2100
- });
2101
- });
2102
- wrapper.addEventListener('mouseleave', () => {
2103
- video.classList.remove('active');
2104
- video.pause();
2105
- video.currentTime = 0;
2106
- image.classList.remove('hidden');
2107
- });
2108
- let touchTimeout;
2109
- wrapper.addEventListener('touchstart', (e) => {
2110
- e.preventDefault();
2111
- clearTimeout(touchTimeout);
2112
- wrapper.classList.add('touched');
2113
- image.classList.add('hidden');
2114
- video.classList.add('active');
2115
- video.play().catch(err => {
2116
- console.error('Video playback failed:', err);
2117
- image.classList.remove('hidden');
2118
- video.classList.remove('active');
2119
- wrapper.classList.remove('touched');
2120
- });
2121
- });
2122
- wrapper.addEventListener('touchend', () => {
2123
- touchTimeout = setTimeout(() => {
2124
- video.pause();
2125
- video.classList.remove('active');
2126
- image.classList.remove('hidden');
2127
- wrapper.classList.remove('touched');
2128
- }, 500);
2129
- });
2130
- });
2131
- const decreaseBtn = document.getElementById('decreaseQuantity');
2132
- const increaseBtn = document.getElementById('increaseQuantity');
2133
- const quantityInput = document.getElementById('quantityInput');
2134
- decreaseBtn.addEventListener('click', () => {
2135
- let value = parseInt(quantityInput.value) || 1;
2136
- if (value > 1) {
2137
- quantityInput.value = value - 1;
2138
- }
2139
- });
2140
- increaseBtn.addEventListener('click', () => {
2141
- let value = parseInt(quantityInput.value) || 1;
2142
- quantityInput.value = value + 1;
2143
- });
2144
- document.querySelectorAll('.toggle-details').forEach(link => {
2145
- link.addEventListener('click', () => {
2146
- const details = link.nextElementSibling;
2147
- if (details.classList.contains('show')) {
2148
- details.classList.remove('show');
2149
- link.textContent = 'Show Details';
2150
- } else {
2151
- details.classList.add('show');
2152
- link.textContent = 'Hide Details';
2153
  }
2154
- });
2155
- });
2156
- fetch('/cart')
2157
- .then(response => response.json())
2158
- .then(data => {
2159
- if (data.success) {
2160
- updateCartUI(data.cart);
2161
- } else {
2162
- updateCartUI(getCartLocalStorage());
 
 
2163
  }
2164
- })
2165
- .catch(err => {
2166
- console.error('Error fetching cart:', err);
2167
- updateCartUI(getCartLocalStorage());
2168
- });
2169
- if ('webkitSpeechRecognition' in window) {
2170
- recognition = new webkitSpeechRecognition();
2171
- recognition.continuous = false;
2172
- recognition.interimResults = false;
2173
- recognition.lang = 'en-US';
2174
- recognition.onstart = () => {
2175
- document.getElementById('mic-icon-animation').classList.add('active');
2176
- document.getElementById('mic-status').textContent = 'Listening...';
2177
- };
2178
- recognition.onresult = (event) => {
2179
- const transcript = event.results[0][0].transcript.trim().toLowerCase();
2180
- console.log('Recognized speech:', transcript);
2181
- const matchedItem = menuItems.find(item =>
2182
- item.name.toLowerCase().includes(transcript)
2183
- );
2184
- if (matchedItem) {
2185
- const micStatus = document.getElementById('mic-status');
2186
- const micItemDetails = document.getElementById('mic-item-details');
2187
- const micItemName = document.getElementById('mic-item-name');
2188
- const micItemImage = document.getElementById('mic-item-image');
2189
- micStatus.style.display = 'none';
2190
- micItemDetails.style.display = 'block';
2191
- micItemName.textContent = matchedItem.name;
2192
- micItemImage.src = matchedItem.image || '/static/placeholder.jpg';
2193
- setTimeout(() => {
2194
- recognition.stop();
2195
- const card = document.querySelector(`.menu-card[data-item-name="${matchedItem.name}"]`);
2196
- if (card) {
2197
- card.classList.add('highlighted');
2198
- card.scrollIntoView({ behavior: 'smooth', block: 'center' });
2199
- setTimeout(() => card.classList.remove('highlighted'), 2000);
2200
- const buttonContainer = card.querySelector('.button-container');
2201
- if (buttonContainer) {
2202
- if (matchedItem.section === 'Soft Drinks') {
2203
- showSoftDrinkModal(buttonContainer.querySelector('.add-to-cart-btn'));
2204
- } else {
2205
- showItemDetails(
2206
- matchedItem.name,
2207
- matchedItem.price,
2208
- matchedItem.image2 || matchedItem.image,
2209
- matchedItem.description,
2210
- matchedItem.section,
2211
- matchedItem.category
2212
- );
2213
- const modal = new bootstrap.Modal(document.getElementById('itemModal'));
2214
- modal.show();
2215
- }
2216
- }
2217
- const micModal = bootstrap.Modal.getInstance(document.getElementById('micModal'));
2218
- if (micModal) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2219
  micModal.hide();
2220
  resetMicModal();
2221
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2222
  }
2223
- }, 2000);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2224
  } else {
2225
- document.getElementById('mic-status').textContent = 'Item not found. Try again.';
2226
- }
2227
- };
2228
- recognition.onerror = (event) => {
2229
- console.error('Speech recognition error:', event.error);
2230
- document.getElementById('mic-status').textContent = 'Error occurred. Please try again.';
2231
- document.getElementById('mic-icon-animation').classList.remove('active');
2232
- };
2233
- recognition.onend = () => {
2234
- document.getElementById('mic-icon-animation').classList.remove('active');
2235
- };
2236
- document.getElementById('micIcon').addEventListener('click', () => {
2237
- if (!recognition) return;
2238
- const micModal = new bootstrap.Modal(document.getElementById('micModal'));
2239
- micModal.show();
2240
- resetMicModal();
2241
- recognition.start();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2242
  });
2243
- document.getElementById('stopMicBtn').addEventListener('click', stopSpeechRecognition);
2244
- } else {
2245
- document.getElementById('micIcon').style.display = 'none';
2246
- }
2247
- });
2248
- </script>
2249
  </body>
2250
- </html>
 
 
36
  display: flex;
37
  flex-direction: column;
38
  box-shadow: 0 4px 8px rgba(0,0,0,0.1);
 
 
 
 
39
  }
40
  .menu-card.highlighted {
41
  border: 3px solid #0FAA39;
 
73
  width: 100%;
74
  height: 100%;
75
  object-fit: cover;
 
76
  opacity: 1;
77
  transition: opacity 0.3s ease;
78
  }
 
92
  margin-bottom: 5px;
93
  }
94
  .addbutton .btn {
95
+ background-color: #28a745;
96
  color: white;
97
  padding: 10px 20px;
98
  font-size: 16px;
99
  font-weight: bold;
100
+ border-radius: 5px;
101
  border: none;
102
+ transition: background-color 0.3s ease;
103
  margin-left: 13px;
104
  }
105
  .addbutton .btn:hover {
106
+ background-color: #218838;
 
107
  }
108
  .button-container {
109
  display: flex;
 
132
  align-items: center;
133
  justify-content: center;
134
  padding: 0;
135
+ transition: background-color 0.3s ease;
136
  }
137
  .btn-primary:hover {
138
  background-color: #0D9232;
139
  border-color: #0D9232;
 
140
  }
141
  .btn-primary:active,
142
  .btn-primary:focus {
 
157
  width: 40px;
158
  height: 40px;
159
  border-radius: 50%;
160
+ background: linear-gradient(45deg, #FF4500, #000000, #1E90FF);
161
  cursor: pointer;
162
  display: flex;
163
  align-items: center;
 
169
  }
170
  .avatar-icon:hover {
171
  transform: scale(1.1);
172
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
173
  }
174
  .dropdown-menu {
175
  position: absolute;
176
  right: 0;
177
  top: 100%;
178
+ background: linear-gradient(135deg, #ffffff, #f8f9fa);
179
  border-radius: 12px;
180
  width: 240px;
181
  box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
182
  display: none;
183
+ border: 1px solid rgba(0, 0, 0, 0.05);
184
  padding: 12px 0;
185
  animation: slideDown 0.3s ease-out;
186
  z-index: 1000;
187
+ font-family: 'Segoe UI', Arial, sans-serif;
188
  }
189
  .dropdown-menu.show {
190
  display: block;
 
192
  .dropdown-menu .dropdown-item {
193
  padding: 12px 18px;
194
  text-decoration: none;
195
+ color: #2c3e50;
196
  display: flex;
197
  align-items: center;
198
  font-size: 15px;
199
  font-weight: 500;
200
+ transition: all 0.2s ease;
201
+ border-radius: 8px;
202
+ margin: 0 8px;
203
  }
204
  .dropdown-menu .dropdown-item i {
205
  margin-right: 12px;
206
  font-size: 18px;
207
  color: #0FAA39;
208
+ transition: color 0.2s ease;
209
  }
210
  .dropdown-menu .dropdown-item:hover {
211
  background-color: #e6f4ea;
212
+ color: #0FAA39;
213
  transform: translateX(5px);
214
  }
215
  .dropdown-menu .dropdown-item:hover i {
216
  color: #0D9232;
217
  }
218
+ .dropdown-menu .dropdown-item:active {
219
+ background-color: #d1e7dd;
220
+ }
221
  @keyframes slideDown {
222
  from {
223
  opacity: 0;
224
+ transform: translateY(-15px);
225
  }
226
  to {
227
  opacity: 1;
 
241
  justify-content: space-between;
242
  align-items: center;
243
  z-index: 1000;
 
244
  }
245
  .search-bar-container {
246
  position: absolute;
 
262
  background-color: #fff;
263
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
264
  outline: none;
 
 
 
 
265
  }
266
  .search-bar-container input::placeholder {
267
  color: #888;
268
  }
269
+ .search-bar-container input:focus {
270
+ border-bottom: 2px solid #FFA07A;
271
+ }
272
  .search-icon {
273
  position: absolute;
274
  left: 15px;
 
281
  font-size: 18px;
282
  color: #888;
283
  cursor: pointer;
284
+ transition: color 0.3s ease;
 
 
 
 
285
  }
286
  .mic-icon.active {
287
+ color: #007bff;
 
288
  }
289
  /* Addon Section */
290
  .addon-section {
 
406
  #softDrinkModal .modal-content {
407
  border-radius: 12px;
408
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
409
+ background-color: #fff;
410
  overflow: hidden;
411
  }
412
  #softDrinkModal .modal-header {
 
426
  text-align: center;
427
  }
428
  #softDrinkModal .modal-body img {
429
+ max-height: 160px;
430
+ width: 100%;
431
  object-fit: cover;
 
432
  border-radius: 8px;
433
  margin-bottom: 15px;
434
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
 
 
 
 
435
  }
436
  #softDrinkModal .modal-body h5 {
437
  font-size: 1.4rem;
 
459
  margin-bottom: 20px;
460
  }
461
  #softDrinkModal .quantity-controls .btn {
462
+ width: 40px;
463
+ height: 40px;
464
  border-radius: 50%;
465
  padding: 0;
466
+ font-size: 1.2rem;
467
+ line-height: 40px;
468
  text-align: center;
469
  background-color: #e9ecef;
470
  border: none;
471
  color: #333;
472
+ transition: background-color 0.2s ease;
473
  }
474
  #softDrinkModal .quantity-controls .btn:hover {
475
  background-color: #d1d4d7;
 
476
  }
477
  #softDrinkModal .quantity-controls input {
478
  width: 60px;
479
+ height: 40px;
480
  text-align: center;
481
+ font-size: 1.1rem;
482
  font-weight: 600;
483
  border: 1px solid #ced4da;
484
  border-radius: 6px;
 
493
  #softDrinkModal .modal-footer .btn-primary {
494
  background-color: #0FAA39;
495
  border-color: #0FAA39;
496
+ padding: 10px 30px;
497
  text-align: center;
498
+ font-size: 1rem;
499
  font-weight: 600;
500
  border-radius: 8px;
501
+ transition: background-color 0.2s ease;
502
  width: auto;
503
  }
504
  #softDrinkModal .modal-footer .btn-primary:hover {
505
  background-color: #0D9232;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
506
  }
507
+ /* Item Modal Quantity Controls */
508
  #itemModal .quantity-controls {
509
  display: flex;
510
  justify-content: center;
 
513
  margin-bottom: 20px;
514
  }
515
  #itemModal .quantity-controls .btn {
516
+ width: 40px;
517
+ height: 40px;
518
  border-radius: 50%;
519
  padding: 0;
520
+ font-size: 1.2rem;
521
+ line-height: 40px;
522
  text-align: center;
523
  background-color: #e9ecef;
524
  border: none;
525
  color: #333;
526
+ transition: background-color 0.2s ease;
527
  }
528
  #itemModal .quantity-controls .btn:hover {
529
  background-color: #d1d4d7;
 
530
  }
531
  #itemModal .quantity-controls input {
532
  width: 60px;
533
+ height: 40px;
534
  text-align: center;
535
+ font-size: 1.1rem;
536
  font-weight: 600;
537
  border: 1px solid #ced4da;
538
  border-radius: 6px;
539
  background-color: #f8f9fa;
540
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
541
  /* Filter Form Styling */
542
  #filter-form {
543
  display: flex;
 
606
  #micModal .modal-content {
607
  border-radius: 12px;
608
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
609
+ background-color: #fff;
610
  text-align: center;
611
  }
612
  #micModal .modal-header {
 
629
  align-items: center;
630
  gap: 15px;
631
  min-height: 200px;
 
632
  }
633
  #micModal .modal-body i#mic-icon-animation {
634
  font-size: 2.5rem;
635
+ color: #007bff;
 
636
  animation: pulse 2s infinite;
637
  }
 
 
 
 
 
 
 
 
 
 
 
 
638
  #micModal .modal-body p#mic-status {
639
  font-size: 1.1rem;
640
  color: #333;
641
  margin: 0;
642
  }
643
  #micModal .modal-body #mic-item-image {
644
+ max-height: 150px;
645
+ width: 100%;
646
  object-fit: cover;
 
647
  border-radius: 8px;
648
  margin-bottom: 10px;
649
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
 
 
 
 
 
 
 
 
650
  }
651
  #micModal .modal-body #mic-item-details.show {
652
  animation: fadeIn 0.3s ease;
 
662
  padding: 10px 20px;
663
  font-size: 1rem;
664
  border-radius: 8px;
 
665
  }
666
  #micModal .modal-footer .btn-secondary:hover {
667
  background-color: #5a6268;
668
+ border-color: #5a6268;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
669
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
670
  @keyframes checkmark {
671
  from { transform: scale(0); }
672
  to { transform: scale(1); }
 
688
  50% { transform: scale(1.2); }
689
  100% { transform: scale(1); }
690
  }
 
 
 
 
 
 
 
 
 
 
 
691
  .modal-header {
692
  padding: 10px 15px;
693
  }
 
701
  padding: 15px;
702
  }
703
  .modal-body #modal-img {
704
+ max-height: 200px;
705
+ width: 100%;
706
  object-fit: cover;
 
707
  border-radius: 8px;
708
  margin-bottom: 10px;
 
 
 
709
  }
710
  .modal-body #modal-name {
711
  font-size: 20px;
 
904
  text-align: center;
905
  min-width: 0;
906
  white-space: nowrap;
 
 
 
 
907
  }
908
  .bottom-action-bar .btn-order-history {
909
  background: linear-gradient(45deg, #FF8C00, #32CD32);
 
912
  }
913
  .bottom-action-bar .btn-order-history:hover {
914
  background: linear-gradient(45deg, #FF4500, #228B22);
915
+ border-color: transparent;
916
  color: #000000;
917
  }
918
  .bottom-action-bar .btn-view-cart {
 
922
  }
923
  .bottom-action-bar .btn-view-cart:hover {
924
  background-color: #0D9232;
925
+ border-color: #0D9232;
926
  color: white;
927
  }
928
  .cart-icon-badge {
 
936
  justify-content: center;
937
  font-size: 12px;
938
  margin-left: 8px;
 
939
  }
940
  /* Mobile-Specific Styles */
941
  @media (max-width: 576px) {
 
973
  }
974
  .dropdown-menu {
975
  width: 200px;
976
+ border-radius: 8px;
977
+ padding: 8px 0;
978
  }
979
  .dropdown-menu .dropdown-item {
980
+ padding: 8px 12px;
981
+ font-size: 13px;
982
  }
983
  .dropdown-menu .dropdown-item i {
984
+ font-size: 14px;
985
+ margin-right: 8px;
986
  }
987
  .modal-dialog {
988
  max-width: 90%;
 
999
  padding: 12px;
1000
  }
1001
  .modal-body #modal-img {
1002
+ max-height: 150px;
1003
+ width: 100%;
1004
+ max-width: 150px;
1005
  margin: 0 auto 8px;
1006
  display: block;
1007
  }
 
1143
  padding: 15px;
1144
  }
1145
  #softDrinkModal .modal-body img {
1146
+ max-height: 130px;
 
1147
  margin-bottom: 12px;
1148
  }
1149
  #softDrinkModal .modal-body h5 {
 
1155
  margin-bottom: 15px;
1156
  }
1157
  #softDrinkModal .quantity-controls .btn {
1158
+ width: 32px;
1159
+ height: 32px;
1160
+ font-size: 1rem;
1161
+ line-height: 32px;
1162
  }
1163
  #softDrinkModal .quantity-controls input {
1164
  width: 50px;
1165
+ height: 32px;
1166
+ font-size: 0.9rem;
1167
  }
1168
  #softDrinkModal .modal-footer {
1169
  padding: 10px;
1170
  }
1171
  #softDrinkModal .modal-footer .btn-primary {
1172
+ padding: 8px 20px;
1173
+ font-size: 0.9rem;
1174
  }
1175
  /* Mobile-Specific Item Modal Styles */
 
 
 
 
 
 
 
1176
  #itemModal .quantity-controls .btn {
1177
+ width: 32px;
1178
+ height: 32px;
1179
+ font-size: 1rem;
1180
+ line-height: 32px;
1181
  }
1182
  #itemModal .quantity-controls input {
1183
  width: 50px;
1184
+ height: 32px;
1185
+ font-size: 0.9rem;
1186
  }
1187
  #itemModal .modal-footer .btn-primary {
1188
+ padding: 8px 15px;
1189
+ font-size: 0.9rem;
1190
  }
1191
  /* Mobile-Specific Filter Form Styles */
1192
  #filter-form {
 
1225
  font-size: 1rem;
1226
  }
1227
  #micModal .modal-body #mic-item-image {
1228
+ max-height: 120px;
 
1229
  margin-bottom: 8px;
1230
  }
1231
  #micModal .modal-body #mic-item-name {
 
1236
  padding: 8px 15px;
1237
  font-size: 0.9rem;
1238
  }
1239
+ }
1240
+ .autocomplete-suggestions {
1241
+ position: absolute;
1242
+ top: 100%;
1243
+ left: 0;
1244
+ right: 0;
1245
+ background-color: #fff;
1246
+ border: 1px solid #ced4da;
1247
+ border-radius: 4px;
1248
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
1249
+ max-height: 150px;
1250
+ overflow-y: auto;
1251
+ z-index: 1000;
1252
+ display: none;
1253
+ }
1254
+ .autocomplete-suggestion {
1255
+ padding: 8px 12px;
1256
+ cursor: pointer;
1257
+ font-size: 0.9rem;
1258
+ color: #333;
1259
+ transition: background-color 0.2s ease;
1260
+ }
1261
+ .autocomplete-suggestion:hover {
1262
+ background-color: #e6f4ea;
1263
+ }
1264
+ .autocomplete-suggestions::-webkit-scrollbar {
1265
+ width: 6px;
1266
+ }
1267
+ .autocomplete-suggestions::-webkit-scrollbar-track {
1268
+ background: #f1f1f1;
1269
+ }
1270
+ .autocomplete-suggestions::-webkit-scrollbar-thumb {
1271
+ background: #0FAA39;
1272
+ border-radius: 10px;
1273
+ }
1274
+ .autocomplete-suggestions::-webkit-scrollbar-thumb:hover {
1275
+ background: #0D9232;
1276
  }
1277
  </style>
1278
  </head>
 
1293
  <input type="text" id="searchBar" class="form-control" placeholder="Search items or sections..." autocomplete="off">
1294
  <i class="bi bi-search search-icon"></i>
1295
  <i class="bi bi-mic mic-icon" id="micIcon"></i>
 
1296
  </div>
1297
  </div>
1298
 
 
1301
  <div class="toggle-container">
1302
  <!-- Veg Only Toggle -->
1303
  <input type="checkbox" id="veg-toggle" name="veg"
1304
+ {% if selected_category == "Veg" %}checked{% endif %}
1305
  class="custom-toggle" onchange="handleToggle('veg')"
1306
  aria-label="Toggle Vegetarian filter">
1307
  <label for="veg-toggle">Veg</label>
 
1325
  <label for="custom-dish-name" class="form-label">Dish Name</label>
1326
  <input type="text" class="form-control" id="custom-dish-name" name="name" required>
1327
  </div>
1328
+ <div class="mb-3 position-relative">
1329
  <label for="custom-dish-description" class="form-label">Dish Description</label>
1330
  <textarea class="form-control" id="custom-dish-description" name="description" required></textarea>
1331
+ <div id="descriptionSuggestions" class="autocomplete-suggestions"></div>
1332
  </div>
1333
  <button type="submit" class="btn btn-primary">Submit Custom Dish</button>
1334
  </form>
 
1379
  data-item-section="{{ item.Section__c | default(section) }}"
1380
  data-item-category="{{ selected_category }}"
1381
  data-item-description="{{ item.Description__c | default('No description') }}"
1382
+ data-item-image2="{{ item.Image2__c | default(item.Image1__c) }}">
1383
  {% if item.Section__c == 'Soft Drinks' %}
1384
  <button class="btn btn-primary add-to-cart-btn" onclick="showSoftDrinkModal(this)">ADD</button>
1385
  {% else %}
1386
  <button class="btn btn-primary"
1387
  data-bs-toggle="modal"
1388
  data-bs-target="#itemModal"
1389
+ onclick="showItemDetails('{{ item.Name | default('Unnamed Item') }}', '{{ item.Price__c | default('0.00') }}', '{{ item.Image2__c | default(item.Image1__c) }}', '{{ item.Description__c | default('No description') }}', '{{ item.Section__c | default(section) }}', '{{ selected_category }}')">
1390
  ADD
1391
  </button>
1392
  {% if item.Section__c != 'Apetizer' and item.Section__c != 'Customized dish' %}
 
1438
  <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
1439
  </div>
1440
  <div class="modal-body">
1441
+ <img id="modal-img" class="img-fluid rounded mb-3 d-block mx-auto" alt="Item Image" style="max-height: 200px; object-fit: cover;" loading="lazy" decoding="async">
1442
  <h5 id="modal-name" class="fw-bold text-center"></h5>
1443
  <p id="modal-price" class="text-muted text-center"></p>
1444
  <p id="modal-description" class="text-secondary"></p>
 
1525
  {
1526
  name: "{{ item.Name | default('Unnamed Item') }}",
1527
  section: "{{ item.Section__c | default(section) }}",
1528
+ image: "{{ item.Image1__c | default('/static/placeholder.jpg') }}"
 
 
 
 
1529
  },
1530
  {% endfor %}
1531
  {% endfor %}
1532
  ];
1533
+ const ingredientsList = [
1534
+ "Basmati Rice", "Bell Pepper", "Biryani Masala", "Butter", "Capsicum", "Cauliflower",
1535
+ "Chickpea Flour (Besan)", "Chickpea Flour (for batter)", "Chickpeas (Channa)", "Chili Powder",
1536
+ "Chili Sauce", "Coconut Milk", "Coriander Powder", "Cornflour", "Cream", "Cumin Powder",
1537
+ "Cumin Seeds", "Curd (Yogurt)", "Curry Leaves", "Fish (e.g., King Fish or Salmon)",
1538
+ "Fresh Coriander Leaves", "Garam Masala", "Garlic", "Ghee (Clarified Butter)", "Ginger",
1539
+ "Ginger-Garlic Paste", "Goat Meat (Mutton)", "Green Chilies", "Honey",
1540
+ "Kasuri Methi (dried fenugreek leaves)", "Lemon Juice", "Mango Puree", "Mint Leaves",
1541
+ "Mixed Vegetables (Carrot, Peas, Potato, Cauliflower)", "Mixed Vegetables (Carrot, Peas, Potato)",
1542
+ "Mustard Seeds", "Mutton (Goat Meat)", "Oil", "Oil (for frying)", "Onion",
1543
+ "Paneer (Indian Cottage Cheese)", "Peas", "Potatoes", "Prawns", "Red Chili Powder",
1544
+ "Rice Flour", "Saffron", "Salt", "Soy Sauce", "Spring Onion", "Tamarind (for sourness)",
1545
+ "Tomato Ketchup", "Tomatoes", "Turmeric Powder", "Vinegar", "Water", "Wheat Flour (for dough)",
1546
+ "Whole Wheat Flour", "Yogurt (Curd)"
1547
+ ];
1548
  function addToCartLocalStorage(payload) {
1549
  let cart = JSON.parse(localStorage.getItem('cart')) || [];
1550
  const existingItem = cart.find(item =>
 
1699
  modalSectionEl.setAttribute('data-section', section);
1700
  modalSectionEl.setAttribute('data-category', selectedCategory);
1701
  document.getElementById('quantityInput').value = 1;
1702
+ fetch(`/api/addons?item_name=${encodeURIComponent(name)}&item_section=${encodeURIComponent(section)}`)
 
 
1703
  .then(response => response.json())
1704
  .then(data => {
1705
  const addonsList = document.getElementById('addons-list');
1706
  addonsList.classList.remove('addon-loading');
1707
  addonsList.innerHTML = '';
1708
  if (!data.success || !data.addons || data.addons.length === 0) {
1709
+ addonsList.innerHTML = '<p>No customization options available.</p>';
1710
+ return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1711
  }
1712
+ data.addons.forEach(addon => {
1713
+ const sectionDiv = document.createElement('div');
1714
+ sectionDiv.classList.add('addon-section');
1715
+ const title = document.createElement('h6');
1716
+ title.innerText = addon.name;
1717
+ sectionDiv.appendChild(title);
1718
+ const optionsContainer = document.createElement('div');
1719
+ optionsContainer.classList.add('addon-options');
1720
+ addon.options.forEach((option, index) => {
1721
+ const optionId = `addon-${addon.name.replace(/\s+/g, '')}-${index}`;
1722
+ const listItem = document.createElement('div');
1723
+ listItem.classList.add('form-check');
1724
+ listItem.innerHTML = `
1725
+ <input type="checkbox" class="form-check-input addon-option" id="${optionId}" value="${option}"
1726
+ data-name="${option}" data-group="${addon.name}" data-price="${addon.extra_charge ? addon.extra_charge_amount : 0}"
1727
+ aria-label="Select ${option} for ${addon.name}">
1728
+ <label class="form-check-label" for="${optionId}">
1729
+ ${option} ${addon.extra_charge ? `<span class="extra-charge">($${addon.extra_charge_amount.toFixed(2)})</span>` : ''}
1730
+ </label>
1731
+ `;
1732
+ optionsContainer.appendChild(listItem);
1733
+ });
1734
+ sectionDiv.appendChild(optionsContainer);
1735
+ addonsList.appendChild(sectionDiv);
1736
+ });
1737
+ const addonSections = addonsList.querySelectorAll('.addon-section');
1738
+ addonSections.forEach(section => {
1739
+ const title = section.querySelector('h6');
1740
+ const options = section.querySelector('.addon-options');
1741
+ title.addEventListener('click', () => {
1742
+ section.classList.toggle('collapsed');
1743
+ options.classList.toggle('collapsed');
1744
+ });
1745
+ });
1746
+ document.querySelectorAll('.addon-option').forEach(checkbox => {
1747
+ checkbox.addEventListener('change', updateModalPrice);
1748
+ });
1749
+ document.querySelectorAll('.addon-option').forEach(checkbox => {
1750
+ checkbox.addEventListener('change', function () {
1751
+ const groupName = this.getAttribute('data-group');
1752
+ const isMultiSelectGroup = ["Extra Toppings", "Choose Raita/Sides", "Select Dip/Sauce", "Extra Add-ons", "Make it a Combo", "Beverages", "Sauces"].includes(groupName);
1753
+ if (!isMultiSelectGroup && this.checked) {
1754
+ document.querySelectorAll(`.addon-option[data-group="${groupName}"]`).forEach(otherCheckbox => {
1755
+ if (otherCheckbox !== this) {
1756
+ otherCheckbox.checked = false;
1757
+ }
1758
+ });
1759
+ }
1760
+ });
1761
+ });
1762
+ if (window.most_common_addons && window.most_common_addons.length > 0) {
1763
+ const checkboxes = document.querySelectorAll('.addon-option');
1764
+ const categorySelection = {
1765
+ "Select Spice Level": null,
1766
+ "Choose Spice Level": null,
1767
+ "Raita/Sides": [],
1768
+ };
1769
+ for (let spice of window.most_common_addons) {
1770
+ const isSpiceLevel = ["Mild", "Medium", "Spicy", "Extra Spicy"].includes(spice);
1771
+ if (isSpiceLevel) {
1772
+ checkboxes.forEach(checkbox => {
1773
+ const checkboxName = checkbox.getAttribute('data-name').trim();
1774
+ const checkboxGroup = checkbox.getAttribute('data-group');
1775
+ if ((checkboxGroup === "Select Spice Level" || checkboxGroup === "Choose Spice Level") &&
1776
+ checkboxName === spice && categorySelection[checkboxGroup] === null) {
1777
+ console.log(`Pre-selecting highest-count spice level: ${checkboxName}`);
1778
+ checkbox.checked = true;
1779
+ categorySelection[checkboxGroup] = checkboxName;
1780
+ }
1781
+ });
1782
+ if (categorySelection["Select Spice Level"] || categorySelection["Choose Spice Level"]) break;
1783
+ }
1784
+ }
1785
+ checkboxes.forEach(checkbox => {
1786
+ const checkboxName = checkbox.getAttribute('data-name').trim();
1787
+ const checkboxGroup = checkbox.getAttribute('data-group');
1788
+ if (checkboxGroup === "Raita/Sides" && window.most_common_addons.includes(checkboxName)) {
1789
+ console.log(`Pre-selecting add-on: ${checkboxName}`);
1790
+ checkbox.checked = true;
1791
+ categorySelection["Raita/Sides"].push(checkboxName);
1792
+ }
1793
+ });
1794
+ }
1795
+ })
1796
+ .catch(err => {
1797
+ console.error('Error fetching add-ons:', err);
1798
+ document.getElementById('addons-list').classList.remove('addon-loading');
1799
+ document.getElementById('addons-list').innerHTML = '<p>Error loading customization options.</p>';
1800
+ });
1801
+ }
1802
+ function addToCartFromModal() {
1803
+ if (isProcessingRequest) return;
1804
+ isProcessingRequest = true;
1805
+ const modalSectionEl = document.getElementById('modal-section');
1806
+ const section = modalSectionEl.getAttribute('data-section');
1807
+ const selectedCategory = modalSectionEl.getAttribute('data-category');
1808
+ const itemName = document.getElementById('modal-name').innerText;
1809
+ const itemPrice = parseFloat(document.getElementById('modal-price').innerText.replace('$', '')) || 0;
1810
+ const itemImage = document.getElementById('modal-img').src;
1811
+ const quantity = parseInt(document.getElementById('quantityInput').value) || 1;
1812
+ const instructions = document.getElementById('modal-instructions').value;
1813
+ const selectedAddOns = Array.from(
1814
+ document.querySelectorAll('#addons-list input[type="checkbox"]:checked')
1815
+ ).map(addon => ({
1816
+ name: addon.getAttribute('data-name'),
1817
+ price: parseFloat(addon.getAttribute('data-price')) || 0
1818
+ }));
1819
+ if (!itemName || isNaN(itemPrice) || !section || !itemImage || quantity < 1) {
1820
+ console.error('Invalid cart item data:', { itemName, itemPrice, section, itemImage, quantity });
1821
+ alert('Invalid item data. Please try again.');
1822
+ isProcessingRequest = false;
1823
+ return;
1824
+ }
1825
+ const cartPayload = {
1826
+ itemName: itemName,
1827
+ itemPrice: itemPrice,
1828
+ itemImage: itemImage,
1829
+ section: section,
1830
+ category: selectedCategory,
1831
+ addons: selectedAddOns,
1832
+ instructions: instructions,
1833
+ quantity: quantity
1834
+ };
1835
+ fetch('/cart/add', {
1836
+ method: 'POST',
1837
+ headers: {
1838
+ 'Content-Type': 'application/json',
1839
+ },
1840
+ body: JSON.stringify(cartPayload)
1841
+ })
1842
+ .then(response => response.json())
1843
+ .then(data => {
1844
+ if (data.success) {
1845
+ updateCartUI(data.cart);
1846
+ const modal = bootstrap.Modal.getInstance(document.getElementById('itemModal'));
1847
+ modal.hide();
1848
+ } else {
1849
+ console.error('Failed to add item to cart:', data.error);
1850
+ const cart = addToCartLocalStorage(cartPayload);
1851
+ updateCartUI(cart);
1852
+ const modal = bootstrap.Modal.getInstance(document.getElementById('itemModal'));
1853
+ modal.hide();
1854
  }
1855
+ })
1856
+ .catch(err => {
1857
+ console.error('Error adding item to cart:', err);
1858
+ const cart = addToCartLocalStorage(cartPayload);
1859
+ updateCartUI(cart);
1860
+ const modal = bootstrap.Modal.getInstance(document.getElementById('itemModal'));
1861
+ modal.hide();
1862
+ })
1863
+ .finally(() => {
1864
+ isProcessingRequest = false;
1865
  });
1866
+ }
1867
+ function handleToggle(source) {
1868
+ const form = document.getElementById("filter-form");
1869
+ const veg = document.getElementById("veg-toggle");
1870
+ const custom = document.getElementById("category-CustomizedDish");
1871
+ if (source === 'veg') {
1872
+ if (veg.checked) {
1873
+ custom.checked = false;
1874
+ }
1875
+ } else if (source === 'custom') {
1876
+ if (custom.checked) {
1877
+ veg.checked = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1878
  }
1879
  }
1880
+ if (!custom.checked && !veg.checked) {
1881
+ custom.checked = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1882
  }
1883
+ form.submit();
1884
+ }
1885
+ function stopSpeechRecognition() {
1886
+ if (recognition) {
1887
+ recognition.stop();
1888
+ document.getElementById('micIcon').classList.remove('active');
1889
+ const micModal = bootstrap.Modal.getInstance(document.getElementById('micModal'));
1890
+ if (micModal) {
1891
+ micModal.hide();
1892
+ resetMicModal();
1893
+ }
1894
  }
1895
+ }
1896
+ function resetMicModal() {
1897
+ document.getElementById('mic-status').textContent = 'Say the name of a menu item...';
1898
+ document.getElementById('mic-status').style.display = 'block';
1899
+ document.getElementById('mic-item-details').style.display = 'none';
1900
+ document.getElementById('mic-item-image').src = '';
1901
+ document.getElementById('mic-item-name').textContent = '';
1902
+ }
1903
+ document.addEventListener('DOMContentLoaded', function () {
1904
+ const avatarContainer = document.querySelector('.avatar-dropdown-container');
1905
+ const dropdownMenu = document.querySelector('.dropdown-menu');
1906
+ avatarContainer.addEventListener('click', function (event) {
1907
+ event.stopPropagation();
1908
+ dropdownMenu.classList.toggle('show');
1909
+ });
1910
+ document.addEventListener('click', function (event) {
1911
+ if (!avatarContainer.contains(event.target)) {
1912
+ dropdownMenu.classList.remove('show');
1913
+ }
1914
+ });
1915
+ const dropdownItems = document.querySelectorAll('.dropdown-item');
1916
+ dropdownItems.forEach(item => {
1917
+ item.addEventListener('click', function () {
1918
+ dropdownMenu.classList.remove('show');
1919
+ });
1920
+ });
1921
+
1922
+ // Search functionality
1923
+ const searchBar = document.getElementById('searchBar');
1924
+ searchBar.addEventListener('input', debounce(() => {
1925
+ const query = searchBar.value.toLowerCase();
1926
+ document.querySelectorAll('.menu-card').forEach(card => {
1927
+ const itemName = card.getAttribute('data-item-name').toLowerCase();
1928
+ const section = card.getAttribute('data-item-section').toLowerCase();
1929
+ if (itemName.includes(query) || section.includes(query)) {
1930
+ card.style.display = 'block';
1931
+ } else {
1932
+ card.style.display = 'none';
1933
+ }
1934
+ });
1935
+ }, 300));
1936
+
1937
+ // Enhanced video hover handling for desktop and touch for mobile
1938
+ document.querySelectorAll('.media-wrapper').forEach(wrapper => {
1939
+ const video = wrapper.querySelector('.menu-video');
1940
+ const image = wrapper.querySelector('.menu-image');
1941
+
1942
+ // Desktop hover events
1943
+ wrapper.addEventListener('mouseenter', () => {
1944
+ image.classList.add('hidden');
1945
+ video.classList.add('active');
1946
+ video.play().catch(err => {
1947
+ console.error('Video playback failed:', err);
1948
+ image.classList.remove('hidden');
1949
+ video.classList.remove('active');
1950
+ });
1951
+ });
1952
+ wrapper.addEventListener('mouseleave', () => {
1953
+ video.classList.remove('active');
1954
+ video.pause();
1955
+ video.currentTime = 0;
1956
+ image.classList.remove('hidden');
1957
+ });
1958
+
1959
+ // Mobile touch events
1960
+ let touchTimeout;
1961
+ wrapper.addEventListener('touchstart', (e) => {
1962
+ e.preventDefault();
1963
+ wrapper.classList.add('touched');
1964
+ image.classList.add('hidden');
1965
+ video.classList.add('active');
1966
+ video.play().catch(err => {
1967
+ console.error('Video playback failed:', err);
1968
+ image.classList.remove('hidden');
1969
+ video.classList.remove('active');
1970
+ });
1971
+ touchTimeout = setTimeout(() => {
1972
+ video.pause();
1973
+ video.classList.remove('active');
1974
+ image.classList.remove('hidden');
1975
+ wrapper.classList.remove('touched');
1976
+ }, 3000);
1977
+ });
1978
+ wrapper.addEventListener('touchend', () => {
1979
+ clearTimeout(touchTimeout);
1980
+ setTimeout(() => {
1981
+ video.pause();
1982
+ video.classList.remove('active');
1983
+ image.classList.remove('hidden');
1984
+ wrapper.classList.remove('touched');
1985
+ }, 500);
1986
+ });
1987
+ });
1988
+
1989
+ // Quantity controls for item modal
1990
+ const decreaseBtn = document.getElementById('decreaseQuantity');
1991
+ const increaseBtn = document.getElementById('increaseQuantity');
1992
+ const quantityInput = document.getElementById('quantityInput');
1993
+
1994
+ decreaseBtn.addEventListener('click', () => {
1995
+ let value = parseInt(quantityInput.value) || 1;
1996
+ if (value > 1) {
1997
+ quantityInput.value = value - 1;
1998
+ }
1999
+ });
2000
+
2001
+ increaseBtn.addEventListener('click', () => {
2002
+ let value = parseInt(quantityInput.value) || 1;
2003
+ quantityInput.value = value + 1;
2004
+ });
2005
+
2006
+ // Toggle item details
2007
+ document.querySelectorAll('.toggle-details').forEach(link => {
2008
+ link.addEventListener('click', () => {
2009
+ const details = link.nextElementSibling;
2010
+ if (details.classList.contains('show')) {
2011
+ details.classList.remove('show');
2012
+ link.textContent = 'Show Details';
2013
+ } else {
2014
+ details.classList.add('show');
2015
+ link.textContent = 'Hide Details';
2016
+ }
2017
+ });
2018
+ });
2019
+
2020
+ // Initialize cart UI
2021
+ fetch('/cart')
2022
+ .then(response => response.json())
2023
+ .then(data => {
2024
+ if (data.success) {
2025
+ updateCartUI(data.cart);
2026
+ } else {
2027
+ updateCartUI(getCartLocalStorage());
2028
+ }
2029
+ })
2030
+ .catch(err => {
2031
+ console.error('Error fetching cart:', err);
2032
+ updateCartUI(getCartLocalStorage());
2033
+ });
2034
+
2035
+ // Enhanced speech recognition setup
2036
+ if ('webkitSpeechRecognition' in window) {
2037
+ recognition = new webkitSpeechRecognition();
2038
+ recognition.continuous = false;
2039
+ recognition.interimResults = false;
2040
+ recognition.lang = 'en-US';
2041
+
2042
+ recognition.onstart = () => {
2043
+ document.getElementById('micIcon').classList.add('active');
2044
+ document.getElementById('mic-status').textContent = 'Listening...';
2045
+ };
2046
+
2047
+ recognition.onresult = (event) => {
2048
+ const transcript = event.results[0][0].transcript.trim().toLowerCase();
2049
+ console.log('Recognized speech:', transcript);
2050
+ const matchedItem = menuItems.find(item =>
2051
+ item.name.toLowerCase().includes(transcript)
2052
+ );
2053
+
2054
+ if (matchedItem) {
2055
+ // Show item details in mic modal
2056
+ document.getElementById('mic-status').style.display = 'none';
2057
+ document.getElementById('mic-item-details').style.display = 'block';
2058
+ document.getElementById('mic-item-name').textContent = matchedItem.name;
2059
+ document.getElementById('mic-item-image').src = matchedItem.image;
2060
+
2061
+ // Stop recognition and hide modal after 2 seconds
2062
+ recognition.stop();
2063
+ setTimeout(() => {
2064
+ const micModal = bootstrap.Modal.getInstance(document.getElementById('micModal'));
2065
  micModal.hide();
2066
  resetMicModal();
2067
+
2068
+ // Navigate to the matched item
2069
+ const card = document.querySelector(`.menu-card[data-item-name="${matchedItem.name}"]`);
2070
+ if (card) {
2071
+ card.classList.add('highlighted');
2072
+ card.scrollIntoView({ behavior: 'smooth', block: 'center' });
2073
+ setTimeout(() => card.classList.remove('highlighted'), 3000);
2074
+ const buttonContainer = card.querySelector('.button-container');
2075
+ if (buttonContainer) {
2076
+ if (matchedItem.section === 'Soft Drinks') {
2077
+ showSoftDrinkModal(buttonContainer.querySelector('.add-to-cart-btn'));
2078
+ } else {
2079
+ showItemDetails(
2080
+ buttonContainer.getAttribute('data-item-name'),
2081
+ buttonContainer.getAttribute('data-item-price'),
2082
+ buttonContainer.getAttribute('data-item-image2'),
2083
+ buttonContainer.getAttribute('data-item-description'),
2084
+ matchedItem.section,
2085
+ buttonContainer.getAttribute('data-item-category')
2086
+ );
2087
+ const modal = new bootstrap.Modal(document.getElementById('itemModal'));
2088
+ modal.show();
2089
+ }
2090
+ }
2091
+ }
2092
+ }, 2000);
2093
+ } else {
2094
+ document.getElementById('mic-status').textContent = 'Item not found. Try again.';
2095
  }
2096
+ };
2097
+
2098
+ recognition.onerror = (event) => {
2099
+ console.error('Speech recognition error:', event.error);
2100
+ document.getElementById('mic-status').textContent = 'Error occurred. Please try again.';
2101
+ document.getElementById('micIcon').classList.remove('active');
2102
+ };
2103
+
2104
+ recognition.onend = () => {
2105
+ document.getElementById('micIcon').classList.remove('active');
2106
+ };
2107
+
2108
+ document.getElementById('micIcon').addEventListener('click', () => {
2109
+ if (!recognition) return;
2110
+ const micModal = new bootstrap.Modal(document.getElementById('micModal'));
2111
+ micModal.show();
2112
+ resetMicModal();
2113
+ recognition.start();
2114
+ });
2115
  } else {
2116
+ document.getElementById('micIcon').style.display = 'none';
2117
+ }
2118
+
2119
+ // Autocomplete for custom dish description
2120
+ const descriptionInput = document.getElementById('custom-dish-description');
2121
+ const suggestionsContainer = document.getElementById('descriptionSuggestions');
2122
+
2123
+ if (descriptionInput && suggestionsContainer) {
2124
+ descriptionInput.addEventListener('input', debounce(() => {
2125
+ const query = descriptionInput.value.toLowerCase();
2126
+ suggestionsContainer.innerHTML = '';
2127
+
2128
+ if (query.length < 2) {
2129
+ suggestionsContainer.style.display = 'none';
2130
+ return;
2131
+ }
2132
+
2133
+ const filteredIngredients = ingredientsList.filter(ingredient =>
2134
+ ingredient.toLowerCase().includes(query)
2135
+ );
2136
+
2137
+ if (filteredIngredients.length === 0) {
2138
+ suggestionsContainer.style.display = 'none';
2139
+ return;
2140
+ }
2141
+
2142
+ filteredIngredients.forEach(ingredient => {
2143
+ const suggestionItem = document.createElement('div');
2144
+ suggestionItem.classList.add('autocomplete-suggestion');
2145
+ suggestionItem.textContent = ingredient;
2146
+ suggestionItem.addEventListener('click', () => {
2147
+ const currentValue = descriptionInput.value;
2148
+ const words = currentValue.split(' ');
2149
+ words[words.length - 1] = ingredient;
2150
+ descriptionInput.value = words.join(' ') + ' ';
2151
+ suggestionsContainer.innerHTML = '';
2152
+ suggestionsContainer.style.display = 'none';
2153
+ descriptionInput.focus();
2154
+ });
2155
+ suggestionsContainer.appendChild(suggestionItem);
2156
+ });
2157
+
2158
+ suggestionsContainer.style.display = 'block';
2159
+ }, 300));
2160
+
2161
+ document.addEventListener('click', (event) => {
2162
+ if (!descriptionInput.contains(event.target) && !suggestionsContainer.contains(event.target)) {
2163
+ suggestionsContainer.style.display = 'none';
2164
+ }
2165
+ });
2166
+ }
2167
  });
2168
+ </script>
 
 
 
 
 
2169
  </body>
2170
+ </html>
2171
+ </xaiArtifact>