salesloginmenu / app.py
geethareddy's picture
Update app.py
e6a8069 verified
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.