geethareddy commited on
Commit
8f66bde
·
verified ·
1 Parent(s): 5e81e51

Update templates/cart.html

Browse files
Files changed (1) hide show
  1. templates/cart.html +483 -375
templates/cart.html CHANGED
@@ -6,118 +6,114 @@
6
  <title>Cart</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
  <style>
11
- body {
 
12
  font-family: Arial, sans-serif;
13
- background-color: #fdf4e3;
14
  color: #333;
15
  }
16
  .cart-container {
17
  max-width: 768px;
18
  margin: 20px auto;
19
  padding: 15px;
20
- background-color: #FFFFFF;
21
  border-radius: 10px;
22
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
23
  }
24
- .cart-container2 {
25
- background-color: #FFFFFF;
26
- }
27
- .back-button {
28
- position: absolute;
29
- top: 15px;
30
- left: 15px;
31
- display: inline-block;
32
- background-color: green;
33
- color: white;
34
- padding: 10px 20px;
35
- text-decoration: none;
36
- font-weight: bold;
37
- border-radius: 4px;
38
- z-index: 10;
39
- }
40
- .back-button:hover {
41
- background-color: darkgreen;
42
- }
43
  .cart-item {
44
- display: flex;
45
- align-items: flex-start;
46
- justify-content: space-between;
47
- border: 1px solid transparent;
48
- padding: 30px 15px 15px;
49
- background-color: #fff;
50
- box-sizing: border-box;
51
- min-height: 100px;
52
- position: relative;
53
- border: 1px solid #fdf4e3;
54
- border-radius: 8px;
55
- }
56
- .remove-btn {
57
- border: none;
58
- background-color: transparent;
59
- cursor: pointer;
60
- font-size: 1.2rem;
61
- margin-bottom: 10px;
62
- transition: color 0.3s ease;
63
- position: relative;
64
- top: -35px;
65
- left: 50px;
66
- }
67
- .remove-btn i {
68
- color: red;
69
- }
70
- .remove-btn:hover {
71
- color: black;
72
- background-color: transparent;
73
- }
74
- .remove-btn:focus {
75
- outline: none;
76
- background-color: transparent;
77
- }
78
- .text-primary {
79
- color: #2e7d32;
80
- text-align: right;
81
- font-weight: bold;
82
- white-space: nowrap;
83
- }
84
- .image-wrapper {
85
- width: 80px;
86
- height: 80px !important;
87
- display: flex;
88
- align-items: center;
89
- justify-content: center;
90
- }
91
- .cart-item img {
92
- width: 70px;
93
- height: 70px;
94
- object-fit: cover;
95
- border-radius: 5px;
96
- border: 1px solid #ffcc80;
97
- margin: 0;
98
- }
 
 
 
 
 
 
 
 
 
99
  .cart-item img:hover {
100
  transform: scale(1.05);
101
  }
102
  .cart-item-title {
103
  font-size: 1.1rem;
104
- font-weight: bold;
105
  }
 
106
  .checkout-button {
107
- background-color: #ff5722;
108
- color: #ffffff;
109
- padding: 12px;
110
- border-radius: 8px;
111
- border: none;
112
- width: 100%;
113
- font-size: 1.2rem;
114
- cursor: pointer;
115
- transition: background-color 0.3s, color 0.3s;
116
- }
117
- .checkout-button:hover {
118
- background-color: #ff5722;
119
- color: #ffffff;
120
- }
121
  .add-back-button {
122
  padding: 6px 20px;
123
  font-size: 0.9rem;
@@ -132,10 +128,12 @@
132
  background-color: #fff;
133
  color: #0FAA39;
134
  }
 
135
  .cart-item-details {
136
  flex: 1;
137
  margin-left: 15px;
138
  }
 
139
  .cart-item-quantity {
140
  display: flex;
141
  align-items: center;
@@ -158,193 +156,224 @@
158
  font-size: 1rem;
159
  margin: 0 5px;
160
  }
