Refactor food item flow and barcode handling

Updated routes and templates to improve the process of adding and logging food items by barcode. The add_food_item route now accepts a barcode parameter, and barcode lookups redirect to item creation if not found. The log_food flow now uses session variables for item and meal selection, and the get_item.html template uses fetch to handle barcode lookups and redirects accordingly.
This commit is contained in:
2025-07-08 11:43:22 +02:00
parent bb5b2e8bc7
commit 5ae82e379e
3 changed files with 57 additions and 29 deletions

View File

@@ -59,9 +59,9 @@ fields = [
] ]
@user_bp.route("/add_food_item", methods=["POST"]) @user_bp.route("/add_food_item/<string:barcode>", methods=["GET", "POST"])
def add_food_item(): def add_food_item(barcode):
form = FoodItemForm() form = FoodItemForm(barcode=barcode)
if form.validate_on_submit(): if form.validate_on_submit():
print("[DEBUG] Valid form") print("[DEBUG] Valid form")
@@ -92,9 +92,9 @@ def add_food_item():
else: else:
print("[DEBUG] Invalid form") print("[DEBUG] Invalid form")
if form.barcode.data: if form.barcode.data:
return redirect(url_for("user.food_item", barcode=form.barcode.data)) return render_template("add_food_item.html", form=form)
else: else:
return redirect(url_for("scan")) return redirect("/")
@user_bp.route("/edit_food_item/<int:id>", methods=["GET", "POST"]) @user_bp.route("/edit_food_item/<int:id>", methods=["GET", "POST"])
@@ -119,7 +119,7 @@ def edit_food_item(id: int):
return redirect(url_for("user.dashboard")) return redirect(url_for("user.dashboard"))
@user_bp.route("/food_item/<int:barcode>", methods=["GET"]) @user_bp.route("/food_item/<string:barcode>", methods=["GET"])
def food_item(barcode): def food_item(barcode):
food = FoodItem.query.filter_by(barcode=barcode).first() food = FoodItem.query.filter_by(barcode=barcode).first()
if food: if food:
@@ -161,24 +161,27 @@ def add_food_item_manual():
return render_template("add_food_item_manual.html", form=form) return render_template("add_food_item_manual.html", form=form)
@user_bp.route("/log_food/<int:item_id>", methods=["GET", "POST"]) @user_bp.route("/log_food", methods=["GET", "POST"])
def log_food(item_id): def log_food():
form = FoodLogForm() form = FoodLogForm()
if item_id is not None: item_id = session["item_id"]
if db.session.get(FoodItem, item_id): meal_type = session["meal_type"]
if form.validate_on_submit(): if item_id is None or meal_type is None:
assert form.amount.data is not None return redirect("/")
db.session.add( if db.session.get(FoodItem, item_id):
FoodLog( if form.validate_on_submit():
item_id, assert form.amount.data is not None
current_user.id, db.session.add(
form.amount.data, FoodLog(
part_of_day=0, item_id,
) current_user.id,
form.amount.data,
part_of_day=meal_type,
) )
db.session.commit() )
return redirect(url_for("user.dashboard")) db.session.commit()
return render_template("log_food.html", item_id=item_id, form=form) return redirect(url_for("user.dashboard"))
return render_template("log_food.html", form=form)
@user_bp.route("/overview", methods=["GET"]) @user_bp.route("/overview", methods=["GET"])
@@ -193,7 +196,14 @@ def select_meal(meal_type: int):
return redirect(url_for("user.scan_product")) return redirect(url_for("user.scan_product"))
@user_bp.route("/get_userid", methods=["GET"]) @user_bp.route("/select_item/<int:item_id>", methods=["GET"])
def select_item(item_id: int):
assert type(item_id) is int
session["item_id"] = item_id
return redirect(url_for("user.log_food"))
@user_bp.route("/get_foodid", methods=["GET"])
def scan_product(): def scan_product():
return render_template("get_item.html") return render_template("get_item.html")
@@ -221,9 +231,13 @@ def test():
@user_bp.route("/foodId_from_barcode/<string:barcode>", methods=["GET"]) @user_bp.route("/foodId_from_barcode/<string:barcode>", methods=["GET"])
def foodId_from_barcode(barcode: str): def foodId_from_barcode(barcode: str):
if barcode.isdigit(): # Check if barcode contains only digits
return jsonify({"food_id": barcode}) if not barcode.isdigit():
else:
return abort( return abort(
400, description="Invalid barcode: must contain only digits" 400, description="Invalid barcode: must contain only digits"
) )
item = current_user.food_items.filter_by(barcode=barcode).first()
if item is None:
return redirect(url_for("user.add_food_item", barcode=barcode))
return jsonify({"item_id": item.id})

View File

@@ -1,7 +1,7 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block content %} {% block content %}
<form method="POST" action="{{ url_for('user.add_food_item') }}"> <form method="POST">
{{ form.hidden_tag() }} {{ form.hidden_tag() }}
<div class="mb-3"> <div class="mb-3">

View File

@@ -49,8 +49,22 @@
if (result) { if (result) {
// Result found, this should post the barcode // Result found, this should post the barcode
const codeText = result.getText(); const codeText = result.getText();
const baseURL = "{{url_for('user.food_item', barcode='0')}}" const baseURL = "{{url_for('user.foodId_from_barcode', barcode='!')}}"
window.location.href = baseURL.replace("0", encodeURIComponent(codeText)) fetch(baseURL.replace("!", encodeURIComponent(codeText)))
.then(response => {
if (!response.ok) {
throw new Error('Network response was not OK');
}
return response.json(); // or response.text(), response.blob(), etc.
})
.then(data => {
const baseURL2 = "{{url_for('user.select_item', item_id='0')}}"
window.location.href = baseURL2.replace("0", encodeURIComponent(data["item_id"]))
})
.catch(error => {
console.error('Fetch error:', error);
});
} }
}); });
}); });