134 lines
6.1 KiB
Python
134 lines
6.1 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
|
|
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 == 'president':
|
|
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()
|
|
|
|
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()
|
|
|
|
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()
|
|
|
|
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 next match for each tryout the player is in
|
|
today = date.today()
|
|
next_matches = []
|
|
for reg in stats['my_registrations']:
|
|
tryout = reg.tryout
|
|
# Find matches where player participates (team membership or direct participant)
|
|
player_teams = Team.query.join(TeamMember).filter(
|
|
Team.tryout_id == tryout.id,
|
|
TeamMember.player_id == user.id
|
|
).all()
|
|
|
|
# Get matches for this tryout that include the player
|
|
tryout_matches = Match.query.filter(
|
|
Match.tryout_id == tryout.id,
|
|
Match.status == 'scheduled'
|
|
).order_by(Match.date, Match.start_time).all()
|
|
|
|
for match in tryout_matches:
|
|
# Check if player is in this match
|
|
is_participant = False
|
|
if match.match_type == 'team_vs_team':
|
|
# Check if player is on team1 or team2
|
|
if match.team1_id in [t.id for t in player_teams] or match.team2_id in [t.id for t in player_teams]:
|
|
is_participant = True
|
|
else:
|
|
# Check if player is in match participants
|
|
participant = MatchParticipant.query.filter_by(
|
|
match_id=match.id,
|
|
player_id=user.id
|
|
).first()
|
|
if participant:
|
|
is_participant = True
|
|
|
|
if is_participant:
|
|
# Check if match is upcoming
|
|
match_date = match.date
|
|
if match_date >= today:
|
|
next_matches.append({
|
|
'tryout': tryout,
|
|
'match': match,
|
|
'team': player_teams[0] if player_teams else None
|
|
})
|
|
break # Only get the next match per tryout
|
|
|
|
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) |