161
- .cart-summary {
162
- position: relative;
163
- text-align: left;
164
- margin-top: 15px;
165
- padding: 20px;
166
- background-color: #fff;
167
- border-radius: 12px;
168
- border: 2px solid #fdf4e3;
169
- box-shadow: 0 6px 15px rgba(0, 0, 0, 0.1);
170
- }
171
- .cart-item-instructions {
172
- word-wrap: break-word;
173
- white-space: normal;
174
- overflow: hidden;
175
- max-width: 100%;
176
- word-break: break-word;
177
- }
178
- .coupon-selection {
179
- display: flex;
180
- justify-content: space-between;
181
- align-items: center;
182
- font-size: 1rem;
183
- margin-bottom: 20px;
184
- position: relative;
185
- }
186
- .coupon-selection label {
187
- font-weight: bold;
188
- color: black;
189
- }
190
- .coupon-selection a {
191
- color: #007bff;
192
- font-size: 1rem;
193
- text-decoration: none;
194
- text-align: right;
195
- }
196
- #couponDropdown {
197
- width: 30%;
198
- display: none;
199
- background-color: #fff;
200
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
201
- z-index: 10;
202
- margin-top: 10px;
203
- margin-left: auto;
204
- margin-right: 0;
205
- }
206
- #couponDropdown.show {
207
- display: block;
208
- }
209
- .bill-details {
210
- display: grid;
211
- grid-template-columns: 1fr 1fr;
212
- grid-gap: 10px;
213
- margin-bottom: 10px;
214
- }
215
- .bill-details .label {
216
- font-weight: 600;
217
- font-size: 1rem;
218
- }
219
- .bill-details .amount {
220
- text-align: right;
221
- font-weight: 600;
222
- font-size: 1rem;
223
- }
224
- .dotted-line {
225
- border-bottom: 2px dotted #ccc;
226
- margin: 15px 0;
227
- }
228
- .total-bill {
229
- display: grid;
230
- grid-template-columns: 1fr 1fr;
231
- font-weight: 600;
232
- font-size: 1.2rem;
233
- margin-top: 10px;
234
- margin-bottom: 10px;
235
- }
236
- .total-bill .label {
237
- font-size: 1.1rem;
238
- }
239
- .total-bill .amount {
240
- text-align: right;
241
- font-size: 1.1rem;
242
- color: #2e7d32;
243
- }
244
- .cart-summary.has-dropdown {
245
- margin-bottom: 80px;
246
- }
247
- .suggestion-section {
248
- margin-top: 25px;
249
- padding: 15px;
250
- background-color: #fff;
251
- border-radius: 10px;
252
- border: 2px solid #fdf4e3;
253
- }
254
- .suggestion-items-container {
255
- display: flex;
256
- overflow-x: auto;
257
- gap: 10px;
258
- padding-bottom: 10px;
259
- padding-top: 10px;
260
- }
261
- .suggestion-item {
262
- display: flex;
263
- align-items: center;
264
- justify-content: flex-start;
265
- flex-shrink: 0;
266
- width: 160px;
267
- padding: 10px;
268
- border-radius: 8px;
269
- background-color: #fff;
270
- box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
271
- transition: transform 0.3s ease;
272
- margin-right: 10px;
273
- position: relative;
274
- text-align: left;
275
- overflow: visible;
276
- border: 2px solid #fdf4e3;
277
- }
278
- .suggestion-item:hover {
279
- transform: scale(1.05);
280
- }
281
- .suggestion-item img {
282
- width: 50px;
283
- height: 50px;
284
- object-fit: cover;
285
- border-radius: 5px;
286
- margin-right: 12px;
287
- }
288
- .suggestion-item div {
289
- flex-grow: 1;
290
- text-align: left;
291
- }
292
- .add-back-button {
293
- position: absolute;
294
- top: -5px;
295
- right: -10px;
296
- font-size: 1rem;
297
- padding: 0;
298
- width: 30px;
299
- height: 30px;
300
- background-color: #fff;
301
- color: #0FAA39;
302
- border: 2px solid #0FAA39;
303
- border-radius: 0;
304
- cursor: pointer;
305
- transition: background-color 0.3s, color 0.3s, border-color 0.3s;
306
- z-index: 2;
307
- }
308
- .add-back-button:hover {
309
- background-color: #fff;
310
- color: #0FAA39;
311
- border-color: #0FAA39;
312
- z-index: 3;
313
- }
314
- .suggestion-items-container::-webkit-scrollbar {
315
- height: 8px;
316
- }
317
- .suggestion-items-container::-webkit-scrollbar-thumb {
318
- background-color: #fff;
319
- border-radius: 4px;
320
- }
321
- .suggestion-items-container::-webkit-scrollbar-track {
322
- background-color: #f1f1f1;
323
- }
324
- .cart-item-actions {
325
- display: flex;
326
- align-items: flex-start;
327
- margin-left: auto;
328
- }
329
- h4.mb-4.fw-bold {
330
- text-align: center;
331
- color: #FF5722;
332
- }
333
- .cart-container h4 {
334
- text-align: center;
335
- color: #FF5722;
336
- font-weight: bold;
337
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338
  </style>
339
  </head>
340
  <body>
341
  <div class="container">
342
  <div class="cart-container">
343
  <div style="text-align: right;">
344
- <a href="/menu" style="text-decoration: none; font-size: 1.5rem; color: #007bff;">×</a>
345
  </div>
346
 
347
- <h4 class="mb-4 fw-bold">Your Cart</h4>
348
 
349
  <!-- Cart Items -->
350
  <div class="cart-container2">
@@ -358,7 +387,7 @@
358
  {{ item.Name }}
359
  </div>
360
  <div class="cart-item-addons">
361
- <small class="text-muted">Add-ons: {{ item.Add_Ons__c|join(', ') if item.Add_Ons__c else 'None' }}</small>
362
  </div>
363
  <div class="cart-item-instructions">
364
  <small class="text-muted">Instructions: {{ item.Instructions__c or "None" }}</small>
@@ -370,15 +399,20 @@
370
  </div>
371
  </div>
372
  <div class="cart-item-actions">
 
 
 
373
  <button type="button" class="btn btn-light text-dark remove-btn" onclick="removeItemFromCart('{{ item.Name }}')">
374
  <i class="bi bi-trash"></i>
375
  </button>
 
376
  <div class="text-primary" style="color: #000 !important;">
377
  $<span class="base-price">{{ item.Price__c }}</span>
378
  </div>
379
  </div>
380
  </div>
381
  {% else %}
 
382
  <p>No items in your cart.</p>
383
  {% endfor %}
384
  </div>
@@ -395,113 +429,122 @@
395
  <div>{{ suggestion.Name }}</div>
396
  <div class="text-muted">${{ suggestion.Price__c }}</div>
397
  </div>
 
398
  <button class="add-back-button" onclick="addToCartSuggestion('{{ suggestion.Name }}', '{{ suggestion.Price__c }}', '{{ suggestion.Image1__c }}', '{{ suggestion.Id }}')">+</button>
 
 
399
  </div>
400
  {% endfor %}
401
  </div>
402
  </div>
 
403
  {% endif %}
404
 
405
  <!-- Subtotal -->
406
  <div class="cart-summary">
407
- {% if coupons %}
408
- <div class="coupon-selection d-flex justify-content-between align-items-center">
409
- <label class="text-dark font-weight-bold mb-0">Apply Coupon</label>
410
- <a href="javascript:void(0);" id="applyCouponLink" onclick="toggleCouponDropdown()" class="text-primary">+ Apply Coupon</a>
411
- </div>
412
- <select id="couponDropdown" class="form-select mt-2" style="display:none;" onchange="calculateDiscount()">
413
- <option value="">Select a coupon</option>
414
- {% for coupon in coupons %}
415
- <option value="{{ coupon }}">{{ coupon }}</option>
416
- {% endfor %}
417
- </select>
418
- {% endif %}
 
 
 
 
 
419
 
420
  <div class="bill-details">
421
  <div class="label">Cart Total</div>
422
- <div class="amount" id="cartTotal">${{ subtotal }}</div>
 
 
423
  <div class="label">Discount</div>
424
- <div class="amount" id="discountText">-$0.00</div>
 
 
 
 
425
  </div>
426
 
427
  <div class="dotted-line"></div>
428
 
429
  <div class="total-bill">
430
- <div class="label">To Pay</div>
431
- <div class="amount" id="totalBillText">${{ subtotal }}</div>
432
  </div>
433
  <button class="checkout-button" onclick="proceedToOrder()">Proceed to Order</button>
434
  </div>
435
  </div>
436
  </div>
437
 
438
- <script>
439
- // Base URL for API requests
440
- const BASE_URL = window.location.hostname === '127.0.0.1' ? 'http://127.0.0.1:5000' : 'https://your-backend-url.com';
441
 
 
 
442
  function updateQuantity(action, itemName, customerEmail) {
443
  let quantityInput = document.querySelector(`input[data-item-name="${itemName}"]`);
444
- if (!quantityInput) {
445
- alert("Quantity input not found for item: " + itemName);
446
- return;
447
- }
448
-
449
  let quantity = parseInt(quantityInput.value);
450
- let originalQuantity = quantity;
451
-
452
  if (action === 'increase') {
453
  quantity++;
454
  } else if (action === 'decrease' && quantity > 1) {
455
  quantity--;
456
  }
457
 
 
458
  if (isNaN(quantity) || quantity < 1) {
459
  alert("Invalid quantity!");
460
  return;
461
  }
462
 
463
- quantityInput.value = quantity;
464
- updateSubtotal();
465
-
466
- fetch(`${BASE_URL}/cart/update_quantity`, {
467
  method: 'POST',
468
  headers: { 'Content-Type': 'application/json' },
469
- body: JSON.stringify({ email: customerEmail, item_name: itemName, quantity: quantity }),
470
- credentials: 'include'
471
  })
472
  .then(response => response.json())
473
  .then(data => {
474
  if (data.success) {
475
- console.log(`Quantity updated for ${itemName}: ${quantity}`);
476
- updateSubtotal();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
477
  } else {
478
- quantityInput.value = originalQuantity;
479
- updateSubtotal();
480
- alert(`Error updating quantity: ${data.error || 'Unknown error'}`);
481
  }
482
  })
483
- .catch(err => {
484
- quantityInput.value = originalQuantity;
485
- updateSubtotal();
486
- alert(`Network error while updating quantity: ${err.message}`);
487
- console.error("Error:", err);
488
- });
489
- }
490
-
491
- function updateSubtotal() {
492
- let subtotal = 0;
493
- document.querySelectorAll('.cart-item').forEach(item => {
494
- const quantity = parseInt(item.querySelector('input').value);
495
- const basePrice = parseFloat(item.querySelector('.base-price').innerText);
496
- subtotal += basePrice * quantity;
497
- });
498
-
499
- document.getElementById('cartTotal').innerText = `$${subtotal.toFixed(2)}`;
500
- calculateDiscount();
501
  }
502
-
503
  function toggleCouponDropdown() {
504
  let couponDropdown = document.getElementById('couponDropdown');
 
 
505
  if (couponDropdown.style.display === "none" || couponDropdown.style.display === "") {
506
  couponDropdown.style.display = "block";
507
  } else {
@@ -509,129 +552,194 @@
509
  }
510
  }
511
 
 
512
  function calculateDiscount() {
513
- let couponDropdown = document.getElementById('couponDropdown');
514
- let selectedCoupon = couponDropdown ? couponDropdown.value.trim() : "";
515
- let subtotal = parseFloat(document.getElementById('cartTotal').innerText.replace('$', ''));
516
 
 
517
  if (selectedCoupon && selectedCoupon.toLowerCase() !== "none") {
 
518
  let discount = subtotal * 0.10;
519
  let total = subtotal - discount;
520
- document.getElementById("discountText").innerText = `-$${discount.toFixed(2)}`;
 
 
521
  document.getElementById("totalBillText").innerText = `$${total.toFixed(2)}`;
522
  } else {
523
- document.getElementById("discountText").innerText = `-$0.00`;
 
524
  document.getElementById("totalBillText").innerText = `$${subtotal.toFixed(2)}`;
525
  }
526
  }
527
 
 
 
 
528
  function proceedToOrder() {
529
  let couponDropdown = document.getElementById('couponDropdown');
530
- let selectedCoupon = couponDropdown ? couponDropdown.value.trim() : "";
 
 
 
 
 
 
 
 
 
 
 
 
531
 
 
532
  if (selectedCoupon === "" || selectedCoupon === "None" || selectedCoupon === "Null") {
533
- selectedCoupon = null;
534
  }
535
 
536
- fetch(`${BASE_URL}/cart/checkout`, {
 
537
  method: 'POST',
538
  headers: { 'Content-Type': 'application/json' },
539
- body: JSON.stringify({ selectedCoupon: selectedCoupon }),
540
- credentials: 'include'
541
  })
542
  .then(response => response.json())
543
  .then(data => {
544
  if (data.success) {
545
- alert(data.message);
546
- window.location.href = '/order';
547
  } else {
548
- alert(data.error || data.message);
549
  }
550
  })
551
  .catch(err => console.error('Error during checkout:', err));
552
  }
553
 
554
- function removeItemFromCart(itemName) {
555
- fetch(`${BASE_URL}/cart/remove/${encodeURIComponent(itemName)}`, {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
556
  method: 'POST',
557
  headers: { 'Content-Type': 'application/json' },
558
- credentials: 'include'
559
  })
560
  .then(response => response.json())
561
  .then(data => {
562
  if (data.success) {
563
- alert(data.message);
564
  location.reload();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
565
  } else {
566
  alert(data.message);
567
  }
568
  })
569
  .catch(err => console.error('Error removing item:', err));
570
  }
571
-
572
  function addToCart(itemName, customerEmail) {
573
- fetch(`${BASE_URL}/cart/add_item`, {
574
  method: "POST",
575
  headers: { "Content-Type": "application/json" },
576
  body: JSON.stringify({
577
  email: customerEmail,
578
- item_name: itemName.trim(),
579
- quantity: 1
580
- }),
581
- credentials: 'include'
582
  })
583
  .then(response => response.json())
584
  .then(data => {
585
  if (data.success) {
586
  alert("Item added/updated successfully.");
587
- location.reload();
588
  } else {
589
  alert(data.error || "Failed to add item to cart.");
590
  }
591
  })
592
- .catch(err => {
593
- console.error("Error adding item to cart:", err);
594
- alert("An error occurred while adding the item to the cart.");
595
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
596
  }
597
-
598
  function addToCartSuggestion(itemName, itemPrice, itemImage, itemId) {
599
- const customerEmail = "{{ customer_email }}";
 
600
  const data = {
601
  item_name: itemName,
602
  item_price: itemPrice,
603
  item_image: itemImage,
604
  item_id: itemId,
605
- addons: [],
606
- instructions: "",
607
  customer_email: customerEmail
608
  };
609
-
610
- fetch(`${BASE_URL}/cart/add_suggestion_to_cart`, {
611
  method: 'POST',
612
- headers: { 'Content-Type': 'application/json' },
613
- body: JSON.stringify(data),
614
- credentials: 'include'
 
615
  })
616
  .then(response => response.json())
617
  .then(data => {
618
  if (data.success) {
619
  alert('Item added to cart!');
620
- location.reload();
621
  } else {
622
  alert('Error adding item to cart: ' + data.error);
623
  }
624
  })
625
- .catch(err => {
626
- console.error('Error adding item:', err);
627
- alert('An error occurred while adding the item to the cart.');
628
- });
629
  }
630
 
631
- // Initialize subtotal on page load
632
- document.addEventListener('DOMContentLoaded', function() {
633
- updateSubtotal();
634
- });
635
  </script>
 
636
  </body>
637
  </html>
 
6
  <title>Cart</title>
7
  <!-- Bootstrap CSS -->
8
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
 
9
  <style>
10
+
11
+ body {
12
  font-family: Arial, sans-serif;
13
+ background-color: #f3f4f6;
14
  color: #333;
15
  }
16
  .cart-container {
17
  max-width: 768px;
18
  margin: 20px auto;
19
  padding: 15px;
20
+ background-color: #fdf4e3;
21
  border-radius: 10px;
22
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
23
  }
24
+ .cart-container2 {
25
+ background-color: #fdf4e3;
26
+ }
27
+
28
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  .cart-item {
30
+ display: flex;
31
+ align-items: flex-start;
32
+ justify-content: space-between;
33
+ border: 1px solid transparent; /* Set the border to transparent */
34
+ padding: 30px 15px 15px;
35
+ background-color: #fff;/* Padding for the content */
36
+ box-sizing: border-box;
37
+ min-height: 100px;
38
+ position: relative; /* Make the cart item a reference for the absolute positioning of the remove icon */
39
+ }
40
+
41
+ .remove-btn {
42
+ border: none; /* Remove the border around the button */
43
+ background-color: transparent; /* Transparent background */
44
+ cursor: pointer; /* Change cursor to pointer */
45
+ font-size: 1.2rem; /* Slightly decrease the size of the trash icon */
46
+ margin-bottom: 10px; /* Add space below the delete icon */
47
+ transition: color 0.3s ease; /* Smooth transition for icon color */
48
+ position: relative; /* Make it relative for movement */
49
+ top: -35px; /* Move the button 10px upwards */
50
+ left: 50px; /* Move the button 30px to the right */
51
+ }
52
+
53
+ .remove-btn i {
54
+ color: red; /* Make the trash icon red */
55
+ }
56
+
57
+
58
+ /* Hover effect */
59
+ .remove-btn:hover {
60
+ color: black; /* Change the icon color to black on hover */
61
+ background-color: transparent; /* Keep background transparent on hover */
62
+ }
63
+ /* Prevent background color on focus or click */
64
+ .remove-btn:focus {
65
+ outline: none; /* Remove the outline */
66
+ background-color: transparent; /* Keep background transparent after clicking */
67
+ }
68
+ .text-primary {
69
+ color: #000 !important; /* Ensure the price is black */
70
+ text-align: right; /* Center-align the price */
71
+ font-weight: bold; /* Make the price text bold */
72
+ white-space: nowrap; /* Prevent price text from wrapping */
73
+ }
74
+ /* For the image container */
75
+ .image-wrapper {
76
+ width: 80px; /* Width of the image container */
77
+ height: 80px !important; /* Set the height of the container to match the image */
78
+ display: flex; /* Flex container for the image */
79
+ align-items: center; /* Center image vertically */
80
+ justify-content: center; /* Center image horizontally */
81
+ }
82
+
83
+ /* For the image */
84
+ .cart-item img {
85
+ width: 70px; /* Set the width to 70px */
86
+ height: 70px; /* Set the height to 70px */
87
+ object-fit: cover; /* Ensure the image covers the container without stretching */
88
+ border-radius: 5px; /* Optional: rounded corners */
89
+ border: 1px solid #ffcc80; /* Light orange border around images */
90
+ margin: 0; /* Ensure no extra space around the image */
91
+ }
92
+
93
+
94
  .cart-item img:hover {
95
  transform: scale(1.05);
96
  }
97
  .cart-item-title {
98
  font-size: 1.1rem;
99
+ font-weight: bold; /* Make the title text bold */
100
  }
101
+
102
  .checkout-button {
103
+ background-color: #0FAA39; /* Green background */
104
+ color: #fff; /* White text */
105
+ padding: 12px;
106
+ border-radius: 8px;
107
+ border: none;
108
+ width: 100%;
109
+ font-size: 1.2rem;
110
+ cursor: pointer;
111
+ transition: background-color 0.3s, color 0.3s;
112
+ }
113
+ .checkout-button:hover {
114
+ background-color: #0FAA39; /* Keep the background green on hover */
115
+ color: #fff; /* Keep the text white on hover */
116
+ }
117
  .add-back-button {
118
  padding: 6px 20px;
119
  font-size: 0.9rem;
 
128
  background-color: #fff;
129
  color: #0FAA39;
130
  }
131
+
132
  .cart-item-details {
133
  flex: 1;
134
  margin-left: 15px;
135
  }
136
+
137
  .cart-item-quantity {
138
  display: flex;
139
  align-items: center;
 
156
  font-size: 1rem;
157
  margin: 0 5px;
158
  }
159
+ /* Make the parent container position relative */
160
+ .cart-summary {
161
+ position: relative; /* Make sure dropdown is positioned relative to this container */
162
+ text-align: left;
163
+ margin-top: 15px;
164
+ padding: 20px;
165
+ background-color: #fff;
166
+ border-radius: 12px;
167
+ box-shadow: 0 6px 15px rgba(0, 0, 0, 0.1);
168
+ }
169
+ /* Coupon Section styling */
170
+ .coupon-selection {
171
+ display: flex; /* Use flexbox to align items */
172
+ justify-content: space-between; /* Space between the label and the link */
173
+ align-items: center;
174
+ font-size: 1rem;
175
+ margin-bottom: 20px; /* Add space below Apply Coupon section */
176
+ position: relative; /* Ensure dropdown is within this container */
177
+ }
178
+ /* Ensure the Apply Coupon label and link are aligned correctly */
179
+ .coupon-selection label {
180
+ font-weight: bold;
181
+ color: black;
182
+ }
183
+ .coupon-selection a {
184
+ color: #007bff; /* Blue for the link */
185
+ font-size: 1rem;
186
+ text-decoration: none;
187
+ text-align: right;
188
+ }
189
+ /* Coupon Dropdown styling */
190
+ #couponDropdown {
191
+ width: 30%; /* Set dropdown to 30% of the width */
192
+ display: none; /* Hidden by default */
193
+ background-color: #fff;
194
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); /* Add shadow */
195
+ z-index: 10; /* Ensure it's above other content */
196
+ margin-top: 10px; /* Add space from the link */
197
+ margin-left: auto; /* Push it to the right side */
198
+ margin-right: 0; /* Ensure it doesn't overflow outside */
199
+ }
200
+ /* Show the dropdown when it's active */
201
+ #couponDropdown.show {
202
+ display: block;
203
+ }
204
+ /* Ensure Apply Coupon section aligns correctly */
205
+ .coupon-selection {
206
+ display: flex;
207
+ justify-content: space-between;
208
+ align-items: center;
209
+ font-size: 1rem;
210
+ margin-bottom: 20px; /* Add space below Apply Coupon section */
211
+ }
212
+ /* Apply Coupon link and label styles */
213
+ .coupon-selection label {
214
+ font-weight: bold;
215
+ color: black;
216
+ }
217
+ .coupon-selection a {
218
+ color: #007bff; /* Blue for the link */
219
+ font-size: 1rem;
220
+ text-decoration: none;
221
+ text-align: right;
222
+ }
223
+ /* Bill details grid structure */
224
+ .bill-details {
225
+ display: grid;
226
+ grid-template-columns: 1fr 1fr; /* Two-column layout */
227
+ grid-gap: 10px;
228
+ margin-bottom: 10px;
229
+ }
230
+ /* Adjust label and amount for bill details */
231
+ .bill-details .label {
232
+ font-weight: 600;
233
+ font-size: 1rem;
234
+ }
235
+ .bill-details .amount {
236
+ text-align: right;
237
+ font-weight: 600;
238
+ font-size: 1rem;
239
+ }
240
+ /* Divider line between bill sections */
241
+ .dotted-line {
242
+ border-bottom: 2px dotted #ccc;
243
+ margin: 15px 0;
244
+ }
245
+ /* Total bill grid layout */
246
+ .total-bill {
247
+ display: grid;
248
+ grid-template-columns: 1fr 1fr;
249
+ font-weight: 600;
250
+ font-size: 1.2rem;
251
+ margin-top: 10px;
252
+ margin-bottom: 10px; /* Add 10px space between To Pay and Submit Button */
253
+ }
254
+ .total-bill .label {
255
+ font-size: 1.1rem;
256
+ }
257
+ .total-bill .amount {
258
+ text-align: right;
259
+ font-size: 1.1rem;
260
+ color: #000; /* Changed from green to black */
261
+ }
262
+ /* Margin to add space for dropdown when visible */
263
+ .cart-summary.has-dropdown {
264
+ margin-bottom: 80px; /* Create space below the content when dropdown is visible */
265
+ }
266
+ .checkout-button {
267
+ background-color: #0FAA39;
268
+ color: #fff;
269
+ padding: 12px;
270
+ border-radius: 8px;
271
+ border: none;
272
+ height: 44px;
273
+ width: 100%;
274
+ font-size: 1.2rem;
275
+ cursor: pointer;
276
+ transition: background-color 0.3s, color 0.3s;
277
+ display: flex;
278
+ justify-content: center;
279
+ align-items: center;
280
+ text-align: center;
281
+ }
282
+ .suggestion-section {
283
+ margin-top: 25px;
284
+ padding: 15px;
285
+ background-color: #fff;
286
+ border-radius: 10px;
287
+ }
288
+ .suggestion-items-container {
289
+ display: flex;
290
+ overflow-x: auto; /* Horizontal scrolling */
291
+ gap: 10px; /* Space between items */
292
+ padding-bottom: 10px;
293
+ padding-top: 10px;
294
+ }
295
+ /* Styling for the suggestion item card */
296
+ .suggestion-item {
297
+ display: flex; /* Align items horizontally */
298
+ align-items: center; /* Center image and text vertically */
299
+ justify-content: flex-start; /* Align items to the start (left side) */
300
+ flex-shrink: 0;
301
+ width: 160px; /* Set fixed width for each suggestion item */
302
+ padding: 10px;
303
+ border-radius: 8px; /* Rounded corners */
304
+ background-color: #fff;
305
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
306
+ transition: transform 0.3s ease;
307
+ margin-right: 10px; /* Ensure there's space between the cards */
308
+ position: relative; /* For positioning the + icon */
309
+ text-align: left; /* Align text to the left */
310
+ overflow: visible; /* Allow the button to overflow outside */
311
+ }
312
+ .suggestion-item:hover {
313
+ transform: scale(1.05); /* Slight zoom effect on hover */
314
+ }
315
+ .suggestion-item img {
316
+ width: 50px; /* Set a fixed width for the image */
317
+ height: 50px; /* Set a fixed height for the image */
318
+ object-fit: cover; /* Ensure image fits correctly without distortion */
319
+ border-radius: 5px; /* Rounded corners for the image */
320
+ margin-right: 12px; /* Space between the image and text */
321
+ }
322
+ .suggestion-item div {
323
+ flex-grow: 1; /* Allow the text section to expand and fill available space */
324
+ text-align: left; /* Align text to the left */
325
+ }
326
+ /* Styling for the + symbol button (with green border, white background, and black text) */
327
+ .add-back-button {
328
+ position: absolute;
329
+ top: -5px;
330
+ right: -10px;
331
+ font-size: 1rem; /* Smaller font size */
332
+ padding: 0; /* Remove padding */
333
+ width: 30px; /* Set fixed width */
334
+ height: 30px; /* Set fixed height */
335
+ background-color: #fff;
336
+ color: #0FAA39;
337
+ border: 2px solid #0FAA39;
338
+ border-radius: 0; /* Square shape */
339
+ cursor: pointer;
340
+ transition: background-color 0.3s, color 0.3s, border-color 0.3s;
341
+ z-index: 2; /* Increased z-index to ensure it stays above the borders */
342
+ }
343
+ .add-back-button:hover {
344
+ background-color: #fff; /* Green background on hover */
345
+ color: #0FAA39; /* White color for the + symbol when hovered */
346
+ border-color: #0FAA39; /* Green border on hover */
347
+ z-index: 3; /* Ensure button stays on top when hovered */
348
+ }
349
+ /* Ensure the scroll container works fine */
350
+ .suggestion-items-container::-webkit-scrollbar {
351
+ height: 8px; /* Height of the scrollbar */
352
+ }
353
+ .suggestion-items-container::-webkit-scrollbar-thumb {
354
+ background-color: #fff; /* Green color for scrollbar thumb */
355
+ border-radius: 4px;
356
+ }
357
+ .suggestion-items-container::-webkit-scrollbar-track {
358
+ background-color: #f1f1f1;
359
+ }
360
+
361
+ .cart-item-actions {
362
+ display: flex; /* Use flexbox to align items horizontally */
363
+ align-items: flex-start; /* Align the price at the top of the cart item (like the item name) */
364
+ margin-left: auto; /* This will push the price to the right side of the cart item */
365
+ }
366
+
367
  </style>
