nagasurendra commited on
Commit
40e55c3
·
verified ·
1 Parent(s): 0a4887e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +282 -0
app.py CHANGED
@@ -1,3 +1,285 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
 
3
  # The Gradio Blocks Interface
 
1
+ import bcrypt
2
+ import gradio as gr
3
+ from simple_salesforce import Salesforce
4
+
5
+ # Salesforce Connection
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
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
+
156
+ function openModal(name, image2, description, price) {
157
+ const modal = document.getElementById('modal');
158
+ modal.style.display = 'block';
159
+ modal.style.position = 'fixed';
160
+ modal.style.width = window.innerWidth <= 768 ? '90%' : '30%';
161
+ modal.style.top = `${event.clientY}px`;
162
+ modal.style.left = '50%';
163
+ modal.style.transform = 'translate(-50%, -50%)';
164
+ document.getElementById('modal-image').src = image2;
165
+ document.getElementById('modal-name').innerText = name;
166
+ document.getElementById('modal-description').innerText = description;
167
+ document.getElementById('modal-price').innerText = price;
168
+ document.getElementById('quantity').value = 1;
169
+ document.getElementById('special-instructions').value = '';
170
+ resetAddOns(); // Reset add-ons when opening the modal
171
+ }
172
+
173
+ function closeModal() {
174
+ document.getElementById('modal').style.display = 'none';
175
+ }
176
+
177
+ function addToCart() {
178
+ const name = document.getElementById('modal-name').innerText;
179
+ const price = parseFloat(document.getElementById('modal-price').innerText.replace('$', ''));
180
+ const quantity = parseInt(document.getElementById('quantity').value) || 1;
181
+ const instructions = document.getElementById('special-instructions').value;
182
+ const selectedAddOns = Array.from(document.querySelectorAll('input[name="biryani-extra"]:checked'));
183
+ const extras = selectedAddOns.map(extra => ({
184
+ name: extra.value,
185
+ price: parseFloat(extra.getAttribute('data-price')),
186
+ quantity: 1 // Default quantity for add-ons is 1
187
+ }));
188
+ const extrasCost = extras.reduce((total, extra) => total + (extra.price * extra.quantity), 0);
189
+ const totalCost = (price * quantity) + extrasCost;
190
+
191
+ // Add the item to the cart with its specific add-ons
192
+ cart.push({ name, price, quantity, extras, instructions, totalCost });
193
+ totalCartCost += totalCost; // Update the total cost of the cart
194
+ updateCartButton();
195
+ updateCartTotalCost(); // Update total cost displayed
196
+ closeModal();
197
+ }
198
+
199
+ function updateCartButton() {
200
+ const cartButton = document.getElementById('cart-button');
201
+ cartButton.innerText = `View Cart (${cart.length} items)`;
202
+ }
203
+
204
+ function openCartModal() {
205
+ const cartModal = document.getElementById('cart-modal');
206
+ const cartItemsContainer = document.getElementById('cart-items');
207
+ cartItemsContainer.innerHTML = "";
208
+ cart.forEach((item, index) => {
209
+ 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(', ');
210
+ cartItemsContainer.innerHTML += `
211
+ <div style="border: 1px solid #ddd; padding: 10px; margin-bottom: 10px; border-radius: 8px;">
212
+ <h3>${item.name}</h3>
213
+ <p>Quantity: <input type="number" value="${item.quantity}" min="1" style="width: 50px;" onchange="updateCartItem(${index}, 'item', this.value)" /></p>
214
+ <p>Extras: ${extrasList || 'None'}</p>
215
+ <p>Special Instructions: ${item.instructions || 'None'}</p>
216
+ <p>Total Cost: $<span id="item-${index}-total">${item.totalCost.toFixed(2)}</span></p>
217
+ <button onclick="removeFromCart(${index})" style="color: red;">Remove</button>
218
+ </div>
219
+ `;
220
+ });
221
+ cartModal.style.display = 'block';
222
+ }
223
+
224
+ function closeCartModal() {
225
+ document.getElementById('cart-modal').style.display = 'none';
226
+ }
227
+
228
+ function removeFromCart(index) {
229
+ totalCartCost -= cart[index].totalCost; // Deduct the cost of the removed item from total cost
230
+ cart.splice(index, 1);
231
+ updateCartButton();
232
+ updateCartTotalCost(); // Update total cost displayed
233
+ openCartModal();
234
+ }
235
+
236
+ function updateCartItem(index, type, value) {
237
+ if (type === 'item') {
238
+ cart[index].quantity = parseInt(value);
239
+ } else if (type === 'extra') {
240
+ cart[index].extras[0].quantity = parseInt(value); // Assuming one add-on for simplicity
241
+ }
242
+ const item = cart[index];
243
+ const price = item.price;
244
+ const extrasCost = item.extras.reduce((total, extra) => total + (extra.price * extra.quantity), 0);
245
+ item.totalCost = (price * item.quantity) + extrasCost;
246
+ document.getElementById(`item-${index}-total`).innerText = item.totalCost.toFixed(2);
247
+ updateCartTotalCost(); // Update total cost displayed
248
+ }
249
+
250
+ function updateCartTotalCost() {
251
+ const totalCostElement = document.getElementById('cart-total-cost');
252
+ totalCartCost = cart.reduce((total, item) => total + item.totalCost, 0);
253
+ totalCostElement.innerText = `Total Cart Cost: $${totalCartCost.toFixed(2)}`;
254
+ }
255
+
256
+ function proceedToCheckout() {
257
+ // Trigger the final order page and send the cart data
258
+ const finalOrderPage = document.getElementById('final-order-section');
259
+ const cartPage = document.getElementById('cart-section');
260
+ cartPage.style.display = 'none';
261
+ finalOrderPage.style.display = 'block';
262
+
263
+ // Show the cart details on the final order page
264
+ const finalOrderItems = document.getElementById('final-order-items');
265
+ const finalOrderTotal = document.getElementById('final-order-total');
266
+ let itemsHtml = '';
267
+ let totalBill = 0;
268
+ cart.forEach(item => {
269
+ itemsHtml += `<p>${item.name} (x${item.quantity}) - $${item.totalCost.toFixed(2)}</p>`;
270
+ totalBill += item.totalCost;
271
+ });
272
+ finalOrderItems.innerHTML = itemsHtml;
273
+ finalOrderTotal.innerHTML = `Total Bill: $${totalBill.toFixed(2)}`;
274
+ }
275
+
276
+ function goBackToMenu() {
277
+ const finalOrderPage = document.getElementById('final-order-section');
278
+ const cartPage = document.getElementById('cart-section');
279
+ finalOrderPage.style.display = 'none';
280
+ cartPage.style.display = 'block';
281
+ }
282
+ </script>
283
  import gradio as gr
284
 
285
  # The Gradio Blocks Interface