Add player injury status display feature

- Added injury status processing in app.py to check multiple Sleeper API fields
- Filter out 'Active' status to only display actual injury conditions
- Added injury status display in dashboard template with red styling
- Added CSS styling for injury status badges with red color and border
- Only non-active injury statuses (IR, SUS, PUP, DNI, Questionable, OUT) will be shown

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
efigueroa 2025-09-06 22:57:42 -07:00
parent 9589a69c9b
commit 10f8e07ed4
4 changed files with 120 additions and 18 deletions

95
app.py
View file

@ -1,4 +1,4 @@
from flask import Flask, render_template, jsonify from flask import Flask, render_template, jsonify, request, session, redirect, url_for
from datetime import datetime from datetime import datetime
import os import os
import sys import sys
@ -28,7 +28,11 @@ def get_league_color(league_index):
@app.context_processor @app.context_processor
def inject_apis(): def inject_apis():
"""Make API and version available to all templates""" """Make API and version available to all templates"""
return dict(sleeper_api=sleeper_api, app_version=app.config['VERSION']) return dict(
sleeper_api=sleeper_api,
app_version=app.config['VERSION'],
current_theme=session.get('theme', 'light')
)
@app.route('/') @app.route('/')
def index(): def index():
@ -36,6 +40,40 @@ def index():
print("DEBUG: Index route accessed", flush=True) print("DEBUG: Index route accessed", flush=True)
return render_template('index.html') return render_template('index.html')
@app.route('/dashboard')
def dashboard_form():
"""Handle form submission from homepage"""
username = request.args.get('username')
if username:
return dashboard_current(username.strip())
else:
return redirect(url_for('index'))
# Add theme handling route
@app.route('/toggle_theme', methods=['POST'])
def toggle_theme():
"""Toggle between light and dark theme"""
current_theme = session.get('theme', 'light')
new_theme = 'dark' if current_theme == 'light' else 'light'
session['theme'] = new_theme
# Get return URL from form or default to index
return_url = request.form.get('return_url', url_for('index'))
return redirect(return_url)
# Add timezone handling route
@app.route('/set_timezone', methods=['POST'])
def set_timezone():
"""Set user's timezone preference"""
timezone = request.form.get('timezone')
if timezone:
session['user_timezone'] = timezone
print(f"DEBUG: Set user timezone to: {timezone}", flush=True)
# Get return URL from form or default to index
return_url = request.form.get('return_url', url_for('index'))
return redirect(return_url)
@app.route('/<username>') @app.route('/<username>')
def dashboard_current(username): def dashboard_current(username):
"""Dashboard for current NFL week""" """Dashboard for current NFL week"""
@ -89,10 +127,12 @@ def dashboard(username, week):
for i, league in enumerate(leagues): for i, league in enumerate(leagues):
print(f"DEBUG: League {i+1}: ID={league.get('league_id')}, Name='{league.get('name')}'", flush=True) print(f"DEBUG: League {i+1}: ID={league.get('league_id')}, Name='{league.get('name')}'", flush=True)
# Get NFL game schedule for the week # Get NFL game schedule for the week with user's timezone
user_timezone = session.get('user_timezone', 'America/Los_Angeles') # Default to PST
print(f"DEBUG: Using timezone: {user_timezone}", flush=True)
print(f"DEBUG: Calling get_week_schedule() for week {week}, season {season}", flush=True) print(f"DEBUG: Calling get_week_schedule() for week {week}, season {season}", flush=True)
try: try:
schedule = espn_api.get_week_schedule(week, season) schedule = espn_api.get_week_schedule(week, season, user_timezone)
print(f"DEBUG: Schedule retrieved successfully", flush=True) print(f"DEBUG: Schedule retrieved successfully", flush=True)
except Exception as e: except Exception as e:
print(f"ERROR: ESPN schedule fetch failed: {str(e)}", flush=True) print(f"ERROR: ESPN schedule fetch failed: {str(e)}", flush=True)
@ -110,6 +150,7 @@ def dashboard(username, week):
matchups = sleeper_api.get_matchups(league_id, week) matchups = sleeper_api.get_matchups(league_id, week)
print(f"DEBUG: Found {len(matchups) if matchups else 0} matchups", flush=True) print(f"DEBUG: Found {len(matchups) if matchups else 0} matchups", flush=True)
# Get rosters to find user's team # Get rosters to find user's team
print(f"DEBUG: Calling get_rosters() for league {league_id}", flush=True) print(f"DEBUG: Calling get_rosters() for league {league_id}", flush=True)
rosters = sleeper_api.get_rosters(league_id) rosters = sleeper_api.get_rosters(league_id)
@ -141,21 +182,56 @@ def dashboard(username, week):
opponent_user = sleeper_api.get_user_by_id(opponent_owner_id) opponent_user = sleeper_api.get_user_by_id(opponent_owner_id)
print(f"DEBUG: Opponent user: {opponent_user.get('display_name') if opponent_user else 'None'}", flush=True) print(f"DEBUG: Opponent user: {opponent_user.get('display_name') if opponent_user else 'None'}", flush=True)
# Get all players on user's roster for calendar # Get all players on user's roster for calendar with starter info
all_players = [] all_players = []
if user_roster and user_roster.get('players'): if user_roster and user_roster.get('players') and user_matchup:
players_list = user_roster['players'] players_list = user_roster['players']
print(f"DEBUG: Processing {len(players_list)} total players for calendar", flush=True) starters_list = user_matchup.get('starters', [])
print(f"DEBUG: Processing {len(players_list)} total players, {len(starters_list)} starters", flush=True)
for player_id in players_list: for player_id in players_list:
try: try:
# Get player details from Sleeper API # Get player details from Sleeper API
player = sleeper_api.get_player_info(player_id) player = sleeper_api.get_player_info(player_id)
if player: if player:
# Add starter status to player data
player['is_starter'] = player_id in starters_list
# Check multiple possible injury status fields
injury_status = (
player.get('injury_status') or
player.get('status') or
player.get('injury_designation') or
player.get('practice_participation')
)
# Only show injury status if it's not "Active" or None
if injury_status and injury_status.lower() != 'active':
player['injury_status'] = injury_status
else:
player['injury_status'] = None
# Print any player with injury status (only non-Active)
if player['injury_status']:
player_name = f"{player.get('first_name', '')} {player.get('last_name', '')}".strip()
print(f"DEBUG: {player_name} has injury status: {player['injury_status']}", flush=True)
all_players.append(player) all_players.append(player)
except Exception as e: except Exception as e:
print(f"ERROR: Failed to get player info for {player_id}: {str(e)}", flush=True) print(f"ERROR: Failed to get player info for {player_id}: {str(e)}", flush=True)
# Calculate winning/losing status
user_points = user_matchup['points'] if user_matchup else 0
opponent_points = opponent_matchup['points'] if opponent_matchup else 0
# Determine status
if user_points > opponent_points:
match_status = 'winning'
elif user_points < opponent_points:
match_status = 'losing'
else:
match_status = 'tied'
# Store processed league data # Store processed league data
league_info = { league_info = {
'league': league, 'league': league,
@ -164,7 +240,10 @@ def dashboard(username, week):
'opponent_matchup': opponent_matchup, 'opponent_matchup': opponent_matchup,
'opponent_user': opponent_user, 'opponent_user': opponent_user,
'user_roster': user_roster, 'user_roster': user_roster,
'all_players': all_players 'all_players': all_players,
'match_status': match_status,
'user_points': user_points,
'opponent_points': opponent_points
} }
league_data.append(league_info) league_data.append(league_info)
print(f"DEBUG: League '{league['name']}' processed successfully", flush=True) print(f"DEBUG: League '{league['name']}' processed successfully", flush=True)

