Files
team-tryouts/routes/main.py
T

158 lines
7.4 KiB
Python

"""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)