From 882eb1af666cb6ecab7a74185be8c5ca6eaccc94 Mon Sep 17 00:00:00 2001 From: Bkolb Date: Sat, 11 Apr 2026 19:35:07 +0200 Subject: [PATCH] =?UTF-8?q?403=20und=20404=20h=C3=BCbsch=20gemacht?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/flask-postgres/app/app.py | 20 +- app/flask-postgres/app/templates/403.html | 49 +++-- app/flask-postgres/app/templates/404.html | 29 +++ app/flask-postgres/app/templates/base.html | 62 ++++-- app/flask-postgres/styles/site.css | 207 +++++++++++++++++++++ 5 files changed, 332 insertions(+), 35 deletions(-) create mode 100644 app/flask-postgres/app/templates/404.html diff --git a/app/flask-postgres/app/app.py b/app/flask-postgres/app/app.py index ff6e162..7a05808 100644 --- a/app/flask-postgres/app/app.py +++ b/app/flask-postgres/app/app.py @@ -336,7 +336,7 @@ def allgemein(): @app.route("/login", methods=["GET", "POST"]) def login(): error_message = "" - next_url = request.args.get("next") or request.form.get("next") or url_for("preise") + next_url = request.args.get("next") or request.form.get("next") or url_for("course_list") if request.method == "POST": email = request.form.get("email", "").strip().lower() @@ -2462,4 +2462,20 @@ def download_certificate_admin(guid): certificate_dir = "/app/files/certificates" filename = f"{guid}.pdf" - return send_from_directory(certificate_dir, filename, as_attachment=True) \ No newline at end of file + return send_from_directory(certificate_dir, filename, as_attachment=True) + +@app.errorhandler(403) +def forbidden(e): + return render_template( + "403.html", + page_title="Zugriff verweigert", + **get_current_user() + ), 403 + +@app.errorhandler(404) +def not_found(e): + return render_template( + "404.html", + page_title="Seite nicht gefunden", + **get_current_user() + ), 404 \ No newline at end of file diff --git a/app/flask-postgres/app/templates/403.html b/app/flask-postgres/app/templates/403.html index 617ccb1..a73d569 100644 --- a/app/flask-postgres/app/templates/403.html +++ b/app/flask-postgres/app/templates/403.html @@ -1,18 +1,31 @@ - - - - - - {{ page_title }} - - - -
-
-

Kein Zugriff

-

Sie haben keine Berechtigung für diese Seite.

-

Zurück zur Startseite

-
-
- - \ No newline at end of file +{% extends "base.html" %} + +{% block content %} + +
+ +
+ +
🚫
+ +

Zugriff verweigert

+ +

+ Sie haben keine Berechtigung, diese Seite aufzurufen. +

+ +
+ + + {% if is_logged_in %} + Zu den Kursen + {% else %} + Login + {% endif %} +
+ +
+ +
+ +{% endblock %} \ No newline at end of file diff --git a/app/flask-postgres/app/templates/404.html b/app/flask-postgres/app/templates/404.html new file mode 100644 index 0000000..9d30183 --- /dev/null +++ b/app/flask-postgres/app/templates/404.html @@ -0,0 +1,29 @@ +{% extends "base.html" %} + +{% block content %} + +
+ +
+ +
🔍
+ +

Seite nicht gefunden

+ +

+ Die angeforderte Seite existiert nicht oder wurde verschoben. +