View file

@ -69,4 +69,7 @@ class SleeperAPI:
def get_player_info(self, player_id): def get_player_info(self, player_id):
"""Get specific player info""" """Get specific player info"""
players = self.get_players() players = self.get_players()
return players.get(str(player_id)) player_info = players.get(str(player_id))
return player_info

View file

@ -1097,4 +1097,18 @@ body {
padding: 0 12px 12px 12px; padding: 0 12px 12px 12px;
} }
/* Player Injury Status Styling */
.injury-status {
color: #dc2626 !important; /* Red color */
font-weight: 700;
font-size: 10px;
margin-left: 4px;
padding: 1px 3px;
background-color: rgba(220, 38, 38, 0.1);
border: 1px solid #dc2626;
border-radius: 3px;
text-transform: uppercase;
letter-spacing: 0.5px;
}

View file

@ -23,7 +23,7 @@
<!-- Compact league scores at top --> <!-- Compact league scores at top -->
<section class="scores-summary"> <section class="scores-summary">
{% for league_info in league_data %} {% for league_info in league_data %}
<div class="score-row {{ league_info.match_status }}"> <div class="score-row">
<div class="league-info"> <div class="league-info">
<!-- League color dot --> <!-- League color dot -->
<span class="league-dot" style="background-color: {{ league_info.league_color }};"></span> <span class="league-dot" style="background-color: {{ league_info.league_color }};"></span>
@ -31,16 +31,13 @@
</div> </div>
<div class="score-compact"> <div class="score-compact">
<!-- Win/Loss indicator --> <!-- Win/Loss indicator -->
<span class="match-indicator {{ league_info.match_status }}"> <span class="match-indicator">
{% if league_info.match_status == 'winning' %} {% if league_info.match_status == 'winning' %}
<span class="indicator-icon">↗️</span> <span class="indicator-icon">↗️</span>
<span class="indicator-text">W</span>
{% elif league_info.match_status == 'losing' %} {% elif league_info.match_status == 'losing' %}
<span class="indicator-icon">↘️</span> <span class="indicator-icon">↘️</span>
<span class="indicator-text">L</span>
{% else %} {% else %}
<span class="indicator-icon">↔️</span> <span class="indicator-icon">↔️</span>
<span class="indicator-text">T</span>
{% endif %} {% endif %}
</span> </span>
@ -61,10 +58,11 @@
<!-- Main calendar section --> <!-- Main calendar section -->
<section class="schedule-section"> <section class="schedule-section">
<h2>Week {{ week }} Games <h2>Week {{ week }} Games
<br>
{% if session.get('user_timezone') %} {% if session.get('user_timezone') %}
<span class="timezone-info">({{ session.get('user_timezone')|replace('_', ' ')|replace('America/', '') }})</span> <span class="timezone-info">timezone: ({{ session.get('user_timezone') }})</span>
{% else %} {% else %}
<span class="timezone-info">(PST/PDT)</span> <span class="timezone-info">timezone: (PST/PDT)</span>
{% endif %} {% endif %}
</h2> </h2>
<div class="calendar-rows"> <div class="calendar-rows">
@ -127,7 +125,11 @@
{% for player in starters %} {% for player in starters %}
<div class="player-pill starter {{ player.fantasy_positions[0]|lower if player.fantasy_positions else 'flex' }}"> <div class="player-pill starter {{ player.fantasy_positions[0]|lower if player.fantasy_positions else 'flex' }}">
<span class="pos">{{ player.fantasy_positions[0] if player.fantasy_positions else 'FLEX' }}</span> <span class="pos">{{ player.fantasy_positions[0] if player.fantasy_positions else 'FLEX' }}</span>
<span class="name">{{ player.last_name }}</span> <span class="name">{{ player.last_name }}
{% if player.injury_status %}
<span class="injury-status">{{ player.injury_status }}</span>
{% endif %}
</span>
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
@ -139,7 +141,11 @@
{% for player in bench_players %} {% for player in bench_players %}
<div class="player-pill bench {{ player.fantasy_positions[0]|lower if player.fantasy_positions else 'flex' }}"> <div class="player-pill bench {{ player.fantasy_positions[0]|lower if player.fantasy_positions else 'flex' }}">
<span class="pos">{{ player.fantasy_positions[0] if player.fantasy_positions else 'FLEX' }}</span> <span class="pos">{{ player.fantasy_positions[0] if player.fantasy_positions else 'FLEX' }}</span>
<span class="name">{{ player.last_name }}</span> <span class="name">{{ player.last_name }}
{% if player.injury_status %}
<span class="injury-status">{{ player.injury_status }}</span>
{% endif %}
</span>
</div> </div>
{% endfor %} {% endfor %}
</div> </div>