Spaces:
Runtime error
Runtime error
| import gradio as gr | |
| import bcrypt | |
| from simple_salesforce import Salesforce | |
| # Salesforce Connection (Replace with your actual credentials) | |
| sf = Salesforce(username='diggavalli98@gmail.com', password='Sati@1020', security_token='sSSjyhInIsUohKpG8sHzty2q') | |
| # Function to Hash Password | |
| def hash_password(password): | |
| return bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8') | |
| # Function to Verify Password | |
| def verify_password(plain_password, hashed_password): | |
| return bcrypt.checkpw(plain_password.encode('utf-8'), hashed_password.encode('utf-8')) | |
| # Signup function | |
| def signup(name, email, phone, password): | |
| try: | |
| email = email.strip() | |
| query = f"SELECT Id FROM Customer_Login__c WHERE Email__c = '{email}'" | |
| result = sf.query(query) | |
| if len(result['records']) > 0: | |
| return "Email already exists! Please use a different email." | |
| hashed_password = hash_password(password) | |
| sf.Customer_Login__c.create({ | |
| 'Name': name.strip(), | |
| 'Email__c': email, | |
| 'Phone_Number__c': phone.strip(), | |
| 'Password__c': hashed_password | |
| }) | |
| return "Signup successful! You can now login." | |
| except Exception as e: | |
| return f"Error during signup: {str(e)}" | |
| # Login function | |
| def login(email, password): | |
| try: | |
| email = email.strip() | |
| query = f"SELECT Name, Password__c FROM Customer_Login__c WHERE Email__c = '{email}'" | |
| result = sf.query(query) | |
| if len(result['records']) == 0: | |
| return "Invalid email or password.", None | |
| user = result['records'][0] | |
| stored_password = user['Password__c'] | |
| if verify_password(password.strip(), stored_password): | |
| return "Login successful!", user['Name'] | |
| else: | |
| return "Invalid email or password.", None | |
| except Exception as e: | |
| return f"Error during login: {str(e)}", None | |
| # Function to load menu data from Salesforce | |
| def load_menu_from_salesforce(): | |
| try: | |
| query = "SELECT Name, Price__c, Description__c, Image1__c, Image2__c, Veg_NonVeg__c, Section__c FROM Menu_Item__c" | |
| result = sf.query(query) | |
| return result['records'] | |
| except Exception as e: | |
| print(f"Error loading menu from Salesforce: {e}") | |
| return [] | |
| # Function to load add-ons data from Salesforce | |
| def load_add_ons_from_salesforce(): | |
| try: | |
| query = "SELECT Name, Price__c, Id FROM Add_Ons__c" | |
| result = sf.query(query) | |
| return result['records'] | |
| except Exception as e: | |
| print(f"Error loading add-ons from Salesforce: {e}") | |
| return [] | |
| # Cart Management | |
| cart = [] | |
| total_cart_cost = 0 | |
| cart_id = None | |
| def add_to_cart(item_name, item_price, quantity, special_instructions, selected_addon_ids): | |
| global total_cart_cost, cart_id | |
| total_cost = item_price * quantity | |
| selected_addons = [addon for addon in load_add_ons_from_salesforce() if addon['Id'] in selected_addon_ids] | |
| addons_cost = sum(addon['Price__c'] for addon in selected_addons) | |
| try: | |
| if not cart_id: | |
| cart_record = sf.Cart__c.create({'Total_Cost__c': total_cost + addons_cost}) | |
| cart_id = cart_record['id'] | |
| addon_ids_str = ';'.join(selected_addon_ids) if selected_addon_ids else '' | |
| cart_item = sf.Cart_Item__c.create({ | |
| 'Name': item_name, | |
| 'Quantity__c': quantity, | |
| 'Price__c': item_price, | |
| 'Special_Instructions__c': special_instructions, | |
| 'Cart__c': cart_id, | |
| 'Add_ons__c': addon_ids_str | |
| }) | |
| sf.Cart__c.update(cart_id, {'Total_Cost__c': sf.Cart__c.get(cart_id)['Total_Cost__c'] + total_cost + addons_cost}) | |
| cart.append({ | |
| 'name': item_name, | |
| 'price': item_price, | |
| 'quantity': quantity, | |
| 'instructions': special_instructions, | |
| 'total_cost': total_cost + addons_cost, | |
| 'addons': selected_addons, | |
| 'cart_item_id': cart_item['id'] | |
| }) | |
| total_cart_cost += total_cost + addons_cost | |
| return cart, total_cart_cost | |
| except Exception as e: | |
| print(f"Error adding to cart: {e}") | |
| return f"Error adding to cart: {str(e)}" | |
| def remove_from_cart(index): | |
| global total_cart_cost, cart_id | |
| if 0 <= index < len(cart): | |
| try: | |
| cart_item_id = cart[index].get('cart_item_id') # Use get() to avoid KeyError | |
| if cart_item_id: | |
| sf.Cart_Item__c.delete(cart_item_id) | |
| total_cart_cost -= cart[index]['total_cost'] | |
| if cart_id: # Check if cart_id exists before updating | |
| sf.Cart__c.update(cart_id, {'Total_Cost__c': total_cart_cost}) | |
| cart.pop(index) | |
| return cart, total_cart_cost | |
| except Exception as e: | |
| print(f"Error removing from cart: {e}") | |
| return f"Error removing from cart: {str(e)}" | |
| else: | |
| return "Invalid item index", total_cart_cost | |
| # Checkout Summary | |
| def proceed_to_checkout(): | |
| summary = "" | |
| for item in cart: | |
| summary += f"{item['name']} (x{item['quantity']}) - ${item['total_cost']:.2f}\n" | |
| if item.get('instructions'): | |
| summary += f"Instructions: {item['instructions']}\n" | |
| if item.get('addons'): | |
| summary += f"Add-ons: {', '.join([addon['Name'] for addon in item['addons']])}\n" | |
| summary += f"Total Bill: <span class="math-inline">\{total\_cart\_cost\:\.2f\}" | |
| return summary | |
| \# Function to filter menu items based on user preference | |
| def filter\_menu\(preference\)\: | |
| menu\_data \= load\_menu\_from\_salesforce\(\) | |
| filtered\_data \= \{\} | |
| for item in menu\_data\: | |
| if "Section\_\_c" not in item or "Veg\_NonVeg\_\_c" not in item\: | |
| continue | |
| section \= item\["Section\_\_c"\]\.strip\(\) | |
| if section not in filtered\_data\: | |
| filtered\_data\[section\] \= \[\] | |
| 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"\]\)\: | |
| filtered\_data\[section\]\.append\(item\) | |
| if not any\(filtered\_data\.values\(\)\)\: | |
| return "<p\>No items match your filter\.</p\>" | |
| html\_content \= '<div style\="padding\: 0 10px; max\-width\: 1200px; margin\: auto;"\>' | |
| for section, items in filtered\_data\.items\(\)\: | |
| html\_content \+\= f"<h2 style\='text\-align\: center; margin\-top\: 5px;'\>\{section\}</h2\>" | |
| html\_content \+\= '<div style\="display\: grid; grid\-template\-columns\: repeat\(auto\-fit, minmax\(250px, 1fr\)\); gap\: 15px; justify\-content\: center; margin\-top\: 10px;"\>' | |
| for item in items\: | |
| image\_url \= item\.get\('Image1\_\_c', ''\) | |
| html\_content \+\= f""" | |
| <div style\="border\: 1px solid \#ddd; border\-radius\: 10px; box\-shadow\: 0px 4px 8px rgba\(0, 0, 0, 0\.1\); overflow\: hidden; height\: 350px;"\> | |
| <img src\="\{image\_url\}" style\="width\: 100%; height\: 200px; object\-fit\: cover; cursor\: pointer;" | |
| onclick\="openModal\('\{item\['Name'\]\}', '\{item\.get\('Image2\_\_c', ''\)\}', '\{item\['Description\_\_c'\]\}', \{item\['Price\_\_c'\]\}\)"\> | |
| <div style\="padding\: 10px;"\> | |
| <h3 style\='font\-size\: 1\.2em; text\-align\: center;'\>\{item\['Name'\]\}</h3\> | |
| <p style\='font\-size\: 1\.1em; color\: green; text\-align\: center;'\></span>{item['Price__c']}</p> | |
| <p style='font-size: 0.9em; text-align: justify; margin: 5px;'>{item['Description__c'] or ''}</p> | |
| </div> | |
| </div> | |
| """ | |
| html_content += '</div>' | |
| html_content += '</div>' | |
| return html_content | |
| # Function to generate HTML for the modal popup | |
| def generate_modal_html(item_name, item_image, item_description, item_price): | |
| add_ons = load_add_ons_from_salesforce() | |
| add_ons_html = "" | |
| for i, add_on in enumerate(add_ons): | |
| add_ons_html += f""" | |
| <div> | |
| <input type="checkbox" id="add-on_{i}" name="add-on" value="{add_on['Id']}" data-price="{add_on['Price__c']}"> | |
| <label for="add-on_{i}">{add_on['Name']} - ${add_on['Price__c']}</label> | |
| </div> | |
| """ | |
| modal_content = f""" | |
| <div id="modal-content" style="background: white; padding: 20px; width: 60%; box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2); position: absolute; top: 20%; left: 20%; z-index: 1000; display: none;"> | |
| <img src="{item_image}" style="width: 100%; height: 250px; object-fit: cover; border-radius: 8px;"> | |
| <h3>{item_name}</h3> | |
| <p>{item_description}</p> | |
| <p>Price: ${item_price}</p> | |
| <label for="quantity">Quantity:</label> | |
| <input type="number" id="quantity" name="quantity" value="1" min="1" style="width: 50px;"> | |
| <br> | |
| <textarea id="special-instructions" name="special-instructions" placeholder="Add your special instructions here..." style="width: calc(100% - 22px); height: 60px; margin-top: 10px;"></textarea> | |
| <br> | |
| <div style="margin-top: 10px;"> | |
| <h4>Select Add-ons:</h4> | |
| {add_ons_html} | |
| </div> | |
| <button type="submit" style="background-color: #28a745; color: white; padding: 10px 20px; border: none; font-size: 14px; border-radius: 5px; cursor: pointer; margin-top: 10px;">Add to Cart</button> | |
| <button type="button" onclick="closeModal()" style="background-color: #ff5722; color: white; padding: 10px 20px; border: none; font-size: 14px; border-radius: 5px; cursor: pointer; margin-top: 10px; float: right;">Close</button> | |
| </div> | |
| """ | |
| return modal_content | |
| # --- Gradio App --- | |
| with gr.Blocks() as app: | |
| # Hidden components to store data | |
| hidden_item_name = gr.State("") | |
| hidden_item_price = gr.State(0) | |
| with gr.Row(): | |
| gr.HTML("<h1 style='text-align: center;'>Welcome to Biryani Hub</h1>") | |
| with gr.Row(visible=True) as login_page: | |
| with gr.Column(): | |
| login_email = gr.Textbox(label="Email") | |
| login_password = gr.Textbox(label="Password", type="password") | |
| login_button = gr.Button("Login") | |
| signup_button = gr.Button("Go to Signup") | |
| login_output = gr.Textbox(label="Status") | |
| with gr.Row(visible=False) as signup_page: | |
| with gr.Column(): | |
| signup_name = gr.Textbox(label="Name") | |
| signup_email = gr.Textbox(label="Email") | |
| signup_phone = gr.Textbox(label="Phone") | |
| signup_password = gr.Textbox(label="Password", type="password") | |
| submit_signup = gr.Button("Signup") | |
| login_redirect = gr.Button("Go to Login") | |
| signup_output = gr.Textbox(label="Status") | |
| with gr.Row(visible=False) as menu_page: | |
| with gr.Column() as menu_column: | |
| preference = gr.Radio(choices=["All", "Veg", "Non-Veg"], label="Filter Preference", value="All") | |
| menu_output = gr.HTML(filter_menu("All")) | |
| modal_html = gr.HTML(generate_modal_html("", "", "", 0)) | |
| 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;'>View Cart</div>") | |
| cart_summary = gr.Textbox(label="Cart Summary", interactive=False) | |
| checkout_button = gr.Button("Proceed to Checkout", visible=False) | |
| with gr.Form(): | |
| item_name_hidden = gr.Textbox(visible=False) | |
| item_price_hidden = gr.Number(visible=False) | |
| submit_button = gr.Button("Add to Cart", visible=False) | |
| submit_button.click( | |
| fn=lambda *args: add_to_cart(*args), | |
| inputs=[item_name_hidden, item_price_hidden, gr.Number(value=1, label="Quantity"), gr.Textbox(label="Special Instructions"), gr.CheckboxGroup(choices=[add_on['Id'] for add_on in load_add_ons_from_salesforce()], label="Add-ons", value=[])], | |
| outputs=[cart_summary, gr.Number(label="Total Cart Cost")] | |
| ) | |
| def update_cart_summary_and_checkout_button(cart, total_cart_cost): | |
| cart_summary_str = proceed_to_checkout() | |
| checkout_visibility = True if cart else False | |
| return gr.update(value=cart_summary_str), gr.update(visible=checkout_visibility) | |
| submit_button.click( | |
| fn=update_cart_summary_and_checkout_button, | |
| inputs=[cart_summary, gr.Number(label="Total Cart Cost")], | |
| outputs=[cart_summary, checkout_button] | |
| ) | |
| checkout_button.click(proceed_to_checkout, [], cart_summary) | |
| # --- Event Handlers --- | |
| login_button.click( | |
| lambda email, password: (gr.update(visible=False), gr.update(visible=True), gr.update(value=filter_menu("All")), "Login successful!") | |
| if login(email, password)[0] == "Login successful!" else (gr.update(), gr.update(), gr.update(), "Invalid email or password."), | |
| [login_email, login_password], [login_page, menu_page, menu_output, login_output] | |
| ) | |
| submit_signup.click( | |
| lambda name, email, phone, password: signup(name, email, phone, password), | |
| inputs=[signup_name, signup_email, signup_phone, signup_password], | |
| outputs=signup_output | |
| ) | |
| signup_button.click( | |
| lambda: (gr.update(visible=False), gr.update(visible=True)), | |
| inputs=[], | |
| outputs=[login_page, signup_page] | |
| ) | |
| login_redirect.click( | |
| lambda: (gr.update(visible=True), gr.update(visible=False)), | |
| inputs=[], | |
| outputs=[login_page, signup_page] | |
| ) | |
| preference.change(lambda pref: filter_menu(pref), [preference], menu_output) | |
| # When an image is clicked, open the modal and populate it with item details | |
| def open_modal(item_name, item_image, item_description, item_price): | |
| return gr. |