DynamicMenu / app.py
dschandra's picture
Update app.py
c57f3fe verified
raw
history blame
6.24 kB
import gradio as gr
import pandas as pd
# Load menu data from Excel file
def load_menu(file_path="menu.xlsx"):
menu_df = pd.read_excel(file_path)
menu_df.columns = menu_df.columns.str.strip().str.lower()
column_mapping = {
"name": next((col for col in menu_df.columns if "name" in col), None),
"price": next((col for col in menu_df.columns if "price" in col), None),
"description": next((col for col in menu_df.columns if "description" in col), None),
"image": next((col for col in menu_df.columns if "image" in col), None),
}
missing_columns = [key for key, col in column_mapping.items() if col is None]
if missing_columns:
raise ValueError(f"Excel file is missing one or more required columns: {missing_columns}")
menu = []
for _, row in menu_df.iterrows():
menu.append({
"name": row[column_mapping["name"]],
"price": row[column_mapping["price"]],
"description": row[column_mapping["description"]],
"image": row[column_mapping["image"]],
})
return menu
# Initialize menu and cart
menu_data = load_menu("menu.xlsx")
cart = {}
# Function to render the menu
def display_menu():
"""
Generate the menu as HTML with functional Add buttons tied to Gradio's backend.
"""
menu_html = ""
for item in menu_data:
if item["name"] in cart:
# Quantity selector if the item is already in the cart
menu_html += f"""
<div style="display: flex; align-items: center; margin-bottom: 15px; border: 1px solid #ddd; padding: 10px; border-radius: 5px;">
<img src="{item['image']}" alt="{item['name']}" style="width: 80px; height: 80px; border-radius: 5px; margin-right: 15px;">
<div>
<h4 style="margin: 0;">{item['name']} - ${item['price']}</h4>
<p style="font-size: 12px; color: gray;">{item['description']}</p>
</div>
<div style="margin-left: auto; display: flex; align-items: center;">
<button onclick="decrease_quantity('{item['name']}')" style="background-color: #dc3545; color: white; border: none; padding: 5px; border-radius: 5px;">-</button>
<span style="margin: 0 10px;">{cart[item['name']]['quantity']}</span>
<button onclick="increase_quantity('{item['name']}')" style="background-color: #28a745; color: white; border: none; padding: 5px; border-radius: 5px;">+</button>
</div>
</div>
"""
else:
# Add button if the item is not in the cart
menu_html += f"""
<div style="display: flex; align-items: center; margin-bottom: 15px; border: 1px solid #ddd; padding: 10px; border-radius: 5px;">
<img src="{item['image']}" alt="{item['name']}" style="width: 80px; height: 80px; border-radius: 5px; margin-right: 15px;">
<div>
<h4 style="margin: 0;">{item['name']} - ${item['price']}</h4>
<p style="font-size: 12px; color: gray;">{item['description']}</p>
</div>
<button name="add-{item['name']}" style="background-color: #28a745; color: white; border: none; padding: 8px 12px; border-radius: 5px; cursor: pointer; margin-left: auto;">Add</button>
</div>
"""
return menu_html
# Function to add items to the cart
# Add to Cart Logic
def add_to_cart(item_name):
"""
Add an item to the cart and return the updated menu and cart summary.
"""
if item_name in cart:
cart[item_name]["quantity"] += 1
else:
for item in menu_data:
if item["name"] == item_name:
cart[item_name] = {
"name": item["name"],
"price": item["price"],
"quantity": 1
}
break
return display_menu(), update_cart_summary()
# Function to update the cart summary
def update_cart_summary():
num_items = sum(item["quantity"] for item in cart.values())
total_price = sum(item["price"] * item["quantity"] for item in cart.values())
return f"{num_items} items added", f"Total: ${total_price:.2f}"
# Function to render the cart page
def display_cart():
if not cart:
return "Your cart is empty."
cart_html = "<h3>Your Cart:</h3>"
total_price = 0
for item in cart.values():
item_total = item["price"] * item["quantity"]
total_price += item_total
cart_html += f"""
<div style="display: flex; align-items: center; margin-bottom: 15px; border: 1px solid #ddd; padding: 10px; border-radius: 5px;">
<h4 style="margin: 0;">{item['name']}</h4>
<div style="margin-left: auto; display: flex; align-items: center;">
<button onclick="update_quantity('{item['name']}', 'decrease')" style="background-color: #dc3545; color: white; border: none; padding: 5px; border-radius: 5px;">-</button>
<span style="margin: 0 10px;">{item['quantity']}</span>
<button onclick="update_quantity('{item['name']}', 'increase')" style="background-color: #28a745; color: white; border: none; padding: 5px; border-radius: 5px;">+</button>
</div>
<p style="margin: 0 0 0 15px;">${item_total:.2f}</p>
</div>
"""
cart_html += f"<h4>Total: ${total_price:.2f}</h4>"
cart_html += '<button style="padding: 10px; background-color: #28a745; color: white; border: none; border-radius: 5px;">Place Order</button>'
return cart_html
# Gradio Interface
with gr.Blocks() as demo:
gr.Markdown("# Dynamic Food Menu")
menu_html = gr.HTML(value=display_menu())
cart_summary = gr.HTML(value="No items added to cart.")
# Hidden input for item name
item_name_input = gr.Textbox(visible=False)
# Add Button Logic
add_button = gr.Button("Add to Cart", visible=False)
add_button.click(fn=add_to_cart, inputs=item_name_input, outputs=[menu_html, cart_summary])
# Display Menu and Cart Summary
menu_html.render()
cart_summary.render()
demo.launch()