368
  </head>
369
  <body>
370
  <div class="container">
371
  <div class="cart-container">
372
  <div style="text-align: right;">
373
+ <a href="/menu" style="text-decoration: none; font-size: 1.5rem; color: #007bff;">&times;</a>
374
  </div>
375
 
376
+ <h4 class="mb-4 fw-bold">Your Cart</h4>
377
 
378
  <!-- Cart Items -->
379
  <div class="cart-container2">
 
387
  {{ item.Name }}
388
  </div>
389
  <div class="cart-item-addons">
390
+ <small class="text-muted">Add-ons: {{ item.Add_Ons__c }}</small>
391
  </div>
392
  <div class="cart-item-instructions">
393
  <small class="text-muted">Instructions: {{ item.Instructions__c or "None" }}</small>
 
399
  </div>
400
  </div>
401
  <div class="cart-item-actions">
402
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
403
+
404
+ <!-- Delete Button with Trash Icon and onclick handler -->
405
  <button type="button" class="btn btn-light text-dark remove-btn" onclick="removeItemFromCart('{{ item.Name }}')">
406
  <i class="bi bi-trash"></i>
407
  </button>
408
+
409
  <div class="text-primary" style="color: #000 !important;">
410
  $<span class="base-price">{{ item.Price__c }}</span>
