dschandra commited on
Commit
c4d9933
·
verified ·
1 Parent(s): 4d44977

Update templates/menu.html

Browse files
Files changed (1) hide show
  1. templates/menu.html +565 -270
templates/menu.html CHANGED
@@ -7,333 +7,483 @@
7
  <!-- Bootstrap CSS -->
8
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/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
- margin: 0;
15
- padding: 0;
16
- display: flex;
17
- flex-direction: column;
18
- }
19
-
20
- .container {
21
- max-width: 900px;
22
- }
23
-
24
- .menu-card {
25
- max-width: 350px;
26
- border-radius: 15px;
27
- overflow: hidden;
28
- background-color: #fff;
29
- margin: auto;
30
- }
31
-
32
- .menu-image {
33
- height: 200px;
34
- width: 100%;
35
- object-fit: cover;
36
- border-radius: 15px 15px 0 0;
37
- }
38
-
39
- .card-title {
40
- font-size: 1.2rem;
41
- font-weight: bold;
42
- }
43
-
44
- .card-text {
45
- font-size: 1rem;
46
- color: #6c757d;
47
- }
48
-
49
- .btn-primary {
50
- font-size: 14px;
51
- font-weight: bold;
52
- border-radius: 5px;
53
- width: 100px;
54
- background-color: #0FAA39;
55
- border-color: #28a745;
56
- }
57
-
58
- .btn-primary:hover {
59
- background-color: #0FAA39;
60
- border-color: #ffffff;
61
- }
62
-
63
- .btn-primary:active,
64
- .btn-primary:focus {
65
- background-color: #4a5d68;
66
- border-color: #ffffff;
67
- box-shadow: none;
68
- }
69
-
70
- .view-cart-container {
71
- position: fixed;
72
- bottom: 20px;
73
- right: 20px;
74
- z-index: 999;
75
- }
76
-
77
- .view-cart-button {
78
- background-color: #0FAA39;
79
- color: #fff;
80
- padding: 10px 20px;
81
- border-radius: 30px;
82
- font-size: 1rem;
83
- font-weight: bold;
84
- text-decoration: none;
85
- box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
86
- display: flex;
87
- align-items: center;
88
- justify-content: center;
89
- }
90
-
91
- .view-cart-button:hover {
92
- background-color: #109835;
93
- text-decoration: none;
94
- }
95
-
96
- /* Modal and customization sections */
97
- .addon-section {
98
- background-color: #f8f9fa;
99
- border: 2px solid #ff6b35;
100
- border-radius: 8px;
101
- padding: 12px;
102
- margin-bottom: 15px;
103
- }
104
-
105
- .addon-section h6 {
106
- margin-bottom: 10px;
107
- font-size: 1.1rem;
108
- font-weight: bold;
109
- color: #333;
110
- }
111
-
112
- .addon-section .form-check {
113
- margin-left: 10px;
114
- }
115
-
116
- /* Quantity Control */
117
- #decrease-quantity, #increase-quantity {
118
- width: 30px;
119
- height: 30px;
120
- font-size: 18px;
121
- }
122
-
123
- #add-to-cart {
124
- font-size: 18px;
125
- padding: 15px;
126
- background-color: #4CAF50;
127
- color: white;
128
- font-weight: bold;
129
- border-radius: 5px;
130
- border: none;
131
- }
132
-
133
- #add-to-cart:hover {
134
- background-color: #45a049;
135
- }
136
-
137
- .form-check-label {
138
- font-size: 16px;
139
- margin-left: 8px;
140
- }
141
- </style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
  </head>
143
  <body>
144
- <div class="fixed-top-bar">
145
- <!-- Avatar and Dropdown -->
146
- <div class="avatar-dropdown-container">
147
- <div class="avatar-icon">
148
- <span>{{ first_letter }}</span>
149
- </div>
150
- <div class="dropdown-menu">
151
- <a href="{{ url_for('customer_details') }}" class="dropdown-item">View Profile</a>
152
- <a href="{{ url_for('order_history') }}" class="dropdown-item">Order History</a>
153
- <a href="{{ url_for('logout') }}" class="dropdown-item">Logout</a>
154
- </div>
155
- </div>
156
 
157
- <!-- Search Bar Section -->
158
- <div class="search-bar-container">
159
- <input type="text" id="searchBar" class="form-control" placeholder="Search items or sections..." onkeyup="filterMenu()">
160
- <i class="bi bi-search search-icon"></i>
 
 
 
 
 
 
161
  </div>
162
  </div>
163
 
