from flask import Blueprint, render_template, request, redirect, url_for, flash from app.auth import login_required, get_current_user from app.db import query, query_one, execute, execute_returning from app.utils import calculate_bmi, check_milestones bp = Blueprint("checkin", __name__) @bp.route("/checkin", methods=["GET"]) @login_required def index(): user = get_current_user() checkins = query( "SELECT * FROM checkins WHERE user_id = %s ORDER BY checked_in_at DESC", (user["id"],), ) return render_template("checkin.html", user=user, checkins=checkins) @bp.route("/checkin", methods=["POST"]) @login_required def create(): user = get_current_user() weight_kg = request.form.get("weight_kg") notes = request.form.get("notes", "").strip() if not weight_kg: flash("Weight is required.", "error") return redirect(url_for("checkin.index")) try: weight_kg = float(weight_kg) except ValueError: flash("Invalid weight value.", "error") return redirect(url_for("checkin.index")) bmi = calculate_bmi(weight_kg, user.get("height_cm")) checkin = execute_returning( """INSERT INTO checkins (user_id, weight_kg, bmi, notes) VALUES (%s, %s, %s, %s) RETURNING *""", (user["id"], weight_kg, bmi, notes or None), ) check_milestones(user["id"], user) # If HTMX request, return just the new row if request.headers.get("HX-Request"): return render_template("partials/checkin_row.html", c=checkin, user=user) flash("Check-in recorded!", "success") return redirect(url_for("checkin.index")) @bp.route("/checkin//edit", methods=["GET"]) @login_required def edit_form(checkin_id): user = get_current_user() checkin = query_one( "SELECT * FROM checkins WHERE id = %s AND user_id = %s", (checkin_id, user["id"]), ) if not checkin: return "", 404 return render_template("partials/checkin_edit_row.html", c=checkin, user=user) @bp.route("/checkin//view", methods=["GET"]) @login_required def view_row(checkin_id): user = get_current_user() checkin = query_one( "SELECT * FROM checkins WHERE id = %s AND user_id = %s", (checkin_id, user["id"]), ) if not checkin: return "", 404 return render_template("partials/checkin_row.html", c=checkin, user=user) @bp.route("/checkin/", methods=["PUT"]) @login_required def update(checkin_id): user = get_current_user() weight_kg = request.form.get("weight_kg") notes = request.form.get("notes", "").strip() checkin = query_one( "SELECT * FROM checkins WHERE id = %s AND user_id = %s", (checkin_id, user["id"]), ) if not checkin: return "", 404 if not weight_kg: flash("Weight is required.", "error") return render_template("partials/checkin_edit_row.html", c=checkin, user=user) try: weight_kg = float(weight_kg) except ValueError: flash("Invalid weight value.", "error") return render_template("partials/checkin_edit_row.html", c=checkin, user=user) bmi = calculate_bmi(weight_kg, user.get("height_cm")) execute( """UPDATE checkins SET weight_kg = %s, bmi = %s, notes = %s WHERE id = %s AND user_id = %s""", (weight_kg, bmi, notes or None, checkin_id, user["id"]), ) check_milestones(user["id"], user) updated = query_one( "SELECT * FROM checkins WHERE id = %s", (checkin_id,) ) return render_template("partials/checkin_row.html", c=updated, user=user) @bp.route("/checkin/", methods=["DELETE"]) @login_required def delete(checkin_id): user = get_current_user() execute( "DELETE FROM checkins WHERE id = %s AND user_id = %s", (checkin_id, user["id"]), ) if request.headers.get("HX-Request"): return "" flash("Check-in deleted.", "info") return redirect(url_for("checkin.index"))