from flask import Blueprint, render_template from app.auth import login_required from app.db import query bp = Blueprint("leaderboard", __name__) @bp.route("/leaderboard") @login_required def index(): # Get all users with their weight stats users = query(""" SELECT u.id, u.display_name, u.username, u.starting_weight_kg, u.goal_weight_kg, (SELECT weight_kg FROM checkins WHERE user_id = u.id ORDER BY checked_in_at ASC LIMIT 1) as first_weight, (SELECT weight_kg FROM checkins WHERE user_id = u.id ORDER BY checked_in_at DESC LIMIT 1) as current_weight, (SELECT COUNT(*) FROM checkins WHERE user_id = u.id) as total_checkins, (SELECT checked_in_at FROM checkins WHERE user_id = u.id ORDER BY checked_in_at DESC LIMIT 1) as last_checkin FROM users u ORDER BY u.created_at """) # Calculate rankings ranked = [] for u in users: start_w = float(u["starting_weight_kg"] or u["first_weight"] or 0) current_w = float(u["current_weight"] or start_w) if start_w > 0: weight_lost = start_w - current_w pct_lost = round((weight_lost / start_w) * 100, 1) else: weight_lost = 0 pct_lost = 0 goal = float(u["goal_weight_kg"]) if u["goal_weight_kg"] else None goal_progress = None if goal and start_w > goal: total_to_lose = start_w - goal goal_progress = min(100, round((weight_lost / total_to_lose) * 100, 1)) if total_to_lose > 0 else 0 ranked.append({ **u, "weight_lost": round(weight_lost, 1), "pct_lost": pct_lost, "goal_progress": goal_progress, }) # Sort by % lost (descending) ranked.sort(key=lambda x: x["pct_lost"], reverse=True) return render_template("leaderboard.html", ranked=ranked)