164
- <!-- Category Filter -->
165
- <form method="get" action="/menu" class="text-center mb-4">
166
- <label class="form-label fw-bold">Select a Category:</label>
167
- <div class="form-check form-check-inline">
168
- <input type="radio" id="category-All" name="category" value="All" class="custom-radio" {% if selected_category == "All" %}checked{% endif %} onchange="this.form.submit()">
169
- <label class="form-check-label" for="category-All">All</label>
170
-
171
- <input type="radio" id="category-Veg" name="category" value="Veg" class="custom-radio" {% if selected_category == "Veg" %}checked{% endif %} onchange="this.form.submit()">
172
- <label class="form-check-label" for="category-Veg">Veg</label>
173
-
174
- <input type="radio" id="category-NonVeg" name="category" value="Non veg" class="custom-radio" {% if selected_category == "Non veg" %}checked{% endif %} onchange="this.form.submit()">
175
- <label class="form-check-label" for="category-NonVeg">Non veg</label>
176
-
177
- <input type="radio" id="category-CustomizedDish" name="category" value="Customized Dish" class="custom-radio" {% if selected_category == "Customized Dish" %}checked{% endif %} onchange="this.form.submit()">
178
- <label class="form-check-label" for="category-CustomizedDish">Customized Dish</label>
179
- </div>
180
- </form>
 
 
 
 
 
 
 
 
 
 
 
181
 
182
- <!-- Menu Section -->
183
  <div class="container mt-4">
184
  <h1 class="text-center">Menu</h1>
185
-
186
- <!-- Display text boxes for Customized Dish -->
187
- {% if selected_category == "Customized Dish" %}
188
- <div id="custom-dish-form" class="mt-4">
189
- <h3>Create Your Custom Dish</h3>
190
- <form method="POST" action="/generate_custom_dish">
191
- <div class="mb-3">
192
- <label for="custom-dish-name" class="form-label">Dish Name</label>
193
- <input type="text" class="form-control" id="custom-dish-name" name="name" required>
194
- </div>
195
- <div class="mb-3">
196
- <label for="custom-dish-description" class="form-label">Dish Description</label>
197
- <textarea class="form-control" id="custom-dish-description" name="description" required></textarea>
198
- </div>
199
- <button type="submit" class="btn btn-primary">Submit</button>
200
- </form>
201
  </div>
202
- {% else %}
203
- <!-- Display Menu Items -->
204
- {% for section, items in ordered_menu.items() %}
205
- <h3>{{ section }}</h3>
206
- <div class="row">
207
- {% for item in items %}
208
- <div class="col-md-6 mb-4">
209
- <div class="card menu-card">
210
- <img src="{{ item.Image1__c }}" class="card-img-top menu-image" alt="{{ item.Name }}" onerror="this.src='/static/placeholder.jpg';">
211
- <div class="card-body">
212
- <h5 class="card-title">{{ item.Name }}</h5>
213
- <p class="card-text">${{ item.Price__c }}</p>
214
- <button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#itemModal"
215
- onclick="showItemDetails('{{ item.Name }}', {{ item.Price__c }}, '{{ item.Image2__c }}', '{{ item.Description__c }}', '{{ item.Section__c }}', '{{ selected_category }}')">
216
- Add
217
- </button>
218
- </div>
 
 
 
 
 
 
 
219
  </div>
220
  </div>
221
- {% endfor %}
222
- </div>
223
- {% endfor %}
224
- {% endif %}
 
 
 
225
  </div>
226
 
227
  <!-- View Cart Button -->
228
  <div class="view-cart-container">
229
- <a href="/cart" class="view-cart-button">View Cart</a>
 
 
230
  </div>
231
 
232
- <!-- Modal for Item Details -->
233
- <div class="modal fade" id="itemModal" tabindex="-1" aria-labelledby="itemModalLabel" aria-hidden="true">
234
- <div class="modal-dialog modal-dialog-centered">
235
- <div class="modal-content">
236
- <div class="modal-header">
237
- <h5 class="modal-title" id="itemModalLabel">Item Details</h5>
238
- </div>
239
- <div class="modal-body">
240
- <!-- Item Image -->
241
- <img id="modal-img" class="img-fluid rounded mb-3 d-block mx-auto" alt="Item Image" style="max-height: 200px; object-fit: cover;">
242
- <!-- Item Name -->
243
- <h5 id="modal-name" class="fw-bold text-center"></h5>
244
- <!-- Item Price -->
245
- <p id="modal-price" class="text-muted text-center"></p>
246
-
247
- <!-- Quantity Control -->
248
- <div class="d-flex align-items-center justify-content-center mb-3">
249
- <button id="decrease-quantity" class="btn btn-light">-</button>
250
- <input type="number" id="quantity" class="form-control mx-2" value="1" min="1" readonly style="width: 60px;">
251
- <button id="increase-quantity" class="btn btn-light">+</button>
252
- </div>
253
 
254
- <!-- Add to Cart Button -->
255
- <button id="add-to-cart" class="btn btn-success w-100">Add item ₹<span id="total-price">490</span></button>
256
- <!-- Customization Addons -->
257
- <div id="addons-list" class="addons-container">Loading customization options...</div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
258
  </div>
 
 
 
259
  </div>
260
  </div>
261
  </div>
 
262
 
263
  <!-- JavaScript -->
264
  <script>
