Initial commit
This commit is contained in:
95
app/routes/api.py
Normal file
95
app/routes/api.py
Normal file
@@ -0,0 +1,95 @@
|
||||
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/<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"].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"].strftime("%d %b")
|
||||
labels.append(label)
|
||||
changes.append(change)
|
||||
|
||||
return jsonify({"labels": labels, "changes": changes})
|
||||
Reference in New Issue
Block a user