nagasurendra commited on
Commit
00864ee
·
verified ·
1 Parent(s): 19d4e5e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +72 -220
app.py CHANGED
@@ -1,159 +1,51 @@
1
- import gradio as gr
2
- import bcrypt
3
- from simple_salesforce import Salesforce
4
-
5
- # Salesforce Connection (use your credentials)
6
- sf = Salesforce(username='[email protected]', 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
- })
34
- return "Signup successful! You can now login."
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 based on preference
77
- def filter_menu(preference):
78
- menu_data = load_menu_from_salesforce()
79
- filtered_data = {}
80
-
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
- # Function to generate 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 functionality
150
  def modal_js():
151
  modal_script = """
152
  <script>
153
  let cart = [];
154
  let totalCartCost = 0;
155
-
156
- // Add item to cart
 
 
 
 
 
 
 
 
 
 
157
  function addToCart() {
158
  const name = document.getElementById('modal-name').innerText;
159
  const price = parseFloat(document.getElementById('modal-price').innerText.replace('$', ''));
@@ -163,114 +55,75 @@ def modal_js():
163
  const extras = selectedAddOns.map(extra => ({
164
  name: extra.value,
165
  price: parseFloat(extra.getAttribute('data-price')),
166
- quantity: 1 // Default quantity for add-ons is 1
167
  }));
168
  const extrasCost = extras.reduce((total, extra) => total + (extra.price * extra.quantity), 0);
169
  const totalCost = (price * quantity) + extrasCost;
170
-
171
- // Add item to cart
172
  cart.push({ name, price, quantity, extras, instructions, totalCost });
173
  totalCartCost += totalCost;
174
  updateCartButton();
175
  updateCartTotalCost();
176
  closeModal();
177
  }
178
-
179
  function updateCartButton() {
180
  const cartButton = document.getElementById('cart-button');
181
  cartButton.innerText = `View Cart (${cart.length} items)`;
182
  }
183
-
184
  function openCartModal() {
185
  const cartModal = document.getElementById('cart-modal');
186
  const cartItemsContainer = document.getElementById('cart-items');
187
  cartItemsContainer.innerHTML = "";
188
  cart.forEach((item, index) => {
189
- 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(', ');
190
  cartItemsContainer.innerHTML += `
191
- <div style="border: 1px solid #ddd; padding: 10px; margin-bottom: 10px; border-radius: 8px;">
192
  <h3>${item.name}</h3>
193
- <p>Quantity: <input type="number" value="${item.quantity}" min="1" style="width: 50px;" onchange="updateCartItem(${index}, 'item', this.value)" /></p>
194
  <p>Extras: ${extrasList || 'None'}</p>
195
  <p>Special Instructions: ${item.instructions || 'None'}</p>
196
- <p>Total Cost: $<span id="item-${index}-total">${item.totalCost.toFixed(2)}</span></p>
197
- <button onclick="removeFromCart(${index})" style="color: red;">Remove</button>
198
  </div>
199
  `;
200
  });
 
201
  cartModal.style.display = 'block';
202
  }
203
-
204
  function closeCartModal() {
205
  document.getElementById('cart-modal').style.display = 'none';
206
  }
207
-
208
- function removeFromCart(index) {
209
- totalCartCost -= cart[index].totalCost;
210
- cart.splice(index, 1);
211
- updateCartButton();
212
- updateCartTotalCost();
213
- openCartModal();
214
- }
215
-
216
- function updateCartItem(index, type, value) {
217
- if (type === 'item') {
218
- cart[index].quantity = parseInt(value);
219
- } else if (type === 'extra') {
220
- cart[index].extras[0].quantity = parseInt(value);
221
- }
222
- const item = cart[index];
223
- const price = item.price;
224
- const extrasCost = item.extras.reduce((total, extra) => total + (extra.price * extra.quantity), 0);
225
- item.totalCost = (price * item.quantity) + extrasCost;
226
- document.getElementById(`item-${index}-total`).innerText = item.totalCost.toFixed(2);
227
- updateCartTotalCost();
228
- }
229
-
230
- function updateCartTotalCost() {
231
- const totalCostElement = document.getElementById('cart-total-cost');
232
- totalCartCost = cart.reduce((total, item) => total + item.totalCost, 0);
233
- totalCostElement.innerText = `Total Cart Cost: $${totalCartCost.toFixed(2)}`;
234
- }
235
-
236
- function proceedToCheckout() {
237
- let checkoutSummary = "<h1>Checkout Summary</h1>";
238
- cart.forEach(item => {
239
- checkoutSummary += `
240
- <h3>${item.name}</h3>
241
- <p>Quantity: ${item.quantity}</p>
242
- <p>Extras: ${item.extras.map(extra => `${extra.name} x${extra.quantity}`).join(', ')}</p>
243
- <p>Special Instructions: ${item.instructions}</p>
244
- <p>Total: $${item.totalCost.toFixed(2)}</p>
245
  `;
246
  });
247
- checkoutSummary += `<p><strong>Total Cart Cost: $${totalCartCost.toFixed(2)}</strong></p>`;
248
- document.getElementById('checkout-summary').innerHTML = checkoutSummary;
249
  document.getElementById('cart-modal').style.display = 'none';
250
- document.getElementById('checkout-page').style.display = 'block';
251
-
252
- // Clear cart after submission
253
  cart = [];
254
  totalCartCost = 0;
255
  updateCartButton();
256
  updateCartTotalCost();
257
- }
258
-
259
- function goBackToMenu() {
260
- document.getElementById('menu-page').style.display = 'block';
261
- document.getElementById('cart-modal').style.display = 'none';
262
- }
263
-
264
- function resetAddOns() {
265
- const checkboxes = document.querySelectorAll('input[name="biryani-extra"]');
266
- checkboxes.forEach(checkbox => checkbox.checked = false);
267
  }
268
  </script>
269
-
270
-
271
-
272
  """
