geethareddy commited on
Commit
2887f28
·
verified ·
1 Parent(s): b77a0a8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +225 -237
app.py CHANGED
@@ -5,28 +5,29 @@ from simple_salesforce import Salesforce
5
  # Salesforce Connection
6
  sf = Salesforce(username='diggavalli98@gmail.com', password='Sati@1020', security_token='sSSjyhInIsUohKpG8sHzty2q')
7
 
8
- cart = [] # Global cart to store added items
9
-
10
- # Hash Password
11
  def hash_password(password):
12
  return bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
13
 
14
- # Verify Password
15
  def verify_password(plain_password, hashed_password):
16
  return bcrypt.checkpw(plain_password.encode('utf-8'), hashed_password.encode('utf-8'))
17
 
18
- # Signup Function
19
  def signup(name, email, phone, password):
20
  try:
21
- query = f"SELECT Id FROM Customer_Login__c WHERE Email__c = '{email.strip()}'"
 
22
  result = sf.query(query)
 
23
  if len(result['records']) > 0:
24
  return "Email already exists! Please use a different email."
25
 
26
  hashed_password = hash_password(password)
 
27
  sf.Customer_Login__c.create({
28
  'Name': name.strip(),
29
- 'Email__c': email.strip(),
30
  'Phone_Number__c': phone.strip(),
31
  'Password__c': hashed_password
32
  })
@@ -34,275 +35,262 @@ def signup(name, email, phone, password):
34
  except Exception as e:
35
  return f"Error during signup: {str(e)}"
36
 
37
- # Login Function
38
  def login(email, password):
39
  try:
40
- query = f"SELECT Name, Password__c FROM Customer_Login__c WHERE Email__c = '{email.strip()}'"
 
41
  result = sf.query(query)
 
42
  if len(result['records']) == 0:
43
  return "Invalid email or password.", None
44
 
45
  user = result['records'][0]
46
- if verify_password(password.strip(), user['Password__c']):
 
 
47
  return "Login successful!", user['Name']
48
  else:
49
  return "Invalid email or password.", None
50
  except Exception as e:
51
  return f"Error during login: {str(e)}", None
52
 
53
- # Load Menu Data from Salesforce
54
  def load_menu_from_salesforce():
55
  try:
56
- query = "SELECT Name, Price__c, Description__c, Image2__c, Veg_NonVeg__c FROM Menu_Item__c"
 
 
 
 
 
 
 
 
 
57
  result = sf.query(query)
58
  return result['records']
59
  except Exception as e:
60
  return []
61
 
62
- # Filter Menu Items
63
  def filter_menu(preference):
64
  menu_data = load_menu_from_salesforce()
65
- filtered_data = []
66
- for item in menu_data:
67
- veg_nonveg = item.get("Veg_NonVeg__c", "").strip().lower()
68
- if preference == "All":
69
- filtered_data.append(item)
70
- elif preference == "Veg" and veg_nonveg in ["veg", "vegetarian"]:
71
- filtered_data.append(item)
72
- elif preference == "Non-Veg" and veg_nonveg in ["non-veg", "non veg", "nonvegetarian"]:
73
- filtered_data.append(item)
74
- return filtered_data
75
 
76
- # Render Menu as HTML with Add Button
77
- def render_menu_html(menu_data):
78
- html_content = '<div style="display: flex; flex-direction: column; gap: 20px; align-items: center;">'
79
  for item in menu_data:
80
- html_content += f"""
81
- <div class=\"menu-card\" style=\"display: flex; flex-direction: row; gap: 20px; border: 1px solid #ddd; border-radius: 10px; padding: 15px; width: 80%; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); align-items: center;\">
82
- <img src="{item.get('Image2__c', '')}" alt="{item['Name']}" style=\"width: 150px; height: 150px; object-fit: cover; border-radius: 10px;\">
83
- <div style=\"flex-grow: 1;\">
84
- <h3 style=\"margin: 0; font-size: 1.5em;\">{item['Name']}</h3>
85
- <p style=\"margin: 5px 0; font-size: 1.2em; color: green;\">${item['Price__c']}</p>
86
- <p style=\"margin: 5px 0; font-size: 1em; color: #555;\">{item['Description__c']}</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  </div>
88
- <button onclick=\"showPopup('{item['Name']}', '{item['Description__c']}', '{item['Price__c']}', '{item.get('Image2__c', '')}')\" style=\"background-color: green; color: white; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer;\">Add</button>
89
- </div>
90
- """
91
  html_content += '</div>'