411
  </div>
412
  </div>
413
  </div>
414
  {% else %}
415
+ <!-- Code to handle the case when cart_items is empty -->
416
  <p>No items in your cart.</p>
417
  {% endfor %}
418
  </div>
 
429
  <div>{{ suggestion.Name }}</div>
430
  <div class="text-muted">${{ suggestion.Price__c }}</div>
431
  </div>
432
+ <!-- Replace add button with a cart icon -->
433
  <button class="add-back-button" onclick="addToCartSuggestion('{{ suggestion.Name }}', '{{ suggestion.Price__c }}', '{{ suggestion.Image1__c }}', '{{ suggestion.Id }}')">+</button>
434
+
435
+
436
  </div>
437
  {% endfor %}
438
  </div>
439
  </div>
440
+
441
  {% endif %}
442
 
443
  <!-- Subtotal -->
444
  <div class="cart-summary">
445
+ <!-- Coupon Section -->
446
+ {% if coupons %}
447
+ <div class="coupon-selection d-flex justify-content-between align-items-center">
448
+ <label class="text-dark font-weight-bold mb-0">Apply Coupon</label>
449
+ <a href="javascript:void(0);" id="applyCouponLink" onclick="toggleCouponDropdown()" class="text-primary">+ Apply Coupon</a>
450
+ </div>
451
+
452
+ <!-- Coupon Dropdown, positioned below Apply Coupon -->
453
+ <select id="couponDropdown" class="form-select mt-2" style="display:none;" onchange="calculateDiscount()">
454
+ <option value="">Select a coupon</option>
455
+ {% for coupon in coupons %}
456
+ <option value="{{ coupon }}">{{ coupon }}</option>
457
+ {% endfor %}
458
+ </select>
459
+ {% endif %}
460
+
461
+
462
 
