from flask import Blueprint, jsonify from app.auth import login_required from app.db import query bp = Blueprint("api", __name__, url_prefix="/api") @bp.route("/chart-data/") @login_required def chart_data(user_id): """Return weight & BMI over time for Chart.js.""" checkins = query( """SELECT weight_kg, bmi, checked_in_at FROM checkins WHERE user_id = %s ORDER BY checked_in_at ASC""", (user_id,), ) labels = [c["checked_in_at"].strftime("%d %b") for c in checkins] weights = [float(c["weight_kg"]) for c in checkins] bmis = [float(c["bmi"]) if c["bmi"] else None for c in checkins] return jsonify({ "labels": labels, "weights": weights, "bmis": bmis, }) @bp.route("/comparison") @login_required def comparison(): """Return all-user comparison data for bar charts.""" users = query(""" SELECT u.id, u.display_name, u.username, u.starting_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 FROM users u WHERE (SELECT COUNT(*) FROM checkins WHERE user_id = u.id) > 0 ORDER BY u.display_name """) names = [] pct_lost = [] kg_lost = [] 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: lost = start_w - current_w pct = round((lost / start_w) * 100, 1) else: lost = 0 pct = 0 names.append(u["display_name"] or u["username"]) pct_lost.append(pct) kg_lost.append(round(lost, 1)) return jsonify({ "names": names, "pct_lost": pct_lost, "kg_lost": kg_lost, }) @bp.route("/weekly-change/") @login_required def weekly_change(user_id): """Return weekly weight changes for bar chart.""" checkins = query( """SELECT weight_kg, checked_in_at FROM checkins WHERE user_id = %s ORDER BY checked_in_at ASC""", (user_id,), ) if len(checkins) < 2: return jsonify({"labels": [], "changes": []}) labels = [] changes = [] for i in range(1, len(checkins)): prev_w = float(checkins[i - 1]["weight_kg"]) curr_w = float(checkins[i]["weight_kg"]) change = round(curr_w - prev_w, 1) label = checkins[i]["checked_in_at"].strftime("%d %b") labels.append(label) changes.append(change) return jsonify({"labels": labels, "changes": changes})