|
import gradio as gr |
|
import pandas as pd |
|
import sqlite3 |
|
import os |
|
import datetime |
|
|
|
DATA_DIR = "data" |
|
os.makedirs(DATA_DIR, exist_ok=True) |
|
|
|
|
|
DB_PATH = os.path.join(DATA_DIR, "teamup.db") |
|
|
|
|
|
def init_db(): |
|
with sqlite3.connect(DB_PATH) as conn: |
|
conn.execute(""" |
|
CREATE TABLE IF NOT EXISTS teamup ( |
|
id INTEGER PRIMARY KEY AUTOINCREMENT, |
|
Name TEXT, |
|
Discord TEXT UNIQUE, |
|
City TEXT, |
|
Country TEXT, |
|
Address TEXT, |
|
Looking TEXT, |
|
Onlinecheck TEXT, |
|
Languages TEXT, |
|
Laptop TEXT, |
|
Robot TEXT, |
|
Skills TEXT, |
|
Describe3 TEXT, |
|
Experience TEXT, |
|
Idea TEXT |
|
); |
|
""") |
|
print("β
SQLite database initialized.") |
|
init_db() |
|
|
|
|
|
conn = sqlite3.connect(DB_PATH) |
|
c = conn.cursor() |
|
c.execute(''' |
|
CREATE TABLE IF NOT EXISTS teamup ( |
|
discord TEXT PRIMARY KEY, |
|
name TEXT, |
|
city TEXT, |
|
country TEXT, |
|
address TEXT, |
|
looking TEXT, |
|
onlinecheck TEXT, |
|
languages TEXT, |
|
laptop TEXT, |
|
robot TEXT, |
|
skills TEXT, |
|
describe3 TEXT, |
|
experience TEXT, |
|
idea TEXT |
|
) |
|
''') |
|
conn.commit() |
|
conn.close() |
|
|
|
ADMIN_CODE = os.getenv("ADMIN_CODE", "") |
|
|
|
ALL_COUNTRIES = sorted(list(set([ |
|
"United States of America", "United Kingdom", "India", "France", "Germany", "Canada", "Australia", "Japan", "Brazil", "Mexico", |
|
"Afghanistan", "Albania", "Algeria", "Andorra", "Angola", "Argentina", "Armenia", "Austria", "Azerbaijan", |
|
"Bangladesh", "Belgium", "Bhutan", "Bolivia", "Bosnia and Herzegovina", "Botswana", "Bulgaria", "Cambodia", |
|
"Chile", "China", "Colombia", "Croatia", "Cuba", "Czech Republic", "Denmark", "Dominican Republic", "Ecuador", |
|
"Egypt", "Estonia", "Ethiopia", "Finland", "Greece", "Hungary", "Iceland", "Indonesia", "Iran", "Iraq", "Ireland", |
|
"Israel", "Italy", "Jordan", "Kenya", "Kuwait", "Latvia", "Lithuania", "Luxembourg", "Malaysia", "Malta", "Morocco", |
|
"Nepal", "Netherlands", "New Zealand", "Nigeria", "Norway", "Pakistan", "Peru", "Philippines", "Poland", "Portugal", |
|
"Qatar", "Romania", "Russia", "Saudi Arabia", "Serbia", "Singapore", "Slovakia", "Slovenia", "South Africa", "South Korea", |
|
"Spain", "Sri Lanka", "Sweden", "Switzerland", "Thailand", "Tunisia", "Turkey", "Ukraine", "United Arab Emirates", "Vietnam", |
|
"Zambia", "Zimbabwe" |
|
]))) |
|
|
|
LANGUAGES = ["English", "French", "Spanish", "German", "Portuguese", "Chinese", "Arabic", "Hindi"] |
|
|
|
|
|
def submit_profile(name, discord, city, country, address, looking, onlinecheck, languages, laptop, robot, skills, describe3, experience, idea): |
|
if not discord or not city or not country or not laptop or not robot: |
|
return "β Please fill in all required fields." |
|
|
|
lang_str = ", ".join(languages) if isinstance(languages, list) else languages |
|
|
|
conn = sqlite3.connect(DB_FILE) |
|
c = conn.cursor() |
|
c.execute(""" |
|
INSERT INTO teamup (discord, name, city, country, address, looking, onlinecheck, languages, laptop, robot, skills, describe3, experience, idea) |
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) |
|
ON CONFLICT(discord) DO UPDATE SET |
|
name=excluded.name, |
|
city=excluded.city, |
|
country=excluded.country, |
|
address=excluded.address, |
|
looking=excluded.looking, |
|
onlinecheck=excluded.onlinecheck, |
|
languages=excluded.languages, |
|
laptop=excluded.laptop, |
|
robot=excluded.robot, |
|
skills=excluded.skills, |
|
describe3=excluded.describe3, |
|
experience=excluded.experience, |
|
idea=excluded.idea |
|
""", (discord, name, city.title(), country.title(), address, looking, onlinecheck, lang_str.lower(), laptop, robot, skills, describe3, experience, idea)) |
|
conn.commit() |
|
conn.close() |
|
return "β
Profile saved!" |
|
|
|
|
|
def filter_by_fields(selected_country, selected_city, selected_language): |
|
conn = sqlite3.connect(DB_FILE) |
|
df = pd.read_sql_query("SELECT * FROM teamup", conn) |
|
conn.close() |
|
|
|
if df.empty: |
|
return "<p>No data available.</p>" |
|
|
|
df["City"] = df["city"].str.title() |
|
df["Country"] = df["country"].str.title() |
|
df["Languages"] = df["languages"] |
|
|
|
if selected_country != "All": |
|
df = df[df["Country"] == selected_country.title()] |
|
if selected_city != "All": |
|
df = df[df["City"] == selected_city.title()] |
|
if selected_language != "All": |
|
df = df[df["Languages"].str.contains(selected_language.lower(), na=False)] |
|
|
|
if df.empty: |
|
return "<p>No participants match your filters.</p>" |
|
|
|
html = "<table style='width:100%; border-collapse: collapse;'><tr>" |
|
headers = ["Discord", "Name", "City", "Country", "Looking", "Onlinecheck", "Languages", "Laptop", "Robot", "Skills", "Describe3", "Experience", "Idea"] |
|
for col in headers: |
|
html += f"<th style='border:1px solid #ccc; padding:6px;'>{col}</th>" |
|
html += "</tr>" |
|
|
|
for _, row in df.iterrows(): |
|
html += "<tr>" |
|
for col in ["discord", "name", "City", "Country", "looking", "onlinecheck", "Languages", "laptop", "robot", "skills", "describe3", "experience", "idea"]: |
|
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_city_filter(country): |
|
conn = sqlite3.connect(DB_FILE) |
|
c = conn.cursor() |
|
if country == "All": |
|
c.execute("SELECT DISTINCT city FROM teamup") |
|
else: |
|
c.execute("SELECT DISTINCT city FROM teamup WHERE country = ?", (country.title(),)) |
|
cities = [r[0].title() for r in c.fetchall() if r[0]] |
|
conn.close() |
|
return gr.update(choices=["All"] + sorted(cities), value="All") |
|
|
|
|
|
def delete_by_discord(discord, code): |
|
if code != ADMIN_CODE: |
|
return "β Invalid admin code." |
|
conn = sqlite3.connect(DB_FILE) |
|
c = conn.cursor() |
|
c.execute("DELETE FROM teamup WHERE lower(discord) = ?", (discord.lower(),)) |
|
conn.commit() |
|
conn.close() |
|
return f"ποΈ Deleted user with Discord: {discord}" |
|
|
|
with gr.Blocks(css=".gr-dropdown { max-height: 100px; overflow-y: auto; font-size: 12px; }") as demo: |
|
gr.Markdown("# π LeRobot Worldwide Hackathon - Team-Up Dashboard") |
|
|
|
with gr.Row(): |
|
with gr.Column(): |
|
name = gr.Text(label="Name") |
|
discord = gr.Text(label="π€ Discord Username *") |
|
city = gr.Text(label="π City *") |
|
country = gr.Dropdown(label="π Country *", choices=ALL_COUNTRIES, value="France") |
|
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=LANGUAGES, label="Languages Spoken *") |
|
laptop = gr.Text(label="π» Laptop Setup *") |
|
robot = gr.Text(label="π€ Robot Setup *") |
|
skills = gr.Text(label="π§ 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 β
") |
|
status = gr.Textbox(label="", interactive=False) |
|
|
|
with gr.Column(): |
|
country_filter = gr.Dropdown(label="Filter by Country", choices=["All"] + ALL_COUNTRIES, value="All") |
|
city_filter = gr.Dropdown(label="Filter by City", choices=["All"], value="All") |
|
language_filter = gr.Dropdown(label="Filter by Language", choices=["All"] + LANGUAGES, value="All") |
|
table_html = gr.HTML(label="Matching Participants") |
|
|
|
country_filter.change(fn=update_city_filter, inputs=[country_filter], outputs=[city_filter]) |
|
for dropdown in [country_filter, city_filter, language_filter]: |
|
dropdown.change(fn=filter_by_fields, inputs=[country_filter, city_filter, language_filter], outputs=[table_html]) |
|
|
|
submit_btn.click(fn=submit_profile, inputs=[name, discord, city, country, address, looking, onlinecheck, languages, laptop, robot, skills, describe3, experience, idea], outputs=[status]) |
|
submit_btn.click(fn=filter_by_fields, inputs=[country_filter, city_filter, language_filter], outputs=[table_html]) |
|
|
|
gr.Markdown("---\n### π‘οΈ Admin Panel") |
|
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]) |
|
|
|
demo.launch() |
|
|
|
|