Preeeeet's picture
Update app.py
aaf845c verified
Raw
History Blame Contribute Delete
7.24 kB
import gradio as gr
import pandas as pd
# Custom CSS for enhanced styling
custom_css = """
footer {visibility: hidden}
.app-title {
text-align: center;
color: #2F4F4F;
font-size: 2em !important;
font-weight: 500;
margin-bottom: 0.5em !important;
text-transform: lowercase;
}
.logo-container {
text-align: center;
margin-bottom: 1em;
}
.logo-img {
width: 200px;
height: auto;
margin: 0 auto;
display: block;
}
.filter-section {
background: #f8f9fa;
padding: 20px;
border-radius: 12px;
margin-bottom: 2em;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.results-section {
margin-top: 2em;
}
.dataframe {
border-radius: 8px !important;
overflow: hidden !important;
box-shadow: 0 4px 6px rgba(0,0,0,0.05) !important;
}
.button-primary {
background: linear-gradient(45deg, #4B0082, #6A5ACD) !important;
color: white !important;
border: none !important;
padding: 12px 24px !important;
border-radius: 8px !important;
transition: transform 0.2s ease !important;
}
.button-primary:hover {
transform: translateY(-1px);
}
.button-secondary {
background: linear-gradient(45deg, #228B22, #32CD32) !important;
border: none !important;
}
.empty-state {
text-align: center;
padding: 40px 20px;
background: #f8f9fa;
border-radius: 12px;
margin: 2em 0;
color: #666;
}
.footer-text {
text-align: center;
color: #666;
margin-top: 2em !important;
font-style: italic;
}
"""
# Load the Excel file
data = pd.read_excel('Indigenous Business Directory by Gov of Canada.xlsx')
# Updated service types
service_types = ["All", "Electrical", "Mechanical", "HVAC", "Sprinkler", "Plumbing",
"Demo", "Paint", "Millwork", "Flooring", "Drywall/Framing",
"Concrete/Scanning", "Excavation", "Steel"]
def update_city_options(province):
if not province:
return gr.Dropdown(choices=[], label="Select City", multiselect=True)
cities = ["All"] + data[data['Province'] == province]['City'].unique().tolist()
return gr.Dropdown(choices=cities, label="Select City", multiselect=True)
def search_directory(province, cities, service_types):
if not province:
return pd.DataFrame(columns=["Company Name", "Mail", "Website", "Phone", "Fax", "Address"])
filtered_data = data[data['Province'] == province]
if cities and "All" not in cities:
filtered_data = filtered_data[filtered_data['City'].isin(cities)]
if service_types and "All" not in service_types:
service_filter = filtered_data['Company Description'].apply(
lambda desc: any(service.lower() in str(desc).lower() for service in service_types)
)
filtered_data = filtered_data[service_filter]
if filtered_data.empty:
return pd.DataFrame(columns=["Company Name", "Mail", "Website", "Phone", "Fax", "Address"])
filtered_data['Address'] = (
filtered_data['Address 1'].astype(str) + ", " +
filtered_data['City'].astype(str) + ", " +
filtered_data['Province'].astype(str)
)
result_df = filtered_data.rename(
columns={
'Company Operating Name': 'Company Name',
'Email': 'Mail',
'URL': 'Website',
'Phone Number': 'Phone',
'Fax Number': 'Fax'
}
)[['Company Name', 'Mail', 'Website', 'Phone', 'Fax', 'Address']]
return result_df
def export_results_to_excel(province, cities, service_types):
results_df = search_directory(province, cities, service_types)
if results_df.empty:
raise gr.Error("No results to export!")
cities = cities or []
service_types = service_types or []
filename = f"Search_Results_{province}_{'_'.join(map(str, cities))}_{'_'.join(map(str, service_types))}.xlsx"
results_df.to_excel(filename, index=False)
return filename
with gr.Blocks(
theme=gr.themes.Default(
primary_hue="indigo",
secondary_hue="emerald",
neutral_hue="slate",
radius_size="md",
text_size="md"
),
css=custom_css
) as app:
# Header Section
gr.HTML("""
<div class="logo-container">
<img src="https://i.ibb.co/zTtwDGMM/HKC-updatedlogo-original.png" class="logo-img" alt="Logo">
</div>
""")
gr.Markdown("<div class='app-title'>Indigenous business directory</div>")
gr.Markdown(
"""<div class='app-description'>
Discover and connect with Indigenous-owned businesses across Canada
</div>"""
)
# Filter Section
with gr.Row(variant="panel", elem_classes="filter-section"):
with gr.Column():
province_input = gr.Dropdown(
label="Select Province",
choices=[""] + sorted(data['Province'].unique()),
interactive=True,
allow_custom_value=False
)
city_input = gr.Dropdown(
label="Select City",
choices=[],
multiselect=True,
interactive=True
)
service_input = gr.Dropdown(
label="Select Service Type",
choices=service_types,
multiselect=True,
interactive=True
)
# Action Buttons
with gr.Row():
search_btn = gr.Button(
"🔍 Search Businesses",
variant="primary",
elem_classes="button-primary"
)
export_btn = gr.Button(
"📤 Export Results",
variant="secondary",
elem_classes="button-secondary"
)
# Results Section
with gr.Column(elem_classes="results-section"):
gr.Markdown("### Search Results")
output = gr.Dataframe(
headers=["Company Name", "Mail", "Website", "Phone", "Fax", "Address"],
datatype=["str", "str", "str", "str", "str", "str"],
interactive=False,
row_count=(10, "paginated"),
wrap=True,
elem_id="results-table"
)
# Empty State
empty_state = gr.HTML(
"""<div class='empty-state'>
<h3>No results found</h3>
<p>Try adjusting your filters or search criteria</p>
</div>""",
visible=False
)
# Footer
gr.Markdown("---")
gr.Markdown(
"""<div class='footer-text'>
🇨🇦 Proudly supporting Indigenous businesses in Canada
</div>"""
)
# Interactions
province_input.change(
fn=update_city_options,
inputs=province_input,
outputs=city_input
)
def toggle_empty_state(results):
return gr.HTML.update(visible=results.empty)
search_btn.click(
fn=search_directory,
inputs=[province_input, city_input, service_input],
outputs=output
).then(
fn=toggle_empty_state,
inputs=output,
outputs=empty_state
)
export_output = gr.File(label="Download Exported File")
export_btn.click(
fn=export_results_to_excel,
inputs=[province_input, city_input, service_input],
outputs=export_output
)
if __name__ == "__main__":
app.launch()