463
  <div class="bill-details">
464
  <div class="label">Cart Total</div>
465
+ <div class="amount">${{ subtotal }}</div>
466
+
467
+
468
  <div class="label">Discount</div>
469
+ <div class="amount" id="discountText">-${{ discount }}</div>
470
+
471
+
472
+
473
+
474
  </div>
475
 
476
  <div class="dotted-line"></div>
477
 
478
  <div class="total-bill">
479
+ <div class="label">To Pay</div>
480
+ <div class="amount" id="totalBillText">${{ subtotal }}</div>
481
  </div>
482
  <button class="checkout-button" onclick="proceedToOrder()">Proceed to Order</button>
483
  </div>
484
  </div>
485
  </div>
486
 
 
 
 
487
 
488
+ <script>
489
+ // Example function to handle the increase/decrease button clicks
490
  function updateQuantity(action, itemName, customerEmail) {
491
  let quantityInput = document.querySelector(`input[data-item-name="${itemName}"]`);
 
 
 
 
 
492
  let quantity = parseInt(quantityInput.value);
493
+ // Update quantity based on action
 
494
  if (action === 'increase') {
495
  quantity++;
496
  } else if (action === 'decrease' && quantity > 1) {
497
  quantity--;
498
  }
499
 
500
+ // Validate quantity
501
  if (isNaN(quantity) || quantity < 1) {
502
  alert("Invalid quantity!");
503
  return;
504
  }
505
 
506
+ // Send updated quantity to the server
507
+ fetch('/cart/update_quantity', {
 
 
508
  method: 'POST',
509
  headers: { 'Content-Type': 'application/json' },
510
+ body: JSON.stringify({ email: customerEmail, item_name: itemName, quantity: quantity })
 
511
  })
512
  .then(response => response.json())
513
  .then(data => {
514
  if (data.success) {
515
+ // Update the item price and quantity in the UI
516
+ quantityInput.value = quantity;
517
+ let itemElement = quantityInput.closest(".cart-item"); // Locate the parent cart item
518
+ if (itemElement) {
519
+ let basePriceElement = itemElement.querySelector(".base-price");
520
+ let addonsPriceElement = itemElement.querySelector(".addons-price");
521
+
522
+ // Update the base price
523
+ if (basePriceElement) {
524
+ basePriceElement.innerText = data.new_item_price.toFixed(2); // Assuming backend sends this
525
+ }
526
+
527
+ // Update add-ons price if needed (optional)
528
+ if (addonsPriceElement && data.addons_price !== undefined) {
529
+ addonsPriceElement.innerText = data.addons_price.toFixed(2);
530
+ }
531
+ } else {
532
+ console.error(`Parent cart item element not found for item: ${itemName}`);
533
+ }
534
+ location.reload();
535
+
536
+ // Recalculate subtotal dynamically
537
+
538
  } else {
539
+ alert("Error updating quantity: " + data.error);
 
 
540
  }
541
  })
542
+ .catch(err => console.error("Error:", err));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
543
  }
 
