nagasurendra commited on
Commit
1b8720d
·
verified ·
1 Parent(s): a80b70a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +207 -83
app.py CHANGED
@@ -1,4 +1,5 @@
1
  import gradio as gr
 
2
  import pandas as pd
3
 
4
  # Function to load the menu data
@@ -24,15 +25,15 @@ def filter_menu(preference):
24
  html_content = ""
25
  for _, item in filtered_data.iterrows():
26
  html_content += f"""
27
- <div style="display: flex; align-items: center; border: 1px solid #ddd; border-radius: 8px; padding: 15px; margin-bottom: 10px; box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);">
28
- <div style="flex: 1; margin-right: 15px;">
29
- <h3 style="margin: 0; font-size: 18px;">{item['Dish Name']}</h3>
30
- <p style="margin: 5px 0; font-size: 16px; color: #888;">${item['Price ($)']}</p>
31
- <p style="margin: 5px 0; font-size: 14px; color: #555;">{item['Description']}</p>
32
  </div>
33
- <div style="flex-shrink: 0; text-align: center;">
34
- <img src="{item['Image URL']}" alt="{item['Dish Name']}" style="width: 100px; height: 100px; border-radius: 8px; object-fit: cover; margin-bottom: 10px;">
35
- <button style="background-color: #28a745; color: white; border: none; padding: 8px 15px; font-size: 14px; border-radius: 5px; cursor: pointer;" onclick="openModal('{item['Dish Name']}', '{item['Image URL']}', '{item['Description']}', '{item['Price ($)']}', event)">Add</button>
36
  </div>
37
  </div>
38
  """