273
  return modal_script
 
 
274
  with gr.Blocks() as app:
275
  with gr.Row():
276
  gr.HTML("<h1 style='text-align: center;'>Welcome to Biryani Hub</h1>")
@@ -297,20 +150,19 @@ with gr.Blocks() as app:
297
  with gr.Column():
298
  preference = gr.Radio(choices=["All", "Veg", "Non-Veg"], label="Filter Preference", value="All")
299
  menu_output = gr.HTML()
300
- 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>")
301
- 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 onclick='goBackToMenu()' style='background: #ff5722; color: white; padding: 10px 20px; border-radius: 5px; border: none; cursor: pointer;'>Back</button><button onclick='proceedToCheckout()' style='background: #28a745; color: white; padding: 10px 20px; border-radius: 5px; border: none; cursor: pointer;'>Submit</button></div></div>")
 
 
 
 
302
  gr.HTML(create_modal_window())
303
  gr.HTML(modal_js())
304
 
305
- with gr.Row(visible=False) as checkout_page:
306
- with gr.Column():
307
- gr.HTML("<div id='checkout-summary'></div>")
308
-
309
  login_button.click(
310
  lambda email, password: (gr.update(visible=False), gr.update(visible=True), gr.update(value=filter_menu("All")), "Login successful!")
311
  if login(email, password)[0] == "Login successful!" else (gr.update(), gr.update(), gr.update(), "Invalid email or password."),
312
  [login_email, login_password], [login_page, menu_page, menu_output, login_output]
313
  )
314
- preference.change(lambda pref: filter_menu(pref), [preference], menu_output)
315
 
316
  app.launch()
 
1
+ # Updated Cart Modal HTML
2
+ def create_cart_modal():
3
+ cart_modal_html = """
4
+ <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;">
5
+ <div style="padding: 20px;">
6
+ <div style="text-align: right;">
7
+ <button onclick="closeCartModal()" style="background: none; border: none; font-size: 24px; cursor: pointer;">&times;</button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  </div>
9
+ <h1>Your Cart</h1>
10
+ <div id="cart-items"></div>
11
+ <p id="cart-total-cost" style="font-size: 1.2em; font-weight: bold;">Total Cart Cost: $0.00</p>
12
+ <button style="background: #ff5722; color: white; padding: 10px 20px; border-radius: 5px; border: none; cursor: pointer;" onclick="proceedToCheckout()">Proceed to Checkout</button>
13
+ <button style="background: #007bff; color: white; padding: 10px 20px; border-radius: 5px; border: none; cursor: pointer;" onclick="submitOrder()">Submit Order</button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
15
  </div>
16
  """
17
+ return cart_modal_html
18
+
19
+ # Final Order Page HTML
20
+ def create_final_order_page():
21
+ final_order_html = """
22
+ <div id="final-order-page" style="display: none; padding: 20px; max-width: 1200px; margin: auto;">
23
+ <h1>Final Order</h1>
24
+ <div id="final-order-items"></div>
25
+ <p id="final-order-total-cost" style="font-size: 1.2em; font-weight: bold;">Total Order Cost: $0.00</p>
26
+ <button onclick="confirmOrder()" style="background-color: #28a745; color: white; padding: 10px 20px; border-radius: 5px; cursor: pointer;">Confirm Order</button>
27
+ </div>
28
+ """
29
+ return final_order_html
30
 
31
+ # Updated JavaScript for Submit Order
32
  def modal_js():
