Swathi6 commited on
Commit
15316a5
·
verified ·
1 Parent(s): 402ab6e

Update templates/menu.html

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