265
- let itemPrice = 490; // Static price from the item details
266
- let quantity = 1;
267
-
268
- // Update total price based on quantity and customization options
269
- function updatePrice() {
270
- let totalPrice = itemPrice * quantity;
271
- const selectedAddOns = document.querySelectorAll('.addon-option:checked');
272
- selectedAddOns.forEach(addon => {
273
- totalPrice += parseFloat(addon.getAttribute('data-price') || 0); // Add addon prices
274
- });
275
- document.getElementById('total-price').innerText = totalPrice;
276
- }
277
-
278
- // Decrease quantity
279
- document.getElementById('decrease-quantity').addEventListener('click', function() {
280
- if (quantity > 1) {
281
- quantity--;
282
- document.getElementById('quantity').value = quantity;
283
- updatePrice();
284
- }
285
- });
286
-
287
- // Increase quantity
288
- document.getElementById('increase-quantity').addEventListener('click', function() {
289
- quantity++;
290
  document.getElementById('quantity').value = quantity;
291
  updatePrice();
292
- });
293
-
 
 
 
 
 
 
 
294
  function showItemDetails(name, price, image, description, section, selectedCategory) {
295
  document.getElementById('modal-name').innerText = name;
296
- document.getElementById('modal-price').innerText = `$${price}`;
297
  document.getElementById('modal-img').src = image || '/static/placeholder.jpg';
298
  document.getElementById('modal-description').innerText = description || 'No description available.';
299
- itemPrice = price; // Static price remains as selected price
300
- updatePrice(); // Update the price based on quantity and customization
301
-
302
  // Set section and category for reference
303
  const modalSectionEl = document.getElementById('modal-section');
304
  modalSectionEl.setAttribute('data-section', section);
305
  modalSectionEl.setAttribute('data-category', selectedCategory);
306
-
307
  // Fetch customization options based on the section
308
- fetch(`/api/addons?item_name=${encodeURIComponent(name)}&item_section=${encodeURIComponent(section)}`)
309
  .then(response => response.json())
310
  .then(data => {
311
  const addonsList = document.getElementById('addons-list');
312
  addonsList.innerHTML = ''; // Clear previous content
313
-
314
  if (!data.success || !data.addons || data.addons.length === 0) {
315
  addonsList.innerHTML = '<p>No customization options available.</p>';
316
  return;
317
  }
318
-
319
  // Display customization options inside styled divs
320
  data.addons.forEach(addon => {
321
  const sectionDiv = document.createElement('div');
322
- sectionDiv.classList.add('addon-section');
 
323
  const title = document.createElement('h6');
324
  title.innerText = addon.name;
325
  sectionDiv.appendChild(title);
 
326
  const optionsContainer = document.createElement('div');
327
  addon.options.forEach((option, index) => {
328
- const optionId = `addon-${addon.name.replace(/\s+/g, '')}-${index}`;
329
  const listItem = document.createElement('div');
330
  listItem.classList.add('form-check');
331
- listItem.innerHTML = `
332
- <input type="checkbox" class="form-check-input addon-option" id="${optionId}" value="${option}" data-name="${option}" data-price="${addon.extra_charge ? addon.extra_charge_amount : 0}">
 
333
  <label class="form-check-label" for="${optionId}">
334
- ${option} ${addon.extra_charge ? `($${addon.extra_charge_amount})` : ''}
335
  </label>
336
- `;
337
  optionsContainer.appendChild(listItem);
338
  });
339
  sectionDiv.appendChild(optionsContainer);
@@ -345,6 +495,151 @@
345
  document.getElementById('addons-list').innerHTML = '<p>Error loading customization options.</p>';
346
  });
347
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
348
  </script>
 
 
 
349
  </body>
350
  </html>
 
 
 
 
7
  <!-- Bootstrap CSS -->
8
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/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; /* Updated background color */
14
+ margin: 0;
15
+ padding: 0;
16
+ display: flex;
17
+ flex-direction: column;
18
+ }
19
+ .container {
20
+ max-width: 900px;
21
+ }
22
+ .menu-card {
23
+ max-width: 350px;
24
+ border-radius: 15px;
25
+ overflow: hidden;
26
+ background-color: #fff;
27
+ margin: auto;
28
+ }
29
+ .menu-image {
30
+ height: 200px; /* Fix height for consistency */
31
+ width: 100%; /* Make sure the width spans the entire card */
32
+ object-fit: cover; /* Ensures the image covers the box without distortion */
33
+ border-radius: 15px 15px 0 0; /* Keeps the rounded corners at the top */
34
+ }
35
+ }
36
+ .card-title {
37
+ font-size: 1.2rem;
38
+ font-weight: bold;
39
+ }
40
+ .card-text {
41
+ font-size: 1rem;
42
+ color: #6c757d;
43
+ }
44
+ .btn-primary {
45
+ font-size: 14px;
46
+ font-weight: bold;
47
+ border-radius: 5px;
48
+ width: 100px;
49
+ background-color: #0FAA39; /* Updated button background color */
50
+ border-color: #28a745;
51
+
52
+ }
53
+ .btn-primary:hover {
54
+ background-color: #0FAA39;
55
+ border-color: #ffffff;
56
+ }
57
+ .btn-primary:active,
58
+ .btn-primary:focus {
59
+ background-color: #4a5d68;
60
+ border-color: #ffffff;
61
+ box-shadow: none;
62
+ }
63
+ .view-cart-container {
64
+ position: fixed;
65
+ bottom: 20px;
66
+ right: 20px;
67
+ z-index: 999;
68
+ }
69
+ .view-cart-button {
70
+ background-color: #0FAA39; /* Updated View Cart button background color */
71
+ color: #fff;
72
+ padding: 10px 20px;
73
+ border-radius: 30px;
74
+ font-size: 1rem;
75
+ font-weight: bold;
76
+ text-decoration: none;
77
+ box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
78
+ display: flex;
79
+ align-items: center;
80
+ justify-content: center;
81
+ }
82
+ .view-cart-button:hover {
83
+ background-color: #109835; /* Slightly darker shade for hover effect */
84
+ text-decoration: none;
85
+ }
86
+ .avatar-dropdown-container {
87
+ position: relative;
88
+ }
89
+ .avatar-icon {
90
+ width: 40px;
91
+ height: 40px;
92
+ border-radius: 50%;
93
+ background-color: #5bbfc1;
94
+ cursor: pointer;
95
+ display: flex;
96
+ align-items: center;
97
+ justify-content: center;
98
+ color: white;
99
+ font-size: 20px;
100
+ font-weight: bold;
101
+ }
102
+ .dropdown-menu {
103
+ position: absolute;
104
+ right: 0;
105
+ top: 100%;
106
+ background-color: #fff;
107
+ border-radius: 5px;
108
+ width: 200px; /* Adjust width as needed */
109
+ box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
110
+ display: none;
111
+ }
112
+ .avatar-dropdown-container:hover .dropdown-menu {
113
+ display: block;
114
+ }
115
+ .dropdown-menu .dropdown-item {
116
+ padding: 10px 15px;
117
+ text-decoration: none;
118
+ color: #333;
119
+ border-bottom: 1px solid #ddd;
120
+ display: block; /* Make each item stack vertically */
121
+ }
122
+ .dropdown-menu .dropdown-item:last-child {
123
+ border-bottom: none; /* Remove the bottom border from the last item */
124
+ }
125
+ .dropdown-menu .dropdown-item:hover {
126
+ background-color: #f1f1f1;
127
+ }
128
+ .fixed-search-container {
129
+ position: absolute;
130
+ top: 90px; /* Move it slightly lower */
131
+ left: 50%;
132
+ transform: translateX(-50%);
133
+ width: 80%;
134
+ max-width: 600px;
135
+ z-index: 999; /* Keep it above content */
136
+ background-color: white;
137
+ padding: 10px;
138
+ border-radius: 25px;
139
+ box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);
140
+ }
141
+ /* Ensure the category filter dropdown does not overlap */
142
+ form.text-center.mb-4 {
143
+ margin-top: 120px !important; /* Increase spacing below search bar */
144
+ }
145
+ /* Ensure the container has enough margin so nothing is overlapped */
146
+ .container {
147
+ margin-top: 180px; /* Adjust spacing based on navbar and search bar */
148
+ }
149
+ .fixed-top-bar {
150
+ position: fixed;
151
+ top: 0;
152
+ left: 0;
153
+ width: 100%;
154
+ height: 54px; /* Adjust the height as needed */
155
+ z-index: 1000;
156
+ background-color: #FF6B35;
157
+ color: white;
158
+ padding: 15px;
159
+ display: flex;
160
+ justify-content: space-between;
161
+ align-items: center; /* Vertically align items */
162
+ z-index: 10000; /* Make sure it's at the top */
163
+ }
164
+ .avatar-dropdown-container {
165
+ position: absolute;
166
+ right: 20px; /* Adjust the value as needed to position it properly */
167
+ top: 50%; /* Adjust top to place it within the header */
168
+ transform: translateY(-50%); /* Correct the alignment to be perfectly centered */
169
+ display: flex;
170
+ align-items: center;
171
+ justify-content: center;
172
+ }
173
+ .search-bar-container {
174
+ position: absolute;
175
+ left: 20px;
176
+ top: 50%;
177
+ transform: translateY(-50%);
178
+ display: flex;
179
+ justify-content: flex-start;
180
+ align-items: center;
181
+ width: 300px; /* Adjust width as needed */
182
+ }
183
+ .search-bar-container input {
184
+ width: 100%;
185
+ padding: 8px 10px 8px 30px; /* Add padding for the icon */
186
+ font-size: 16px;
187
+ border-radius: 20px;
188
+ border: none;
189
+ }
190
+ .search-icon {
191
+ position: absolute;
192
+ left: 10px; /* Position the icon inside the input box */
193
+ font-size: 20px;
194
+ color: #888; /* Icon color */
195
+ }
196
+ /* Style for customization sections */
197
+ .addon-section {
198
+ background-color: #f8f9fa; /* Light gray background */
199
+ border: 2px solid #ff6b35; /* Border color */
200
+ border-radius: 8px;
201
+ padding: 12px;
202
+ margin-bottom: 15px; /* Spacing between sections */
203
+ }
204
+ /* Customization section title */
205
+ .addon-section h6 {
206
+ margin-bottom: 10px;
207
+ font-size: 1.1rem;
208
+ font-weight: bold;
209
+ color: #333;
210
+ }
211
+ /* Style for add-on checkboxes */
212
+ .addon-section .form-check {
213
+ margin-left: 10px;
214
+ }
215
+ /* Category Filter with Custom Radio Buttons */
216
+ form.text-center.mb-4 {
217
+ display: flex;
218
+ flex-direction: column;
219
+ align-items: center;
220
+ }
221
+ .form-check {
222
+ display: inline-block;
223
+ margin-right: 15px;
224
+ margin-bottom: 15px; /* Add space between buttons */
225
+ }
226
+ .form-check-inline {
227
+ display: inline-block;
228
+ margin-right: 10px; /* Space between radio buttons */
229
+ }
230
+ .form-check-label {
231
+ font-size: 16px;
232
+ margin-left: 8px; /* Space between radio button and label */
233
+ }
234
+ .custom-radio {
235
+ appearance: none;
236
+ -webkit-appearance: none;
237
+ -moz-appearance: none;
238
+ width: 20px; /* Size of the radio button */
239
+ height: 20px; /* Size of the radio button */
240
+ border: 3px solid #4CAF50; /* Green border */
241
+ border-radius: 50%; /* Round shape */
242
+ margin-right: 10px; /* Space between button and label */
243
+ outline: none;
244
+ cursor: pointer;
245
+ position: relative;
246
+ display: inline-block;
247
+ }
248
+ .custom-radio:checked {
249
+ background-color: #4CAF50; /* Green color when checked */
250
+ border-color: #4CAF50; /* Matching border color */
251
+ }
252
+ .custom-radio:checked::after {
253
+ content: '';
254
+ position: absolute;
255
+ top: 5px; /* Adjust position for better alignment */
256
+ left: 5px; /* Adjust position for better alignment */
257
+ /* width: 10px; /* Increase inner dot size */
258
+ /* height: 10px; /* Increase inner dot size */
259
+ /* background-color: #fff; /* White dot when checked */
260
+ border-radius: 50%;
261
+ }
262
+ .custom-radio:hover {
263
+ border-color: #388E3C; /* Darker green on hover */
264
+ }
265
+ /* Optional: Style the labels */
266
+ .form-check-label {
267
+ font-size: 16px;
268
+ margin-left: 8px; /* Space between radio button and label */
269
+ }
270
+ #decrease-quantity, #increase-quantity {
271
+ width: 30px;
272
+ height: 30px;
273
+ font-size: 18px;
274
+ }
275
+ #add-to-cart {
276
+ font-size: 18px;
277
+ padding: 15px;
278
+ background-color: #4CAF50;
279
+ color: white;
280
+ font-weight: bold;
281
+ border-radius: 5px;
282
+ border: none;
283
+ }
284
+ #add-to-cart:hover {
285
+ background-color: #45a049; /* Slightly darker green on hover */
286
+ }
287
+ </style>
288
  </head>
