Files
gh-christianlouis-leagueledger/app/views/leaderboard.py
T
Christian Krakau-Louis 0de2eb5830 Implement user authentication and management system with FastAPI
- Added authentication routes for login, registration, password reset, and account deletion in `auth.py`.
- Implemented user profile management, including updating user information and changing passwords.
- Created dashboard views to display user-specific information and recent activity in `dashboard.py`.
- Developed leaderboard views to show team rankings and points in `leaderboard.py`.
- Added QR code generation and redemption functionality in `qr.py` and `redeem.py`.
- Implemented team management features, allowing users to create and join teams in `teams.py`.
- Introduced session debugging utility to assist with session-related issues in `debug_session.py`.
- Configured Docker Compose for MySQL database and FastAPI application with environment variables.
- Updated requirements.txt to include necessary dependencies for the application.
2025-04-11 17:46:59 +02:00

90 lines
2.6 KiB
Python

#!/usr/bin/env python3
"""
Leaderboard views for displaying team rankings.
"""
from fastapi import APIRouter, Depends, Request, Query
from fastapi.responses import HTMLResponse
from sqlalchemy.orm import Session
from sqlalchemy import func, desc
from datetime import datetime, timedelta
from ..db import SessionLocal
from ..models import Team, TeamMembership, QRTicket
from ..templates_config import templates
router = APIRouter()
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@router.get("/", response_class=HTMLResponse)
async def show_leaderboard(
request: Request,
timeframe: str = Query("all", regex="^(week|month|all)$"),
db: Session = Depends(get_db)
):
"""Show the leaderboard with team rankings."""
# Define cutoff date based on timeframe
cutoff_date = None
if timeframe == "week":
cutoff_date = datetime.now() - timedelta(days=7)
time_label = "This Week"
elif timeframe == "month":
cutoff_date = datetime.now() - timedelta(days=30)
time_label = "This Month"
else:
timeframe = "all" # Ensure valid value
time_label = "All Time"
# Base query to get teams
query = db.query(
Team.id,
Team.name,
func.coalesce(func.sum(QRTicket.points), 0).label('total_points')
).join(
QRTicket,
QRTicket.redeemed_at_team == Team.id,
isouter=True
)
# Apply time filter if needed
if cutoff_date:
# Note: This assumes QRTicket has a created_at or similar timestamp field
# If not, you would need to add one to track when points were added
# For now, this is a placeholder that assumes all tickets are from "now"
# query = query.filter(QRTicket.created_at >= cutoff_date)
pass
# Group and order
teams_ranking = query.group_by(Team.id).order_by(desc('total_points')).all()
# Add ranks
ranked_teams = []
for idx, team in enumerate(teams_ranking):
ranked_teams.append({
'rank': idx + 1,
'id': team.id,
'name': team.name,
'points': team.total_points,
'change': 0 # Placeholder for rank change - would require historical data
})
# Get top 3 teams for podium display
top_teams = ranked_teams[:3] if len(ranked_teams) >= 3 else ranked_teams + [None] * (3 - len(ranked_teams))
return templates.TemplateResponse(
"leaderboard.html",
{
"request": request,
"teams": ranked_teams,
"top_teams": top_teams,
"timeframe": timeframe,
"time_label": time_label
}
)