544
  function toggleCouponDropdown() {
545
  let couponDropdown = document.getElementById('couponDropdown');
546
+
547
+ // Toggle the visibility of the coupon dropdown
548
  if (couponDropdown.style.display === "none" || couponDropdown.style.display === "") {
549
  couponDropdown.style.display = "block";
550
  } else {
 
552
  }
553
  }
554
 
555
+
556
  function calculateDiscount() {
557
+ let couponDropdown = document.getElementById('couponDropdown'); // Get coupon dropdown
558
+ let selectedCoupon = couponDropdown.value.trim(); // Get the selected coupon value
559
+ let subtotal = parseFloat("{{ subtotal }}"); // Get the subtotal (from the backend)
560
 
561
+ // If a valid coupon is selected
562
  if (selectedCoupon && selectedCoupon.toLowerCase() !== "none") {
563
+ // Apply 10% discount
564
  let discount = subtotal * 0.10;
565
  let total = subtotal - discount;
566
+
567
+ // Update UI with discount and total bill
568
+ document.getElementById("discountText").innerText = `$${discount.toFixed(2)}`;
569
  document.getElementById("totalBillText").innerText = `$${total.toFixed(2)}`;
570
  } else {
571
+ // If no coupon is selected or "None" is selected, reset the discount
572
+ document.getElementById("discountText").innerText = `$0.00`;
573
  document.getElementById("totalBillText").innerText = `$${subtotal.toFixed(2)}`;
574
  }
575
  }
