mirror of
https://github.com/StefBuwalda/cal_counter.git
synced 2025-10-29 19:00:00 +00:00
Add manual food item entry and update food item management
Introduces a new route and template for manually adding food items. Updates food item edit and delete operations to use the food item's ID instead of barcode and adds ownership checks. Adjusts form and model to make barcode optional, and updates navigation and dashboard templates to reflect these changes.
This commit is contained in:
1
app.py
1
app.py
@@ -115,7 +115,6 @@ def add_food_item():
|
||||
assert form.protein.data is not None
|
||||
assert form.carbs.data is not None
|
||||
assert form.fat.data is not None
|
||||
assert form.barcode.data is not None
|
||||
db.session.add(
|
||||
FoodItem(
|
||||
name=form.name.data,
|
||||
|
||||
@@ -23,11 +23,9 @@
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ url_for('scan') }}">Scan</a>
|
||||
</li>
|
||||
{% if current_user.is_admin %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ url_for('admin.food_items') }}">Food Items</a>
|
||||
<a class="nav-link" href="{{ url_for('user.add_food_item_manual') }}">Add Manually</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
<ul class="navbar-nav ms-auto">
|
||||
{% if current_user.is_authenticated %}
|
||||
|
||||
@@ -2,6 +2,7 @@ from flask import Blueprint, redirect, url_for, render_template, flash
|
||||
from flask_login import current_user
|
||||
from application import db
|
||||
from forms import FoodItemForm
|
||||
from models import FoodItem
|
||||
|
||||
user_bp = Blueprint(
|
||||
"user",
|
||||
@@ -22,14 +23,17 @@ def dashboard():
|
||||
return render_template("dashboard.html", items=items)
|
||||
|
||||
|
||||
@user_bp.route("/delete_food_item/<int:barcode>", methods=["POST"])
|
||||
def delete_food_item(barcode: int):
|
||||
item = current_user.food_items.filter_by(barcode=barcode).first()
|
||||
@user_bp.route("/delete_food_item/<int:id>", methods=["POST"])
|
||||
def delete_food_item(id: int):
|
||||
item = FoodItem.query.get(id)
|
||||
if item:
|
||||
db.session.delete(item)
|
||||
db.session.commit()
|
||||
if item.owner_id == current_user.id:
|
||||
db.session.delete(item)
|
||||
db.session.commit()
|
||||
else:
|
||||
flash("You do not own this food item!")
|
||||
else:
|
||||
flash(f"You do not own a food item with barcode {barcode}")
|
||||
flash("This food item does not exist")
|
||||
return redirect(url_for("user.dashboard"))
|
||||
|
||||
|
||||
@@ -45,23 +49,52 @@ fields = [
|
||||
]
|
||||
|
||||
|
||||
@user_bp.route("/edit_food_item/<int:barcode>", methods=["GET", "POST"])
|
||||
def edit_food_item(barcode: int):
|
||||
item = current_user.food_items.filter_by(barcode=barcode).first()
|
||||
@user_bp.route("/edit_food_item/<int:id>", methods=["GET", "POST"])
|
||||
def edit_food_item(id: int):
|
||||
item = FoodItem.query.get(id)
|
||||
if item:
|
||||
form = FoodItemForm()
|
||||
if form.validate_on_submit():
|
||||
item.updateFromForm(form=form)
|
||||
db.session.commit()
|
||||
return redirect(url_for("user.dashboard"))
|
||||
form.barcode.data = item.barcode
|
||||
form.name.data = item.name
|
||||
form.energy.data = item.energy_100
|
||||
form.protein.data = item.protein_100
|
||||
form.carbs.data = item.carbs_100
|
||||
form.sugar.data = item.sugar_100
|
||||
form.fat.data = item.fat_100
|
||||
form.saturated_fat.data = item.saturated_fat_100
|
||||
return render_template("edit_food_item.html", form=form)
|
||||
else:
|
||||
if item.owner_id == current_user.id:
|
||||
form = FoodItemForm()
|
||||
if form.validate_on_submit():
|
||||
item.updateFromForm(form=form)
|
||||
db.session.commit()
|
||||
return redirect(url_for("user.dashboard"))
|
||||
form.barcode.data = item.barcode
|
||||
form.name.data = item.name
|
||||
form.energy.data = item.energy_100
|
||||
form.protein.data = item.protein_100
|
||||
form.carbs.data = item.carbs_100
|
||||
form.sugar.data = item.sugar_100
|
||||
form.fat.data = item.fat_100
|
||||
form.saturated_fat.data = item.saturated_fat_100
|
||||
return render_template("edit_food_item.html", form=form)
|
||||
return redirect(url_for("user.dashboard"))
|
||||
|
||||
|
||||
@user_bp.route("/add_food_item_manual", methods=["GET", "POST"])
|
||||
def add_food_item_manual():
|
||||
form = FoodItemForm()
|
||||
for item in form:
|
||||
print(item)
|
||||
if form.validate_on_submit():
|
||||
assert form.name.data is not None
|
||||
assert form.energy.data is not None
|
||||
assert form.protein.data is not None
|
||||
assert form.carbs.data is not None
|
||||
assert form.fat.data is not None
|
||||
db.session.add(
|
||||
FoodItem(
|
||||
name=form.name.data,
|
||||
owner_id=current_user.id,
|
||||
energy=form.energy.data,
|
||||
protein=form.protein.data,
|
||||
carbs=form.carbs.data,
|
||||
fat=form.fat.data,
|
||||
barcode=form.barcode.data,
|
||||
saturated_fat=form.saturated_fat.data,
|
||||
sugar=form.sugar.data,
|
||||
)
|
||||
)
|
||||
db.session.commit()
|
||||
return redirect(url_for("user.dashboard"))
|
||||
return render_template("add_food_item_manual.html", form=form)
|
||||
|
||||
49
application/user/templates/add_food_item_manual.html
Normal file
49
application/user/templates/add_food_item_manual.html
Normal file
@@ -0,0 +1,49 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<form method="POST">
|
||||
{{ form.hidden_tag() }}
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.barcode.label(class="form-label") }}
|
||||
{{ form.barcode(class="form-control") }}
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.name.label(class="form-label") }}
|
||||
{{ form.name(class="form-control") }}
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.energy.label(class="form-label") }}
|
||||
{{ form.energy(class="form-control") }}
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.protein.label(class="form-label") }}
|
||||
{{ form.protein(class="form-control") }}
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.carbs.label(class="form-label") }}
|
||||
{{ form.carbs(class="form-control") }}
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.sugar.label(class="form-label") }}
|
||||
{{ form.sugar(class="form-control") }}
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.fat.label(class="form-label") }}
|
||||
{{ form.fat(class="form-control") }}
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.saturated_fat.label(class="form-label") }}
|
||||
{{ form.saturated_fat(class="form-control") }}
|
||||
</div>
|
||||
|
||||
{{ form.submit(class="btn btn-primary") }}
|
||||
</form>
|
||||
{% endblock%}
|
||||
@@ -33,10 +33,10 @@ Food Nutritional Info
|
||||
<td class="bg-body-tertiary">{{ food.protein_100 }}</td>
|
||||
<td class="bg-body-tertiary">
|
||||
<div class="d-flex gap-1">
|
||||
<form method="GET" action="{{ url_for('user.edit_food_item', barcode=food.barcode) }}">
|
||||
<form method="GET" action="{{ url_for('user.edit_food_item', id=food.id) }}">
|
||||
<button type="submit" class="btn btn-warning btn-sm">Edit</button>
|
||||
</form>
|
||||
<form method="POST" action="{{ url_for('user.delete_food_item', barcode=food.barcode) }}"
|
||||
<form method="POST" action="{{ url_for('user.delete_food_item', id=food.id) }}"
|
||||
onsubmit="return confirm('Are you sure you want to delete this item?');">
|
||||
<button type="submit" class="btn btn-danger btn-sm">Delete</button>
|
||||
</form>
|
||||
|
||||
6
forms.py
6
forms.py
@@ -6,7 +6,7 @@ from wtforms import (
|
||||
IntegerField,
|
||||
FloatField,
|
||||
)
|
||||
from wtforms.validators import DataRequired, InputRequired
|
||||
from wtforms.validators import DataRequired, InputRequired, Optional
|
||||
|
||||
|
||||
class LoginForm(FlaskForm):
|
||||
@@ -16,12 +16,12 @@ class LoginForm(FlaskForm):
|
||||
|
||||
|
||||
class FoodItemForm(FlaskForm):
|
||||
barcode = IntegerField("Barcode", validators=[InputRequired()])
|
||||
barcode = IntegerField("Barcode", validators=[Optional()])
|
||||
name = StringField("Product Name", validators=[DataRequired()])
|
||||
energy = IntegerField("Energy per 100g", validators=[InputRequired()])
|
||||
protein = FloatField("protein per 100g", validators=[InputRequired()])
|
||||
carbs = FloatField("carbs per 100g", validators=[InputRequired()])
|
||||
sugar = FloatField("sugar per 100g")
|
||||
sugar = FloatField("sugar per 100g", validators=[Optional()])
|
||||
fat = FloatField("fat per 100g", validators=[InputRequired()])
|
||||
saturated_fat = FloatField("saturated_fat per 100g")
|
||||
submit = SubmitField("Add Item")
|
||||
|
||||
@@ -39,7 +39,7 @@ class Unit(db.Model):
|
||||
class FoodItem(db.Model):
|
||||
__tablename__ = "food_item"
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
barcode = db.Column(db.Integer, nullable=False)
|
||||
barcode = db.Column(db.Integer)
|
||||
owner_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)
|
||||
name = db.Column(db.String(150), nullable=False)
|
||||
|
||||
@@ -62,7 +62,7 @@ class FoodItem(db.Model):
|
||||
protein: float,
|
||||
carbs: float,
|
||||
fat: float,
|
||||
barcode: int,
|
||||
barcode: Optional[int] = None,
|
||||
sugar: Optional[float] = None,
|
||||
saturated_fat: Optional[float] = None,
|
||||
):
|
||||
|
||||
Reference in New Issue
Block a user