92
- return html_content
93
 
94
- # Add Item to Cart
95
- def add_to_cart(name, price, quantity, addons, instructions):
96
- global cart
97
- item = {
98
- "name": name,
99
- "price": price,
100
- "quantity": quantity,
101
- "addons": addons,
102
- "instructions": instructions
103
- }
104
- cart.append(item)
105
- return render_cart_html()
106
 
107
- # Render Cart as HTML
108
- def render_cart_html():
109
- global cart
110
- if not cart:
111
- return "<p>Your cart is empty.</p>"
112
- html_content = '<div style="display: flex; flex-direction: column; gap: 20px; align-items: center;">'
113
- for index, item in enumerate(cart):
114
- html_content += f"""
115
- <div class=\"cart-item\" style=\"display: flex; flex-direction: column; gap: 10px; border: 1px solid #ddd; border-radius: 10px; padding: 15px; width: 80%; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);\">
116
- <h3>{item['name']}</h3>
117
- <p>Price: ${item['price']}</p>
118
- <p>Quantity: {item['quantity']}</p>
119
- <p>Add-ons: {', '.join(item['addons']) if item['addons'] else 'None'}</p>
120
- <p>Instructions: {item['instructions']}</p>
121
- <button onclick=\"removeFromCart({index})\" style=\"background-color: red; color: white; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer;\">Remove</button>
122
- </div>
123
- """
124
- html_content += '</div>'
125
  return html_content
126
 
