Update templates/combined_summary.html
Browse files- templates/combined_summary.html +101 -66
templates/combined_summary.html
CHANGED
@@ -398,7 +398,7 @@
|
|
398 |
border-color: #10B981;
|
399 |
}
|
400 |
/* Green border when section is visible */
|
401 |
-
.ingredients
|
402 |
border: 2px solid #10B981;
|
403 |
}
|
404 |
/* Ensure ingredient section is smooth */
|
@@ -447,8 +447,8 @@
|
|
447 |
z-index: 1;
|
448 |
position: relative;
|
449 |
}
|
450 |
-
|
451 |
-
display: none;
|
452 |
}
|
453 |
/* Tier details animation */
|
454 |
.tier-details {
|
@@ -476,6 +476,15 @@
|
|
476 |
outline: none;
|
477 |
transform: scale(1.05);
|
478 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
479 |
/* Responsive adjustments */
|
480 |
@media (max-width: 768px) {
|
481 |
.custom-class {
|
@@ -492,6 +501,9 @@
|
|
492 |
.grid {
|
493 |
grid-template-columns: repeat(2, 1fr);
|
494 |
}
|
|
|
|
|
|
|
495 |
}
|
496 |
@media (max-width: 480px) {
|
497 |
.custom-class {
|
@@ -571,6 +583,10 @@
|
|
571 |
.grid {
|
572 |
grid-template-columns: repeat(2, 1fr);
|
573 |
}
|
|
|
|
|
|
|
|
|
574 |
}
|
575 |
@media (min-width: 768px) {
|
576 |
.grid {
|
@@ -589,14 +605,13 @@
|
|
589 |
|
590 |
<div class="container mx-auto p-6 pt-2">
|
591 |
<!-- Order Confirmation -->
|
592 |
-
<!--
|
593 |
-
|
594 |
-
|
595 |
-
<input type="hidden" id="deliveryTimeSeconds" value="{{ delivery_time_seconds | default('') }}">
|
596 |
|
597 |
<div id="orderConfirmationSection" class="section bg-white shadow-sm rounded-xl p-6 mb-6 order-confirmed hidden" role="alert">
|
598 |
<h1 class="text-center text-2xl font-bold text-orange-500">Order Confirmed!</h1>
|
599 |
-
<p class="text-center text-gray-600 mt-2">Estimated delivery time: <span id="countdownTimer"></span></p>
|
600 |
</div>
|
601 |
|
602 |
<!-- Reward Status Section -->
|
@@ -613,7 +628,7 @@
|
|
613 |
<path d="M18 9H6a4 4 0 0 1 0-8h12a4 4 0 0 1 0 8Z"></path>
|
614 |
</svg>
|
615 |
</div>
|
616 |
-
<span class="ml-2 text-xl font-bold text-orange-500" id="currentTier">{{ current_tier }}
|
617 |
<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">
|
618 |
<path id="arrowPath" d="M19 9l-7 7-7-7"></path>
|
619 |
</svg>
|
@@ -974,7 +989,7 @@
|
|
974 |
? healthBenefitsList.map(item => `<li>${item.trim()}</li>`).join('')
|
975 |
: '<li>No health benefits available.</li>';
|
976 |
funFactsUl.innerHTML = funFactsList.length
|
977 |
-
?
|
978 |
: '<li>No fun facts available.</li>';
|
979 |
|
980 |
modal.style.display = 'flex';
|
@@ -997,7 +1012,78 @@
|
|
997 |
}
|
998 |
}
|
999 |
|
1000 |
-
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1001 |
document.addEventListener('DOMContentLoaded', () => {
|
1002 |
try {
|
1003 |
const progressBar = document.getElementById('progressBar');
|
@@ -1011,8 +1097,11 @@
|
|
1011 |
} else {
|
1012 |
progressBar.classList.add('range-200-plus');
|
1013 |
}
|
|
|
|
|
|
|
1014 |
} catch (e) {
|
1015 |
-
console.error('Error
|
1016 |
}
|
1017 |
|
1018 |
// Lazy load images with IntersectionObserver
|
@@ -1035,62 +1124,8 @@
|
|
1035 |
img.classList.remove('lazyload');
|
1036 |
});
|
1037 |
}
|
1038 |
-
|
1039 |
-
// Initialize the timer
|
1040 |
-
initTimer();
|
1041 |
});
|
1042 |
|
1043 |
-
// Timer logic
|
1044 |
-
function initTimer() {
|
1045 |
-
const deliveryTimeInput = document.getElementById('deliveryTimeSeconds');
|
1046 |
-
const orderConfirmationSection = document.getElementById('orderConfirmationSection');
|
1047 |
-
const countdownTimerSpan = document.getElementById('countdownTimer');
|
1048 |
-
|
1049 |
-
// Parse the value, default to 0 if not a valid number or empty
|
1050 |
-
let remainingSeconds = parseInt(deliveryTimeInput.value, 10) || 0;
|
1051 |
-
|
1052 |
-
// Check if delivery time is a valid positive number provided for a *new* order
|
1053 |
-
if (remainingSeconds > 0) {
|
1054 |
-
// Show the section and start the timer
|
1055 |
-
orderConfirmationSection.classList.remove('hidden');
|
1056 |
-
countdownTimerSpan.textContent = formatTime(remainingSeconds); // Display initial time
|
1057 |
-
|
1058 |
-
const timerInterval = setInterval(() => {
|
1059 |
-
remainingSeconds--;
|
1060 |
-
|
1061 |
-
if (remainingSeconds >= 0) {
|
1062 |
-
countdownTimerSpan.textContent = formatTime(remainingSeconds);
|
1063 |
-
}
|
1064 |
-
|
1065 |
-
if (remainingSeconds < 0) {
|
1066 |
-
clearInterval(timerInterval);
|
1067 |
-
countdownTimerSpan.textContent = 'Delivered!';
|
1068 |
-
// Keep the section visible to show the "Delivered!" message
|
1069 |
-
// Optional: Hide the section after a short delay if preferred
|
1070 |
-
/*
|
1071 |
-
setTimeout(() => {
|
1072 |
-
orderConfirmationSection.classList.add('hidden');
|
1073 |
-
}, 3000); // Hide after 3 seconds
|
1074 |
-
*/
|
1075 |
-
}
|
1076 |
-
}, 1000);
|
1077 |
-
} else {
|
1078 |
-
// If deliveryTimeSeconds is 0 or less, or not provided
|
1079 |
-
// This means it's not a new order with a pending timer.
|
1080 |
-
// Hide the confirmation section entirely.
|
1081 |
-
orderConfirmationSection.classList.add('hidden');
|
1082 |
-
}
|
1083 |
-
}
|
1084 |
-
|
1085 |
-
// Helper function to format seconds into m:ss
|
1086 |
-
function formatTime(seconds) {
|
1087 |
-
const minutes = Math.floor(seconds / 60);
|
1088 |
-
const remainingSeconds = seconds % 60;
|
1089 |
-
const paddedSeconds = remainingSeconds < 10 ? '0' + remainingSeconds : remainingSeconds;
|
1090 |
-
return `${minutes}m ${paddedSeconds}s`;
|
1091 |
-
}
|
1092 |
-
|
1093 |
-
|
1094 |
// Close modals on outside click
|
1095 |
document.addEventListener('click', (e) => {
|
1096 |
try {
|
|
|
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 */
|
|
|
447 |
z-index: 1;
|
448 |
position: relative;
|
449 |
}
|
450 |
+
.order-confirmed.hidden {
|
451 |
+
display: none;
|
452 |
}
|
453 |
/* Tier details animation */
|
454 |
.tier-details {
|
|
|
476 |
outline: none;
|
477 |
transform: scale(1.05);
|
478 |
}
|
479 |
+
/* Timer styles */
|
480 |
+
.countdown-timer {
|
481 |
+
font-weight: 600;
|
482 |
+
color: #C2410C;
|
483 |
+
background: #FFE4D6;
|
484 |
+
padding: 4px 8px;
|
485 |
+
border-radius: 8px;
|
486 |
+
display: inline-block;
|
487 |
+
}
|
488 |
/* Responsive adjustments */
|
489 |
@media (max-width: 768px) {
|
490 |
.custom-class {
|
|
|
501 |
.grid {
|
502 |
grid-template-columns: repeat(2, 1fr);
|
503 |
}
|
504 |
+
.countdown-timer {
|
505 |
+
font-size: 0.875rem;
|
506 |
+
}
|
507 |
}
|
508 |
@media (max-width: 480px) {
|
509 |
.custom-class {
|
|
|
583 |
.grid {
|
584 |
grid-template-columns: repeat(2, 1fr);
|
585 |
}
|
586 |
+
.countdown-timer {
|
587 |
+
font-size: 0.75rem;
|
588 |
+
padding: 3px 6px;
|
589 |
+
}
|
590 |
}
|
591 |
@media (min-width: 768px) {
|
592 |
.grid {
|
|
|
605 |
|
606 |
<div class="container mx-auto p-6 pt-2">
|
607 |
<!-- Order Confirmation -->
|
608 |
+
<!-- Hidden inputs for order ID and order count -->
|
609 |
+
<input type="hidden" id="currentOrderId" value="{{ order_id | default('') }}">
|
610 |
+
<input type="hidden" id="orderCount" value="{{ order_items | length }}">
|
|
|
611 |
|
612 |
<div id="orderConfirmationSection" class="section bg-white shadow-sm rounded-xl p-6 mb-6 order-confirmed hidden" role="alert">
|
613 |
<h1 class="text-center text-2xl font-bold text-orange-500">Order Confirmed!</h1>
|
614 |
+
<p class="text-center text-gray-600 mt-2">Estimated delivery time: <span id="countdownTimer" class="countdown-timer"></span></p>
|
615 |
</div>
|
616 |
|
617 |
<!-- Reward Status Section -->
|
|
|
628 |
<path d="M18 9H6a4 4 0 0 1 0-8h12a4 4 0 0 1 0 8Z"></path>
|
629 |
</svg>
|
630 |
</div>
|
631 |
+
<span class="ml-2 text-xl font-bold text-orange-500" id="currentTier">{{ current_tier }}</span>
|
632 |
<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">
|
633 |
<path id="arrowPath" d="M19 9l-7 7-7-7"></path>
|
634 |
</svg>
|
|
|
989 |
? healthBenefitsList.map(item => `<li>${item.trim()}</li>`).join('')
|
990 |
: '<li>No health benefits available.</li>';
|
991 |
funFactsUl.innerHTML = funFactsList.length
|
992 |
+
? funfactsList.map(item => `<li>${item.trim()}</li>`).join('')
|
993 |
: '<li>No fun facts available.</li>';
|
994 |
|
995 |
modal.style.display = 'flex';
|
|
|
1012 |
}
|
1013 |
}
|
1014 |
|
1015 |
+
// Timer logic
|
1016 |
+
function initTimer() {
|
1017 |
+
const orderId = document.getElementById('currentOrderId').value;
|
1018 |
+
const orderCount = parseInt(document.getElementById('orderCount').value, 10) || 0;
|
1019 |
+
const orderConfirmationSection = document.getElementById('orderConfirmationSection');
|
1020 |
+
const countdownTimerSpan = document.getElementById('countdownTimer');
|
1021 |
+
|
1022 |
+
// Determine timer duration based on order count
|
1023 |
+
const timerDurationSeconds = orderCount >= 3 ? 45 * 60 : 15 * 60; // 45 min for 3+ orders, 15 min otherwise
|
1024 |
+
|
1025 |
+
// Check if order is new and has a valid order ID
|
1026 |
+
if (!orderId) {
|
1027 |
+
// No valid order ID: hide confirmation section
|
1028 |
+
orderConfirmationSection.classList.add('hidden');
|
1029 |
+
return;
|
1030 |
+
}
|
1031 |
+
|
1032 |
+
// Check if order is already delivered
|
1033 |
+
const deliveredOrders = JSON.parse(localStorage.getItem('deliveredOrders') || '[]');
|
1034 |
+
if (deliveredOrders.includes(orderId)) {
|
1035 |
+
// Order is delivered: show "Delivered!" message
|
1036 |
+
orderConfirmationSection.classList.remove('hidden');
|
1037 |
+
countdownTimerSpan.textContent = 'Delivered!';
|
1038 |
+
return;
|
1039 |
+
}
|
1040 |
+
|
1041 |
+
// Check for existing timer in localStorage
|
1042 |
+
let timerData = JSON.parse(localStorage.getItem('orderTimerData') || '{}');
|
1043 |
+
let endTime = timerData[orderId] ? parseInt(timerData[orderId], 10) : null;
|
1044 |
+
|
1045 |
+
// If no timer exists for this order, start a new one
|
1046 |
+
if (!endTime) {
|
1047 |
+
endTime = Date.now() + timerDurationSeconds * 1000;
|
1048 |
+
timerData[orderId] = endTime;
|
1049 |
+
localStorage.setItem('orderTimerData', JSON.stringify(timerData));
|
1050 |
+
}
|
1051 |
+
|
1052 |
+
// Update timer display
|
1053 |
+
function updateTimer() {
|
1054 |
+
const now = Date.now();
|
1055 |
+
const timeLeftSeconds = Math.max(0, Math.floor((endTime - now) / 1000));
|
1056 |
+
|
1057 |
+
if (timeLeftSeconds <= 0) {
|
1058 |
+
// Timer expired: mark order as delivered and refresh page
|
1059 |
+
deliveredOrders.push(orderId);
|
1060 |
+
localStorage.setItem('deliveredOrders', JSON.stringify(deliveredOrders));
|
1061 |
+
delete timerData[orderId];
|
1062 |
+
localStorage.setItem('orderTimerData', JSON.stringify(timerData));
|
1063 |
+
orderConfirmationSection.classList.remove('hidden');
|
1064 |
+
countdownTimerSpan.textContent = 'Delivered!';
|
1065 |
+
window.location.reload(); // Refresh page on timer expiry
|
1066 |
+
return;
|
1067 |
+
}
|
1068 |
+
|
1069 |
+
// Format time as MM:SS
|
1070 |
+
const minutes = Math.floor(timeLeftSeconds / 60);
|
1071 |
+
const seconds = timeLeftSeconds % 60;
|
1072 |
+
const paddedSeconds = seconds < 10 ? '0' + seconds : seconds;
|
1073 |
+
countdownTimerSpan.textContent = `${minutes}m ${paddedSeconds}s`;
|
1074 |
+
|
1075 |
+
// Show confirmation section
|
1076 |
+
orderConfirmationSection.classList.remove('hidden');
|
1077 |
+
|
1078 |
+
// Schedule next update
|
1079 |
+
setTimeout(updateTimer, 1000);
|
1080 |
+
}
|
1081 |
+
|
1082 |
+
// Start timer
|
1083 |
+
updateTimer();
|
1084 |
+
}
|
1085 |
+
|
1086 |
+
// Set progress bar color based on points and initialize timer
|
1087 |
document.addEventListener('DOMContentLoaded', () => {
|
1088 |
try {
|
1089 |
const progressBar = document.getElementById('progressBar');
|
|
|
1097 |
} else {
|
1098 |
progressBar.classList.add('range-200-plus');
|
1099 |
}
|
1100 |
+
|
1101 |
+
// Initialize the timer
|
1102 |
+
initTimer();
|
1103 |
} catch (e) {
|
1104 |
+
console.error('Error during DOMContentLoaded:', e);
|
1105 |
}
|
1106 |
|
1107 |
// Lazy load images with IntersectionObserver
|
|
|
1124 |
img.classList.remove('lazyload');
|
1125 |
});
|
1126 |
}
|
|
|
|
|
|
|
1127 |
});
|
1128 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1129 |
// Close modals on outside click
|
1130 |
document.addEventListener('click', (e) => {
|
1131 |
try {
|