576
 
577
+
578
+
579
+
580
  function proceedToOrder() {
581
  let couponDropdown = document.getElementById('couponDropdown');
582
+
583
+ // Initialize selectedCoupon to an empty string by default
584
+ let selectedCoupon = "";
585
+
586
+ // Only proceed if couponDropdown exists
587
+ if (couponDropdown) {
588
+ // If the value is not null or undefined, strip the value
589
+ if (couponDropdown.value != null) {
590
+ selectedCoupon = couponDropdown.value.trim(); // safely call .trim() if value is not null
591
+ } else {
592
+ selectedCoupon = ""; // Assign empty string if value is null
593
+ }
594
+ }
595
 
596
+ // If no coupon is selected or the value is empty, treat it as no coupon
597
  if (selectedCoupon === "" || selectedCoupon === "None" || selectedCoupon === "Null") {
598
+ selectedCoupon = null; // Treat it as no coupon selected
599
  }
600
 
601
+ // Send the selected coupon to the backend for processing
602
+ fetch('/checkout', {
603
  method: 'POST',
604
  headers: { 'Content-Type': 'application/json' },
605
+ body: JSON.stringify({ selectedCoupon: selectedCoupon })
 
606
  })
607
  .then(response => response.json())
608
  .then(data => {
609
  if (data.success) {
610
+ alert(data.message); // Success message
611
+ window.location.href = '/order'; // Redirect to order page
612
  } else {
613
+ alert(data.error || data.message); // Handle error message
614
  }
615
  })
616
  .catch(err => console.error('Error during checkout:', err));
617
  }