289
  <body>
 
 
 
 
 
 
 
 
 
 
 
 
290
 
291
+ <div class="fixed-top-bar">
292
+ <!-- Avatar and Dropdown -->
293
+ <div class="avatar-dropdown-container">
294
+ <div class="avatar-icon">
295
+ <span>{{ first_letter }}</span> <!-- Display the first letter of the customer's name -->
296
+ </div>
297
+ <div class="dropdown-menu">
298
+ <a href="{{ url_for('customer_details') }}" class="dropdown-item">View Profile</a>
299
+ <a href="{{ url_for('order_history') }}" class="dropdown-item">Order History</a>
300
+ <a href="{{ url_for('logout') }}" class="dropdown-item">Logout</a>
301
  </div>
302
  </div>
303
 
304
+ <!-- Search Bar Section -->
305
+ <div class="search-bar-container">
306
+ <input type="text" id="searchBar" class="form-control" placeholder="Search items or sections..." onkeyup="filterMenu()">
307
+ <i class="bi bi-search search-icon"></i> <!-- Search icon inside the input -->
308
+ </div>
309
+ </div>
310
+
311
+ <!-- Category Filter with Custom Radio Buttons -->
312
+ <form method="get" action="/menu" class="text-center mb-4">
313
+ <label class="form-label fw-bold">Select a Category:</label>
314
+ <div class="form-check form-check-inline">
315
+ <input type="radio" id="category-All" name="category" value="All" class="custom-radio"
316
+ {% if selected_category == "All" %}checked{% endif %} onchange="this.form.submit()">
317
+ <label class="form-check-label" for="category-All">All</label>
318
+
319
+ <input type="radio" id="category-Veg" name="category" value="Veg" class="custom-radio"
320
+ {% if selected_category == "Veg" %}checked{% endif %} onchange="this.form.submit()">
321
+ <label class="form-check-label" for="category-Veg">Veg</label>
322
+
323
+ <input type="radio" id="category-NonVeg" name="category" value="Non veg" class="custom-radio"
324
+ {% if selected_category == "Non veg" %}checked{% endif %} onchange="this.form.submit()">
325
+ <label class="form-check-label" for="category-NonVeg">Non veg</label>
326
+
327
+ <input type="radio" id="category-CustomizedDish" name="category" value="Customized Dish" class="custom-radio"
328
+ {% if selected_category == "Customized Dish" %}checked{% endif %} onchange="this.form.submit()">
329
+ <label class="form-check-label" for="category-CustomizedDish">Customized Dish</label>
330
+ </div>
331
+ </form>
332
 