@@ -89,29 +90,22 @@ modal_and_cart_js = """
89
  "Veg Manchurian": 12
90
  };
91
  let finalized = false;
92
- function openModal(name, image, description, price, event) {
93
  if (finalized) {
94
  alert("You cannot add more items after finalizing your order.");
95
  return;
96
  }
97
  const modal = document.getElementById('modal');
98
  modal.style.display = 'block';
99
- modal.style.position = 'absolute';
100
-
101
- try {
102
- // Get button position and adjust modal location
103
- const buttonRect = event.target.getBoundingClientRect();
104
- modal.style.top = `${window.scrollY + buttonRect.top}px`;
105
- modal.style.left = `${window.scrollX + buttonRect.left}px`;
106
- } catch (e) {
107
- console.error("Dynamic positioning failed, centering modal:", e);
108
- modal.style.position = 'fixed';
109
- modal.style.top = '15%';
110
- modal.style.left = '50%';
111
- modal.style.transform = 'translate(-50%, -50%)';
112
  }
113
-
114
- modal.style.width = window.innerWidth <= 768 ? "90%" : "30%";
 
115
  document.getElementById('modal-image').src = image;
116
  document.getElementById('modal-name').innerText = name;
117
  document.getElementById('modal-description').innerText = description;
@@ -124,75 +118,205 @@ modal_and_cart_js = """
124
  function closeModal() {
125
  document.getElementById('modal').style.display = 'none';
126
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
  </script>
128
  """
129
 
130
- # Gradio app definition
131
- def app():
132
- with gr.Blocks() as demo:
133
- gr.Markdown("## Dynamic Menu with Preferences")
 
 
 
 
 
 
 
 
 
 
 
 
 
134
 
135
- # Radio button for selecting preference
136
- selected_preference = gr.Radio(
137
- choices=["All", "Vegetarian", "Halal/Non-Veg", "Guilt-Free"],
138
- value="All",
139
- label="Choose a Preference",
140
- )
141
 
142
- # Output area for menu items
143
- menu_output = gr.HTML(value=filter_menu("All"))
 
 
 
144
 
145
- # Floating cart display
146
- cart_output = gr.HTML(value="Your cart is empty.", elem_id="floating-cart")
147
 
148
- # Final order display
149
- final_order_output = gr.HTML(value="", elem_id="final-order")
 
 
 
 
 
 
 
150
 
151
- # Modal window
152
- modal_window = gr.HTML("""
153
- <div id="modal" style="display: none; position: fixed; background: white; border-radius: 8px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); padding: 20px; z-index: 1000;">
154
- <div style="text-align: right;">
155
- <button onclick="closeModal()" style="background: none; border: none; font-size: 18px; cursor: pointer;">&times;</button>
156
- </div>
157
- <img id="modal-image" style="width: 100%; height: auto; border-radius: 8px; margin-bottom: 20px;" />
158
- <h2 id="modal-name"></h2>
159
- <p id="modal-description"></p>
160
- <p id="modal-price"></p>
161
- <!-- Biryani Extras -->
162
- <label for="biryani-extras">Biryani Extras :</label>
163
- <div id="biryani-extras-options" style="display: flex; flex-wrap: wrap; gap: 10px; margin: 10px 0;">
164
- <label><input type="checkbox" name="biryani-extra" value="Thums up" /> Thums up + $2.00</label>
165
- <label><input type="checkbox" name="biryani-extra" value="Sprite" /> Sprite + $2.00</label>
166
- <label><input type="checkbox" name="biryani-extra" value="Extra Raitha" /> Extra Raitha + $1.00</label>
167
- <label><input type="checkbox" name="biryani-extra" value="Extra Salan" /> Extra Salan + $2.00</label>
168
- <label><input type="checkbox" name="biryani-extra" value="Extra Onion & Lemon" /> Extra Onion & Lemon + $2.00</label>
169
- <label><input type="checkbox" name="biryani-extra" value="Chilli Chicken" /> Chilli Chicken + $14.00</label>
170
- <label><input type="checkbox" name="biryani-extra" value="Veg Manchurian" /> Veg Manchurian + $12.00</label>
171
- </div>
172
- <!-- Quantity and Special Instructions -->
173
- <label for="quantity">Quantity:</label>
174
- <input type="number" id="quantity" value="1" min="1" style="width: 50px;" />
175
- <br><br>
176
- <textarea id="special-instructions" placeholder="Add special instructions here..." style="width: 100%; height: 60px;"></textarea>
177
- <br><br>
178
- <!-- Add to Cart Button -->
179
- <button style="background-color: #28a745; color: white; border: none; padding: 10px 20px; font-size: 14px; border-radius: 5px; cursor: pointer;" onclick="addToCart()">Add to Cart</button>
180
- </div>
181
- """)
182
 
183
- # Update menu dynamically based on preference
184
- selected_preference.change(filter_menu, inputs=[selected_preference], outputs=[menu_output])
185
 
186
- # Layout
187
- gr.Row([selected_preference])
188
- gr.Row(menu_output)
189
- gr.Row(cart_output)
190
- gr.Row(modal_window)
191
- gr.Row(final_order_output)
192
- gr.HTML(modal_and_cart_js)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
 
194
- return demo
195
 
196
  if __name__ == "__main__":
197
- demo = app()
198
- demo.launch()
 
1
  import gradio as gr
2
+ from utils.database_handler import check_credentials, save_user
3
  import pandas as pd
4
 
5
  # Function to load the menu data
 
25
  html_content = ""
26
  for _, item in filtered_data.iterrows():
27
  html_content += f"""
28
+ <div style=\"display: flex; align-items: center; border: 1px solid #ddd; border-radius: 8px; padding: 15px; margin-bottom: 10px; box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);\">
29
+ <div style=\"flex: 1; margin-right: 15px;\">
30
+ <h3 style=\"margin: 0; font-size: 18px;\">{item['Dish Name']}</h3>
31
+ <p style=\"margin: 5px 0; font-size: 16px; color: #888;\">${item['Price ($)']}</p>
32
+ <p style=\"margin: 5px 0; font-size: 14px; color: #555;\">{item['Description']}</p>
33
  </div>
34
+ <div style=\"flex-shrink: 0; text-align: center;\">
35
+ <img src=\"{item['Image URL']}\" alt=\"{item['Dish Name']}\" style=\"width: 100px; height: 100px; border-radius: 8px; object-fit: cover; margin-bottom: 10px;\">
36
+ <button style=\"background-color: #28a745; color: white; border: none; padding: 8px 15px; font-size: 14px; border-radius: 5px; cursor: pointer;\" onclick=\"alert('{item['Dish Name']} added!');\">Add</button>
37
  </div>
38
  </div>
39
  """
 
90
  "Veg Manchurian": 12
91
  };
92
  let finalized = false;
93
+ function openModal(name, image, description, price) {
94
  if (finalized) {
95
  alert("You cannot add more items after finalizing your order.");
96
  return;
97
  }
98
  const modal = document.getElementById('modal');
99
  modal.style.display = 'block';
100
+ modal.style.position = 'fixed';
101
+ if (window.innerWidth <= 768) {
102
+ modal.style.width = '90%';
103
+ } else {
104
+ modal.style.width = '30%';
 
 
 
 
 
 
 
 
105
  }
106
+ modal.style.top = '15%';
107
+ modal.style.left = '50%';
108
+ modal.style.transform = 'translate(-50%, -50%)';
109
  document.getElementById('modal-image').src = image;
110
  document.getElementById('modal-name').innerText = name;
111
  document.getElementById('modal-description').innerText = description;
 
118
  function closeModal() {
119
  document.getElementById('modal').style.display = 'none';
120
  }
121
+ function addToCart() {
122
+ if (finalized) {
123
+ alert("You cannot add more items after finalizing your order.");
124
+ return;
125
+ }
126
+ const name = document.getElementById('modal-name').innerText;
127
+ const price = parseFloat(document.getElementById('modal-price').innerText.replace('$', ''));
128
+ const quantity = parseInt(document.getElementById('quantity').value) || 1;
129
+ const instructions = document.getElementById('special-instructions').value;
130
+ const extras = Array.from(document.querySelectorAll('input[name="biryani-extra"]:checked')).map(extra => extra.value);
131
+ const extrasCost = extras.reduce((sum, extra) => sum + (extrasPrices[extra] || 0), 0);
132
+ const itemTotal = (price + extrasCost) * quantity;
133
+ const cartItem = { name, price, quantity, instructions, extras, itemTotal, extrasQuantities: extras.map(() => 1) };
134
+ cart.push(cartItem);
135
+ alert(`${name} added to cart!`);
136
+ updateCartDisplay();
137
+ closeModal();
138
+ }
139
+ function updateCartDisplay() {
140
+ let totalBill = 0;
141
+ let cartHTML = "<div class='cart-container'>";
142
+ cart.forEach((item, index) => {
143
+ totalBill += item.itemTotal;
144
+ const extras = item.extras.map((extra, i) => {
145
+ const extraQuantity = item.extrasQuantities ? item.extrasQuantities[i] || 1 : 1;
146
+ const extraTotal = extrasPrices[extra] * extraQuantity;
147
+ totalBill += extraTotal;
148
+ return `<div class='cart-item'>
149
+ <span>${extra}</span>
150
+ <span>Price: $${extrasPrices[extra].toFixed(2)}</span>
151
+ <div class='quantity-container'>
152
+ <label for='extra-quantity-${index}-${i}'>Quantity:</label>
153
+ <input type='number' id='extra-quantity-${index}-${i}' value='${extraQuantity}' min='1' style='width: 50px;' onchange='updateExtraQuantity(${index}, ${i}, this.value)'>
154
+ </div>
155
+ <span>Total: $${extraTotal.toFixed(2)}</span>
156
+ <input type='checkbox' id='extra-remove-${index}-${i}' onclick='removeExtra(${index}, ${i})'> Remove
157
+ </div>`;
158
+ }).join('');
159
+ cartHTML += `<div class='cart-item'>
160
+ <span>${item.name}</span>
161
+ <span>Item Price: $${item.price.toFixed(2)}</span>
162
+ <div class='quantity-container'>
163
+ <label for='item-quantity-${index}'>Quantity:</label>
164
+ <input type='number' id='item-quantity-${index}' value='${item.quantity}' min='1' style='width: 50px;' onchange='updateItemQuantity(${index}, this.value)'>
165
+ </div>
166
+ <span>Total: $${(item.price * item.quantity).toFixed(2)}</span>
167
+ <input type='checkbox' id='item-remove-${index}' onclick='removeItem(${index})'> Remove
168
+ </div>
169
+ ${extras}
170
+ <div class='cart-item'><strong>Instructions:</strong> ${item.instructions || "None"}</div>`;
171
+ });
172
+ cartHTML += `</div><p class='cart-total'>Total Bill: $${totalBill.toFixed(2)}</p>`;
173
+ cartHTML += `<button style='margin-top: 10px; background-color: #007bff; color: white; border: none; padding: 10px; border-radius: 5px; width: 100%; cursor: pointer;' onclick='submitCart()'>Submit</button>`;
174
+ document.getElementById('floating-cart').innerHTML = cartHTML;
175
+ }
176
+ function updateItemQuantity(index, newQuantity) {
177
+ const quantity = parseInt(newQuantity) || 1;
178
+ cart[index].quantity = quantity;
179
+ cart[index].itemTotal = cart[index].price * quantity;
180
+ updateCartDisplay();
181
+ }
182
+ function updateExtraQuantity(cartIndex, extraIndex, newQuantity) {
183
+ const quantity = parseInt(newQuantity) || 1;
184
+ cart[cartIndex].extrasQuantities = cart[cartIndex].extrasQuantities || [];
185
+ cart[cartIndex].extrasQuantities[extraIndex] = quantity;
186
+ updateCartDisplay();
187
+ }
188
+ function removeExtra(cartIndex, extraIndex) {
189
+ cart[cartIndex].extras.splice(extraIndex, 1);
190
+ if (cart[cartIndex].extrasQuantities) {
191
+ cart[cartIndex].extrasQuantities.splice(extraIndex, 1);
192
+ }
193
+ updateCartDisplay();
194
+ }
195
+ function removeItem(index) {
196
+ cart.splice(index, 1);
197
+ updateCartDisplay();
198
+ }
199
+ function submitCart() {
200
+ let finalOrderHTML = "<h3>Final Order:</h3><ul>";
201
+ let totalBill = 0;
202
+ cart.forEach(item => {
203
+ totalBill += item.itemTotal;
204
+ const extras = item.extras.map((extra, i) => {
205
+ const extraQuantity = item.extrasQuantities ? item.extrasQuantities[i] || 1 : 1;
206
+ const extraTotal = extrasPrices[extra] * extraQuantity;
207
+ totalBill += extraTotal;
208
+ return `${extra} (x${extraQuantity}) - $${extraTotal.toFixed(2)}`;
209
+ }).join(', ');
210
+ finalOrderHTML += `<li>
211
+ ${item.name} (x${item.quantity}) - $${item.itemTotal.toFixed(2)}
212
+ <br>Extras: ${extras}
213
+ <br>Instructions: ${item.instructions || "None"}
214
+ </li>`;
215
+ });
216
+ finalOrderHTML += `</ul><p><strong>Total Bill: $${totalBill.toFixed(2)}</strong></p>`;
217
+ document.getElementById('final-order').innerHTML = finalOrderHTML;
218
+ alert("Your final order has been submitted!");
219
+ }
220
  </script>
221
  """
222
 
223
+ def app_interface():
224
+ # Login Button Actions
225
+ def authenticate_user(email, password):
226
+ if check_credentials(email, password):
227
+ return (
228
+ gr.update(visible=False), # Hide login page
229
+ gr.update(visible=True), # Show preferences page
230
+ gr.update(visible=True), # Show menu page
231
+ "", # Clear any error message
232
+ )
233
+ else:
234
+ return (
235
+ gr.update(visible=True), # Show error box
236
+ gr.update(visible=False), # Keep preferences page hidden
237
+ gr.update(visible=False), # Keep menu page hidden
238
+ "Invalid email or password. Try again.", # Error message
239
+ )
240
 
241
+ def navigate_to_signup():
242
+ return gr.update(visible=False), gr.update(visible=True)
 
 
 
 
243
 
244
+ def create_account(name, phone, email, password):
245
+ if save_user(name, phone, email, password):
246
+ return "Account created successfully! You can now log in.", gr.update(visible=True), gr.update(visible=False)
247
+ else:
248
+ return "Email already exists. Try logging in.", gr.update(visible=False), gr.update(visible=True)
249
 
250
+ def navigate_to_login():
251
+ return gr.update(visible=True), gr.update(visible=False)
252
 
253
+ with gr.Blocks() as app:
254
+ # Login Page
255
+ with gr.Column(visible=True) as login_section:
256
+ gr.Markdown("# Login Page")
257
+ email = gr.Textbox(label="Email", placeholder="Enter your email")
258
+ password = gr.Textbox(label="Password", placeholder="Enter your password", type="password")
259
+ error_box = gr.Markdown("", visible=False)
260
+ login_btn = gr.Button("Login")
261
+ create_account_btn = gr.Button("Create an Account")
262
 
263
+ # Sign-Up Page
264
+ with gr.Column(visible=False) as signup_section:
265
+ gr.Markdown("# Sign Up Page")
266
+ name = gr.Textbox(label="Name", placeholder="Enter your full name")
267
+ phone = gr.Textbox(label="Phone", placeholder="Enter your phone number")
268
+ signup_email = gr.Textbox(label="Email", placeholder="Enter your email")
269
+ signup_password = gr.Textbox(label="Password", placeholder="Enter a password", type="password")
270
+ success_message = gr.Markdown("", visible=False)
271
+ error_message = gr.Markdown("", visible=False)
272
+ submit_btn = gr.Button("Sign Up")
273
+ back_to_login_btn = gr.Button("Back to Login")
274
+
275
+ # Preferences Page
276
+ with gr.Column(visible=False) as preference_section:
277
+ gr.Markdown("# Preferences Page")
278
+
279
+ # Menu Page
280
+ with gr.Column(visible=False) as menu_section:
281
+ gr.Markdown("## Dynamic Menu with Preferences")
282
+
283
+ selected_preference = gr.Radio(
284
+ choices=["All", "Vegetarian", "Halal/Non-Veg", "Guilt-Free"],
285
+ value="All",
286
+ label="Choose a Preference",
287
+ )
 
 
 
 
 
 
288
 
289
+ menu_output = gr.HTML(value=filter_menu("All"))
290
+ cart_output = gr.HTML(value="Your cart is empty.", elem_id="floating-cart")
291
 
292
+ selected_preference.change(filter_menu, inputs=[selected_preference], outputs=[menu_output])
293
+
294
+ # Button Actions for Login
295
+ login_btn.click(
296
+ authenticate_user,
297
+ inputs=[email, password],
298
+ outputs=[login_section, preference_section, menu_section, error_box],
299
+ )
300
+ create_account_btn.click(
301
+ navigate_to_signup,
302
+ inputs=[],
303
+ outputs=[login_section, signup_section],
304
+ )
305
+
306
+ # Button Actions for Sign-Up
307
+ submit_btn.click(
308
+ create_account,
309
+ inputs=[name, phone, signup_email, signup_password],
310
+ outputs=[success_message, signup_section, login_section],
311
+ )
312
+ back_to_login_btn.click(
313
+ navigate_to_login,
314
+ inputs=[],
315
+ outputs=[login_section, signup_section],
316
+ )
317
 
318
+ return app
319
 
320
  if __name__ == "__main__":
321
+ app = app_interface()
322
+ app.launch()