618
 
619
+
620
+
621
+ function calculateSubtotal() {
622
+ let subtotal = 0;
623
+ document.querySelectorAll('.cart-item').forEach(item => {
624
+ const quantity = parseInt(item.querySelector('input').value);
625
+ const basePrice = parseFloat(item.querySelector('.base-price').innerText.replace('$', '')); // Base Price
626
+ const addonsPrice = parseFloat(item.querySelector('.addons-price').innerText.replace('$', '')) || 0; // Add-ons Price
627
+ subtotal += (basePrice * quantity) + addonsPrice; // Include add-ons price in subtotal
628
+ });
629
+
630
+ // Update the subtotal in the HTML
631
+ document.querySelector('.cart-summary p').innerText = `Subtotal: $${subtotal.toFixed(2)}`;
632
+ return subtotal;
633
+ }
634
+ function addSuggestion(itemId) {
635
+ fetch(`/cart/add_suggestion/${itemId}`, {
636
  method: 'POST',
637
  headers: { 'Content-Type': 'application/json' },
638
+ body: JSON.stringify({})
639
  })
640
  .then(response => response.json())
641
  .then(data => {
642
  if (data.success) {
643
+ alert('Item added to cart!');
644
  location.reload();
645
+ } else {
646
+ alert(data.error);
647
+ }
648
+ })
649
+ .catch(err => console.error('Error adding suggestion:', err));
650
+ }
651
+ function removeItemFromCart(itemName) {
652
+ fetch(`/cart/remove/${encodeURIComponent(itemName)}`, {
653
+ method: 'POST',
654
+ headers: {
655
+ 'Content-Type': 'application/json'
656
+ }
657
+ })
658
+ .then(response => response.json())
659
+ .then(data => {
660
+ if (data.success) {
661
+ alert(data.message);
662
+ location.reload(); // Reload the page to update the cart
663
  } else {
664
  alert(data.message);
665
  }
666
  })
667
  .catch(err => console.error('Error removing item:', err));
668
  }
 
669
  function addToCart(itemName, customerEmail) {
670
+ fetch(`/cart/add_item`, {
671
  method: "POST",
672
  headers: { "Content-Type": "application/json" },
673
  body: JSON.stringify({
674
  email: customerEmail,
675
+ item_name: itemName.trim(), //Ensure the item name is trimmed
676
+ quantity: 0 // DEFAULT QUANTITY PASSED HERE
677
+ })
 
678
  })
679
  .then(response => response.json())
680
  .then(data => {
681
  if (data.success) {
682
  alert("Item added/updated successfully.");
683
+ location.reload(); // Reload the page to update the cart
684
  } else {
685
  alert(data.error || "Failed to add item to cart.");
686
  }
687
  })
688
+ .catch(err => console.error("Error adding item to cart:", err));
689
+ }
690
+ function addSuggestion(itemId) {
691
+ fetch(`/cart/add_suggestion/${itemId}`, {
692
+ method: 'POST',
693
+ headers: { 'Content-Type': 'application/json' },
694
+ body: JSON.stringify({})
695
+ })
696
+ .then(response => response.json())
697
+ .then(data => {
698
+ if (data.success) {
699
+ alert('Item added to cart!');
700
+ location.reload();
701
+ } else {
702
+ alert(data.error);
703
+ }
704
+ })
705
+ .catch(err => console.error('Error adding suggestion:', err));
706
  }
 
707
  function addToCartSuggestion(itemName, itemPrice, itemImage, itemId) {
708
+ const customerEmail = "{{ customer_email }}"; // Get customer email from session
709
+ // Create the data object to send to the ser ver
710
  const data = {
711
  item_name: itemName,
712
  item_price: itemPrice,
713
  item_image: itemImage,
714
  item_id: itemId,
715
+ addons: [], // Default to empty, you can adjust if needed
716
+ instructions: "", // Default to empty, you can adjust if needed
717
  customer_email: customerEmail
718
  };
719
+ // Send the data to the backend via a POST request
720
+ fetch('/cart/add_suggestion_to_cart', {
721
  method: 'POST',
722
+ headers: {
723
+ 'Content-Type': 'application/json'
724
+ },
725
+ body: JSON.stringify(data)
726
  })
727
  .then(response => response.json())
728
  .then(data => {
729
  if (data.success) {
730
  alert('Item added to cart!');
731
+ location.reload(); // Reload to update the cart view
732
  } else {
733
  alert('Error adding item to cart: ' + data.error);
734
  }
735
  })
736
+ .catch(err => console.error('Error adding item:', err));
 
 
 
737
  }
738
 
739
+
740
+
741
+
 
742
  </script>
743
+
744
  </body>
745
  </html>