diff --git a/add_products.py b/add_products.py new file mode 100644 index 0000000..5b23ad3 --- /dev/null +++ b/add_products.py @@ -0,0 +1,31 @@ +# add_products_from_openfoodfacts.py +# Uruchom w katalogu z app.py + +import urllib.request +import json +from app import db, SuggestedProduct, app + +# URL do pobrania polskich produktów (tylko nazwy) +url = 'https://pl.openfoodfacts.org/cgi/search.pl?search_simple=1&action=process&json=1&fields=product_name&page_size=1000' + +with urllib.request.urlopen(url) as response: + data = json.loads(response.read()) + +produkty = [] +for prod in data.get('products', []): + name = prod.get('product_name', '').strip() + if name: + produkty.append(name) + +print(f"Znaleziono {len(produkty)} produktów do dodania.") + +dodane = 0 +with app.app_context(): + for name in produkty: + if not SuggestedProduct.query.filter_by(name=name).first(): + prod = SuggestedProduct(name=name) + db.session.add(prod) + dodane += 1 + db.session.commit() + +print(f'Dodano {dodane} produktów do bazy.') diff --git a/app.py b/app.py index e169907..f985c1e 100644 --- a/app.py +++ b/app.py @@ -44,6 +44,7 @@ PROTECTED_JS_FILES = { "expenses.js", "toggle_button.js", "user_management.js", + "mass_add.js" } os.makedirs(UPLOAD_FOLDER, exist_ok=True) @@ -595,6 +596,12 @@ def uploaded_file(filename): response.headers['Content-Type'] = mime return response +@app.route('/all_products') +@login_required +def all_products(): + suggestions = SuggestedProduct.query.order_by(SuggestedProduct.name).all() + return jsonify([s.name for s in suggestions]) + @app.route('/admin') @login_required @admin_required diff --git a/static/css/style.css b/static/css/style.css index 1fba13e..bff9285 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -192,4 +192,24 @@ input.form-control { opacity: 1; transform: translateY(0); } -} \ No newline at end of file +} + +#mass-add-list li.active { + background: #198754 !important; + color: #fff !important; + font-weight: bold; +} +#mass-add-list li { + transition: background 0.2s; +} +.quantity-input { + width: 60px; + background: #343a40; + color: #fff; + border: 1px solid #495057; + border-radius: 4px; + text-align: center; +} +.add-btn { + margin-left: 10px; +} diff --git a/static/js/mass_add.js b/static/js/mass_add.js new file mode 100644 index 0000000..50b849b --- /dev/null +++ b/static/js/mass_add.js @@ -0,0 +1,88 @@ +document.addEventListener('DOMContentLoaded', function () { + const modal = document.getElementById('massAddModal'); + const productList = document.getElementById('mass-add-list'); + let addedProducts = new Set(); + + document.querySelectorAll('#items li').forEach(li => { + if (li.dataset.name) addedProducts.add(li.dataset.name.toLowerCase()); + }); + + modal.addEventListener('show.bs.modal', async function () { + productList.innerHTML = '
Brak wgranych paragonów do tej listy.
{% endif %} + + {% block scripts %} +