lokeshloki143 commited on
Commit
9c0c1df
·
verified ·
1 Parent(s): a6034d3

Update templates/combined_summary.html

Browse files
Files changed (1) hide show
  1. templates/combined_summary.html +960 -644
templates/combined_summary.html CHANGED
@@ -3,797 +3,1113 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Search Menu</title>
7
- <!-- Bootstrap CSS -->
8
- <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
9
- <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
10
- <!-- Preload Placeholder Image -->
11
- <link rel="preload" href="/static/placeholder.jpg" as="image">
12
  <style>
13
- body {
14
- font-family: Arial, sans-serif;
15
- background-color: #fdf4e3;
16
- margin: 0;
17
- padding: 0;
18
- display: flex;
19
- flex-direction: column;
20
- padding-bottom: 70px;
21
  }
22
- .container {
23
- max-width: 900px;
 
24
  }
25
- .menu-heading {
26
- font-size: 2rem;
27
- font-weight: 700;
28
- color: #fff;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  text-align: center;
30
- padding: 15px 20px;
31
- margin: 20px 0;
32
- background: linear-gradient(45deg, #FFA07A, #FFB347);
33
- border-radius: 10px;
34
- box-shadow: 0 4px 8px rgba(0,0,0,0.2);
 
 
 
35
  width: 100%;
36
- max-width: 900px;
37
  margin-left: auto;
38
  margin-right: auto;
39
  }
40
- .menu-card {
41
- max-width: 350px;
42
- border-radius: 15px;
43
- overflow: hidden;
44
- background-color: #fff;
45
- margin: auto;
46
- display: flex;
47
- flex-direction: column;
48
- box-shadow: 0 4px 8px rgba(0,0,0,0.1);
49
- cursor: pointer;
50
  }
51
- .card-img-container {
 
52
  position: relative;
53
- width: 100%;
54
- height: 200px;
55
  }
56
- .card-img {
57
- height: 100%;
58
- width: 100%;
59
- object-fit: cover;
60
- border-radius: 15px 15px 0 0;
 
 
 
 
 
 
 
 
 
61
  display: block;
 
62
  }
63
- .card-title {
64
- position: absolute;
65
- top: 10px;
66
- left: 50%;
67
- transform: translateX(-50%);
68
- font-size: 1.2rem;
69
- font-weight: 600;
70
- color: #fff;
 
 
 
 
71
  text-align: center;
72
- margin: 0;
73
- padding: 5px 10px;
74
- background-color: rgba(0, 0, 0, 0.5);
75
- border-radius: 5px;
76
- width: 90%;
 
 
 
77
  white-space: nowrap;
78
  overflow: hidden;
79
  text-overflow: ellipsis;
80
- z-index: 1;
 
81
  }
82
- .menu-card .card-body {
83
- padding: 10px;
84
- text-align: center;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  }
86
- .menu-card .card-body .card-text.section {
87
- font-size: 0.9rem;
88
- color: #6c757d;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  text-align: center;
90
- margin-bottom: 10px;
 
 
 
 
91
  }
92
- .avatar-dropdown-container {
 
93
  position: absolute;
94
- right: 10px;
95
  top: 50%;
96
  transform: translateY(-50%);
97
- display: flex;
98
- align-items: center;
99
- justify-content: center;
100
- }
101
- .avatar-icon {
102
  width: 40px;
103
  height: 40px;
104
  border-radius: 50%;
105
- background: linear-gradient(45deg, #FF4500, #000000, #1E90FF);
106
- cursor: pointer;
107
  display: flex;
108
  align-items: center;
109
  justify-content: center;
110
- color: white;
111
  font-size: 20px;
112
- font-weight: bold;
 
 
 
 
113
  }
114
- .dropdown-menu {
115
- position: absolute;
 
 
 
 
 
 
 
 
 
116
  right: 0;
117
- top: 100%;
118
- background-color: #fff8f0;
119
- border-radius: 5px;
120
- width: 220px;
121
- box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
122
- display: none;
123
- border: 1px solid #ffd8b1;
124
- z-index: 1000;
125
  }
126
- .dropdown-menu .dropdown-item {
127
- padding: 12px 16px;
128
- text-decoration: none;
129
- color: #333;
130
- border-bottom: 1px solid #ffd8b1;
131
- display: flex;
132
- align-items: center;
133
- font-size: 15px;
134
- transition: background-color 0.2s ease;
135
- background: linear-gradient(45deg, #FF4500, #000000, #1E90FF);
136
- -webkit-background-clip: text;
137
- -webkit-text-fill-color: transparent;
138
- }
139
- .dropdown-menu .dropdown-item i {
140
- margin-right: 10px;
141
- font-size: 16px;
142
- }
143
- .dropdown-menu .dropdown-item:last-child {
144
- border-bottom: none;
145
- }
146
- .dropdown-menu .dropdown-item:hover {
147
- background-color: #ffe4c4;
148
- color: #333;
149
- -webkit-text-fill-color: #333;
150
- }
151
- .fixed-top-bar {
152
- position: relative; /* Change to relative to allow timer positioning */
153
  top: 0;
154
  left: 0;
155
- width: 100%;
156
- height: 54px;
157
- background: linear-gradient(45deg, #FFA07A, #FFB347);
158
- color: white;
159
- padding: 15px;
160
  display: flex;
161
- justify-content: space-between; /* Space out items */
162
  align-items: center;
163
- z-index: 1000;
 
 
 
 
 
 
 
 
164
  }
165
- /* Style for the timer */
166
- #orderTimer {
167
- color: white;
168
- font-weight: bold;
169
- margin-left: auto; /* Push timer to the right */
170
- margin-right: 80px; /* Add some space before avatar */
171
- font-size: 1.1em;
172
- display: none; /* Initially hidden */
173
  }
174
- .back-arrow-container {
175
- position: absolute;
176
- left: 10px;
177
- top: 50%;
178
- transform: translateY(-50%);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  display: flex;
 
180
  align-items: center;
181
- justify-content: center;
182
  }
183
- .back-arrow {
184
- width: 36px;
185
- height: 36px;
186
  border-radius: 50%;
187
- background: linear-gradient(45deg, #FFA07A, #FFB347);
 
188
  display: flex;
189
  align-items: center;
190
  justify-content: center;
191
- color: white;
192
- font-size: 20px;
 
193
  cursor: pointer;
194
- transition: transform 0.2s ease, background-color 0.2s ease;
195
- text-decoration: none;
196
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
 
 
 
197
  }
198
- .back-arrow:hover {
199
- background: linear-gradient(45deg, #FF8C61, #FF9E2C);
200
- transform: scale(1.1);
 
 
 
 
 
 
 
201
  }
202
- .back-arrow:active {
203
- transform: scale(0.95);
 
204
  }
205
- .search-bar-container {
206
- position: absolute;
207
- left: 60px;
208
- top: 50%;
209
- transform: translateY(-50%);
210
- display: flex;
211
- align-items: center;
212
- width: 300px;
213
- max-width: calc(90% - 60px);
214
  position: relative;
 
215
  }
216
- .search-bar-container input {
217
- width: 100%;
218
- padding: 8px 40px 8px 40px;
219
- font-size: 16px;
220
- border-radius: 25px;
221
- border: none;
222
- background-color: #fff;
223
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
224
- outline: none;
225
- transition: border-bottom 0.3s ease;
226
  }
227
- .search-bar-container input:focus {
228
- border-bottom: 2px solid #FFA07A;
 
 
 
 
 
 
 
 
 
229
  }
230
- .search-bar-container input::placeholder {
231
- color: #888;
 
 
 
 
232
  }
233
- .search-icon {
234
- position: absolute;
235
- left: 15px;
236
- font-size: 18px;
237
- color: #888;
 
 
 
 
 
 
238
  }
239
- .mic-icon {
240
- position: absolute;
241
- right: 15px;
242
- font-size: 18px;
243
- color: #888;
244
- cursor: pointer;
245
- transition: color 0.3s ease;
246
  }
247
- .mic-icon.active {
248
- color: #007bff;
 
249
  }
250
- .search-popup {
251
- position: absolute;
252
- top: 100%;
253
- left: 0;
254
- right: 0;
255
- background-color: #fff;
256
- border-radius: 5px;
257
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
258
- max-height: 300px;
259
- overflow-y: auto;
260
- z-index: 1000;
261
- display: none;
262
- margin-top: 5px;
263
  }
264
- .search-popup-item {
265
- display: flex;
266
- align-items: center;
267
- padding: 10px;
268
- border-bottom: 1px solid #eee;
269
- cursor: pointer;
270
- transition: background-color 0.2s ease;
271
  }
272
- .search-popup-item:hover {
273
- background-color: #f8f9fa;
 
274
  }
275
- .search-popup-item img {
276
- width: 50px;
277
- height: 50px;
278
- object-fit: cover;
279
- border-radius: 5px;
280
- margin-right: 10px;
 
 
 
281
  }
282
- .search-popup-item span {
283
- font-size: 14px;
284
- color: #333;
 
 
285
  }
286
- .bottom-action-bar {
287
- position: fixed;
288
- bottom: 0;
289
- left: 0;
290
- right: 0;
291
- background-color: white;
292
- padding: 10px 20px;
293
- display: flex;
294
- justify-content: space-between;
295
- align-items: center;
296
- box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
297
- z-index: 1000;
298
- max-width: 900px;
299
- margin: 0 auto;
300
  }
301
- .bottom-action-bar .btn {
302
- flex: 1;
303
- margin: 0 5px;
304
- padding: 10px 15px;
305
- border-radius: 8px;
306
- font-weight: bold;
307
- font-size: 16px;
308
- color: white;
309
- display: flex;
310
- align-items: center;
311
- justify-content: center;
312
- text-align: center;
313
- min-width: 0;
314
- white-space: nowrap;
315
  }
316
- .bottom-action-bar .btn-order-history {
317
- background-color: #FFA07A;
318
- border-color: #FFA07A;
319
  }
320
- .bottom-action-bar .btn-order-history:hover {
321
- background-color: #FF8C61;
322
- border-color: #FF8C61;
 
 
 
323
  }
324
- .bottom-action-bar .btn-view-cart {
325
- background-color: #0FAA39;
326
- border-color: #0FAA39;
 
327
  }
328
- .bottom-action-bar .btn-view-cart:hover {
329
- background-color: #0D9232;
330
- border-color: #0D9232;
 
 
 
 
 
331
  }
332
- .cart-icon-badge {
333
- background-color: white;
334
- color: #0FAA39;
335
- border-radius: 50%;
336
- width: 20px;
337
- height: 20px;
338
- display: inline-flex;
339
- align-items: center;
340
- justify-content: center;
341
- font-size: 12px;
342
- margin-left: 8px;
343
  }
344
- .no-results {
345
- text-align: center;
346
- font-size: 1.2rem;
347
- color: #6c757d;
348
- margin-top: 20px;
349
- }
350
- @media (max-width: 768px) { /* Adjust breakpoint for better timer placement */
351
- .fixed-top-bar {
352
- height: auto; /* Allow height to adjust */
353
- flex-direction: column; /* Stack items vertically */
354
- padding: 10px;
355
- }
356
- .back-arrow-container {
357
- position: relative; /* Adjust positioning for stacking */
358
- left: auto;
359
- top: auto;
360
- transform: none;
361
- width: 100%;
362
- justify-content: flex-start;
363
- margin-bottom: 10px;
364
- }
365
- .avatar-dropdown-container {
366
- position: absolute; /* Keep avatar positioned */
367
- right: 10px;
368
- top: 10px; /* Adjust top position */
369
- transform: none;
370
- z-index: 1001; /* Ensure avatar is above others */
371
- }
372
- #orderTimer {
373
- position: relative; /* Adjust positioning for stacking */
374
- margin-left: 0;
375
- margin-right: 0;
376
- text-align: center;
377
- width: 100%;
378
- margin-bottom: 10px;
379
- }
380
- .search-bar-container {
381
- position: relative; /* Adjust positioning for stacking */
382
- left: auto;
383
- top: auto;
384
- transform: none;
385
- width: 100%;
386
- max-width: 100%;
387
- margin-bottom: 10px;
388
- }
389
- .search-bar-container input {
390
- padding: 8px 40px 8px 40px;
391
- font-size: 16px;
392
- border-radius: 25px;
393
  }
394
- .menu-heading {
395
- font-size: 1.8rem; /* Adjust heading size */
396
- }
397
- }
398
-
399
- @media (max-width: 576px) {
400
- .fixed-top-bar {
401
- padding: 8px; /* Reduce padding */
402
  }
403
- .back-arrow-container {
404
- margin-bottom: 8px;
 
405
  }
406
- .back-arrow {
407
- width: 32px;
408
- height: 32px;
409
- font-size: 18px;
410
- }
411
- .avatar-dropdown-container {
412
- right: 8px;
413
- top: 8px;
414
- }
415
- .avatar-icon {
416
- width: 36px;
417
- height: 36px;
418
- font-size: 18px;
419
- }
420
- #orderTimer {
421
- font-size: 1em; /* Further reduce timer font size */
422
- margin-bottom: 8px;
423
- }
424
- .search-bar-container {
425
- margin-bottom: 8px;
426
- }
427
- .search-bar-container input {
428
- padding: 6px 35px 6px 35px;
429
- font-size: 14px;
430
- border-radius: 20px;
431
- }
432
- .search-icon {
433
- left: 12px;
434
- font-size: 16px;
435
  }
436
- .mic-icon {
437
- right: 12px;
438
- font-size: 16px;
 
439
  }
440
- .dropdown-menu {
441
- width: 200px; /* Adjust dropdown width */
442
  }
443
- .dropdown-menu .dropdown-item {
444
- padding: 10px 14px;
445
- font-size: 14px;
446
  }
447
- .menu-heading {
448
- font-size: 1.5rem;
449
- padding: 10px 15px;
450
- margin: 15px 0;
451
  }
452
- .menu-card {
453
- max-width: 100%;
454
  }
455
- .card-img-container {
456
- height: 150px;
 
457
  }
458
- .card-title {
 
 
 
459
  font-size: 1rem;
460
- top: 8px;
461
- padding: 4px 8px;
462
  }
463
- .menu-card .card-body .card-text.section {
464
- font-size: 0.8rem;
 
 
 
 
 
 
 
 
 
465
  }
466
- .bottom-action-bar {
467
- padding: 8px 10px;
468
  }
469
- .bottom-action-bar .btn {
470
- padding: 8px 10px;
471
- font-size: 14px;
472
  }
473
- .cart-icon-badge {
474
- width: 18px;
475
- height: 18px;
476
- font-size: 10px;
477
- margin-left: 5px;
478
  }
479
- .search-popup {
480
- width: 100%;
 
 
481
  }
482
- .search-popup-item img {
 
 
 
 
 
 
 
 
 
483
  width: 40px;
484
  height: 40px;
 
 
 
 
 
 
 
 
 
 
 
485
  }
486
- .search-popup-item span {
487
- font-size: 12px;
 
 
488
  }
489
  }
490
  </style>
491
  </head>
492
- <body>
493
- <div class="fixed-top-bar">
494
- <div class="back-arrow-container">
495
- <a href="{{ url_for('menu.menu') }}" class="back-arrow" aria-label="Back to Menu">
496
- <i class="bi bi-arrow-left"></i>
497
- </a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
498
  </div>
499
- <!-- Timer Display Area -->
500
- <div id="orderTimer"></div>
501
- <div class="search-bar-container">
502
- <input type="text" id="searchBar" class="form-control" placeholder="Search items or sections..." autocomplete="off">
503
- <i class="bi bi-search search-icon"></i>
504
- <i class="bi bi-mic mic-icon" id="micIcon"></i>
505
- <div class="search-popup" id="searchPopup"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
506
  </div>
507
- <div class="avatar-dropdown-container">
508
- <div class="avatar-icon">
509
- <span>{{ first_letter }}</span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
510
  </div>
511
- <div class="dropdown-menu">
512
- <a href="{{ url_for('user_details.customer_details') }}" class="dropdown-item"><i class="bi bi-person"></i> View Profile</a>
513
- <a href="{{ url_for('orderhistory.order_history') }}" class="dropdown-item"><i class="bi bi-clock-history"></i> Order History</a>
514
- <a href="{{ url_for('combined_summary.combined_summary') }}" class="dropdown-item"><i class="bi bi-file-earmark-text"></i> MY Summary</a>
515
- <a href="{{ url_for('logout') }}" class="dropdown-item"><i class="bi bi-box-arrow-right"></i> Logout</a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
516
  </div>
 
517
  </div>
518
 
519
- </div>
 
 
 
 
 
 
 
 
 
 
520
 
521
- <div class="container mt-4">
522
- <h1 class="menu-heading">Search Menu Items</h1>
523
- <div class="row" id="menuItems">
524
- {% for section, items in ordered_menu.items() %}
525
- {% for item in items %}
526
- <div class="col-md-6 mb-4 menu-item" data-name="{{ item.Name | default('Unnamed Item') }}" data-section="{{ item.Section__c | default(section) }}">
527
- <div class="card menu-card" onclick="selectItem('{{ item.Name | default('Unnamed Item') }}', '{{ item.Section__c | default(section) }}')">
528
- <div class="card-img-container">
529
- <img src="{{ item.Image1__c | default('/static/placeholder.jpg') }}" alt="{{ item.Name | default('Unnamed Item') }}" class="card-img" loading="eager" decoding="async" width="350" height="200">
530
- <h5 class="card-title">{{ item.Name | default('Unnamed Item') }}</h5>
531
- </div>
532
- <div class="card-body">
533
- <p class="card-text section">{{ item.Section__c | default(section) }}</p>
534
- </div>
 
 
 
 
 
535
  </div>
536
  </div>
537
- {% endfor %}
538
- {% endfor %}
539
- </div>
540
- <div class="no-results" id="noResults" style="display: none;">
541
- No items found matching your search.
542
  </div>
 
 
 
 
 
543
  </div>
544
 
545
- <div class="bottom-action-bar">
546
- <a href="{{ url_for('orderhistory.order_history') }}" class="btn btn-order-history">
547
- <i class="bi bi-clock-history"></i> Order History
548
- </a>
549
- <a href="{{ url_for('cart.cart') }}" class="btn btn-view-cart">
550
- <i class="bi bi-cart"></i> View Cart
551
- <span id="cart-item-count" class="cart-icon-badge" style="display: none;">0</span>
552
- </a>
553
- </div>
554
-
555
- <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
556
  <script>
557
- const menuItems = [
558
- {% for section, items in ordered_menu.items() %}
559
- {% for item in items %}
560
- {
561
- name: "{{ item.Name | default('Unnamed Item') }}",
562
- section: "{{ item.Section__c | default(section) }}",
563
- image: "{{ item.Image1__c | default('/static/placeholder.jpg') }}"
564
- },
565
- {% endfor %}
566
- {% endfor %}
567
- ];
 
568
 
569
- function updateCartUI(cart) {
570
- if (!Array.isArray(cart)) {
571
- console.error('Invalid cart data:', cart);
572
- return;
 
 
 
 
 
 
 
 
573
  }
574
- let totalQuantity = 0;
575
- cart.forEach(item => {
576
- totalQuantity += item.quantity;
577
- });
578
- const cartItemCount = document.getElementById('cart-item-count');
579
- if (cartItemCount) {
580
- cartItemCount.innerText = totalQuantity;
581
- cartItemCount.style.display = totalQuantity > 0 ? 'inline-flex' : 'none';
 
 
582
  }
583
  }
584
 
585
- function getCartLocalStorage() {
586
- return JSON.parse(localStorage.getItem('cart')) || [];
 
 
 
 
 
 
587
  }
588
 
589
- function selectItem(itemName, section) {
590
- localStorage.setItem('selectedItem', JSON.stringify({ name: itemName, section: section }));
591
- window.location.href = '/menu'; // Assuming '/menu' is the detail page
 
 
 
 
 
 
 
 
 
 
592
  }
593
 
594
- function filterMenuItems(query) {
595
- const menuItemElements = document.querySelectorAll('.menu-item');
596
- const noResults = document.getElementById('noResults');
597
- let hasResults = false;
 
598
 
599
- menuItemElements.forEach(item => {
600
- const name = item.getAttribute('data-name').toLowerCase();
601
- const section = item.getAttribute('data-section').toLowerCase();
602
- const matches = name.includes(query.toLowerCase()) || section.includes(query.toLowerCase());
603
- item.style.display = matches ? '' : 'none';
604
- if (matches) hasResults = true;
605
- });
606
 
607
- noResults.style.display = hasResults ? 'none' : 'block';
608
- }
609
 
610
- function showSearchPopup(query) {
611
- const searchPopup = document.getElementById('searchPopup');
612
- searchPopup.innerHTML = '';
613
- if (!query) {
614
- searchPopup.style.display = 'none';
615
- return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
616
  }
 
617
 
618
- const filteredItems = menuItems.filter(item =>
619
- item.name.toLowerCase().includes(query.toLowerCase()) ||
620
- item.section.toLowerCase().includes(query.toLowerCase())
621
- );
 
622
 
623
- if (filteredItems.length === 0) {
624
- searchPopup.style.display = 'none';
625
- return;
626
- }
627
 
628
- filteredItems.forEach(item => {
629
- const popupItem = document.createElement('div');
630
- popupItem.className = 'search-popup-item';
631
- popupItem.innerHTML = `
632
- <img src="${item.image}" alt="${item.name}">
633
- <span>${item.name}</span>
634
- `;
635
- popupItem.addEventListener('click', () => {
636
- selectItem(item.name, item.section);
637
- });
638
- searchPopup.appendChild(popupItem);
639
- });
 
 
 
 
 
 
 
640
 
641
- searchPopup.style.display = 'block';
 
 
 
 
642
  }
643
 
644
- document.addEventListener('DOMContentLoaded', function () {
645
- // Avatar Dropdown
646
- const avatarContainer = document.querySelector('.avatar-dropdown-container');
647
- const dropdownMenu = document.querySelector('.dropdown-menu');
648
- avatarContainer.addEventListener('click', function (event) {
649
- event.stopPropagation();
650
- dropdownMenu.style.display = dropdownMenu.style.display === 'block' ? 'none' : 'block';
651
- });
652
- document.addEventListener('click', function (event) {
653
- if (!avatarContainer.contains(event.target)) {
654
- dropdownMenu.style.display = 'none';
655
  }
656
- });
657
- const dropdownItems = document.querySelectorAll('.dropdown-item');
658
- dropdownItems.forEach(item => {
659
- item.addEventListener('click', function () {
660
- dropdownMenu.style.display = 'none';
661
- });
662
- });
663
 
664
- // Search Bar Functionality
665
- const searchBar = document.getElementById('searchBar');
666
- const searchPopup = document.getElementById('searchPopup');
667
- const searchQuery = localStorage.getItem('searchQuery');
668
- if (searchQuery) {
669
- searchBar.value = searchQuery;
670
- filterMenuItems(searchQuery);
671
- showSearchPopup(searchQuery);
672
- localStorage.removeItem('searchQuery');
673
- }
674
- searchBar.addEventListener('input', function () {
675
- filterMenuItems(this.value);
676
- showSearchPopup(this.value);
677
- });
678
- document.addEventListener('click', function (event) {
679
- if (!searchBar.contains(event.target) && !searchPopup.contains(event.target)) {
680
- searchPopup.style.display = 'none';
681
  }
682
- });
 
 
683
 
684
- // Voice Recognition
685
- const micIcon = document.getElementById('micIcon');
686
- if ('SpeechRecognition' in window || 'webkitSpeechRecognition' in window) {
687
- const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
688
- const recognition = new SpeechRecognition();
689
- recognition.lang = 'en-US';
690
- recognition.onstart = () => micIcon.classList.add('active');
691
- recognition.onresult = (event) => {
692
- const query = event.results[0][0].transcript.trim();
693
- searchBar.value = query;
694
- filterMenuItems(query);
695
- showSearchPopup(query);
696
- };
697
- recognition.onend = () => micIcon.classList.remove('active');
698
- recognition.onerror = (event) => {
699
- micIcon.classList.remove('active');
700
- console.error('Speech error:', event.error);
701
- };
702
- micIcon.addEventListener('click', () => {
703
- recognition.start();
704
  });
 
705
  } else {
706
- micIcon.style.display = 'none';
707
- }
708
-
709
- // Fetch Cart
710
- fetch('/cart/get')
711
- .then(response => {
712
- if (!response.ok) {
713
- throw new Error(`HTTP error! Status: ${response.status}`);
714
- }
715
- return response.json();
716
- })
717
- .then(data => {
718
- if (data.success) {
719
- updateCartUI(data.cart);
720
- } else {
721
- console.error('Failed to fetch cart:', data.error);
722
- const cart = getCartLocalStorage();
723
- updateCartUI(cart);
724
- }
725
- })
726
- .catch(err => {
727
- console.error('Error fetching cart:', err);
728
- const cart = getCartLocalStorage();
729
- updateCartUI(cart);
730
  });
 
731
 
732
- // --- Timer Logic ---
733
- const orderTimerElement = document.getElementById('orderTimer');
734
- // Get timestamp from Flask template (passed from server)
735
- const completionTimeTimestamp = {{ order_completion_time | default('null') }};
736
-
737
- let timerInterval = null; // Variable to hold the interval ID
738
 
739
- function startTimer(timestamp) {
740
- orderTimerElement.style.display = 'block';
741
- const completionTime = new Date(timestamp * 1000); // Convert timestamp to Date object
 
 
742
 
743
- function updateTimer() {
744
- const now = new Date();
745
- const timeRemaining = completionTime - now;
746
 
747
- if (timeRemaining <= 0) {
748
- orderTimerElement.innerText = 'Order Ready!';
749
- // Clear timer and local storage
750
- clearInterval(timerInterval);
751
- localStorage.removeItem('orderCompletionTime');
752
- // Refresh the page after a short delay
753
- setTimeout(() => {
754
- window.location.reload();
755
- }, 2000); // Refresh after 2 seconds
756
- return;
757
- }
758
 
759
- const minutes = Math.floor((timeRemaining % (1000 * 60 * 60)) / (1000 * 60));
760
- const seconds = Math.floor((timeRemaining % (1000 * 60)) / 1000);
 
761
 
762
- // Add leading zeros if needed
763
- const displayMinutes = String(minutes).padStart(2, '0');
764
- const displaySeconds = String(seconds).padStart(2, '0');
765
 
766
- orderTimerElement.innerText = `Ready In: ${displayMinutes}m ${displaySeconds}s`;
767
- }
768
 
769
- // Initial call to display the timer immediately
770
- updateTimer();
 
 
 
 
 
 
 
 
 
 
 
 
771
 
772
- // Update the timer every second
773
- timerInterval = setInterval(updateTimer, 1000);
774
 
775
- // Store completion time in local storage for persistence
776
- localStorage.setItem('orderCompletionTime', timestamp);
 
 
 
 
 
 
 
 
 
 
 
 
777
  }
 
778
 
779
- // Check if a completion time was passed from the server (new order)
780
- if (completionTimeTimestamp) {
781
- startTimer(completionTimeTimestamp);
782
- } else {
783
- // If not from server, check local storage for an existing timer
784
- const storedCompletionTime = localStorage.getItem('orderCompletionTime');
785
- if (storedCompletionTime) {
786
- const parsedCompletionTime = parseFloat(storedCompletionTime);
787
- // Ensure stored time is valid and in the future
788
- if (!isNaN(parsedCompletionTime) && new Date(parsedCompletionTime * 1000) > new Date()) {
789
- startTimer(parsedCompletionTime);
790
- } else {
791
- // Clear invalid or past timestamp from local storage
792
- localStorage.removeItem('orderCompletionTime');
793
- }
794
  }
795
- }
796
- // --- End Timer Logic ---
 
 
 
 
 
 
 
 
 
 
797
  });
798
  </script>
799
  </body>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <meta http-equiv="x-ua-compatible" content="ie=edge">
7
+ <title>Order Summary</title>
8
+ <script src="https://cdn.tailwindcss.com"></script>
 
 
 
9
  <style>
10
+ /* Custom animations */
11
+ @keyframes fadeIn {
12
+ from { opacity: 0; transform: translateY(10px); }
13
+ to { opacity: 1; transform: translateY(0); }
 
 
 
 
14
  }
15
+ @keyframes lightMoveUp {
16
+ 0% { background-position: 0 100%; }
17
+ 100% { background-position: 0 0%; }
18
  }
19
+ @keyframes shine {
20
+ from { transform: rotate(0deg) translateX(-100%); }
21
+ to { transform: rotate(25deg) translateX(100%); }
22
+ }
23
+ @keyframes pulse {
24
+ 0% { box-shadow: 0 0 0 0 rgba(255, 179, 71, 0.7); }
25
+ 70% { box-shadow: 0 0 0 10px rgba(255, 179, 71, 0); }
26
+ 100% { box-shadow: 0 0 0 0 rgba(255, 179, 71, 0); }
27
+ }
28
+ @keyframes slideDown {
29
+ from { max-height: 0; opacity: 0; }
30
+ to { max-height: 1000px; opacity: 1; }
31
+ }
32
+ .modal, .popup {
33
+ animation: fadeIn 0.3s ease-in-out;
34
+ }
35
+ .progress-bar {
36
+ transition: width 0.6s ease-in-out, background 0.3s ease-in-out;
37
+ }
38
+ /* Progress bar color ranges */
39
+ .progress-bar.range-0-100 {
40
+ background: linear-gradient(90deg, #2DD4BF, #5EEAD4);
41
+ }
42
+ .progress-bar.range-100-200 {
43
+ background: linear-gradient(90deg, #10B981, #34D399);
44
+ }
45
+ .progress-bar.range-200-plus {
46
+ background: linear-gradient(90deg, #F59E0B, #FBBF24);
47
+ }
48
+ .ingredient-button:hover .ingredient-image {
49
+ transform: scale(1.1);
50
+ border-color: #10B981;
51
+ }
52
+ .tier-badge {
53
+ position: relative;
54
+ overflow: hidden;
55
+ background-color: #FFB347;
56
+ animation: pulse 2s infinite;
57
+ will-change: box-shadow;
58
+ }
59
+ .tier-badge::after {
60
+ content: '';
61
+ position: absolute;
62
+ top: -50%;
63
+ left: -50%;
64
+ width: 200%;
65
+ height: 200%;
66
+ background: linear-gradient(45deg, transparent 0%, rgba(255, 255, 255, 0.3) 50%, transparent 100%);
67
+ animation: shine 3s infinite;
68
+ }
69
+ /* Custom class for order items */
70
+ .custom-class {
71
  text-align: center;
72
+ border-radius: 12px;
73
+ border-width: 1px;
74
+ border-color: #E5E7EB;
75
+ padding: 24px !important;
76
+ margin-bottom: 16px;
77
+ background-color: #FFFFFF;
78
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
79
+ transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
80
  width: 100%;
81
+ max-width: clamp(288px, 100%, 488px);
82
  margin-left: auto;
83
  margin-right: auto;
84
  }
85
+ .custom-class:hover {
86
+ transform: translateY(-2px);
87
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
 
 
 
 
 
 
 
88
  }
89
+ /* Order image wrapper for positioning text */
90
+ .order-image-wrapper {
91
  position: relative;
92
+ display: block;
93
+ margin-bottom: 16px;
94
  }
95
+ /* Order image styles */
96
+ .order-image {
97
+ max-width: 100%;
98
+ max-height: 330px;
99
+ width: auto;
100
+ height: auto;
101
+ aspect-ratio: 4/3;
102
+ object-fit: contain;
103
+ border-radius: 10px;
104
+ border: 3px solid #D1D5DB;
105
+ box-sizing: border-box;
106
+ box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
107
+ transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
108
+ will-change: transform, box-shadow;
109
  display: block;
110
+ margin: 0 auto 20px;
111
  }
112
+ .order-image:hover {
113
+ transform: scale(1.04);
114
+ box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
115
+ }
116
+ /* Fallback for placeholder images */
117
+ .order-image[src$="placeholder.jpg"] {
118
+ background: linear-gradient(135deg, #F9FAFB, #E5E7EB);
119
+ object-fit: contain;
120
+ }
121
+ /* Item name below image */
122
+ .order-item-name {
123
+ display: block;
124
  text-align: center;
125
+ color: #000000;
126
+ font-size: 1.5rem;
127
+ font-weight: 600;
128
+ margin-top: 12px;
129
+ padding: 8px 16px;
130
+ background: #FFFFFF;
131
+ border-radius: 8px;
132
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
133
  white-space: nowrap;
134
  overflow: hidden;
135
  text-overflow: ellipsis;
136
+ max-width: 100%;
137
+ transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
138
  }
139
+ .order-image-wrapper:hover .order-item-name {
140
+ transform: translateY(-2px);
141
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
142
+ }
143
+ .history {
144
+ display: flex;
145
+ justify-content: center;
146
+ font-size: 1.75rem;
147
+ font-weight: 700;
148
+ padding: 1.5rem;
149
+ background: linear-gradient(45deg, #FFF7ED, #FFE4D6);
150
+ border-radius: 8px;
151
+ margin-bottom: 1rem;
152
+ }
153
+ /* Scrollable sector images */
154
+ .sector-images-container {
155
+ position: relative;
156
+ display: flex;
157
+ flex-wrap: nowrap;
158
+ overflow-x: auto;
159
+ overflow-y: hidden;
160
+ padding: 0 10px;
161
+ gap: 20px;
162
+ width: 100%;
163
+ max-width: none;
164
+ scroll-behavior: smooth;
165
+ scrollbar-width: thin;
166
+ scrollbar-color: #FFB347 #E5E7EB;
167
+ }
168
+ .sector-images-container::-webkit-scrollbar {
169
+ height: 8px;
170
+ }
171
+ .sector-images-container::-webkit-scrollbar-track {
172
+ background: #E5E7EB;
173
  }
174
+ .sector-images-container::-webkit-scrollbar-thumb {
175
+ background: #FFB347;
176
+ border-radius: 4px;
177
+ }
178
+ .sector-item {
179
+ display: flex;
180
+ flex-direction: column;
181
+ align-items: center;
182
+ margin: 0 auto;
183
+ flex-shrink: 0;
184
+ background: #FFF7ED;
185
+ border-radius: 8px;
186
+ padding: 8px;
187
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
188
+ transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
189
+ }
190
+ .sector-item:hover {
191
+ transform: translateY(-2px);
192
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
193
+ }
194
+ .sector-image {
195
+ max-width: 150px;
196
+ max-height: 100px;
197
+ width: auto;
198
+ height: auto;
199
+ aspect-ratio: 3/2;
200
+ object-fit: contain;
201
+ cursor: pointer;
202
+ border-radius: 8px;
203
+ border: 1px solid #D1D5DB;
204
+ box-sizing: border-box;
205
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
206
+ transition: transform 0.15s ease-in-out;
207
+ will-change: transform;
208
+ }
209
+ .sector-image:hover {
210
+ transform: scale(1.08);
211
+ }
212
+ .sector-name {
213
  text-align: center;
214
+ font-size: 0.75rem;
215
+ font-weight: 600;
216
+ margin-top: 6px;
217
+ max-width: 150px;
218
+ color: #1F2937;
219
  }
220
+ /* Scroll buttons */
221
+ .scroll-button {
222
  position: absolute;
 
223
  top: 50%;
224
  transform: translateY(-50%);
225
+ background: #FFB347;
226
+ color: #FFFFFF;
 
 
 
227
  width: 40px;
228
  height: 40px;
229
  border-radius: 50%;
 
 
230
  display: flex;
231
  align-items: center;
232
  justify-content: center;
 
233
  font-size: 20px;
234
+ cursor: pointer;
235
+ opacity: 0;
236
+ transition: opacity 0.3s ease-in-out, transform 0.2s ease-in-out;
237
+ z-index: 10;
238
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
239
  }
240
+ .scroll-button:hover {
241
+ background: #FF9E2C;
242
+ transform: translateY(-50%) scale(1.1);
243
+ }
244
+ .sector-images-container:hover .scroll-button {
245
+ opacity: 1;
246
+ }
247
+ .scroll-button.left {
248
+ left: 0;
249
+ }
250
+ .scroll-button.right {
251
  right: 0;
 
 
 
 
 
 
 
 
252
  }
253
+ /* Full-width gradient header */
254
+ .back-to-menu {
255
+ position: fixed;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
256
  top: 0;
257
  left: 0;
258
+ right: 0;
 
 
 
 
259
  display: flex;
 
260
  align-items: center;
261
+ padding: 14px 24px;
262
+ background: linear-gradient(45deg, #FFA07A, #FFB347);
263
+ color: #FFFFFF;
264
+ font-size: 1.125rem;
265
+ font-weight: 600;
266
+ text-decoration: none;
267
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
268
+ z-index: 9999;
269
+ transition: background-color 0.3s ease, transform 0.2s ease;
270
  }
271
+ .back-to-menu:hover {
272
+ background: linear-gradient(45deg, #FF8C61, #FF9E2C);
273
+ transform: translateY(-1px);
 
 
 
 
 
274
  }
275
+ /* Content spacing */
276
+ .container {
277
+ margin-top: 90px;
278
+ max-width: 100%;
279
+ padding: 20px;
280
+ }
281
+ /* Sector popup */
282
+ #sector-popup {
283
+ display: none;
284
+ position: fixed;
285
+ inset: 0;
286
+ background: rgba(17, 24, 39, 0.6);
287
+ justify-content: center;
288
+ align-items: center;
289
+ z-index: 10000;
290
+ animation: fadeIn 0.3s ease-in-out;
291
+ }
292
+ #popup-content {
293
+ background: linear-gradient(135deg, #FFFFFF 0%, #F9FAFB 100%);
294
+ padding: 24px;
295
+ border-radius: 12px;
296
+ width: 90%;
297
+ max-width: 550px;
298
+ max-height: 85vh;
299
+ overflow-y: auto;
300
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
301
+ border: 1px solid #E5E7EB;
302
+ position: relative;
303
+ contain: layout;
304
+ }
305
+ .popup-header {
306
+ position: relative;
307
+ padding-bottom: 12px;
308
+ margin-bottom: 16px;
309
+ border-bottom: 2px solid #FFB347;
310
  display: flex;
311
+ justify-content: space-between;
312
  align-items: center;
 
313
  }
314
+ .popup-close {
315
+ background: #FFB347;
316
+ color: #FFFFFF;
317
  border-radius: 50%;
318
+ width: 40px;
319
+ height: 40px;
320
  display: flex;
321
  align-items: center;
322
  justify-content: center;
323
+ font-size: 24px;
324
+ font-weight: bold;
325
+ border: none;
326
  cursor: pointer;
327
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
328
+ line-height: 1;
329
+ padding: 0;
330
+ position: relative;
331
+ overflow: hidden;
332
+ will-change: transform, background;
333
  }
334
+ .popup-close::before {
335
+ content: '';
336
+ position: absolute;
337
+ top: 100%;
338
+ left: 0;
339
+ width: 100%;
340
+ height: 100%;
341
+ background: linear-gradient(to top, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0) 100%);
342
+ animation: lightMoveUp 1.5s infinite linear;
343
+ z-index: 0;
344
  }
345
+ .popup-close:hover {
346
+ background: #FF9E2C;
347
+ transform: scale(1.1);
348
  }
349
+ .popup-close span {
 
 
 
 
 
 
 
 
350
  position: relative;
351
+ z-index: 1;
352
  }
353
+ /* Ingredient modal */
354
+ .ingredient-modal-container {
355
+ display: none;
356
+ position: fixed;
357
+ inset: 0;
358
+ background: rgba(0, 0, 0, 0.6);
359
+ justify-content: center;
360
+ align-items: center;
361
+ z-index: 10000;
362
+ animation: fadeIn 0.3s ease-in-out;
363
  }
364
+ .ingredient-modal {
365
+ background: linear-gradient(135deg, #FFFFFF 0%, #F9FAFB 100%);
366
+ border-radius: 12px;
367
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
368
+ border: 1px solid #E5E7EB;
369
+ width: 90%;
370
+ max-width: 500px;
371
+ max-height: 90vh;
372
+ overflow-y: auto;
373
+ position: relative;
374
+ contain: layout;
375
  }
376
+ .modal-section {
377
+ padding: 16px;
378
+ border-left: 4px solid #2DD4BF;
379
+ margin-bottom: 16px;
380
+ background: #F9FAFB;
381
+ border-radius: 6px;
382
  }
383
+ /* Ingredient images */
384
+ .ingredient-image {
385
+ max-width: 100%;
386
+ max-height: 100px;
387
+ width: 100%;
388
+ height: 100px;
389
+ aspect-ratio: 1/1;
390
+ object-fit: cover;
391
+ border-radius: 6px;
392
+ border: 1px solid #D1D5DB;
393
+ transition: transform 0.3s ease-in-out, border-color 0.3s ease-in-out;
394
  }
395
+ /* Hover effect for ingredient buttons */
396
+ .ingredient-button:hover .ingredient-image {
397
+ transform: scale(1.1);
398
+ border-color: #10B981;
 
 
 
399
  }
400
+ /* Green border when section is visible */
401
+ .ingredients выполнение-section:not(.hidden) .ingredient-image {
402
+ border: 2px solid #10B981;
403
  }
404
+ /* Ensure ingredient section is smooth */
405
+ .ingredients-section {
406
+ transition: opacity 0.3s ease-in-out, max-height 0.3s ease-in-out;
407
+ max-height: 0;
408
+ opacity: 0;
409
+ overflow: hidden;
 
 
 
 
 
 
 
410
  }
411
+ .ingredients-section:not(.hidden) {
412
+ max-height: 1000px;
413
+ opacity: 1;
 
 
 
 
414
  }
415
+ /* Prevent body scroll when modal is open */
416
+ body.modal-open {
417
+ overflow: hidden;
418
  }
419
+ /* Fallback messages */
420
+ .no-data {
421
+ text-align: center;
422
+ color: #6B7280;
423
+ font-size: 1.125rem;
424
+ padding: 20px;
425
+ background: #F9FAFB;
426
+ border-radius: 8px;
427
+ margin-bottom: 20px;
428
  }
429
+ /* Order confirmed section */
430
+ .order-confirmed {
431
+ background: linear-gradient(135deg, #FFF7ED 0%, #FFE4D6 100%);
432
+ position: relative;
433
+ overflow: hidden;
434
  }
435
+ .order-confirmed::before {
436
+ content: '✔';
437
+ position: absolute;
438
+ top: 50%;
439
+ left: 50%;
440
+ transform: translate(-50%, -50%);
441
+ font-size: 120px;
442
+ color: rgba(16, 185, 129, 0.1);
443
+ z-index: 0;
 
 
 
 
 
444
  }
445
+ .order-confirmed h1 {
446
+ font-size: 2.25rem;
447
+ z-index: 1;
448
+ position: relative;
 
 
 
 
 
 
 
 
 
 
449
  }
450
+ .order-confirmed.hidden {
451
+ display: none; /* Add a hidden class for the confirmation section */
 
452
  }
453
+ /* Tier details animation */
454
+ .tier-details {
455
+ overflow: hidden;
456
+ transition: max-height 0.5s ease-in-out, opacity 0.3s ease-in-out;
457
+ max-height: 0;
458
+ opacity: 0;
459
  }
460
+ .tier-details:not(.hidden) {
461
+ max-height: 1000px;
462
+ opacity: 1;
463
+ animation: slideDown 0.5s ease-in-out;
464
  }
465
+ /* Price badge */
466
+ .price-badge {
467
+ display: inline-block;
468
+ background: #FFE4D6;
469
+ padding: 6px 14px;
470
+ border-radius: 14px;
471
+ font-weight: 600;
472
+ color: #C2410C;
473
  }
474
+ /* Show Ingredients button focus style */
475
+ .ingredients-toggle-button:focus {
476
+ outline: none;
477
+ transform: scale(1.05);
 
 
 
 
 
 
 
478
  }
479
+ /* Responsive adjustments */
480
+ @media (max-width: 768px) {
481
+ .custom-class {
482
+ padding: 20px !important;
483
+ max-width: 400px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
484
  }
485
+ .order-image {
486
+ max-height: 270px;
 
 
 
 
 
 
487
  }
488
+ .order-item-name {
489
+ font-size: 1.25rem;
490
+ padding: 6px 12px;
491
  }
492
+ .grid {
493
+ grid-template-columns: repeat(2, 1fr);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
494
  }
495
+ }
496
+ @media (max-width: 480px) {
497
+ .custom-class {
498
+ max-width: 336px;
499
  }
500
+ .order-image {
501
+ max-height: 225px;
502
  }
503
+ .order-item-name {
504
+ font-size: 1.125rem;
 
505
  }
506
+ }
507
+ @media (max-width: 360px) {
508
+ .custom-class {
509
+ max-width: 296px;
510
  }
511
+ .order-image {
512
+ max-height: 195px;
513
  }
514
+ .order-item-name {
515
+ font-size: 1rem;
516
+ padding: 4px 10px;
517
  }
518
+ }
519
+ @media (max-width: 640px) {
520
+ .back-to-menu {
521
+ padding: 12px 16px;
522
  font-size: 1rem;
 
 
523
  }
524
+ .container {
525
+ margin-top: 70px;
526
+ padding: 16px;
527
+ }
528
+ .history {
529
+ font-size: 1.5rem;
530
+ padding: 1rem;
531
+ }
532
+ .sector-image {
533
+ max-width: 120px;
534
+ max-height: 80px;
535
  }
536
+ .sector-name {
537
+ max-width: 120px;
538
  }
539
+ .sector-item {
540
+ padding: 6px;
 
541
  }
542
+ .order-confirmed h1 {
543
+ font-size: 1.75rem;
 
 
 
544
  }
545
+ .scroll-button {
546
+ width: 32px;
547
+ height: 32px;
548
+ font-size: 16px;
549
  }
550
+ #popup-content {
551
+ width: 95%;
552
+ padding: 16px;
553
+ max-height: 80vh;
554
+ }
555
+ .ingredient-modal {
556
+ width: 95%;
557
+ max-height: 80vh;
558
+ }
559
+ .popup-close {
560
  width: 40px;
561
  height: 40px;
562
+ font-size: 24px;
563
+ }
564
+ .popup-close::before {
565
+ animation: lightMoveUp 1.2s infinite linear;
566
+ }
567
+ .ingredient-image {
568
+ max-height: 80px;
569
+ height: 80px;
570
+ }
571
+ .grid {
572
+ grid-template-columns: repeat(2, 1fr);
573
  }
574
+ }
575
+ @media (min-width: 768px) {
576
+ .grid {
577
+ grid-template-columns: repeat(3, 1fr);
578
  }
579
  }
580
  </style>
581
  </head>
582
+ <body class="bg-gray-50">
583
+ <a href="{{ url_for('menu.menu') }}" class="back-to-menu" aria-label="Go back to menu">
584
+ <svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 mr-2" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
585
+ <path d="M15 18l-6-6 6-6"></path>
586
+ </svg>
587
+ Back to Menu
588
+ </a>
589
+
590
+ <div class="container mx-auto p-6 pt-2">
591
+ <!-- Order Confirmation -->
592
+ <!-- Added a hidden input to store delivery time in seconds -->
593
+ <input type="hidden" id="deliveryTimeSeconds" value="{{ delivery_time_seconds | default('') }}">
594
+
595
+ <div id="orderConfirmationSection" class="section bg-white shadow-sm rounded-xl p-6 mb-6 order-confirmed {% if delivery_time_seconds is none or delivery_time_seconds == '' %}hidden{% endif %}" role="alert">
596
+ <h1 class="text-center text-2xl font-bold text-orange-500">Order Confirmed!</h1>
597
+ <p class="text-center text-gray-600 mt-2">Estimated delivery time: <span id="countdownTimer"></span></p>
598
+ </div>
599
+
600
+ <!-- Reward Status Section -->
601
+ <div class="section bg-white rounded-xl shadow-lg p-6 mb-6">
602
+ <div class="flex items-center justify-between mb-4 cursor-pointer" onclick="toggleTierDetails()" aria-expanded="false" aria-controls="tierDetails">
603
+ <div id="tierBadge" class="w-8 h-8 p-1 rounded-full flex items-center justify-center tier-badge">
604
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="text-white">
605
+ <path d="M6 9H4.5a2.5 2.5 0 0 1 0-5H6"></path>
606
+ <path d="M18 9h1.5a2.5 2.5 0 0 0 0-5H18"></path>
607
+ <path d="M4 22h16"></path>
608
+ <path d="M10 14.66V17c0 .55-.47.98-.97 1.21C7.85 18.75 7 20.24 7 22"></path>
609
+ <path d="M14 14.66V17c0 .55.47.98.97 1.21C16.15 18.75 17 20.24 17 22"></path>
610
+ <path d="M9 9c0 .97.64 1.79 1.5 2.05A2 2 0 0 1 12 13c.82 0 1.54-.39 2-1"></path>
611
+ <path d="M18 9H6a4 4 0 0 1 0-8h12a4 4 0 0 1 0 8Z"></path>
612
+ </svg>
613
+ </div>
614
+ <span class="ml-2 text-xl font-bold text-orange-500" id="currentTier">{{ current_tier }} Tier</span>
615
+ <svg id="arrowIcon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="text-gray-600">
616
+ <path id="arrowPath" d="M19 9l-7 7-7-7"></path>
617
+ </svg>
618
+ </div>
619
+
620
+ <!-- Collapsible Content Section -->
621
+ <div id="tierDetails" class="tier-details hidden">
622
+ <div class="text-center mb-6">
623
+ <p class="text-gray-600">Valid through December {{ validity_year }}</p>
624
+ <p class="text-lg font-semibold mt-2 text-yellow-600" id="pointsDisplay">{{ user_points }} points</p>
625
+ </div>
626
+
627
+ <!-- Progress Bar -->
628
+ <div class="relative h-4 bg-gray-200 rounded-full overflow-hidden mb-4">
629
+ <div id="progressBar" class="absolute left-0 top-0 h-full progress-bar" style="width: {{ progress_percentage }}%"></div>
630
+ </div>
631
+
632
+ <div class="flex justify-between text-sm text-gray-600 mb-4">
633
+ <span id="startPoint">{{ start_point }}</span>
634
+ <span id="endPoint">{{ end_point }}</span>
635
+ </div>
636
+
637
+ <p class="text-center text-gray-700">
638
+ You need <span class="font-semibold text-gray-800" id="pointsNeeded">{{ points_needed_for_next_tier }}</span> more
639
+ points to reach
640
+ <span class="font-semibold text-orange-500" id="nextTier">{{ next_tier }}</span>
641
+ </p>
642
+
643
+ <!-- Tier Benefits -->
644
+ <div class="mt-6 bg-gray-50 rounded-xl p-4">
645
+ <h3 class="text-lg font-semibold mb-4 text-gray-800" id="benefitsTitle">
646
+ Benefits of Reaching {{ next_tier }} Tier
647
+ </h3>
648
+ <ul class="space-y-3" id="benefitsList">
649
+ {% if next_tier == "Silver" %}
650
+ <li class="flex items-center">
651
+ <span class="text-2xl mr-3">🏷️</span>
652
+ <span class="text-gray-700">10% discount on next purchase</span>
653
+ </li>
654
+ <li class="flex items-center">
655
+ <span class="text-2xl mr-3">🍹</span>
656
+ <span class="text-gray-700">Free soft drink with your next order</span>
657
+ </li>
658
+ {% elif next_tier == "Gold" %}
659
+ <li class="flex items-center">
660
+ <span class="text-2xl mr-3">🏷️</span>
661
+ <span class="text-gray-700">15% discount on next purchase</span>
662
+ </li>
663
+ <li class="flex items-center">
664
+ <span class="text-2xl mr-3">🍰</span>
665
+ <span class="text-gray-700">Free dessert on next order</span>
666
+ </li>
667
+ {% elif next_tier == "Platinum" %}
668
+ <li class="flex items-center">
669
+ <span class="text-2xl mr-3">🏷️</span>
670
+ <span class="text-gray-700">20% discount on next purchase</span>
671
+ </li>
672
+ <li class="flex items-center">
673
+ <span class="text-2xl mr-3">🍴</span>
674
+ <span class="text-gray-700">Free entrée with your next order</span>
675
+ </li>
676
+ {% else %}
677
+ <li class="text-gray-700">You've reached the highest tier! Enjoy exclusive benefits.</li>
678
+ {% endif %}
679
+ </ul>
680
+ </div>
681
+ </div>
682
+ </div>
683
+
684
+ <!-- Ingredient History -->
685
+ <div class="history">
686
+ <h1 class="text-center text-2xl font-bold text-orange-500">Ingredient History</h1>
687
  </div>
688
+ {% if sector_details %}
689
+ <div class="sector-images-container" role="region" aria-label="Ingredient History Carousel">
690
+ <button class="scroll-button left" onclick="scrollContainer('left')" aria-label="Scroll left">
691
+ <svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
692
+ <path d="M15 18l-6-6 6-6"></path>
693
+ </svg>
694
+ </button>
695
+ {% for sector_name, sector in sector_details.items() %}
696
+ <div class="sector-item">
697
+ <img
698
+ src="{{ sector.image_url | default('/static/placeholder.jpg') }}"
699
+ alt="{{ sector_name }}"
700
+ class="sector-image lazyload"
701
+ loading="lazy"
702
+ onclick="showSectorDescription('{{ sector.description | escape }}')"
703
+ role="img"
704
+ aria-describedby="sector-name-{{ loop.index }}"
705
+ onerror="this.src='/static/placeholder.jpg'; this.alt='Placeholder image'"
706
+ >
707
+ <h3 id="sector-name-{{ loop.index }}" class="sector-name">{{ sector_name }}</h3>
708
+ </div>
709
+ {% endfor %}
710
+ <button class="scroll-button right" onclick="scrollContainer('right')" aria-label="Scroll right">
711
+ <svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
712
+ <path d="M9 18l6-6-6-6"></path>
713
+ </svg>
714
+ </button>
715
+ </div>
716
+ {% else %}
717
+ <div class="no-data">No sector details available.</div>
718
+ {% endif %}
719
+
720
+ <!-- Popup for Sector Description -->
721
+ <div id="sector-popup" class="popup" style="display:none;" role="dialog" aria-modal="true" aria-labelledby="sector-popup-title">
722
+ <div id="popup-content">
723
+ <div class="popup-header flex justify-between items-center">
724
+ <h3 id="sector-popup-title" class="text-xl font-semibold text-gray-800">Origin History</h3>
725
+ <button onclick="closePopup()" class="popup-close" aria-label="Close sector description popup"><span>×</span></button>
726
+ </div>
727
+ <p id="sector-description" class="text-gray-700 leading-relaxed"></p>
728
+ </div>
729
  </div>
730
+
731
+ <!-- Order Items Section -->
732
+ <div class="text-center text-2xl font-bold text-orange-500 mb-6">Previous Orders</div>
733
+ {% if order_items %}
734
+ {% for item in order_items %}
735
+ <div class="custom-class">
736
+ <div class="order-image-wrapper">
737
+ <img
738
+ src="{{ item.image_url | default('/static/placeholder.jpg') }}"
739
+ alt="{{ item.name | escape }}"
740
+ class="order-image lazyload"
741
+ loading="lazy"
742
+ decoding="async"
743
+ role="img"
744
+ aria-label="Image of {{ item.name | escape }}"
745
+ aria-describedby="order-price-{{ loop.index }}"
746
+ onerror="this.src='/static/placeholder.jpg'; this.alt='Placeholder image'"
747
+ />
748
+ <h3 class="order-item-name" id="order-name-{{ loop.index }}">{{ item.name | escape }}</h3>
749
  </div>
750
+ <p id="order-price-{{ loop.index }}" class="text-gray-600 mb-2 price-badge">${{ "%.2f"|format(item.price | default(0)) }}</p>
751
+
752
+ {% if item.category != 'Soft Drink' %}
753
+ <button
754
+ id="ingredientsToggleButton{{ loop.index }}"
755
+ class="ingredients-toggle-button text-green-600 text-sm font-semibold mt-2 ml-2 text-left pb-4 hover:text-green-700"
756
+ onclick="toggleIngredients({{ loop.index }})"
757
+ aria-expanded="false"
758
+ aria-controls="ingredientsSection{{ loop.index }}"
759
+ data-index="{{ loop.index }}"
760
+ >
761
+ Show Ingredients
762
+ </button>
763
+
764
+ <div id="ingredientsSection{{ loop.index }}" class="ingredients-section hidden mt-4" aria-hidden="true">
765
+ {% if item.ingredients and item.ingredients|length > 0 %}
766
+ <div class="grid grid-cols-2 gap-4 sm:grid-cols-3">
767
+ {% for ingredient in item.ingredients %}
768
+ <button
769
+ class="relative group ingredient-button focus:outline-none focus:ring-2 focus:ring-green-500"
770
+ aria-label="View details for {{ ingredient.name | escape }}"
771
+ data-ingredient='{
772
+ "index": "{{ loop.index }}",
773
+ "name": "{{ ingredient.name | escape }}",
774
+ "image": "{{ ingredient.image | default('/static/placeholder.jpg') | escape }}",
775
+ "health_benefits": "{{ ingredient.health_benefits | escape }}",
776
+ "fun_facts": "{{ ingredient.fun_facts | escape }}"
777
+ }'
778
+ onclick="showIngredientDetails(this)"
779
+ >
780
+ <div class="overflow-hidden rounded-lg">
781
+ <img
782
+ src="{{ ingredient.image | default('/static/placeholder.jpg') }}"
783
+ alt="{{ ingredient.name | escape }}"
784
+ class="ingredient-image lazyload"
785
+ loading="lazy"
786
+ decoding="async"
787
+ onerror="this.src='/static/placeholder.jpg'; this.alt='Placeholder image'"
788
+ />
789
+ </div>
790
+ <p class="mt-2 text-center text-sm font-medium text-gray-800">{{ ingredient.name | escape }}</p>
791
+ </button>
792
+ {% endfor %}
793
+ </div>
794
+ {% else %}
795
+ <p class="text-gray-600 text-center">No ingredients available for this item.</p>
796
+ {% endif %}
797
  </div>
798
+ {% endif %}
799
  </div>
800
 
801
+ <!-- Modal for Ingredients -->
802
+ {% if item.category != 'Soft Drink' %}
803
+ <div id="ingredientModal{{ loop.index }}" class="ingredient-modal-container hidden modal" role="dialog" aria-modal="true" aria-labelledby="modalTitle{{ loop.index }}">
804
+ <div class="ingredient-modal">
805
+ <div class="p-6">
806
+ <div class="popup-header flex justify-between items-center mb-4">
807
+ <h3 id="modalTitle{{ loop.index }}" class="text-xl font-semibold text-gray-800"></h3>
808
+ <button onclick="closeModal({{ loop.index }})" class="popup-close" aria-label="Close ingredient details modal"><span>×</span></button>
809
+ </div>
810
+
811
+ <img id="modalImage{{ loop.index }}" src="" alt="" class="w-full max-h-48 object-contain rounded-xl mb-4 border border-gray-200 lazyload" loading="lazy" decoding="async" />
812
 
813
+ <div class="space-y-4">
814
+ <div class="modal-section">
815
+ <h4 class="font-semibold mb-2 text-gray-800 flex items-center">
816
+ <svg class="w-5 h-5 mr-2 text-teal-400" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
817
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
818
+ </svg>
819
+ Health Benefits
820
+ </h4>
821
+ <ul id="healthBenefits{{ loop.index }}" class="list-disc list-inside text-gray-700"></ul>
822
+ </div>
823
+
824
+ <div class="modal-section">
825
+ <h4 class="font-semibold mb-2 text-gray-800 flex items-center">
826
+ <svg class="w-5 h-5 mr-2 text-orange-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
827
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
828
+ </svg>
829
+ Fun Facts
830
+ </h4>
831
+ <ul id="funFacts{{ loop.index }}" class="list-disc list-inside text-gray-700"></ul>
832
  </div>
833
  </div>
834
+ </div>
835
+ </div>
 
 
 
836
  </div>
837
+ {% endif %}
838
+ {% endfor %}
839
+ {% else %}
840
+ <div class="no-data">No previous orders found.</div>
841
+ {% endif %}
842
  </div>
843
 
 
 
 
 
 
 
 
 
 
 
 
844
  <script>
845
+ // Debounce function for performance
846
+ function debounce(func, wait) {
847
+ let timeout;
848
+ return function executedFunction(...args) {
849
+ const later = () => {
850
+ clearTimeout(timeout);
851
+ func(...args);
852
+ };
853
+ clearTimeout(timeout);
854
+ timeout = setTimeout(later, wait);
855
+ };
856
+ }
857
 
858
+ // Scroll container function
859
+ function scrollContainer(direction) {
860
+ try {
861
+ const container = document.querySelector('.sector-images-container');
862
+ const scrollAmount = 200;
863
+ if (direction === 'left') {
864
+ container.scrollLeft -= scrollAmount;
865
+ } else {
866
+ container.scrollLeft += scrollAmount;
867
+ }
868
+ } catch (e) {
869
+ console.error('Error scrolling container:', e);
870
  }
871
+ }
872
+
873
+ // Show sector description popup
874
+ function showSectorDescription(description) {
875
+ try {
876
+ document.getElementById('sector-description').innerText = description || 'No description available.';
877
+ document.getElementById('sector-popup').style.display = 'flex';
878
+ document.body.classList.add('modal-open');
879
+ } catch (e) {
880
+ console.error('Error showing sector description:', e);
881
  }
882
  }
883
 
884
+ // Close sector popup
885
+ function closePopup() {
886
+ try {
887
+ document.getElementById('sector-popup').style.display = 'none';
888
+ document.body.classList.remove('modal-open');
889
+ } catch (e) {
890
+ console.error('Error closing popup:', e);
891
+ }
892
  }
893
 
894
+ // Toggle tier details with animation
895
+ function toggleTierDetails() {
896
+ try {
897
+ const tierDetails = document.getElementById('tierDetails');
898
+ const arrowPath = document.getElementById('arrowPath');
899
+ const toggleButton = tierDetails.parentElement.querySelector('[aria-controls="tierDetails"]');
900
+ const isExpanded = !tierDetails.classList.contains('hidden');
901
+ tierDetails.classList.toggle('hidden');
902
+ arrowPath.setAttribute('d', tierDetails.classList.contains('hidden') ? 'M19 9l-7 7-7-7' : 'M19 15l-7-7-7 7');
903
+ toggleButton.setAttribute('aria-expanded', !isExpanded);
904
+ } catch (e) {
905
+ console.error('Error toggling tier details:', e);
906
+ }
907
  }
908
 
909
+ // Toggle ingredients section
910
+ function toggleIngredients(index) {
911
+ try {
912
+ const section = document.getElementById(`ingredientsSection${index}`);
913
+ const button = document.getElementById(`ingredientsToggleButton${index}`);
914
 
915
+ if (!section || !button) {
916
+ console.error(`Elements not found for index ${index}`);
917
+ return;
918
+ }
 
 
 
919
 
920
+ const isHidden = section.classList.contains('hidden');
 
921
 
922
+ // Close all other ingredient sections
923
+ document.querySelectorAll('.ingredients-section').forEach(s => {
924
+ s.classList.add('hidden');
925
+ s.setAttribute('aria-hidden', 'true');
926
+ });
927
+ document.querySelectorAll('[id^="ingredientsToggleButton"]').forEach(b => {
928
+ b.textContent = 'Show Ingredients';
929
+ b.setAttribute('aria-expanded', 'false');
930
+ });
931
+
932
+ // Toggle the current section
933
+ if (isHidden) {
934
+ section.classList.remove('hidden');
935
+ section.setAttribute('aria-hidden', 'false');
936
+ button.textContent = 'Hide Ingredients';
937
+ button.setAttribute('aria-expanded', 'true');
938
+ } else {
939
+ section.classList.add('hidden');
940
+ section.setAttribute('aria-hidden', 'true');
941
+ button.textContent = 'Show Ingredients';
942
+ button.setAttribute('aria-expanded', 'false');
943
+ }
944
+ } catch (e) {
945
+ console.error('Error toggling ingredients:', e);
946
  }
947
+ }
948
 
949
+ // Show ingredient details modal
950
+ function showIngredientDetails(button) {
951
+ try {
952
+ const data = JSON.parse(button.getAttribute('data-ingredient'));
953
+ const { index, name, image, health_benefits, fun_facts } = data;
954
 
955
+ const healthBenefitsList = (health_benefits || '').split(',').filter(item => item.trim());
956
+ const funFactsList = (fun_facts || '').split(',').filter(item => item.trim());
 
 
957
 
958
+ const modal = document.getElementById(`ingredientModal${index}`);
959
+ if (!modal) {
960
+ console.error(`Modal not found for index ${index}`);
961
+ return;
962
+ }
963
+
964
+ document.getElementById(`modalTitle${index}`).textContent = name || 'Unknown Ingredient';
965
+ const modalImage = document.getElementById(`modalImage${index}`);
966
+ modalImage.src = image || '/static/placeholder.jpg';
967
+ modalImage.alt = name || 'Ingredient image';
968
+
969
+ const healthBenefitsUl = document.getElementById(`healthBenefits${index}`);
970
+ const funFactsUl = document.getElementById(`funFacts${index}`);
971
+ healthBenefitsUl.innerHTML = healthBenefitsList.length
972
+ ? healthBenefitsList.map(item => `<li>${item.trim()}</li>`).join('')
973
+ : '<li>No health benefits available.</li>';
974
+ funFactsUl.innerHTML = funFactsList.length
975
+ ? funFactsList.map(item => `<li>${item.trim()}</li>`).join('')
976
+ : '<li>No fun facts available.</li>';
977
 
978
+ modal.style.display = 'flex';
979
+ document.body.classList.add('modal-open');
980
+ } catch (e) {
981
+ console.error('Error showing ingredient details:', e);
982
+ }
983
  }
984
 
985
+ // Close ingredient modal
986
+ function closeModal(index) {
987
+ try {
988
+ const modal = document.getElementById(`ingredientModal${index}`);
989
+ if (modal) {
990
+ modal.style.display = 'none';
991
+ document.body.classList.remove('modal-open');
 
 
 
 
992
  }
993
+ } catch (e) {
994
+ console.error('Error closing modal:', e);
995
+ }
996
+ }
 
 
 
997
 
998
+ // Set progress bar color based on points
999
+ document.addEventListener('DOMContentLoaded', () => {
1000
+ try {
1001
+ const progressBar = document.getElementById('progressBar');
1002
+ const pointsDisplay = document.getElementById('pointsDisplay');
1003
+ const points = parseInt(pointsDisplay.textContent, 10) || 0;
1004
+
1005
+ if (points <= 100) {
1006
+ progressBar.classList.add('range-0-100');
1007
+ } else if (points <= 200) {
1008
+ progressBar.classList.add('range-100-200');
1009
+ } else {
1010
+ progressBar.classList.add('range-200-plus');
 
 
 
 
1011
  }
1012
+ } catch (e) {
1013
+ console.error('Error setting progress bar color:', e);
1014
+ }
1015
 
1016
+ // Lazy load images with IntersectionObserver
1017
+ const images = document.querySelectorAll('img.lazyload');
1018
+ if ('IntersectionObserver' in window) {
1019
+ const observer = new IntersectionObserver((entries, observer) => {
1020
+ entries.forEach(entry => {
1021
+ if (entry.isIntersecting) {
1022
+ const img = entry.target;
1023
+ img.src = img.src || '/static/placeholder.jpg';
1024
+ img.classList.remove('lazyload');
1025
+ observer.unobserve(img);
1026
+ }
1027
+ });
 
 
 
 
 
 
 
 
1028
  });
1029
+ images.forEach(img => observer.observe(img));
1030
  } else {
1031
+ images.forEach(img => {
1032
+ img.src = img.src || '/static/placeholder.jpg';
1033
+ img.classList.remove('lazyload');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1034
  });
1035
+ }
1036
 
1037
+ // Initialize the timer
1038
+ initTimer();
1039
+ });
 
 
 
1040
 
1041
+ // Timer logic
1042
+ function initTimer() {
1043
+ const deliveryTimeInput = document.getElementById('deliveryTimeSeconds');
1044
+ const orderConfirmationSection = document.getElementById('orderConfirmationSection');
1045
+ const countdownTimerSpan = document.getElementById('countdownTimer');
1046
 
1047
+ let remainingSeconds = parseInt(deliveryTimeInput.value, 10);
 
 
1048
 
1049
+ // Only start timer if delivery time is provided and valid
1050
+ if (!isNaN(remainingSeconds) && remainingSeconds > 0) {
1051
+ orderConfirmationSection.classList.remove('hidden'); // Ensure it's visible for a new order
 
 
 
 
 
 
 
 
1052
 
1053
+ const timerInterval = setInterval(() => {
1054
+ const minutes = Math.floor(remainingSeconds / 60);
1055
+ const seconds = remainingSeconds % 60;
1056
 
1057
+ countdownTimerSpan.textContent = `${minutes}m ${seconds}s`;
 
 
1058
 
1059
+ remainingSeconds--;
 
1060
 
1061
+ if (remainingSeconds < 0) {
1062
+ clearInterval(timerInterval);
1063
+ countdownTimerSpan.textContent = 'Delivered!';
1064
+ // Optionally hide the confirmation section after a short delay
1065
+ setTimeout(() => {
1066
+ orderConfirmationSection.classList.add('hidden');
1067
+ }, 3000); // Hide after 3 seconds
1068
+ }
1069
+ }, 1000);
1070
+ } else {
1071
+ // If no valid delivery time, hide the confirmation section
1072
+ orderConfirmationSection.classList.add('hidden');
1073
+ }
1074
+ }
1075
 
 
 
1076
 
1077
+ // Close modals on outside click
1078
+ document.addEventListener('click', (e) => {
1079
+ try {
1080
+ if (e.target.id === 'sector-popup') {
1081
+ closePopup();
1082
+ }
1083
+ document.querySelectorAll('.ingredient-modal-container').forEach(modal => {
1084
+ if (e.target === modal) {
1085
+ const index = modal.id.replace('ingredientModal', '');
1086
+ closeModal(index);
1087
+ }
1088
+ });
1089
+ } catch (e) {
1090
+ console.error('Error handling outside click:', e);
1091
  }
1092
+ });
1093
 
1094
+ // Keyboard navigation for scroll buttons
1095
+ document.querySelectorAll('.scroll-button').forEach(button => {
1096
+ button.addEventListener('keydown', function(e) {
1097
+ if (e.key === 'Enter' || e.key === ' ') {
1098
+ e.preventDefault();
1099
+ scrollContainer(button.classList.contains('left') ? 'left' : 'right');
 
 
 
 
 
 
 
 
 
1100
  }
1101
+ });
1102
+ });
1103
+
1104
+ // Keyboard navigation for toggle buttons
1105
+ document.querySelectorAll('[id^="ingredientsToggleButton"]').forEach(button => {
1106
+ button.addEventListener('keydown', (e) => {
1107
+ if (e.key === 'Enter' || e.key === ' ') {
1108
+ e.preventDefault();
1109
+ const index = button.getAttribute('data-index');
1110
+ toggleIngredients(index);
1111
+ }
1112
+ });
1113
  });
1114
  </script>
1115
  </body>