333
+ <!-- Show menu items only when Customized Dish is not selected -->
334
  <div class="container mt-4">
335
  <h1 class="text-center">Menu</h1>
336
+
337
+ <!-- Display text boxes for Customized Dish -->
338
+ {% if selected_category == "Customized Dish" %}
339
+ <div id="custom-dish-form" class="mt-4">
340
+ <h3>Create Your Custom Dish</h3>
341
+ <form method="POST" action="/generate_custom_dish">
342
+ <div class="mb-3">
343
+ <label for="custom-dish-name" class="form-label">Dish Name</label>
344
+ <input type="text" class="form-control" id="custom-dish-name" name="name" required>
 
 
 
 
 
 
 
345
  </div>
346
+ <div class="mb-3">
347
+ <label for="custom-dish-description" class="form-label">Dish Description</label>
348
+ <textarea class="form-control" id="custom-dish-description" name="description" required></textarea>
349
+ </div>
350
+ <button type="submit" class="btn btn-primary">Submit</button>
351
+ </form>
352
+ </div>
353
+ {% else %}
354
+
355
+ <!-- Menu Sections -->
356
+ {% for section, items in ordered_menu.items() %}
357
+ <h3>{{ section }}</h3>
358
+ <div class="row">
359
+ {% for item in items %}
360
+ <div class="col-md-6 mb-4">
361
+ <div class="card menu-card">
362
+ <img src="{{ item.Image1__c }}" class="card-img-top menu-image" alt="{{ item.Name }}" onerror="this.src='/static/placeholder.jpg';">
363
+ <div class="card-body">
364
+ <h5 class="card-title">{{ item.Name }}</h5>
365
+ <p class="card-text">${{ item.Price__c }}</p>
366
+ <button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#itemModal"
367
+ onclick="showItemDetails('{{ item.Name }}', '{{ item.Price__c }}', '{{ item.Image2__c }}', '{{ item.Description__c }}', '{{ item.Section__c }}','{{ selected_category }}')">
368
+ Add
369
+ </button>
370
  </div>
