Files
WeightTracker/app/routes/api.py
2026-02-23 08:32:18 +11:00

98 lines
3.0 KiB
Python

from flask import Blueprint, jsonify
from app import SYDNEY_TZ
from app.auth import login_required
from app.db import query
from datetime import timezone
bp = Blueprint("api", __name__, url_prefix="/api")
@bp.route("/chart-data/<int:user_id>")
@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"].replace(tzinfo=timezone.utc).astimezone(SYDNEY_TZ).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/<int:user_id>")
@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"].replace(tzinfo=timezone.utc).astimezone(SYDNEY_TZ).strftime("%d %b")
labels.append(label)
changes.append(change)
return jsonify({"labels": labels, "changes": changes})