"""Main dashboard routes for the Team Tryouts application. This module provides the main dashboard view with role-specific statistics. """ from flask import Blueprint, render_template, redirect, url_for, flash from flask_login import login_required, current_user from extensions import db from models import User, Tryout, Evaluation, TryoutRegistration, Team, TeamMember, Match, MatchParticipant, OrgTeam from sqlalchemy import func from datetime import datetime, date main_bp = Blueprint('main', __name__) @main_bp.route('/') def index(): """Redirect root URL to login page. This is the entry point for the application when no specific route is provided. Returns: Response: Redirect to login page. """ return redirect(url_for('auth.login')) @main_bp.route('/dashboard') @login_required def dashboard(): """Render the main dashboard with role-specific statistics. Displays different statistics based on the user's role: - President: Overview of all users, tryouts, and evaluations - Manager: Their created tryouts and evaluations - Coach: Their evaluations and pending evaluations - Player: Their registrations, evaluations, and upcoming matches - Scout: Top-rated players across all tryouts Returns: Response: Rendered dashboard template with user stats. """ user = current_user stats = {} if user.role == 'admin': stats['total_users'] = User.query.count() stats['total_players'] = User.query.filter_by(role='player').count() stats['total_tryouts'] = Tryout.query.count() stats['total_evaluations'] = Evaluation.query.count() stats['active_tryouts'] = Tryout.query.filter_by(status='in_progress').count() stats['completed_tryouts'] = Tryout.query.filter_by(status='completed').count() stats['recent_users'] = User.query.order_by(User.created_at.desc()).limit(10).all() stats['recent_tryouts'] = Tryout.query.order_by(Tryout.created_at.desc()).limit(10).all() today = date.today() stats['upcoming_matches'] = Match.query.filter( Match.status == 'scheduled', Match.date >= today ).order_by(Match.date, Match.start_time).limit(5).all() elif user.role == 'manager': stats['total_tryouts'] = Tryout.query.filter_by(created_by=user.id).count() stats['active_tryouts'] = Tryout.query.filter_by(created_by=user.id, status='in_progress').count() stats['total_evaluations'] = Evaluation.query.filter_by(evaluator_id=user.id).count() stats['my_tryouts'] = Tryout.query.filter_by(created_by=user.id).order_by(Tryout.date.desc()).limit(5).all() today = date.today() manager_tryout_ids = [t.id for t in Tryout.query.filter_by(created_by=user.id).all()] stats['upcoming_matches'] = Match.query.filter( Match.tryout_id.in_(manager_tryout_ids), Match.status == 'scheduled', Match.date >= today ).order_by(Match.date, Match.start_time).limit(5).all() if manager_tryout_ids else [] elif user.role == 'coach': stats['my_evaluations'] = Evaluation.query.filter_by(evaluator_id=user.id).count() stats['pending_evaluations'] = 0 registrations = TryoutRegistration.query.filter(TryoutRegistration.status.in_(['registered', 'attended'])).all() registered_player_ids = [r.player_id for r in registrations] evaluated_player_ids = [e.player_id for e in Evaluation.query.filter_by(evaluator_id=user.id).all()] stats['pending_evaluations'] = len(set(registered_player_ids) - set(evaluated_player_ids)) stats['my_recent_evaluations'] = Evaluation.query.filter_by(evaluator_id=user.id).order_by(Evaluation.created_at.desc()).limit(10).all() today = date.today() org_team = OrgTeam.query.filter_by(coach_id=user.id).first() coach_tryout_ids = [t.id for t in Tryout.query.filter_by(target_org_team_id=org_team.id).all()] if org_team else [] stats['upcoming_matches'] = Match.query.filter( Match.tryout_id.in_(coach_tryout_ids), Match.status == 'scheduled', Match.date >= today ).order_by(Match.date, Match.start_time).limit(5).all() if coach_tryout_ids else [] elif user.role == 'player': stats['my_tryouts'] = TryoutRegistration.query.filter_by(player_id=user.id).count() stats['my_registrations'] = TryoutRegistration.query.filter_by(player_id=user.id).order_by(TryoutRegistration.registered_at.desc()).limit(5).all() # Get upcoming matches for the player today = date.today() next_matches = [] # Get all tryouts the player is registered for (not just the 5 most recent) all_registrations = TryoutRegistration.query.filter_by(player_id=user.id).all() registered_tryout_ids = [r.tryout_id for r in all_registrations] # Get all matches where player is a participant (any match type) player_participant_matches = MatchParticipant.query.filter_by(player_id=user.id).all() player_match_ids = [p.match_id for p in player_participant_matches] # Get all team memberships for this player player_team_memberships = TeamMember.query.filter_by(player_id=user.id).all() player_team_ids = [tm.team_id for tm in player_team_memberships] # Find all scheduled matches in registered tryouts upcoming_matches = Match.query.filter( Match.tryout_id.in_(registered_tryout_ids), Match.status == 'scheduled', Match.date >= today ).order_by(Match.date, Match.start_time).all() for match in upcoming_matches: is_participant = False team = None if match.match_type == 'team_vs_team': # Check if player is on either team if match.team1_id in player_team_ids: is_participant = True team = next((tm for tm in player_team_memberships if tm.team_id == match.team1_id), None) elif match.team2_id in player_team_ids: is_participant = True team = next((tm for tm in player_team_memberships if tm.team_id == match.team2_id), None) else: # For player_vs_player and player_scrim, check MatchParticipant if match.id in player_match_ids: is_participant = True if is_participant: tryout = match.tryout next_matches.append({ 'tryout': tryout, 'match': match, 'team': team.team if team else None }) stats['next_matches'] = next_matches elif user.role == 'scout': stats['total_players'] = User.query.filter_by(role='player').count() stats['total_evaluations'] = Evaluation.query.count() stats['avg_scores'] = db.session.query( Evaluation.player_id, func.avg(Evaluation.overall_score).label('avg_score') ).group_by(Evaluation.player_id).order_by(func.avg(Evaluation.overall_score).desc()).limit(5).all() stats['top_players'] = [] for row in stats['avg_scores']: p = User.query.get(row.player_id) if p: stats['top_players'].append((p, round(row.avg_score, 1))) return render_template('pages/dashboard.html', user=user, stats=stats)