|
import gradio as gr |
|
import json |
|
import pandas as pd |
|
import os |
|
|
|
DATA_FILE = os.path.join("data", "teamup_data.json") |
|
|
|
ADMIN_CODE = os.getenv("ADMIN_CODE", "") |
|
|
|
|
|
|
|
os.makedirs("data", exist_ok=True) |
|
if not os.path.exists(DATA_FILE) or os.path.getsize(DATA_FILE) == 0: |
|
with open(DATA_FILE, "w") as f: |
|
json.dump([], f) |
|
|
|
def submit_profile(name, discord, city, country, address, looking, onlinecheck, languages, laptop, robot, skills, describe3, experience, idea): |
|
print("π’ Submit button clicked.") |
|
print(f"Incoming: {discord=}, {city=}, {country=}, {languages=}, {laptop=}, {robot=}") |
|
|
|
if not discord or not city or not country or not laptop or not robot: |
|
return "β Please fill in all required fields." |
|
if not languages or not isinstance(languages, list) or len(languages) == 0: |
|
return "β Please select at least one language." |
|
|
|
|
|
if isinstance(country, list): |
|
country = country[0] if country else "" |
|
|
|
with open(DATA_FILE, "r") as f: |
|
data = json.load(f) |
|
|
|
for d in data: |
|
if d["Discord"].lower() == discord.lower(): |
|
d.update({ |
|
"Name": name, |
|
"City": city, |
|
"Country": country, |
|
"Address": address, |
|
"Looking for Team": looking, |
|
"Onlinecheck": onlinecheck, |
|
"Languages": languages, |
|
"Laptop": laptop, |
|
"Robot": robot, |
|
"Skills": skills, |
|
"Describe3": describe3, |
|
"Experience": experience, |
|
"Project Idea": idea |
|
}) |
|
break |
|
else: |
|
data.append({ |
|
"Name": name, |
|
"Discord": discord, |
|
"City": city, |
|
"Country": country, |
|
"Address": address, |
|
"Looking for Team": looking, |
|
"Onlinecheck": onlinecheck, |
|
"Languages": languages, |
|
"Laptop": laptop, |
|
"Robot": robot, |
|
"Skills": skills, |
|
"Describe3": describe3, |
|
"Experience": experience, |
|
"Project Idea": idea |
|
}) |
|
|
|
try: |
|
with open(DATA_FILE, "w") as f: |
|
json.dump(data, f, indent=2) |
|
print(f"β
Successfully wrote {len(data)} profiles to {DATA_FILE}") |
|
except Exception as e: |
|
print(f"β Failed to write to {DATA_FILE}: {e}") |
|
return "β Error saving your profile. Please try again." |
|
|
|
return "β
Profile saved!" |
|
|
|
|
|
def filter_by_fields(selected_country, selected_city, selected_language): |
|
with open(DATA_FILE, "r") as f: |
|
data = json.load(f) |
|
df = pd.DataFrame(data) |
|
|
|
|
|
df["Languages"] = df["Languages"].apply(lambda langs: ", ".join(langs) if isinstance(langs, list) else langs) |
|
|
|
if df.empty or "Country" not in df.columns or "Languages" not in df.columns: |
|
return "<p>No participants found.</p>" |
|
|
|
if selected_country != "All": |
|
df = df[df["Country"] == selected_country] |
|
|
|
if selected_city != "All": |
|
df = df[df["City"] == selected_city] |
|
|
|
if selected_language != "All": |
|
df = df[df["Languages"].apply(lambda langs: selected_language in langs)] |
|
|
|
|
|
|
|
if "Address" in df.columns: |
|
df = df.drop(columns=["Address"]) |
|
|
|
|
|
display_names = { |
|
"Discord": "Discord", |
|
"Name": "Name", |
|
"City": "City", |
|
"Country": "Country", |
|
"Looking for Team": "Looking for Team", |
|
"Onlinecheck": "How?", |
|
"Languages": "Languages", |
|
"Laptop": "Laptop", |
|
"Robot": "Robot", |
|
"Skills": "Skills", |
|
"Describe3": "Describe", |
|
"Experience": "Experience", |
|
"Project Idea": "Project Idea" |
|
} |
|
|
|
html = '<h3 style="margin-top:20px;">π Find your matching Teammates & Register your team <a href="https://forms.gle/gJEMGD4CEA2emhD18" target="_blank">here</a>ππ</h3>' |
|
html += "<table style='width:100%; border-collapse: collapse;'>" |
|
|
|
|
|
html += "<tr>" + "".join( |
|
f"<th style='border: 1px solid #ccc; padding: 6px;'>{display_names.get(col, col)}</th>" |
|
for col in df.columns |
|
) + "</tr>" |
|
|
|
|
|
for _, row in df.iterrows(): |
|
html += "<tr>" |
|
for col in df.columns: |
|
val = row[col] |
|
if col == "Discord": |
|
val = f"<a href='https://discord.com/users/{val}' target='_blank'>{val}</a>" |
|
html += f"<td style='border: 1px solid #eee; padding: 6px;'>{val}</td>" |
|
html += "</tr>" |
|
|
|
html += "</table>" |
|
return html |
|
|
|
|
|
|
|
|
|
def update_dropdowns(): |
|
with open(DATA_FILE, "r") as f: |
|
data = json.load(f) |
|
if not data: |
|
return ["All"], ["All"], ["All"] |
|
df = pd.DataFrame(data) |
|
if "Country" not in df.columns or "Languages" not in df.columns or "City" not in df.columns: |
|
return ["All"], ["All"], ["All"] |
|
country_choices = sorted(list(df["Country"].dropna().unique())) |
|
city_choices = sorted(list(df["City"].dropna().unique())) |
|
language_set = set() |
|
for lang_list in df["Languages"].dropna(): |
|
language_set.update(lang_list) |
|
return ( |
|
["All"] + country_choices, |
|
["All"] + sorted(language_set), |
|
["All"] + city_choices |
|
) |
|
|
|
|
|
|
|
def delete_by_discord(discord, code): |
|
if code != ADMIN_CODE: |
|
return "β Invalid admin code." |
|
with open(DATA_FILE, "r") as f: |
|
data = json.load(f) |
|
new_data = [d for d in data if d["Discord"].lower() != discord.lower()] |
|
with open(DATA_FILE, "w") as f: |
|
json.dump(new_data, f, indent=2) |
|
return f"ποΈ Deleted user with Discord: {discord}" |
|
|
|
with gr.Blocks() as demo: |
|
gr.Markdown("# π LeRobot Worldwide Hackathon - Team-Up Dashboard") |
|
gr.Markdown("1. Submit or update your profile to find matching teammates and contact them on Discord. (Required fields marked with *.) ") |
|
|
|
with gr.Row(): |
|
with gr.Column(): |
|
name = gr.Text(label="Name") |
|
discord = gr.Text(label="π€ Discord Username *") |
|
city = gr.Text(label="π City *") |
|
country = gr.Text(label="π Country *") |
|
address = gr.Text(label="Address (optional)") |
|
looking = gr.Radio(["Yes", "No"], label="π Looking for a team?") |
|
onlinecheck = gr.Radio(["Participate Online", "Join a Local Hackathon"], label="π I will...") |
|
languages = gr.CheckboxGroup(choices=["English", "French", "Spanish", "German", "Portuguese", "Chinese", "Arabic", "Hindi"], label="Languages Spoken *") |
|
laptop = gr.Text(label="π» Laptop Setup *") |
|
robot = gr.Text(label="Robot Setup *") |
|
skills = gr.Text(label="π§ Your Skills (comma separated)") |
|
describe3 = gr.Text(label="π€ 3 Words That Describe You") |
|
experience = gr.Dropdown(choices=["Beginner", "Intermediate", "Advanced"], label="Experience Level", value="Beginner") |
|
idea = gr.Textbox(label="Project Idea (optional)") |
|
submit_btn = gr.Button("Submit or Update Profile β
") |
|
status = gr.Textbox(label="", interactive=False) |
|
|
|
with gr.Column(): |
|
gr.Markdown("π― 2. Choose your preferences to find your teammates (country, city or language)") |
|
country_filter = gr.Dropdown(label="Filter by Country", choices=["All"], value="All", allow_custom_value=False) |
|
city_filter = gr.Dropdown(label="Filter by City", choices=["All"], value="All", allow_custom_value=False) |
|
language_filter = gr.Dropdown(label="Filter by Language", choices=["All"], value="All", allow_custom_value=False) |
|
table_html = gr.HTML(label="Matching Participants") |
|
|
|
submit_btn.click( |
|
submit_profile, |
|
inputs=[name, discord, city, country, address, looking, onlinecheck, languages, laptop, robot, skills, describe3, experience, idea], |
|
outputs=[status] |
|
) |
|
|
|
|
|
|
|
def update_dropdown_choices(): |
|
with open(DATA_FILE, "r") as f: |
|
data = json.load(f) |
|
df = pd.DataFrame(data) |
|
|
|
country_choices = sorted(df["Country"].dropna().unique()) if "Country" in df else [] |
|
city_choices = sorted(df["City"].dropna().unique()) if "City" in df else [] |
|
language_set = set() |
|
if "Languages" in df: |
|
for lang_list in df["Languages"].dropna(): |
|
if isinstance(lang_list, list): |
|
language_set.update(lang_list) |
|
elif isinstance(lang_list, str): |
|
language_set.update(lang_list.split(", ")) |
|
return ( |
|
gr.update(choices=["All"] + list(country_choices), value="All"), |
|
gr.update(choices=["All"] + list(city_choices), value="All"), |
|
gr.update(choices=["All"] + sorted(language_set), value="All") |
|
) |
|
|
|
|
|
|
|
def download_csv(code): |
|
if code != ADMIN_CODE: |
|
raise gr.Error("β Invalid admin code.") |
|
with open(DATA_FILE, "r") as f: |
|
data = json.load(f) |
|
df = pd.DataFrame(data) |
|
csv_path = os.path.join("data", "teamup_export.csv") |
|
df.to_csv(csv_path, index=False) |
|
return csv_path |
|
|
|
with demo: |
|
demo.load( |
|
fn=lambda: filter_by_fields("All", "All", "All"), |
|
inputs=[], |
|
outputs=[table_html] |
|
) |
|
|
|
demo.load(fn=update_dropdown_choices, outputs=[country_filter, city_filter, language_filter]) |
|
|
|
country_filter.change(fn=filter_by_fields, inputs=[country_filter, city_filter, language_filter], outputs=table_html) |
|
city_filter.change(fn=filter_by_fields, inputs=[country_filter, city_filter, language_filter], outputs=table_html) |
|
language_filter.change(fn=filter_by_fields, inputs=[country_filter, city_filter, language_filter], outputs=table_html) |
|
|
|
|
|
|
|
gr.Markdown("---\n### π‘οΈ Admin Panel (delete by Discord)") |
|
admin_discord = gr.Text(label="Discord Username") |
|
admin_code = gr.Text(label="Admin Code", type="password") |
|
del_btn = gr.Button("Delete Profile") |
|
del_status = gr.Textbox(label="Status", interactive=False) |
|
del_btn.click(delete_by_discord, inputs=[admin_discord, admin_code], outputs=del_status) |
|
|
|
|
|
gr.Markdown("---\n### π₯ Admin Export CSV") |
|
export_code = gr.Text(label="Admin Code", type="password") |
|
download_btn = gr.Button("Generate and Download CSV") |
|
download_file = gr.File(label="CSV Export", interactive=False) |
|
download_btn.click(fn=download_csv, inputs=[export_code], outputs=[download_file]) |
|
|
|
demo.launch() |
|
|
|
|