135 lines
4.1 KiB
Python
135 lines
4.1 KiB
Python
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/<int:checkin_id>/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/<int:checkin_id>/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/<int:checkin_id>", 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/<int:checkin_id>", 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"))
|