Refactor food item model and add barcode scanner page

Renamed FoodItems to FoodItem and Units to Unit in models.py, updated related imports and usage throughout the codebase. Added a barcode scanner test page using ZXing in the admin section. Improved food_items.html to display nutritional information in a table. Registered the admin blueprint in app.py and cleaned up blueprint registration in __init__.py. Updated seed.py to use the new FoodItem model.
This commit is contained in:
2025-06-28 12:53:27 +02:00
parent a5312d7ad0
commit d5e8c3fa94
8 changed files with 145 additions and 19 deletions

View File

@@ -2,7 +2,6 @@ from flask import Flask
from flask_login import LoginManager # type: ignore
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from application.admin.routes import admin_bp
app = Flask(__name__) # Init Flask app
@@ -13,6 +12,3 @@ db = SQLAlchemy(app=app) # Init SQLAlchemy
migrate = Migrate(app=app, db=db) # Init Migration
login_manager = LoginManager(app=app) # Init login manager
# Register blueprints
app.register_blueprint(admin_bp)

View File

@@ -1,6 +1,6 @@
from flask import Blueprint, render_template, abort
from flask_login import current_user
from models import FoodItems
from models import FoodItem
admin_bp = Blueprint(
"admin",
@@ -18,5 +18,10 @@ def admin_required():
@admin_bp.route("/food_items", methods=["GET"])
def food_items():
items = FoodItems.query.all()
items = FoodItem.query.all()
return render_template("food_items.html", items=items)
@admin_bp.route("/barcode_test", methods=["GET"])
def barcode_test():
return render_template("barcode_test.html")

View File

@@ -0,0 +1,55 @@
{% extends "base.html" %}
{% block title %}
ZXing Barcode Scanner
{% endblock %}
{% block content %}
<div class="container text-center">
<h1 class="mb-4">📷 ZXing Barcode Scanner</h1>
<div class="mb-3">
<video id="video" class="border rounded shadow-sm" width="100%" style="max-width: 500px;"></video>
</div>
<div class="mb-3">
<button id="startButton" class="btn btn-primary">Start Scanning</button>
<button id="stopButton" class="btn btn-danger ms-2">Stop</button>
</div>
<div>
<h5>Result:</h5>
<p id="result" class="fw-bold text-success"></p>
</div>
</div>
<script type="module">
import { BrowserMultiFormatReader } from 'https://cdn.jsdelivr.net/npm/@zxing/library@0.21.3/+esm';
const codeReader = new BrowserMultiFormatReader();
const videoElement = document.getElementById('video');
const resultElement = document.getElementById('result');
document.getElementById('startButton').addEventListener('click', async () => {
await navigator.mediaDevices.getUserMedia({ video: true });
console.log('[DEBUG] Start button clicked');
const devices = await codeReader.listVideoInputDevices();
console.log('[DEBUG] Cameras found:', devices);
const selectedDeviceId = devices[0]?.deviceId;
if (!selectedDeviceId) {
alert('No camera found!');
return;
}
codeReader.decodeFromVideoDevice(selectedDeviceId, videoElement, (result, err, controls) => {
if (result) {
resultElement.textContent = result.getText();
controls.stop();
}
});
});
document.getElementById('stopButton').addEventListener('click', () => {
codeReader.reset();
resultElement.textContent = '';
});
</script>
{% endblock %}

View File

@@ -1,5 +1,40 @@
{% extends "base.html" %}
{% block title %}
Food Nutritional Info
{% endblock %}
{% block content %}
Hallo
<div class="container mt-5">
<h1 class="mb-4">Food Nutritional Information (per 100g)</h1>
<div class="table-responsive">
<table class="table table-bordered table-hover align-middle">
<thead class="table-dark">
<tr>
<th>Name</th>
<th>Energy (kcal)</th>
<th>Fats (g)</th>
<th>Saturated Fats (g)</th>
<th>Sugars (g)</th>
<th>Carbs (g)</th>
<th>Protein (g)</th>
</tr>
</thead>
<tbody>
{% for food in items %}
<tr>
<td>{{ food.name }}</td>
<td>{{ food.energy_100g }}</td>
<td>{{ food.fats_100g }}</td>
<td>{{ food.saturated_fats_100g }}</td>
<td>{{ food.sugar_100g }}</td>
<td>{{ food.carbs_100g }}</td>
<td>{{ food.protein_100g }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock%}

View File

@@ -10,7 +10,7 @@
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<body class="bg-light p-4">
<nav class="navbar navbar-expand-lg navbar-dark bg-dark mb-4">
<div class="container-fluid">