diff --git a/app.py b/app.py index 5b3deaa..2cbf5f7 100644 --- a/app.py +++ b/app.py @@ -58,11 +58,12 @@ from db import ( get_all_empfehlungen, ) from permissions import admin_required, login_required -from tools import create_assessment_chart, generate_activation_token, send_mail, verify_activation_token, generate_pdf_from_html +from tools import create_assessment_chart, generate_activation_token, send_mail, verify_activation_token, generate_pdf_from_html, get_image_files from datetime import datetime from pathlib import Path from copy import deepcopy + app = Flask(__name__) app.config.from_object(Config) @@ -428,12 +429,16 @@ def admin_themen(): def admin_thema_new(): ansprechpartner = get_all_ansprechpartner() branchen = get_all_branchen() + image_dir = Path(app.root_path) / "static" / "images" + image_files = get_image_files(image_dir) if request.method == "POST": kurztitel = request.form.get("kurztitel", "").strip() titel = request.form.get("titel", "").strip() infotext = request.form.get("infotext", "").strip() zusatztext = request.form.get("zusatztext", "").strip() + pic = request.form.get("pic", "").strip() + reihenfolge = request.form.get("reihenfolge", "").strip() ansprechpartner_ids = [int(x) for x in request.form.getlist("ansprechpartner_ids")] branche_ids = [int(x) for x in request.form.getlist("branche_ids")] @@ -447,6 +452,7 @@ def admin_thema_new(): branchen=branchen, selected_ansprechpartner_ids=ansprechpartner_ids, selected_branche_ids=branche_ids, + image_files=image_files, ) create_thema( @@ -454,6 +460,8 @@ def admin_thema_new(): titel, infotext, zusatztext, + reihenfolge, + pic, ansprechpartner_ids, branche_ids, ) @@ -468,6 +476,7 @@ def admin_thema_new(): branchen=branchen, selected_ansprechpartner_ids=[], selected_branche_ids=[], + image_files=image_files, ) @app.route("/admin/themen//edit", methods=["GET", "POST"]) @@ -480,14 +489,19 @@ def admin_thema_edit(thema_id): ansprechpartner = get_all_ansprechpartner() branchen = get_all_branchen() + image_dir = Path(app.root_path) / "static" / "images" + image_files = get_image_files(image_dir) if request.method == "POST": kurztitel = request.form.get("kurztitel", "").strip() titel = request.form.get("titel", "").strip() infotext = request.form.get("infotext", "").strip() zusatztext = request.form.get("zusatztext", "").strip() + pic = request.form.get("pic", "").strip() + reihenfolge = request.form.get("reihenfolge", "").strip() ansprechpartner_ids = [int(x) for x in request.form.getlist("ansprechpartner_ids")] branche_ids = [int(x) for x in request.form.getlist("branche_ids")] + if not kurztitel or not titel: flash("Kurztitel und Titel sind Pflichtfelder.", "error") @@ -495,6 +509,8 @@ def admin_thema_edit(thema_id): "id": thema_id, "kurztitel": kurztitel, "titel": titel, + "pic": pic, + "reihenfolge": reihenfolge, "infotext": infotext, "zusatztext": zusatztext, } @@ -506,6 +522,7 @@ def admin_thema_edit(thema_id): branchen=branchen, selected_ansprechpartner_ids=ansprechpartner_ids, selected_branche_ids=branche_ids, + image_files=image_files, ) update_thema( @@ -513,7 +530,9 @@ def admin_thema_edit(thema_id): kurztitel, titel, infotext, + reihenfolge, zusatztext, + pic, ansprechpartner_ids, branche_ids, ) @@ -531,6 +550,7 @@ def admin_thema_edit(thema_id): branchen=branchen, selected_ansprechpartner_ids=selected_ansprechpartner_ids, selected_branche_ids=selected_branche_ids, + image_files=image_files, ) @app.route("/admin/themen//delete", methods=["POST"]) @@ -637,6 +657,7 @@ def admin_question_new(): if request.method == "POST": thema_id = request.form.get("thema_id") text = request.form.get("text", "").strip() + reihenfolge = request.form.get("reihenfolge", "").strip() if not thema_id or not text: flash("Thema und Text sind Pflichtfelder.", "error") @@ -647,7 +668,7 @@ def admin_question_new(): themen=themen, ) - create_question(thema_id, text) + create_question(thema_id, text, reihenfolge) flash("Frage wurde erstellt.", "success") return redirect(url_for("admin_questions")) @@ -670,6 +691,7 @@ def admin_question_edit(frage_id): if request.method == "POST": thema_id = request.form.get("thema_id") + reihenfolge = request.form.get("reihenfolge", "").strip() text = request.form.get("text", "").strip() if not thema_id or not text: @@ -677,6 +699,7 @@ def admin_question_edit(frage_id): "id": frage_id, "thema_id": thema_id, "text": text, + "reihenfolge": reihenfolge, } flash("Thema und Text sind Pflichtfelder.", "error") return render_template( @@ -686,7 +709,7 @@ def admin_question_edit(frage_id): themen=themen, ) - update_question(frage_id, thema_id, text) + update_question(frage_id, thema_id, text, reihenfolge) flash("Frage wurde gespeichert.", "success") return redirect(url_for("admin_questions")) @@ -915,6 +938,11 @@ def admin_empfehlungen(): ansprechpartner=ansprechpartner, ) + +@app.route("/images/") +def images(filename): + return send_from_directory(Path(app.root_path) / "/app/static/images", filename) + @app.errorhandler(401) def unauthorized_error(error): return render_template("401.html"), 401 diff --git a/db.py b/db.py index 3518aa5..5928790 100644 --- a/db.py +++ b/db.py @@ -165,9 +165,9 @@ def get_user_groups(user_id): def get_all_themen(): return fetch_all( """ - SELECT id, kurztitel, titel, infotext, zusatztext + SELECT id, kurztitel, titel, infotext, zusatztext, reihenfolge, pic FROM thema - ORDER BY id + ORDER BY reihenfolge,id """ ) @@ -175,7 +175,7 @@ def get_all_themen(): def get_thema_by_id(thema_id): return fetch_one( """ - SELECT id, kurztitel, titel, infotext, zusatztext + SELECT id, kurztitel, titel, infotext, zusatztext, reihenfolge, pic FROM thema WHERE id = %s """, @@ -242,17 +242,17 @@ def get_ansprechpartner_ids_for_thema(thema_id): return [row["ansprechpartner_id"] for row in rows] -def create_thema(kurztitel, titel, infotext, zusatztext, ansprechpartner_ids, branche_ids=None): +def create_thema(kurztitel, titel, infotext, zusatztext, reihenfolge, pic, ansprechpartner_ids, branche_ids=None): if branche_ids is None: branche_ids = [] row = execute_returning( """ - INSERT INTO thema (kurztitel, titel, infotext, zusatztext) - VALUES (%s, %s, %s, %s) + INSERT INTO thema (kurztitel, titel, infotext, zusatztext, reihenfolge, pic) + VALUES (%s, %s, %s, %s, %s, %s) RETURNING id """, - (kurztitel, titel, infotext, zusatztext), + (kurztitel, titel, infotext, zusatztext, reihenfolge, pic), ) thema_id = row["id"] @@ -277,7 +277,7 @@ def create_thema(kurztitel, titel, infotext, zusatztext, ansprechpartner_ids, br return thema_id -def update_thema(thema_id, kurztitel, titel, infotext, zusatztext, ansprechpartner_ids, branche_ids=None): +def update_thema(thema_id, kurztitel, titel, infotext, reihenfolge, zusatztext, pic, ansprechpartner_ids, branche_ids=None): if branche_ids is None: branche_ids = [] @@ -287,10 +287,12 @@ def update_thema(thema_id, kurztitel, titel, infotext, zusatztext, ansprechpartn SET kurztitel = %s, titel = %s, infotext = %s, - zusatztext = %s + zusatztext = %s, + reihenfolge = %s, + pic = %s WHERE id = %s """, - (kurztitel, titel, infotext, zusatztext, thema_id), + (kurztitel, titel, infotext, zusatztext, reihenfolge, pic, thema_id), ) execute( @@ -343,7 +345,7 @@ def get_thema_questions(thema_id): SELECT id, thema_id, text FROM fragen WHERE thema_id = %s - ORDER BY id + ORDER BY reihenfolge, id """, (thema_id,), ) @@ -358,6 +360,7 @@ def get_all_questions_with_thema(): f.thema_id, t.id AS thema_sort_id, t.kurztitel, + t.reihenfolge, t.titel, COALESCE(STRING_AGG(b.branchenname, ' | '), '') AS branchen FROM fragen f @@ -374,7 +377,7 @@ def get_all_questions_with_thema(): t.id, t.kurztitel, t.titel - ORDER BY t.id, f.id + ORDER BY t.reihenfolge, t.id, f.reihenfolge, f.id """ ) @@ -489,7 +492,7 @@ def delete_ansprechpartner(ansprechpartner_id): def get_question_by_id(frage_id): return fetch_one( """ - SELECT id, thema_id, text + SELECT id, thema_id, text, reihenfolge FROM fragen WHERE id = %s """, @@ -497,26 +500,32 @@ def get_question_by_id(frage_id): ) -def create_question(thema_id, text): +def create_question(thema_id, text, reihenfolge): return execute_returning( """ - INSERT INTO fragen (thema_id, text) - VALUES (%s, %s) + INSERT INTO fragen (thema_id, text, reihenfolge) + VALUES (%s, %s, %s) RETURNING id """, - (thema_id, text), + (thema_id, text, reihenfolge), ) -def update_question(frage_id, thema_id, text): +def update_question(question_id, thema_id, text, reihenfolge): execute( """ UPDATE fragen SET thema_id = %s, - text = %s + text = %s, + reihenfolge = %s WHERE id = %s """, - (thema_id, text, frage_id), + ( + thema_id, + text, + reihenfolge, + question_id, + ), ) @@ -724,7 +733,7 @@ def get_next_thema_id_for_branche(current_thema_id, branche_id): def get_thema_for_branche(thema_id, branche_id): return fetch_one( """ - SELECT t.id, t.kurztitel, t.titel, t.infotext, t.zusatztext + SELECT t.id, t.kurztitel, t.titel, t.infotext, t.zusatztext, t.pic FROM thema t JOIN branchenthemen bt ON bt.thema_id = t.id WHERE t.id = %s @@ -754,11 +763,13 @@ def get_all_themen_with_question_count(): t.titel, t.infotext, t.zusatztext, + t.reihenfolge, + t.pic, COUNT(f.id) AS fragen_anzahl FROM thema t LEFT JOIN fragen f ON f.thema_id = t.id GROUP BY t.id, t.kurztitel, t.titel, t.infotext, t.zusatztext - ORDER BY t.id + ORDER BY t.reihenfolge, t.id """ ) diff --git a/static/images/Logo-Erfolgsfaktoren.png b/static/images/Logo-Erfolgsfaktoren.png new file mode 100644 index 0000000..225d21f Binary files /dev/null and b/static/images/Logo-Erfolgsfaktoren.png differ diff --git a/static/images/Logo-Finanz.png b/static/images/Logo-Finanz.png new file mode 100644 index 0000000..497d3f5 Binary files /dev/null and b/static/images/Logo-Finanz.png differ diff --git a/static/images/Logo-Finanzen.png b/static/images/Logo-Finanzen.png new file mode 100644 index 0000000..e068e1a Binary files /dev/null and b/static/images/Logo-Finanzen.png differ diff --git a/static/images/Logo-Hexerei.png b/static/images/Logo-Hexerei.png new file mode 100644 index 0000000..6bbaabc Binary files /dev/null and b/static/images/Logo-Hexerei.png differ diff --git a/static/images/Logo-ITSicherheit.png b/static/images/Logo-ITSicherheit.png new file mode 100644 index 0000000..ff72117 Binary files /dev/null and b/static/images/Logo-ITSicherheit.png differ diff --git a/static/images/Logo-Identifikation.png b/static/images/Logo-Identifikation.png new file mode 100644 index 0000000..6024dd3 Binary files /dev/null and b/static/images/Logo-Identifikation.png differ diff --git a/static/images/Logo-Identitaet.png b/static/images/Logo-Identitaet.png new file mode 100644 index 0000000..1f571be Binary files /dev/null and b/static/images/Logo-Identitaet.png differ diff --git a/static/images/Logo-Liebe.png b/static/images/Logo-Liebe.png new file mode 100644 index 0000000..bef6aab Binary files /dev/null and b/static/images/Logo-Liebe.png differ diff --git a/static/images/Logo-Marketing.png b/static/images/Logo-Marketing.png new file mode 100644 index 0000000..124073a Binary files /dev/null and b/static/images/Logo-Marketing.png differ diff --git a/static/images/Logo-Personal.png b/static/images/Logo-Personal.png new file mode 100644 index 0000000..3a5f281 Binary files /dev/null and b/static/images/Logo-Personal.png differ diff --git a/static/images/Logo-Personal2.png b/static/images/Logo-Personal2.png new file mode 100644 index 0000000..a27d630 Binary files /dev/null and b/static/images/Logo-Personal2.png differ diff --git a/static/images/Logo-Raum.png b/static/images/Logo-Raum.png new file mode 100644 index 0000000..e6876bb Binary files /dev/null and b/static/images/Logo-Raum.png differ diff --git a/static/images/Logo-Softskills.png b/static/images/Logo-Softskills.png new file mode 100644 index 0000000..7f0eff8 Binary files /dev/null and b/static/images/Logo-Softskills.png differ diff --git a/static/images/Logo-Teambuilding.png b/static/images/Logo-Teambuilding.png new file mode 100644 index 0000000..21757cf Binary files /dev/null and b/static/images/Logo-Teambuilding.png differ diff --git a/static/images/Logo-WLB.png b/static/images/Logo-WLB.png new file mode 100644 index 0000000..fd1ccba Binary files /dev/null and b/static/images/Logo-WLB.png differ diff --git a/templates/admin/question_form.html b/templates/admin/question_form.html index 7063703..9b8656a 100644 --- a/templates/admin/question_form.html +++ b/templates/admin/question_form.html @@ -25,6 +25,13 @@ +
+ + +
+
diff --git a/templates/admin/thema_form.html b/templates/admin/thema_form.html index aadbbb4..76cda8d 100644 --- a/templates/admin/thema_form.html +++ b/templates/admin/thema_form.html @@ -11,6 +11,13 @@
+
+ + +
+
@@ -21,6 +28,24 @@
+ + +
+ + +
+
diff --git a/templates/admin/themen_list.html b/templates/admin/themen_list.html index b3dcc61..be3201d 100644 --- a/templates/admin/themen_list.html +++ b/templates/admin/themen_list.html @@ -11,9 +11,10 @@ - + + @@ -21,9 +22,10 @@ {% for thema in themen %} - + +
IDRfg Kurztitel TitelBild Fragen Aktionen
{{ thema.id }}{{ thema.reihenfolge }} {{ thema.kurztitel }} {{ thema.titel }}{{ thema.pic }} {{ thema.fragen_anzahl }} {% if thema.fragen_anzahl < 8 %} diff --git a/templates/topic.html b/templates/topic.html index c8b5840..208b5af 100644 --- a/templates/topic.html +++ b/templates/topic.html @@ -3,6 +3,9 @@ {% block content %}

{{ thema.titel }}

+ {% if thema.pic != "" %} +
+ {% endif %}

{{ thema.infotext }}

{{ thema.zusatztext }}

diff --git a/tools.py b/tools.py index 6e068ac..715e304 100644 --- a/tools.py +++ b/tools.py @@ -7,6 +7,7 @@ import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt from config import Config +from flask import current_app from pathlib import Path from weasyprint import HTML @@ -116,3 +117,29 @@ def create_chart_bytes(labels, yes_counts): plt.close(fig) buffer.seek(0) return buffer + +def get_image_files(image_dir): + allowed_extensions = {".png", ".jpg", ".jpeg", ".gif", ".webp", ".svg"} + + #current_app.logger.error(f"IMAGE DIR: {image_dir}") + #current_app.logger.error(f"EXISTS: {image_dir.exists()}") + + + if not image_dir.exists(): + return [] + + files = sorted( + + file.name + + for file in image_dir.iterdir() + + if file.is_file() + + and file.suffix.lower() in allowed_extensions + + ) + + #current_app.logger.error(f"FILES: {files}") + + return files \ No newline at end of file