371
  </div>
372
+ </div>
373
+ {% endfor %}
374
+ </div>
375
+ {% endfor %}
376
+ </div>
377
+ {% endif %}
378
+
379
  </div>
380
 
381
  <!-- View Cart Button -->
382
  <div class="view-cart-container">
383
+ <a href="/cart" class="view-cart-button">
384
+ View Cart
385
+ </a>
386
  </div>
387
 
388
+ <!-- Bootstrap JS -->
389
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
390
 
391
+ <!-- Modal for Item Details -->
392
+ <div class="modal fade" id="itemModal" tabindex="-1" aria-labelledby="itemModalLabel" aria-hidden="true">
393
+ <div class="modal-dialog modal-dialog-centered">
394
+ <div class="modal-content">
395
+ <div class="modal-header">
396
+ <h5 class="modal-title" id="itemModalLabel">Item Details</h5>
397
+ </div>
398
+ <div class="modal-body">
399
+ <!-- Item Image -->
400
+ <img id="modal-img" class="img-fluid rounded mb-3 d-block mx-auto" alt="Item Image" style="max-height: 200px; object-fit: cover;">
401
+ <!-- Item Name -->
402
+ <h5 id="modal-name" class="fw-bold text-center"></h5>
403
+ <!-- Item Price -->
404
+ <p id="modal-price" class="text-muted text-center"></p>
405
+
406
+ <!-- Quantity Control -->
407
+ <div class="d-flex align-items-center justify-content-center mb-3">
408
+ <button id="decrease-quantity" class="btn btn-light">-</button>
409
+ <input type="number" id="quantity" class="form-control mx-2" value="1" min="1" readonly style="width: 60px;">
410
+ <button id="increase-quantity" class="btn btn-light">+</button>
411
  </div>
412
+
413
+ <!-- Add to Cart Button -->
414
+ <button id="add-to-cart" class="btn btn-success w-100">Add item ₹<span id="total-price">490</span></button>
415
  </div>
416
  </div>
417
  </div>