127
- # Remove Item from Cart
128
- def remove_from_cart(index):
129
- global cart
130
- if 0 <= index < len(cart):
131
- cart.pop(index)
132
- return render_cart_html()
133
-
134
- # Add CSS for Styling
135
- menu_styles = """
136
- <style>
137
- .menu-card:hover {
138
- box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
139
- }
140
- .popup {
141
- position: fixed;
142
- top: 50%;
143
- left: 50%;
144
- transform: translate(-50%, -50%);
145
- background-color: white;
146
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
147
- border-radius: 10px;
148
- width: 400px;
149
- padding: 20px;
150
- display: none;
151
- z-index: 1000;
152
- }
153
- .popup img {
154
- width: 100%;
155
- border-radius: 10px;
156
- }
157
- .popup-content {
158
- margin-top: 15px;
159
- }
160
- .popup-close {
161
- position: absolute;
162
- top: 10px;
163
- right: 10px;
164
- background: none;
165
- border: none;
166
- font-size: 1.5em;
167
- cursor: pointer;
168
- }
169
- .popup-overlay {
170
- position: fixed;
171
- top: 0;
172
- left: 0;
173
- width: 100%;
174
- height: 100%;
175
- background: rgba(0, 0, 0, 0.5);
176
- display: none;
177
- z-index: 999;
178
- }
179
- .addon-container {
180
- margin-top: 15px;
181
- }
182
- .addon-container label {
183
- margin-right: 10px;
184
- }
185
- .addon-container input {
186
- margin-right: 5px;
187
- }
188
- .quantity-container {
189
- margin-top: 15px;
190
- }
191
- .instruction-container {
192
- margin-top: 15px;
193
- }
194
- </style>
195
- """
196
-
197
- # JavaScript for Popup Functionality
198
- menu_script = """
199
- <script>
200
- function showPopup(name, description, price, image) {
201
- const popup = document.getElementById('popup');
202
- const overlay = document.getElementById('popup-overlay');
203
- document.getElementById('popup-title').innerText = name;
204
- document.getElementById('popup-description').innerText = description;
205
- document.getElementById('popup-price').innerText = `$${price}`;
206
- document.getElementById('popup-image').src = image;
207
- popup.style.display = 'block';
208
- overlay.style.display = 'block';
209
- }
210
-
211
- function closePopup() {
212
- const popup = document.getElementById('popup');
213
- const overlay = document.getElementById('popup-overlay');
214
- popup.style.display = 'none';
215
- overlay.style.display = 'none';
216
- }
217
-
218
- function removeFromCart(index) {
219
- GradioAPI.call("remove_from_cart", index).then(function(html) {
220
- document.getElementById('cart-content').innerHTML = html;
221
- });
222
- }
223
- </script>
224
- """
225
-
226
- # Gradio App
227
- with gr.Blocks() as app:
228
- gr.HTML(menu_styles) # Add the CSS
229
- gr.HTML(menu_script) # Add the JavaScript
230
-
231
- # Popup HTML
232
- gr.HTML("""
233
- <div id='popup-overlay' class='popup-overlay' onclick='closePopup()'></div>
234
- <div id='popup' class='popup'>
235
- <button class='popup-close' onclick='closePopup()'>&times;</button>
236
- <img id='popup-image' src='' alt='Item Image'>
237
- <div class='popup-content'>
238
- <h3 id='popup-title'></h3>
239
- <p id='popup-description'></p>
240
- <p id='popup-price' style='color: green; font-size: 1.2em;'></p>
241
-
242
- <h4>Add-ons:</h4>
243
- <div class='addon-container'>
244
- <label><input type='checkbox' value='Thums Up + $2'> Thums Up + $2</label>
245
- <label><input type='checkbox' value='Sprite + $2'> Sprite + $2</label>
246
- <label><input type='checkbox' value='Extra Raitha + $1'> Extra Raitha + $1</label>
247
- <label><input type='checkbox' value='Extra Salan + $2'> Extra Salan + $2</label>
248
- <label><input type='checkbox' value='Extra Onion & Lemon + $2'> Extra Onion & Lemon + $2</label>
249
- <label><input type='checkbox' value='Chilli Chicken + $14'> Chilli Chicken + $14</label>
250
- <label><input type='checkbox' value='Veg Manchurian + $12'> Veg Manchurian + $12</label>
251
- </div>
252
-
253
- <div class='quantity-container'>
254
- <label>Quantity: <input type='number' id='popup-quantity' min='1' value='1'></label>
255
- </div>
256
-
257
- <div class='instruction-container'>
258
- <label>Special Instructions:</label>
259
- <textarea id='popup-instructions' placeholder='Add your special instructions here...' rows='3' style='width: 100%;'></textarea>
260
- </div>
261
 
262
- <button onclick="addToCart()" style='margin-top: 15px; background-color: green; color: white; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer;'>Add to Cart</button>
 
 
 
 
 
 
 
 
 
 
 
263
  </div>
 
 
 
 
264
  </div>
265
- """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
266
 
 
 
267
  with gr.Row():
268
  gr.HTML("<h1 style='text-align: center;'>Welcome to Biryani Hub</h1>")
269
 
270
  with gr.Row(visible=True) as login_page:
271
- login_email = gr.Textbox(label="Email")
272
- login_password = gr.Textbox(label="Password", type="password")
273
- login_button = gr.Button("Login")
274
- login_status = gr.Textbox(label="Status", interactive=False)
 
 
275
 
276
  with gr.Row(visible=False) as signup_page:
277
- signup_name = gr.Textbox(label="Name")
278
- signup_email = gr.Textbox(label="Email")
279
- signup_phone = gr.Textbox(label="Phone")
280
- signup_password = gr.Textbox(label="Password", type="password")
281
- submit_signup = gr.Button("Signup")
282
- signup_status = gr.Textbox(label="Status", interactive=False)
283
- to_login_button = gr.Button("Go to Login")
 
284
 
285
  with gr.Row(visible=False) as menu_page:
286
- preference = gr.Radio(choices=["All", "Veg", "Non-Veg"], label="Choose a Preference", value="All")
287
- menu_output = gr.HTML()
288
- preference.change(lambda p: render_menu_html(filter_menu(p)), inputs=preference, outputs=menu_output)
289
-
290
- with gr.Row(visible=False) as cart_page:
291
- cart_content = gr.HTML()
292
-
293
- def handle_login(email, password):
294
- status, user = login(email, password)
295
- if status == "Login successful!":
296
- return gr.update(visible=False), gr.update(visible=True), gr.update(value=""), status
297
- else:
298
- return gr.update(), gr.update(), gr.update(), status
299
-
300
- def handle_signup(name, email, phone, password):
301
- status = signup(name, email, phone, password)
302
- return status
303
-
304
- login_button.click(handle_login, [login_email, login_password], [login_page, menu_page, login_status])
305
- submit_signup.click(handle_signup, [signup_name, signup_email, signup_phone, signup_password], signup_status)
306
- to_login_button.click(lambda: (gr.update(visible=True), gr.update(visible=False)), None, [login_page, signup_page])
307
-
308
- app.launch()
 
5
  # Salesforce Connection
6
  sf = Salesforce(username='diggavalli98@gmail.com', password='Sati@1020', security_token='sSSjyhInIsUohKpG8sHzty2q')
7
 
8
+ # Function to Hash Password
 
 
9
  def hash_password(password):
10
  return bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
11
 
12
+ # Function to Verify Password
13
  def verify_password(plain_password, hashed_password):
14
  return bcrypt.checkpw(plain_password.encode('utf-8'), hashed_password.encode('utf-8'))
15
 
16
+ # Signup function
17
  def signup(name, email, phone, password):
18
  try:
19
+ email = email.strip()
20
+ query = f"SELECT Id FROM Customer_Login__c WHERE Email__c = '{email}'"
21
  result = sf.query(query)
22
+
23
  if len(result['records']) > 0:
24
  return "Email already exists! Please use a different email."
25
 
26
  hashed_password = hash_password(password)
27
+
28
  sf.Customer_Login__c.create({
29
  'Name': name.strip(),
30
+ 'Email__c': email,
31
  'Phone_Number__c': phone.strip(),
32
  'Password__c': hashed_password
33
  })
 
35
  except Exception as e:
36
  return f"Error during signup: {str(e)}"
37
 
38
+ # Login function
39
  def login(email, password):
40
  try:
41
+ email = email.strip()
42
+ query = f"SELECT Name, Password__c FROM Customer_Login__c WHERE Email__c = '{email}'"
43
  result = sf.query(query)
44
+
45
  if len(result['records']) == 0:
46
  return "Invalid email or password.", None
47
 
48
  user = result['records'][0]
49
+ stored_password = user['Password__c']
50
+
51
+ if verify_password(password.strip(), stored_password):
52
  return "Login successful!", user['Name']
53
  else:
54
  return "Invalid email or password.", None
55
  except Exception as e:
56
  return f"Error during login: {str(e)}", None
57
 
58
+ # Function to load menu data
59
  def load_menu_from_salesforce():
60
  try:
61
+ query = "SELECT Name, Price__c, Description__c, Image1__c, Image2__c, Veg_NonVeg__c, Section__c FROM Menu_Item__c"
62
+ result = sf.query(query)
63
+ return result['records']
64
+ except Exception as e:
65
+ return []
66
+
67
+ # Function to load add-ons data
68
+ def load_add_ons_from_salesforce():
69
+ try:
70
+ query = "SELECT Name, Price__c FROM Add_Ons__c"
71
  result = sf.query(query)
72
  return result['records']
73
  except Exception as e:
74
  return []
75
 
76
+ # Function to filter menu items
77
  def filter_menu(preference):
78
  menu_data = load_menu_from_salesforce()
 
 
 
 
 
 
 
 
 
 
79
 
80
+ filtered_data = {}
 
 
81
  for item in menu_data:
82
+ if "Section__c" not in item or "Veg_NonVeg__c" not in item:
83
+ continue
84
+
85
+ if item["Section__c"] not in filtered_data:
86
+ filtered_data[item["Section__c"]] = []
87
+
88
+ if preference == "All" or (preference == "Veg" and item["Veg_NonVeg__c"] in ["Veg", "Both"]) or (preference == "Non-Veg" and item["Veg_NonVeg__c"] in ["Non veg", "Both"]):
89
+ filtered_data[item["Section__c"].strip()].append(item)
90
+
91
+ html_content = '<div style="padding: 0 10px; max-width: 1200px; margin: auto;">'
92
+ for section, items in filtered_data.items():
93
+ html_content += f"<h2 style='text-align: center; margin-top: 5px;'>{section}</h2>"
94
+ html_content += '<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 15px; justify-content: center; margin-top: 10px;">'
95
+ for item in items:
96
+ html_content += f"""
97
+ <div style="border: 1px solid #ddd; border-radius: 10px; box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); overflow: hidden; height: 350px;">
98
+ <img src="{item.get('Image1__c', '')}" style="width: 100%; height: 200px; object-fit: cover;"
99
+ onclick="openModal('{item['Name']}', '{item.get('Image2__c', '')}', '{item['Description__c']}', '${item['Price__c']}')">
100
+ <div style="padding: 10px;">
101
+ <h3 style='font-size: 1.2em; text-align: center;'>{item['Name']}</h3>
102
+ <p style='font-size: 1.1em; color: green; text-align: center;'>${item['Price__c']}</p>
103
+ <p style='font-size: 0.9em; text-align: justify; margin: 5px;'>{item['Description__c']}</p>
104
+ </div>
105
  </div>
106
+ """
107
+ html_content += '</div>'
 
108
  html_content += '</div>'
 
109
 
110
+ if not any(filtered_data.values()):
111
+ return "<p>No items match your filter.</p>"
 
 
 
 
 
 
 
 
 
 
112
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  return html_content
114
 
115
+ # Create Modal Window HTML
116
+ def create_modal_window():
117
+ add_ons = load_add_ons_from_salesforce()
118
+ add_ons_html = ""
119
+ for add_on in add_ons:
120
+ add_ons_html += f"""
121
+ <label>
122
+ <input type="checkbox" name="biryani-extra" value="{add_on['Name']}" data-price="{add_on['Price__c']}" />
123
+ {add_on['Name']} + ${add_on['Price__c']}
124
+ </label>
125
+ <br>
126
+ """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
 
128
+ modal_html = f"""
129
+ <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;">
130
+ <div style="text-align: right;">
131
+ <button onclick="closeModal()" style="background: none; border: none; font-size: 18px; cursor: pointer;">&times;</button>
132
+ </div>
133
+ <img id="modal-image" style="width: 100%; height: 300px; border-radius: 8px; margin-bottom: 20px;" />
134
+ <h2 id="modal-name"></h2>
135
+ <p id="modal-description"></p>
136
+ <p id="modal-price"></p>
137
+ <label for="biryani-extras"><strong>Add-ons :</strong></label>
138
+ <div id="biryani-extras-options" style="display: flex; flex-wrap: wrap; gap: 10px; margin: 10px 0;">
139
+ {add_ons_html}
140
  </div>
141
+ <label for="quantity">Quantity:</label>
142
+ <input type="number" id="quantity" value="1" min="1" style="width: 50px;" />
143
+ <textarea id="special-instructions" placeholder="Add your special instructions here..." style="width: 100%; height: 60px;"></textarea>
144
+ <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>
145
  </div>
146
+ """
147
+ return modal_html
148
+
149
+ # JavaScript for Modal and Cart
150
+ def modal_js():
151
+ modal_script = """
152
+ <script>
153
+ let cart = [];
154
+ let totalCartCost = 0;
155
+ function openModal(name, image2, description, price) {
156
+ const modal = document.getElementById('modal');
157
+ modal.style.display = 'block';
158
+ modal.style.position = 'fixed';
159
+ modal.style.width = window.innerWidth <= 768 ? '90%' : '30%';
160
+ modal.style.top = ${event.clientY}px;
161
+ modal.style.left = '50%';
162
+ modal.style.transform = 'translate(-50%, -50%)';
163
+ document.getElementById('modal-image').src = image2;
164
+ document.getElementById('modal-name').innerText = name;
165
+ document.getElementById('modal-description').innerText = description;
166
+ document.getElementById('modal-price').innerText = price;
167
+ document.getElementById('quantity').value = 1;
168
+ document.getElementById('special-instructions').value = '';
169
+ resetAddOns(); // Reset add-ons when opening the modal
170
+ }
171
+ function closeModal() {
172
+ document.getElementById('modal').style.display = 'none';
173
+ }
174
+ function addToCart() {
175
+ const name = document.getElementById('modal-name').innerText;
176
+ const price = parseFloat(document.getElementById('modal-price').innerText.replace('$', ''));
177
+ const quantity = parseInt(document.getElementById('quantity').value) || 1;
178
+ const instructions = document.getElementById('special-instructions').value;
179
+ const selectedAddOns = Array.from(document.querySelectorAll('input[name="biryani-extra"]:checked'));
180
+ const extras = selectedAddOns.map(extra => ({
181
+ name: extra.value,
182
+ price: parseFloat(extra.getAttribute('data-price')),
183
+ quantity: 1 // Default quantity for add-ons is 1
184
+ }));
185
+ const extrasCost = extras.reduce((total, extra) => total + (extra.price * extra.quantity), 0);
186
+ const totalCost = (price * quantity) + extrasCost;
187
+ // Add the item to the cart with its specific add-ons
188
+ cart.push({ name, price, quantity, extras, instructions, totalCost });
189
+ totalCartCost += totalCost; // Update the total cost of the cart
190
+ updateCartButton();
191
+ updateCartTotalCost(); // Update total cost displayed
192
+ closeModal();
193
+ }
194
+ function updateCartButton() {
195
+ const cartButton = document.getElementById('cart-button');
196
+ cartButton.innerText = View Cart (${cart.length} items);
197
+ }
198
+ function openCartModal() {
199
+ const cartModal = document.getElementById('cart-modal');
200
+ const cartItemsContainer = document.getElementById('cart-items');
201
+ cartItemsContainer.innerHTML = "";
202
+ cart.forEach((item, index) => {
203
+ const extrasList = item.extras.map(extra => ${extra.name} x<input type="number" value="${extra.quantity}" min="1" style="width: 50px;" onchange="updateCartItem(${index}, 'extra', this.value)" /> (+$${(extra.price * extra.quantity).toFixed(2)})).join(', ');
204
+ cartItemsContainer.innerHTML +=
205
+ <div style="border: 1px solid #ddd; padding: 10px; margin-bottom: 10px; border-radius: 8px;">
206
+ <h3>${item.name}</h3>
207
+ <p>Quantity: <input type="number" value="${item.quantity}" min="1" style="width: 50px;" onchange="updateCartItem(${index}, 'item', this.value)" /></p>
208
+ <p>Extras: ${extrasList || 'None'}</p>
209
+ <p>Special Instructions: ${item.instructions || 'None'}</p>
210
+ <p>Total Cost: $<span id="item-${index}-total">${item.totalCost.toFixed(2)}</span></p>
211
+ <button onclick="removeFromCart(${index})" style="color: red;">Remove</button>
212
+ </div>
213
+ ;
214
+ });
215
+ cartModal.style.display = 'block';
216
+ }
217
+ function closeCartModal() {
218
+ document.getElementById('cart-modal').style.display = 'none';
219
+ }
220
+ function removeFromCart(index) {
221
+ totalCartCost -= cart[index].totalCost; // Deduct the cost of the removed item from total cost
222
+ cart.splice(index, 1);
223
+ updateCartButton();
224
+ updateCartTotalCost(); // Update total cost displayed
225
+ openCartModal();
226
+ }
227
+ function updateCartItem(index, type, value) {
228
+ if (type === 'item') {
229
+ cart[index].quantity = parseInt(value);
230
+ } else if (type === 'extra') {
231
+ cart[index].extras[0].quantity = parseInt(value); // Assuming one add-on for simplicity
232
+ }
233
+ const item = cart[index];
234
+ const price = item.price;
235
+ const extrasCost = item.extras.reduce((total, extra) => total + (extra.price * extra.quantity), 0);
236
+ item.totalCost = (price * item.quantity) + extrasCost;
237
+ document.getElementById(item-${index}-total).innerText = item.totalCost.toFixed(2);
238
+ updateCartTotalCost(); // Update total cost displayed
239
+ }
240
+ function updateCartTotalCost() {
241
+ const totalCostElement = document.getElementById('cart-total-cost');
242
+ totalCartCost = cart.reduce((total, item) => total + item.totalCost, 0);
243
+ totalCostElement.innerText = Total Cart Cost: $${totalCartCost.toFixed(2)};
244
+ }
245
+ function proceedToCheckout() {
246
+ alert("Proceeding to checkout...");
247
+ }
248
+ // Reset all selected add-ons when opening a new item modal
249
+ function resetAddOns() {
250
+ const checkboxes = document.querySelectorAll('input[name="biryani-extra"]');
251
+ checkboxes.forEach(checkbox => checkbox.checked = false); // Uncheck all add-ons
252
+ }
253
+ </script>
254
+ """
255
+ return modal_script
256
 
257
+ # Gradio App
258
+ with gr.Blocks() as app:
259
  with gr.Row():
260
  gr.HTML("<h1 style='text-align: center;'>Welcome to Biryani Hub</h1>")
261
 
262
  with gr.Row(visible=True) as login_page:
263
+ with gr.Column():
264
+ login_email = gr.Textbox(label="Email")
265
+ login_password = gr.Textbox(label="Password", type="password")
266
+ login_button = gr.Button("Login")
267
+ signup_button = gr.Button("Go to Signup")
268
+ login_output = gr.Textbox(label="Status")
269
 
270
  with gr.Row(visible=False) as signup_page:
271
+ with gr.Column():
272
+ signup_name = gr.Textbox(label="Name")
273
+ signup_email = gr.Textbox(label="Email")
274
+ signup_phone = gr.Textbox(label="Phone")
275
+ signup_password = gr.Textbox(label="Password", type="password")
276
+ submit_signup = gr.Button("Signup")
277
+ login_redirect = gr.Button("Go to Login")
278
+ signup_output = gr.Textbox(label="Status")
279
 
280
  with gr.Row(visible=False) as menu_page:
281
+ with gr.Column():
282
+ preference = gr.Radio(choices=["All", "Veg", "Non-Veg"], label="Filter Preference", value="All")
283
+ menu_output = gr.HTML()
284
+ gr.HTML("<div id='cart-button' style='position: fixed; top: 20px; right: 20px; background: #28a745; color: white; padding: 10px 20px; border-radius: 30px; cursor: pointer; z-index: 1000;' onclick='openCartModal()'>View Cart</div>")
285
+ gr.HTML("<div id='cart-modal' style='display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: white; z-index: 1000; overflow-y: auto;'><div style='padding: 20px;'><div style='text-align: right;'><button onclick='closeCartModal()' style='background: none; border: none; font-size: 24px; cursor: pointer;'>&times;</button></div><h1>Your Cart</h1><div id='cart-items'></div><p id='cart-total-cost' style='font-size: 1.2em; font-weight: bold;'>Total Cart Cost: $0.00</p><button style='background: #ff5722; color: white; padding: 10px 20px; border-radius: 5px; border: none; cursor: pointer;' onclick='proceedToCheckout()'>Proceed to Checkout</button></div></div>")
286
+ gr.HTML(create_modal_window())
287
+ gr.HTML(modal_js())
288
+
289
+ login_button.click(
290
+ lambda email, password: (gr.update(visible=False), gr.update(visible=True), gr.update(value=filter_menu("All")), "Login successful!")
291
+ if login(email, password)[0] == "Login successful!" else (gr.update(), gr.update(), gr.update(), "Invalid email or password."),
292
+ [login_email, login_password], [login_page, menu_page, menu_output, login_output]
293
+ )
294
+ preference.change(lambda pref: filter_menu(pref), [preference], menu_output)
295
+
296
+ app.launch()