+ +
+ {% if is_logged_in %} + Zu den Kursen + {% else %} + Preise ansehen + {% endif %} +
+ +
+ +
+ +{% endblock %} \ No newline at end of file diff --git a/app/flask-postgres/app/templates/base.html b/app/flask-postgres/app/templates/base.html index 0005537..b853437 100644 --- a/app/flask-postgres/app/templates/base.html +++ b/app/flask-postgres/app/templates/base.html @@ -29,26 +29,58 @@ {% endif %} {% if is_logged_in %} -
- -
- Profil +
+ + +
+ + + + {% if is_admin %} + + + + + {% endif %} + + {% if is_user_admin %} + + + + + {% endif %} + + {% if is_contentmanager %} + + + + {% endif %} - Logout
{% else %} diff --git a/app/flask-postgres/styles/site.css b/app/flask-postgres/styles/site.css index 96b22a6..6c4e72d 100644 --- a/app/flask-postgres/styles/site.css +++ b/app/flask-postgres/styles/site.css @@ -1443,4 +1443,211 @@ button { .progress-fill { height: 100%; background: linear-gradient(90deg, #22c55e, #15803d); +} + +/* =============================== + User Dropdown Menü (neu) + =============================== */ + +.user-menu { + position: relative; +} + +.user-menu-btn { + background: #eef3f9; + border: none; + padding: 8px 14px; + border-radius: 10px; + cursor: pointer; + font-weight: 600; + color: #1f2f46; +} + +.user-dropdown { + position: absolute; + right: 0; + top: 42px; + min-width: 240px; + background: #ffffff; + border: 1px solid #e2e8f0; + border-radius: 14px; + box-shadow: 0 10px 30px rgba(0,0,0,0.08); + padding: 10px 0; + display: none; + z-index: 1000; +} + +/* Hover öffnen */ +.user-menu:hover .user-dropdown { + display: block; +} + +/* Gruppen */ +.menu-group { + padding: 6px 0; +} + +/* Titel */ +.menu-group-title { + font-size: 11px; + font-weight: 700; + color: #64748b; + padding: 6px 16px; + text-transform: uppercase; + letter-spacing: 0.05em; +} + +/* Links */ +.user-dropdown a { + display: block; + padding: 10px 16px; + color: #1f2937; + text-decoration: none; + font-size: 14px; + transition: background 0.2s ease; +} + +/* Hover Effekt */ +.user-dropdown a:hover { + background: #f1f5f9; +} + +/* Separator */ +.menu-separator { + height: 1px; + background: #e2e8f0; + margin: 6px 0; +} + +/* Pastell-Hintergründe pro Gruppe */ + +.menu-group:nth-child(1) { + background: #f8fafc; +} + +.menu-group:nth-child(3) { + background: #f0fdf4; +} + +.menu-group:nth-child(5) { + background: #fefce8; +} + +.menu-group:nth-child(7) { + background: #fdf2f8; +} + +/*********************/ +/*. User Menü */ +/*********************/ +.top-nav a, +.user-menu-btn, +.lang-btn { + display: inline-flex; + align-items: center; + justify-content: center; + + height: 44px; + min-width: 140px; /* 👈 gleich breit */ + padding: 0 18px; + + border-radius: 22px; + font-weight: 600; + font-size: 15px; + + box-sizing: border-box; +} + +.top-nav a, +.lang-btn { + gap: 8px; +} + +.user-menu { + position: relative; +} + +/* 🔥 WICHTIG: kein Abstand mehr */ +.user-dropdown { + position: absolute; + right: 0; + top: 100%; /* direkt anschließen */ + margin-top: 4px; /* kleiner Abstand erlaubt */ + + min-width: 240px; + background: #fff; + border-radius: 14px; + box-shadow: 0 10px 30px rgba(0,0,0,0.08); + + opacity: 0; + pointer-events: none; + transform: translateY(6px); + transition: all 0.2s ease; +} + +/* 🔥 Hover stabil */ +.user-menu:hover .user-dropdown { + opacity: 1; + pointer-events: auto; + transform: translateY(0); +} + +.user-menu::after { + content: ""; + position: absolute; + top: 100%; + right: 0; + height: 10px; + width: 100%; +} + +/* =============================== + Error Pages + =============================== */ + +.error-page { + display: flex; + justify-content: center; + align-items: center; + padding: 60px 20px; +} + +.error-card { + max-width: 480px; + width: 100%; + background: #ffffff; + border-radius: 18px; + padding: 40px 30px; + text-align: center; + box-shadow: 0 12px 40px rgba(0,0,0,0.08); +} + +.error-icon { + font-size: 48px; + margin-bottom: 15px; +} + +.error-card h1 { + margin-bottom: 10px; + color: #0d2f57; +} + +.error-card p { + color: #475569; + margin-bottom: 25px; +} + +.error-actions { + display: flex; + gap: 12px; + justify-content: center; +} + +.btn-secondary { + background: #e2e8f0; + color: #1f2937; + padding: 10px 16px; + border-radius: 10px; + text-decoration: none; + font-weight: 600; } \ No newline at end of file