import gradio as gr import pandas as pd import plotly.graph_objects as go from datetime import datetime, timedelta import json import random # --- DATA & CONFIG --- # User Credentials USERS = { "admin": {"password": "admin123", "role": "Management"}, "coach": {"password": "coach123", "role": "Coach"}, "manager": {"password": "manager123", "role": "Manager"} } # The 14-Player Roster ROSTER = [ {"id": 1, "name": "Sofia Reyes", "pos": "OH", "num": 4, "trend": "up", "change": "+1.4", "hist": [8.2, 8.4, 8.6, 8.9, 9.1], "focus": 9, "stamina": 9, "spirit": 10}, {"id": 2, "name": "Liam Chen", "pos": "S", "num": 10, "trend": "stable", "change": "0.0", "hist": [8.5, 8.4, 8.5, 8.5, 8.5], "focus": 9, "stamina": 8, "spirit": 9}, {"id": 3, "name": "Marcus Johnson", "pos": "MB", "num": 15, "trend": "up", "change": "+0.8", "hist": [7.1, 7.4, 7.6, 7.9, 8.1], "focus": 8, "stamina": 8, "spirit": 7}, {"id": 4, "name": "Kenji Tanaka", "pos": "OP", "num": 7, "trend": "down", "change": "-0.4", "hist": [9.0, 8.8, 8.7, 8.5, 8.4], "focus": 7, "stamina": 8, "spirit": 6}, {"id": 5, "name": "Elena Volkov", "pos": "L", "num": 1, "trend": "up", "change": "+1.2", "hist": [8.0, 8.2, 8.8, 9.0, 9.2], "focus": 10, "stamina": 9, "spirit": 9}, {"id": 6, "name": "Isaiah Thomas", "pos": "OH", "num": 11, "trend": "stable", "change": "+0.1", "hist": [7.5, 7.5, 7.6, 7.5, 7.6], "focus": 7, "stamina": 8, "spirit": 7}, {"id": 7, "name": "Anna Müller", "pos": "MB", "num": 9, "trend": "up", "change": "+2.0", "hist": [6.5, 7.0, 7.8, 8.2, 8.5], "focus": 9, "stamina": 9, "spirit": 8}, {"id": 8, "name": "Carlos Silva", "pos": "DS", "num": 12, "trend": "stable", "change": "0.0", "hist": [7.8, 7.9, 7.8, 7.9, 7.9], "focus": 8, "stamina": 9, "spirit": 8}, {"id": 9, "name": "Sarah Jenkins", "pos": "OH", "num": 3, "trend": "down", "change": "-1.0", "hist": [8.8, 8.4, 8.1, 7.9, 7.8], "focus": 5, "stamina": 7, "spirit": 5}, {"id": 10, "name": "David Park", "pos": "S", "num": 2, "trend": "up", "change": "+0.5", "hist": [7.0, 7.2, 7.4, 7.5, 7.5], "focus": 8, "stamina": 8, "spirit": 8}, {"id": 11, "name": "Mia Williams", "pos": "OP", "num": 8, "trend": "stable", "change": "+0.2", "hist": [7.2, 7.3, 7.4, 7.4, 7.4], "focus": 7, "stamina": 7, "spirit": 7}, {"id": 12, "name": "James Wilson", "pos": "MB", "num": 14, "trend": "up", "change": "+1.5", "hist": [6.0, 6.5, 7.0, 7.5, 8.0], "focus": 8, "stamina": 8, "spirit": 7}, {"id": 13, "name": "Emily Davis", "pos": "L", "num": 5, "trend": "stable", "change": "0.0", "hist": [8.7, 8.7, 8.6, 8.7, 8.7], "focus": 10, "stamina": 9, "spirit": 10}, {"id": 14, "name": "Ryan Patel", "pos": "OH", "num": 6, "trend": "down", "change": "-0.3", "hist": [8.0, 7.9, 7.8, 7.7, 7.7], "focus": 6, "stamina": 7, "spirit": 6} ] # Initial Schedule Data INITIAL_SCHEDULE = [ {"title": "Pre-Season Camp", "date": "2023-10-15", "type": "Training", "status": "Done"}, {"title": "Regional Finals", "date": "2023-12-05", "type": "Match", "status": "Scheduled"} ] # --- LOGIC HELPERS --- def create_sparkline(data): """Creates a Plotly sparkline figure""" fig = go.Figure(go.Scatter( y=data, mode='lines', fill='tozeroy', line={'color': '#38bdf8', 'width': 2} )) fig.update_layout( margin=dict(l=0, r=0, t=0, b=0), paper_bgcolor='rgba(0,0,0,0)', plot_bgcolor='rgba(0,0,0,0)', xaxis=dict(visible=False), yaxis=dict(visible=False), height=40 ) return fig def get_ai_response(message): """Simulates the Tactical Advisor AI""" msg = message.lower() if "prayer" in msg or "spirit" in msg: return "Prayer is the pillar of discipline. I recommend a 10-minute mindfulness session post-training. 'Verily, with hardship comes ease.' (94:6)" elif "gym" in msg or "strength" in msg: return "I have generated a Plyometric plan:\n1. Box Jumps (4x8)\n2. Lateral Bounds (3x10)\nFocus on explosive landing mechanics." elif "lineup" in msg or "team" in msg: names = [p['name'] for p in random.sample(ROSTER, 6)] return f"Based on current form, I suggest starting: {', '.join(names)}. This combination maximizes court coverage and attack efficiency." elif "defense" in msg: return "Switching to Perimeter Defense. The middle blocker must read the setter's hands. Trust your back-row libero." else: return "Tactical Advisor Online. I have analyzed the roster metrics. We have 3 players with declining stamina trends. Shall I adjust the training load?" # --- GRADIO APP --- css = """ .gradio-container { background-color: #0f172a !important; } .card-bg { background-color: #1e293b !important; border-radius: 12px; padding: 16px; border: 1px solid #334155; height: 100%; } .table-bg { background-color: #1e293b !important; } input, textarea { background-color: #0f172a !important; color: white !important; border: 1px solid #334155 !important; } """ with gr.Blocks(css=css, theme=gr.themes.Soft(primary_hue="sky", neutral_hue="slate", font=gr.themes.GoogleFont("Inter"))) as demo: # --- STATE --- user_state = gr.State(None) schedule_state = gr.State(INITIAL_SCHEDULE) # --- HEADER --- gr.Markdown("""
High Performance Management System
AI-powered coaching assistant. Ask about lineups, drills, or player psychology.
") chatbot = gr.Chatbot(height=400, show_label=False) with gr.Row(): txt = gr.Textbox(show_label=False, placeholder="Ask for tactics...", container=False, scale=9) btn = gr.Button("Send", variant="primary", scale=1) # Quick Actions with gr.Row(): btn_strategy = gr.Button("Strategy Sync", size="sm") btn_gym = gr.Button("Gym Plan", size="sm") # VIEW 3: SCHEDULE with gr.Column(visible=False) as view_schedule: gr.Markdown("