418
+ </div>
419
 
420
  <!-- JavaScript -->
421
  <script>
422
+ let itemPrice = 490; // Replace with dynamic item price
423
+ let quantity = 1;
424
+ // Update total price based on quantity
425
+ function updatePrice() {
426
+ const totalPrice = itemPrice * quantity;
427
+ document.getElementById('total-price').innerText = totalPrice;
428
+ }
429
+ // Decrease quantity
430
+ document.getElementById('decrease-quantity').addEventListener('click', function() {
431
+ if (quantity > 1) {
432
+ quantity--;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
433
  document.getElementById('quantity').value = quantity;
434
  updatePrice();
435
+ }
436
+ });
437
+ // Increase quantity
438
+ document.getElementById('increase-quantity').addEventListener('click', function() {
439
+ quantity++;
440
+ document.getElementById('quantity').value = quantity;
441
+ updatePrice();
442
+ });
443
+
444
  function showItemDetails(name, price, image, description, section, selectedCategory) {
445
  document.getElementById('modal-name').innerText = name;
446
+ document.getElementById('modal-price').innerText = $${price};
447
  document.getElementById('modal-img').src = image || '/static/placeholder.jpg';
448
  document.getElementById('modal-description').innerText = description || 'No description available.';
449
+ document.getElementById('addons-list').innerHTML = 'Loading customization options...';
450
+ document.getElementById('modal-instructions').value = '';
 
451
  // Set section and category for reference
452
  const modalSectionEl = document.getElementById('modal-section');
453
  modalSectionEl.setAttribute('data-section', section);
454
  modalSectionEl.setAttribute('data-category', selectedCategory);
 
455
  // Fetch customization options based on the section
456
+ fetch(/api/addons?item_name=${encodeURIComponent(name)}&item_section=${encodeURIComponent(section)})
457
  .then(response => response.json())
458
  .then(data => {
459
  const addonsList = document.getElementById('addons-list');
460
  addonsList.innerHTML = ''; // Clear previous content
461
+
462
  if (!data.success || !data.addons || data.addons.length === 0) {
463
  addonsList.innerHTML = '<p>No customization options available.</p>';
464
  return;
465
  }
 
466
  // Display customization options inside styled divs
467
  data.addons.forEach(addon => {
468
  const sectionDiv = document.createElement('div');
469
+ sectionDiv.classList.add('addon-section'); // Add styling class
470
+ // Add section title
471
  const title = document.createElement('h6');
472
  title.innerText = addon.name;
473
  sectionDiv.appendChild(title);
474
+ // Create options list
475
  const optionsContainer = document.createElement('div');
476
  addon.options.forEach((option, index) => {
477
+ const optionId = addon-${addon.name.replace(/\s+/g, '')}-${index};
478
  const listItem = document.createElement('div');
479
  listItem.classList.add('form-check');
480
+ listItem.innerHTML =
481
+ <input type="checkbox" class="form-check-input addon-option" id="${optionId}" value="${option}"
482
+ data-name="${option}" data-price="${addon.extra_charge ? addon.extra_charge_amount : 0}">
483
  <label class="form-check-label" for="${optionId}">
484
+ ${option} ${addon.extra_charge ? ($${addon.extra_charge_amount}) : ''}
485
  </label>
486
+ ;
487
  optionsContainer.appendChild(listItem);
488
  });
489
  sectionDiv.appendChild(optionsContainer);
 
495
  document.getElementById('addons-list').innerHTML = '<p>Error loading customization options.</p>';
496
  });
497
  }
498
+ function filterMenu() {
499
+ let input = document.getElementById('searchBar').value.toLowerCase(); // Get the value from search bar
500
+ let sections = document.querySelectorAll('h3'); // Select section headers
501
+ let items = document.querySelectorAll('.menu-card'); // Select all items
502
+ let matchedSections = new Set(); // Store matched sections
503
+
504
+ // Hide all items initially
505
+ items.forEach(item => {
506
+ let itemName = item.querySelector('.card-title').innerText.toLowerCase(); // Get item name
507
+ let itemSection = item.closest('.row').previousElementSibling.innerText.toLowerCase(); // Get section name
508
+
509
+ // If the search matches item name or section, show the item
510
+ if (itemName.includes(input) || (itemSection && itemSection.includes(input))) {
511
+ item.style.display = 'block'; // Show item if it matches search
512
+ matchedSections.add(item.closest('.row')); // Add section to matched list
513
+ } else {
514
+ item.style.display = 'none'; // Hide item if not matched
515
+ }
516
+ });
517
+
518
+ // Show or hide sections based on matched items
519
+ sections.forEach(section => {
520
+ let sectionRow = section.nextElementSibling; // The row containing items
521
+ if (matchedSections.has(sectionRow)) {
522
+ section.style.display = 'block'; // Show section header
523
+ sectionRow.style.display = 'flex'; // Show section items
524
+ } else {
525
+ section.style.display = 'none'; // Hide section header
526
+ sectionRow.style.display = 'none'; // Hide section items
527
+ }
528
+ });
529
+ }
530
+ function addToCartFromModal() {
531
+ const itemName = document.getElementById('modal-name').innerText;
532
+ let itemPrice = parseFloat(document.getElementById('modal-price').innerText.replace('$', ''));
533
+ // Validate item price
534
+ if (isNaN(itemPrice)) {
535
+ alert('Invalid price for the item. Please check the item details.');
536
+ return;
537
+ }
538
+ const itemImage = document.getElementById('modal-img').src;
539
+ console.log(itemName, itemPrice, itemImage); // Log values for debugging
540
+ const modalSectionEl = document.getElementById('modal-section');
541
+ const section = modalSectionEl.getAttribute('data-section');
542
+ const selectedCategory = modalSectionEl.getAttribute('data-category');
543
+ if (!itemName || !itemPrice || !section) {
544
+ console.error('Missing data for cart item:', { itemName, itemPrice, section });
545
+ return;
546
+ }
547
+
548
+ // Collect selected add-ons
549
+ let selectedAddOns = Array.from(
550
+ document.querySelectorAll('#addons-list input[type="checkbox"]:checked')
551
+ ).map(addon => ({
552
+ name: addon.getAttribute('data-name') || 'Default Name', //Fallback Name
553
+ price: parseFloat(addon.getAttribute('data-price') || 0)
554
+ }));
555
+ const instructions = document.getElementById('modal-instructions').value;
556
+ // Prepare data for the cart
557
+ const cartPayload = {
558
+ itemName: itemName,
559
+ itemPrice: itemPrice,
560
+ itemImage: itemImage,
561
+ section: section,
562
+ category: selectedCategory,
563
+ addons: selectedAddOns,
564
+ instructions: instructions
565
+ };
566
+ // Send the cart data to the server
567
+ fetch('/cart/add', {
568
+ method: 'POST',
569
+ headers: {
570
+ 'Content-Type': 'application/json',
571
+ },
572
+ body: JSON.stringify(cartPayload)
573
+ })
574
+ .then(response => response.json())
575
+ .then(data => {
576
+ if (data.success) {
577
+ alert('Item added to cart successfully!');
578
+ updateCartUI(data.cart); // Update cart UI after adding an item
579
+ const modal = document.getElementById('itemModal');
580
+ const modalInstance = bootstrap.Modal.getInstance(modal);
581
+ modalInstance.hide();
582
+ } else {
583
+ alert(data.error || 'Failed to add item to cart.');
584
+ }
585
+ })
586
+ .catch(err => {
587
+ console.error('Error adding item to cart:', err);
588
+ alert('An error occurred while adding the item to the cart.');
589
+ });
590
+ }
591
+ function updateCartUI(cart) {
592
+ if (!Array.isArray(cart)) {
593
+ console.error('Invalid cart data:', cart);
594
+ return;
595
+ }
596
+ const cartIcon = document.getElementById('cart-icon');
597
+ cartIcon.innerText = cart.length; // Assuming cart is an array of items
598
+ }
599
+ function updateCartDisplay(cart) {
600
+ if (!Array.isArray(cart)) {
601
+ console.error('Invalid cart data:', cart);
602
+ return;
603
+ }
604
+ const cartCountElement = document.getElementById('cart-count');
605
+ cartCountElement.innerText = cart.length; // Update cart item count
606
+ // Optionally, show a small success notification that the item was added
607
+ const successNotification = document.createElement('div');
608
+ successNotification.classList.add('success-notification');
609
+ successNotification.innerText = 'Item added to cart!';
610
+ document.body.appendChild(successNotification);
611
+ setTimeout(() => {
612
+ successNotification.remove(); // Remove success notification after a few seconds
613
+ }, 2000);
614
+ }
615
+ // Function to round reward points to a single digit
616
+ function roundRewardPoints() {
617
+ // Get the reward points element
618
+ let rewardPointsElement = document.getElementById('reward-points');
619
+ // Check if the element exists in the DOM
620
+ if (rewardPointsElement) {
621
+ let rewardPointsText = rewardPointsElement.innerText.trim(); // Get and trim the value to remove any extra spaces
622
+ // Check if the innerText is a valid number
623
+ let rewardPoints = parseFloat(rewardPointsText);
624
+ // If it's a valid number, round it to 1 decimal place
625
+ if (!isNaN(rewardPoints)) {
626
+ rewardPointsElement.innerText = rewardPoints.toFixed(1); // Round to 1 decimal place
627
+ } else {
628
+ console.error("Reward points value is not a valid number:", rewardPointsText);
629
+ }
630
+ } else {
631
+ console.error("Reward points element is missing.");
632
+ }
633
+ }
634
+ // Run the function when the page loads
635
+ window.onload = roundRewardPoints;
636
+
637
  </script>
638
+
639
+ <!-- Bootstrap JS -->
640
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
641
  </body>
642
  </html>
643
+ </script>
644
+ </body>
645
+ </html>