33
  modal_script = """
34
  <script>
35
  let cart = [];
36
  let totalCartCost = 0;
37
+ function openModal(name, image2, description, price) {
38
+ const modal = document.getElementById('modal');
39
+ modal.style.display = 'block';
40
+ document.getElementById('modal-image').src = image2;
41
+ document.getElementById('modal-name').innerText = name;
42
+ document.getElementById('modal-description').innerText = description;
43
+ document.getElementById('modal-price').innerText = price;
44
+ resetAddOns(); // Reset add-ons when opening the modal
45
+ }
46
+ function closeModal() {
47
+ document.getElementById('modal').style.display = 'none';
48
+ }
49
  function addToCart() {
50
  const name = document.getElementById('modal-name').innerText;
51
  const price = parseFloat(document.getElementById('modal-price').innerText.replace('$', ''));
 
55
  const extras = selectedAddOns.map(extra => ({
56
  name: extra.value,
57
  price: parseFloat(extra.getAttribute('data-price')),
58
+ quantity: 1
59
  }));
60
  const extrasCost = extras.reduce((total, extra) => total + (extra.price * extra.quantity), 0);
61
  const totalCost = (price * quantity) + extrasCost;
 
 
62
  cart.push({ name, price, quantity, extras, instructions, totalCost });
63
  totalCartCost += totalCost;
64
  updateCartButton();
65
  updateCartTotalCost();
66
  closeModal();
67
  }
 
68
  function updateCartButton() {
69
  const cartButton = document.getElementById('cart-button');
70
  cartButton.innerText = `View Cart (${cart.length} items)`;
71
  }
 
72
  function openCartModal() {
73
  const cartModal = document.getElementById('cart-modal');
74
  const cartItemsContainer = document.getElementById('cart-items');
75
  cartItemsContainer.innerHTML = "";
76
  cart.forEach((item, index) => {
77
+ const extrasList = item.extras.map(extra => `${extra.name} (+$${(extra.price * extra.quantity).toFixed(2)})`).join(', ');
78
  cartItemsContainer.innerHTML += `
79
+ <div style="border: 1px solid #ddd; padding: 10px; margin-bottom: 10px;">
80
  <h3>${item.name}</h3>
81
+ <p>Quantity: ${item.quantity}</p>
82
  <p>Extras: ${extrasList || 'None'}</p>
83
  <p>Special Instructions: ${item.instructions || 'None'}</p>
84
+ <p>Total Cost: $${item.totalCost.toFixed(2)}</p>
 
85
  </div>
86
  `;
87
  });
88
+ document.getElementById('cart-total-cost').innerText = `Total Cart Cost: $${totalCartCost.toFixed(2)}`;
89
  cartModal.style.display = 'block';
90
  }
 
91
  function closeCartModal() {
92
  document.getElementById('cart-modal').style.display = 'none';
93
  }
94
+ function submitOrder() {
95
+ const finalOrderPage = document.getElementById('final-order-page');
96
+ const finalOrderItemsContainer = document.getElementById('final-order-items');
97
+ finalOrderItemsContainer.innerHTML = "";
98
+ cart.forEach((item) => {
99
+ const extrasList = item.extras.map(extra => `${extra.name} (+$${(extra.price * extra.quantity).toFixed(2)})`).join(', ');
100
+ finalOrderItemsContainer.innerHTML += `
101
+ <div style="border: 1px solid #ddd; padding: 10px; margin-bottom: 10px;">
102
+ <h3>${item.name}</h3>
103
+ <p>Quantity: ${item.quantity}</p>
104
+ <p>Extras: ${extrasList || 'None'}</p>
105
+ <p>Special Instructions: ${item.instructions || 'None'}</p>
106
+ <p>Total Cost: $${item.totalCost.toFixed(2)}</p>
107
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  `;
109
  });
110
+ document.getElementById('final-order-total-cost').innerText = `Total Order Cost: $${totalCartCost.toFixed(2)}`;
111
+ finalOrderPage.style.display = 'block';
112
  document.getElementById('cart-modal').style.display = 'none';
113
+ }
114
+ function confirmOrder() {
115
+ alert("Order confirmed! Thank you for your purchase.");
116
  cart = [];
117
  totalCartCost = 0;
118
  updateCartButton();
119
  updateCartTotalCost();
120
+ document.getElementById('final-order-page').style.display = 'none';
 
 
 
 
 
 
 
 
 
121
  }
122
  </script>
 
 
 
123
  """
124
  return modal_script
125
+
126
+ # Gradio App
127
  with gr.Blocks() as app:
128
  with gr.Row():
129
  gr.HTML("<h1 style='text-align: center;'>Welcome to Biryani Hub</h1>")
 
150
  with gr.Column():
151
  preference = gr.Radio(choices=["All", "Veg", "Non-Veg"], label="Filter Preference", value="All")
152
  menu_output = gr.HTML()
153
+ 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;' onclick='openCartModal()'>View Cart</div>")
154
+ 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><button style='background: #007bff; color: white; padding: 10px 20px; border-radius: 5px; border: none; cursor: pointer;' onclick='submitOrder()'>Submit Order</button></div></div>")
155
+
156
+ # Add Final Order Page
157
+ gr.HTML(create_final_order_page())
158
+
159
  gr.HTML(create_modal_window())
160
  gr.HTML(modal_js())
161
 
 
 
 
 
162
  login_button.click(
163
  lambda email, password: (gr.update(visible=False), gr.update(visible=True), gr.update(value=filter_menu("All")), "Login successful!")
164
  if login(email, password)[0] == "Login successful!" else (gr.update(), gr.update(), gr.update(), "Invalid email or password."),
165
  [login_email, login_password], [login_page, menu_page, menu_output, login_output]
166
  )
 
167
 
168
  app.launch()