Compare commits
2 Commits
aa0767f790
...
3f47532e2d
| Author | SHA1 | Date | |
|---|---|---|---|
| 3f47532e2d | |||
| ea4e5d9296 |
@ -30,6 +30,7 @@ from security import (
|
|||||||
contentmanager_required
|
contentmanager_required
|
||||||
)
|
)
|
||||||
from logging_config import setup_logging
|
from logging_config import setup_logging
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
@ -284,7 +285,13 @@ def startup_checks():
|
|||||||
@app.route("/")
|
@app.route("/")
|
||||||
@app.route("/home")
|
@app.route("/home")
|
||||||
def home():
|
def home():
|
||||||
return render_page("home", "Home")
|
return render_template(
|
||||||
|
"index.html",
|
||||||
|
page_title="Info",
|
||||||
|
active_page="home",
|
||||||
|
vat_label=COUNTRY_VAT_LABELS.get(session.get("country", "DE")),
|
||||||
|
**get_current_user()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/preise")
|
@app.route("/preise")
|
||||||
@ -304,13 +311,10 @@ def allgemein():
|
|||||||
"allgemein.html",
|
"allgemein.html",
|
||||||
page_title="Info",
|
page_title="Info",
|
||||||
active_page="allgemein",
|
active_page="allgemein",
|
||||||
|
vat_label=COUNTRY_VAT_LABELS.get(session.get("country", "DE")),
|
||||||
**get_current_user()
|
**get_current_user()
|
||||||
)
|
)
|
||||||
|
|
||||||
# @app.route("/allgemein")
|
|
||||||
# @login_required
|
|
||||||
# def allgemein():
|
|
||||||
# return render_page("allgemein", "Allgemein")
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/login", methods=["GET", "POST"])
|
@app.route("/login", methods=["GET", "POST"])
|
||||||
@ -494,6 +498,7 @@ def admin_mandanten():
|
|||||||
name = request.form.get("name", "").strip()
|
name = request.form.get("name", "").strip()
|
||||||
kontakt_email = request.form.get("kontakt_email", "").strip()
|
kontakt_email = request.form.get("kontakt_email", "").strip()
|
||||||
level = request.form.get("level", "0").strip()
|
level = request.form.get("level", "0").strip()
|
||||||
|
selected_groups = request.form.getlist("groups")
|
||||||
|
|
||||||
admin_name = request.form.get("admin_name", "").strip()
|
admin_name = request.form.get("admin_name", "").strip()
|
||||||
admin_email = request.form.get("admin_email", "").strip().lower()
|
admin_email = request.form.get("admin_email", "").strip().lower()
|
||||||
@ -527,6 +532,8 @@ def admin_mandanten():
|
|||||||
error_message = "Die beiden Admin-Passwörter stimmen nicht überein."
|
error_message = "Die beiden Admin-Passwörter stimmen nicht überein."
|
||||||
elif len(admin_password) < 8:
|
elif len(admin_password) < 8:
|
||||||
error_message = "Das Admin Passwort muss mindestens 8 Zeichen lang sein."
|
error_message = "Das Admin Passwort muss mindestens 8 Zeichen lang sein."
|
||||||
|
elif not selected_groups:
|
||||||
|
error_message = "Mindestens die Admin Gruppe muss ausgewählt werden."
|
||||||
|
|
||||||
if error_message:
|
if error_message:
|
||||||
cur.execute("""
|
cur.execute("""
|
||||||
@ -557,6 +564,7 @@ def admin_mandanten():
|
|||||||
"level": level,
|
"level": level,
|
||||||
"admin_name": admin_name,
|
"admin_name": admin_name,
|
||||||
"admin_email": admin_email,
|
"admin_email": admin_email,
|
||||||
|
"groups": selected_groups,
|
||||||
}
|
}
|
||||||
|
|
||||||
**get_current_user()
|
**get_current_user()
|
||||||
@ -580,19 +588,16 @@ def admin_mandanten():
|
|||||||
new_mandant_id = cur.fetchone()[0]
|
new_mandant_id = cur.fetchone()[0]
|
||||||
|
|
||||||
# Standardgruppen für den neuen Mandanten
|
# Standardgruppen für den neuen Mandanten
|
||||||
cur.execute("""
|
group_ids = {}
|
||||||
INSERT INTO app_group (mandant_id, group_name)
|
|
||||||
VALUES (%s, %s)
|
|
||||||
RETURNING id
|
|
||||||
""", (new_mandant_id, "Useradministration"))
|
|
||||||
useradmin_group_id = cur.fetchone()[0]
|
|
||||||
|
|
||||||
|
for group_name in selected_groups:
|
||||||
cur.execute("""
|
cur.execute("""
|
||||||
INSERT INTO app_group (mandant_id, group_name)
|
INSERT INTO app_group (mandant_id, group_name)
|
||||||
VALUES (%s, %s)
|
VALUES (%s, %s)
|
||||||
RETURNING id
|
RETURNING id
|
||||||
""", (new_mandant_id, "Contentmanager"))
|
""", (new_mandant_id, group_name))
|
||||||
contentmanager_group_id = cur.fetchone()[0]
|
|
||||||
|
group_ids[group_name] = cur.fetchone()[0]
|
||||||
|
|
||||||
# erster Admin-User
|
# erster Admin-User
|
||||||
admin_password_hash = generate_password_hash(admin_password)
|
admin_password_hash = generate_password_hash(admin_password)
|
||||||
@ -604,16 +609,12 @@ def admin_mandanten():
|
|||||||
""", (admin_email, admin_name, new_mandant_id, admin_password_hash, 1))
|
""", (admin_email, admin_name, new_mandant_id, admin_password_hash, 1))
|
||||||
new_admin_user_id = cur.fetchone()[0]
|
new_admin_user_id = cur.fetchone()[0]
|
||||||
|
|
||||||
# User beiden Gruppen zuordnen
|
# User den gewählten Gruppen zuordnen
|
||||||
|
for group_id in group_ids.values():
|
||||||
cur.execute("""
|
cur.execute("""
|
||||||
INSERT INTO user_group (user_id, group_id, mandant_id)
|
INSERT INTO user_group (user_id, group_id, mandant_id)
|
||||||
VALUES (%s, %s, %s)
|
VALUES (%s, %s, %s)
|
||||||
""", (new_admin_user_id, useradmin_group_id, new_mandant_id))
|
""", (new_admin_user_id, group_id, new_mandant_id))
|
||||||
|
|
||||||
cur.execute("""
|
|
||||||
INSERT INTO user_group (user_id, group_id, mandant_id)
|
|
||||||
VALUES (%s, %s, %s)
|
|
||||||
""", (new_admin_user_id, contentmanager_group_id, new_mandant_id))
|
|
||||||
|
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
|
||||||
@ -1603,3 +1604,11 @@ def admin_courses():
|
|||||||
form_values=form_values,
|
form_values=form_values,
|
||||||
**get_current_user()
|
**get_current_user()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@app.route("/impressum")
|
||||||
|
def impressum():
|
||||||
|
return render_template("impressum.html", **get_current_user())
|
||||||
|
|
||||||
|
@app.route("/datenschutz")
|
||||||
|
def datenschutz():
|
||||||
|
return render_template("datenschutz.html", **get_current_user())
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
from functools import wraps
|
from functools import wraps
|
||||||
from flask import session, redirect, url_for, request, abort
|
from flask import session, redirect, url_for, request, abort
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
from db import get_connection
|
from db import get_connection
|
||||||
|
|
||||||
@ -71,6 +72,7 @@ def get_current_user():
|
|||||||
"is_user_admin": user_is_user_admin() if session.get("user_id") else False,
|
"is_user_admin": user_is_user_admin() if session.get("user_id") else False,
|
||||||
"is_contentmanager": user_is_contentmanager() if session.get("user_id") else False,
|
"is_contentmanager": user_is_contentmanager() if session.get("user_id") else False,
|
||||||
"country": country,
|
"country": country,
|
||||||
|
"current_year": datetime.now().year,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -77,5 +77,21 @@
|
|||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
<footer class="site-footer">
|
||||||
|
<div class="footer-inner">
|
||||||
|
|
||||||
|
<div class="footer-left">
|
||||||
|
<strong>Compliance Verification</strong><br>
|
||||||
|
© {{ current_year }} Alle Rechte vorbehalten
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer-links">
|
||||||
|
<a href="/impressum">Impressum</a>
|
||||||
|
<a href="/datenschutz">Datenschutz</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
164
app/flask-postgres/app/templates/datenschutz.html
Normal file
164
app/flask-postgres/app/templates/datenschutz.html
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="content-box">
|
||||||
|
|
||||||
|
<h1>Impressum & Datenschutz</h1>
|
||||||
|
|
||||||
|
<div class="two-col responsive-stack">
|
||||||
|
|
||||||
|
<!-- LINK: IMPRESSUM -->
|
||||||
|
<div class="legal-section">
|
||||||
|
|
||||||
|
<h2>Impressum</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Rechtsanwaltskanzlei Neubauer – Neubauer Legal</strong><br>
|
||||||
|
Dr. Anja Maria Neubauer, Rechtsanwältin<br>
|
||||||
|
Meisenweg 3<br>
|
||||||
|
51149 Köln<br>
|
||||||
|
Deutschland
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
E-Mail: <a href="mailto:kanzlei@neubauer.legal">kanzlei@neubauer.legal</a><br>
|
||||||
|
Telefon: 0800 888 2 880
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Umsatzsteuer-Identifikationsnummer: DE227436885
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Aufsichtsbehörde und Anwaltskammer:</strong><br>
|
||||||
|
Rechtsanwaltskammer Köln<br>
|
||||||
|
Körperschaft des öffentlichen Rechts<br>
|
||||||
|
Riehler Str. 30, 50668 Köln<br>
|
||||||
|
Telefon: +49 (0)221 973010-0<br>
|
||||||
|
Fax: +49 (0)221 973010-50<br>
|
||||||
|
E-Mail: kontakt@rak-koeln.de
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Berufsbezeichnung und berufsrechtliche Vorschriften:</strong><br>
|
||||||
|
Die Berufsbezeichnung „Rechtsanwältin” wurde in der Bundesrepublik Deutschland verliehen.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Bundesrechtsanwaltsordnung (BRAO)</li>
|
||||||
|
<li>Berufsordnung für Rechtsanwälte (BORA)</li>
|
||||||
|
<li>Rechtsanwaltsvergütungsgesetz (RVG)</li>
|
||||||
|
<li>Fachanwaltsordnung (FAO)</li>
|
||||||
|
<li>CCBE-Verhaltenskodex für europäische Rechtsanwälte</li>
|
||||||
|
<li>Gesetz über die Tätigkeit europäischer Rechtsanwälte in Deutschland (EuRAG)</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Diese Vorschriften sind unter <a href="https://www.brak.de" target="_blank">www.brak.de</a> unter „Berufsrecht” verfügbar.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Berufshaftpflichtversicherung:</strong><br>
|
||||||
|
mailo Versicherung AG<br>
|
||||||
|
Riehler Straße 1<br>
|
||||||
|
50668 Köln, Deutschland
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Gebietsabdeckung:</strong><br>
|
||||||
|
Weltweit
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Online-Streitbeilegung (ODR):</strong><br>
|
||||||
|
<a href="https://ec.europa.eu/consumers/odr" target="_blank">
|
||||||
|
https://ec.europa.eu/consumers/odr
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Hinweis gemäß § 36 VSBG:</strong><br>
|
||||||
|
Die Kanzlei Neubauer nimmt nicht an Streitbeilegungsverfahren vor einer Verbraucherschlichtungsstelle teil und ist auch nicht dazu verpflichtet.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- RECHTS: DATENSCHUTZ -->
|
||||||
|
<div class="legal-section">
|
||||||
|
|
||||||
|
<h2>Datenschutzerklärung</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Verantwortlicher</strong><br>
|
||||||
|
Neubauer Legal<br>
|
||||||
|
Dr. Anja Maria Neubauer, Rechtsanwältin<br>
|
||||||
|
Meisenweg 3<br>
|
||||||
|
51149 Köln, Deutschland<br>
|
||||||
|
E-Mail: kanzlei@neubauer.legal
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Allgemeine Informationen zur Datenverarbeitung</strong><br>
|
||||||
|
Personenbezogene Daten werden nur in dem Umfang verarbeitet, wie es für die Funktionalität dieser Website und die angebotenen Dienste erforderlich ist.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Websitezugriff und Logfiles</strong><br>
|
||||||
|
Beim Zugriff auf diese Website werden automatisch Daten wie Browsertyp, IP-Adresse, Datum und Uhrzeit des Zugriffs erfasst.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Diese Daten werden nicht mit anderen personenbezogenen Daten verknüpft und innerhalb von 7 Tagen anonymisiert.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Cookies</strong><br>
|
||||||
|
Diese Website verwendet keine Tracking-Cookies. Es werden nur technisch notwendige Cookies eingesetzt.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Rechte der betroffenen Personen</strong>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Recht auf Auskunft (Art. 15 DSGVO)</li>
|
||||||
|
<li>Recht auf Berichtigung (Art. 16 DSGVO)</li>
|
||||||
|
<li>Recht auf Löschung (Art. 17 DSGVO)</li>
|
||||||
|
<li>Recht auf Einschränkung (Art. 18 DSGVO)</li>
|
||||||
|
<li>Widerspruchsrecht (Art. 21 DSGVO)</li>
|
||||||
|
<li>Recht auf Datenübertragbarkeit (Art. 20 DSGVO)</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Kontakt per E-Mail</strong><br>
|
||||||
|
Daten werden ausschließlich zur Bearbeitung der Anfrage verwendet und anschließend gelöscht.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Datenschutzbeauftragte</strong><br>
|
||||||
|
Rechtsanwältin Anja Neubauer<br>
|
||||||
|
E-Mail: kanzlei@neubauer.legal
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Keine Weitergabe an Dritte</strong><br>
|
||||||
|
Es erfolgt keine Weitergabe personenbezogener Daten an Dritte, außer wenn gesetzlich erforderlich.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Änderungen</strong><br>
|
||||||
|
Diese Datenschutzerklärung kann angepasst werden. Es gilt die jeweils aktuelle Version.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="legal-footer">
|
||||||
|
© 2026 NEUBAUER legal
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
164
app/flask-postgres/app/templates/impressum.html
Normal file
164
app/flask-postgres/app/templates/impressum.html
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="content-box">
|
||||||
|
|
||||||
|
<h1>Impressum & Datenschutz</h1>
|
||||||
|
|
||||||
|
<div class="two-col responsive-stack">
|
||||||
|
|
||||||
|
<!-- LINK: IMPRESSUM -->
|
||||||
|
<div class="legal-section">
|
||||||
|
|
||||||
|
<h2>Impressum</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Rechtsanwaltskanzlei Neubauer – Neubauer Legal</strong><br>
|
||||||
|
Dr. Anja Maria Neubauer, Rechtsanwältin<br>
|
||||||
|
Meisenweg 3<br>
|
||||||
|
51149 Köln<br>
|
||||||
|
Deutschland
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
E-Mail: <a href="mailto:kanzlei@neubauer.legal">kanzlei@neubauer.legal</a><br>
|
||||||
|
Telefon: 0800 888 2 880
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Umsatzsteuer-Identifikationsnummer: DE227436885
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Aufsichtsbehörde und Anwaltskammer:</strong><br>
|
||||||
|
Rechtsanwaltskammer Köln<br>
|
||||||
|
Körperschaft des öffentlichen Rechts<br>
|
||||||
|
Riehler Str. 30, 50668 Köln<br>
|
||||||
|
Telefon: +49 (0)221 973010-0<br>
|
||||||
|
Fax: +49 (0)221 973010-50<br>
|
||||||
|
E-Mail: kontakt@rak-koeln.de
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Berufsbezeichnung und berufsrechtliche Vorschriften:</strong><br>
|
||||||
|
Die Berufsbezeichnung „Rechtsanwältin” wurde in der Bundesrepublik Deutschland verliehen.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Bundesrechtsanwaltsordnung (BRAO)</li>
|
||||||
|
<li>Berufsordnung für Rechtsanwälte (BORA)</li>
|
||||||
|
<li>Rechtsanwaltsvergütungsgesetz (RVG)</li>
|
||||||
|
<li>Fachanwaltsordnung (FAO)</li>
|
||||||
|
<li>CCBE-Verhaltenskodex für europäische Rechtsanwälte</li>
|
||||||
|
<li>Gesetz über die Tätigkeit europäischer Rechtsanwälte in Deutschland (EuRAG)</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Diese Vorschriften sind unter <a href="https://www.brak.de" target="_blank">www.brak.de</a> unter „Berufsrecht” verfügbar.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Berufshaftpflichtversicherung:</strong><br>
|
||||||
|
mailo Versicherung AG<br>
|
||||||
|
Riehler Straße 1<br>
|
||||||
|
50668 Köln, Deutschland
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Gebietsabdeckung:</strong><br>
|
||||||
|
Weltweit
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Online-Streitbeilegung (ODR):</strong><br>
|
||||||
|
<a href="https://ec.europa.eu/consumers/odr" target="_blank">
|
||||||
|
https://ec.europa.eu/consumers/odr
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Hinweis gemäß § 36 VSBG:</strong><br>
|
||||||
|
Die Kanzlei Neubauer nimmt nicht an Streitbeilegungsverfahren vor einer Verbraucherschlichtungsstelle teil und ist auch nicht dazu verpflichtet.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- RECHTS: DATENSCHUTZ -->
|
||||||
|
<div class="legal-section">
|
||||||
|
|
||||||
|
<h2>Datenschutzerklärung</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Verantwortlicher</strong><br>
|
||||||
|
Neubauer Legal<br>
|
||||||
|
Dr. Anja Maria Neubauer, Rechtsanwältin<br>
|
||||||
|
Meisenweg 3<br>
|
||||||
|
51149 Köln, Deutschland<br>
|
||||||
|
E-Mail: kanzlei@neubauer.legal
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Allgemeine Informationen zur Datenverarbeitung</strong><br>
|
||||||
|
Personenbezogene Daten werden nur in dem Umfang verarbeitet, wie es für die Funktionalität dieser Website und die angebotenen Dienste erforderlich ist.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Websitezugriff und Logfiles</strong><br>
|
||||||
|
Beim Zugriff auf diese Website werden automatisch Daten wie Browsertyp, IP-Adresse, Datum und Uhrzeit des Zugriffs erfasst.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Diese Daten werden nicht mit anderen personenbezogenen Daten verknüpft und innerhalb von 7 Tagen anonymisiert.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Cookies</strong><br>
|
||||||
|
Diese Website verwendet keine Tracking-Cookies. Es werden nur technisch notwendige Cookies eingesetzt.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Rechte der betroffenen Personen</strong>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Recht auf Auskunft (Art. 15 DSGVO)</li>
|
||||||
|
<li>Recht auf Berichtigung (Art. 16 DSGVO)</li>
|
||||||
|
<li>Recht auf Löschung (Art. 17 DSGVO)</li>
|
||||||
|
<li>Recht auf Einschränkung (Art. 18 DSGVO)</li>
|
||||||
|
<li>Widerspruchsrecht (Art. 21 DSGVO)</li>
|
||||||
|
<li>Recht auf Datenübertragbarkeit (Art. 20 DSGVO)</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Kontakt per E-Mail</strong><br>
|
||||||
|
Daten werden ausschließlich zur Bearbeitung der Anfrage verwendet und anschließend gelöscht.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Datenschutzbeauftragte</strong><br>
|
||||||
|
Rechtsanwältin Anja Neubauer<br>
|
||||||
|
E-Mail: kanzlei@neubauer.legal
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Keine Weitergabe an Dritte</strong><br>
|
||||||
|
Es erfolgt keine Weitergabe personenbezogener Daten an Dritte, außer wenn gesetzlich erforderlich.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Änderungen</strong><br>
|
||||||
|
Diese Datenschutzerklärung kann angepasst werden. Es gilt die jeweils aktuelle Version.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="legal-footer">
|
||||||
|
© 2026 NEUBAUER legal
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@ -1,53 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
{% extends "base.html" %}
|
||||||
<html lang="de">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>{{ page_title }}</title>
|
|
||||||
<link rel="stylesheet" href="/styles/site.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<header class="site-header">
|
|
||||||
<div class="header-inner">
|
|
||||||
<div class="logo-area">
|
|
||||||
<a href="/home">
|
|
||||||
<img src="/images/Logo-Compliance-Verification-bg-1.png" alt="Logo" class="site-logo">
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<nav class="top-nav">
|
{% block content %}
|
||||||
<a href="/home" class="{% if active_page == 'home' %}active{% endif %}">Home</a>
|
|
||||||
<a href="/preise" class="{% if active_page == 'preise' %}active{% endif %}">Preise</a>
|
|
||||||
<a href="/allgemein" class="{% if active_page == 'allgemein' %}active{% endif %}">Allgemein</a>
|
|
||||||
|
|
||||||
{% if is_logged_in %}
|
|
||||||
<div class="user-menu">
|
|
||||||
<button class="user-menu-toggle" type="button">{{ user_name }} ▾</button>
|
|
||||||
<div class="user-menu-dropdown">
|
|
||||||
<a href="/profil">Profil</a>
|
|
||||||
{% if is_admin %}
|
|
||||||
<a href="/admin/mandanten">Admin</a>
|
|
||||||
{% endif %}
|
|
||||||
<a href="/logout">Logout</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<a href="/login" class="{% if active_page == 'login' %}active{% endif %}">Login</a>
|
|
||||||
{% endif %}
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<main class="content-area">
|
|
||||||
<section class="content-box">
|
|
||||||
{% if active_page == "home" %}
|
|
||||||
{% include "partials/home_content.html" %}
|
{% include "partials/home_content.html" %}
|
||||||
{% elif active_page == "preise" %}
|
{% endblock %}
|
||||||
{% include "partials/preise_content.html" %}
|
|
||||||
{% elif active_page == "allgemein" %}
|
|
||||||
{% include "partials/allgemein_content.html" %}
|
|
||||||
{% endif %}
|
|
||||||
</section>
|
|
||||||
</main>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,6 +1,112 @@
|
|||||||
<div class="hero-box">
|
<!-- HERO -->
|
||||||
<h1>Compliance Verification</h1>
|
<section class="hero-box">
|
||||||
<p>Willkommen auf Ihrem Portal zur geregelten Nutzung von KI in Ihrem Unternehmen.</p>
|
<h1>Compliance. Digitalisierung. Zukunftssicher.</h1>
|
||||||
<p>Besuche insgesamt: {{ visit_count }}</p>
|
<p>
|
||||||
<p>Für die Seiten <strong>Preise</strong> und <strong>Allgemein</strong> ist eine Anmeldung erforderlich.</p>
|
Wir unterstützen Unternehmen dabei, regulatorische Anforderungen effizient umzusetzen
|
||||||
</div>
|
und gleichzeitig die Chancen moderner Technologien optimal zu nutzen.
|
||||||
|
</p>
|
||||||
|
<div class="hero-actions">
|
||||||
|
<a href="/preise" class="btn-primary">Leistungen ansehen</a>
|
||||||
|
<a href="/kontakt" class="btn-secondary">Kontakt aufnehmen</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- LEISTUNGEN -->
|
||||||
|
<section class="section">
|
||||||
|
<h2>Unsere Leistungen</h2>
|
||||||
|
|
||||||
|
<div class="card-grid">
|
||||||
|
<div class="card">
|
||||||
|
<h3>Compliance & Regulierung</h3>
|
||||||
|
<p>
|
||||||
|
Umsetzung gesetzlicher Anforderungen wie EU AI Act, Datenschutz und Governance.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3>KI & Digitalisierung</h3>
|
||||||
|
<p>
|
||||||
|
Strukturierte Einführung von KI-Systemen mit klaren Prozessen und Richtlinien.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3>Schulung</h3>
|
||||||
|
<p>
|
||||||
|
Aufbau von Wissen im Unternehmen mit Trainings und nachvollziehbarer Dokumentation.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- WARUM -->
|
||||||
|
<section class="section alt">
|
||||||
|
<div class="two-col">
|
||||||
|
<div>
|
||||||
|
<h2>Warum Compliance Verification?</h2>
|
||||||
|
<ul class="check-list">
|
||||||
|
<li>Rechtssicherheit für Ihr Unternehmen</li>
|
||||||
|
<li>Klare Dokumentation und Nachweise</li>
|
||||||
|
<li>Strukturierte Umsetzung von KI-Richtlinien</li>
|
||||||
|
<li>Effiziente Schulung Ihrer Mitarbeitenden</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="image-panel">
|
||||||
|
<img src="/images/schulung.png" alt="Schulung">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- MODULE -->
|
||||||
|
<section class="section">
|
||||||
|
<h2>Unsere Module</h2>
|
||||||
|
|
||||||
|
<div class="card-grid">
|
||||||
|
<div class="card">
|
||||||
|
<h3>Modul A – Basis</h3>
|
||||||
|
<p>Grundlagen für alle Mitarbeitenden zur sicheren Nutzung von KI.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3>Modul B – Compliance</h3>
|
||||||
|
<p>Erweiterte Anforderungen für Fachbereiche und Organisation.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3>Modul C – Governance</h3>
|
||||||
|
<p>Ganzheitliche Steuerung und Absicherung im Unternehmen.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- ABLAUF -->
|
||||||
|
<section class="section alt">
|
||||||
|
<h2>So funktioniert es</h2>
|
||||||
|
|
||||||
|
<div class="steps-grid">
|
||||||
|
<div class="step-card">
|
||||||
|
<h3>Analyse</h3>
|
||||||
|
<p>Wir analysieren Ihre aktuelle Situation und Anforderungen.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="step-card">
|
||||||
|
<h3>Umsetzung</h3>
|
||||||
|
<p>Einführung von Prozessen, Richtlinien und Schulungen.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="step-card">
|
||||||
|
<h3>Verifikation</h3>
|
||||||
|
<p>Nachweisbare Compliance und nachhaltige Absicherung.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- CTA -->
|
||||||
|
<section class="section cta-section">
|
||||||
|
<h2>Bereit für den nächsten Schritt?</h2>
|
||||||
|
<p>
|
||||||
|
Starten Sie jetzt mit der strukturierten Umsetzung Ihrer KI-Compliance.
|
||||||
|
</p>
|
||||||
|
<a href="/preise" class="btn-primary">Jetzt starten</a>
|
||||||
|
</section>
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
<div class="hero-box">
|
||||||
|
<h1>Compliance Verification</h1>
|
||||||
|
<p>Willkommen auf Ihrem Portal zur geregelten Nutzung von KI in Ihrem Unternehmen.</p>
|
||||||
|
<p>Besuche insgesamt: {{ visit_count }}</p>
|
||||||
|
<p>Für die Seiten <strong>Preise</strong> und <strong>Allgemein</strong> ist eine Anmeldung erforderlich.</p>
|
||||||
|
</div>
|
||||||
@ -4,20 +4,25 @@ set -euo pipefail
|
|||||||
SRC_ROOT="/Volumes/MacBook SD/Projekte/compliance-verification/app/flask-postgres"
|
SRC_ROOT="/Volumes/MacBook SD/Projekte/compliance-verification/app/flask-postgres"
|
||||||
DST_ROOT="/Volumes/docker/flask-postgres"
|
DST_ROOT="/Volumes/docker/flask-postgres"
|
||||||
|
|
||||||
NAS_USER="BKolb"
|
|
||||||
NAS_HOST="192.168.0.10"
|
|
||||||
CONTAINER_NAME="flask_web"
|
CONTAINER_NAME="flask_web"
|
||||||
|
|
||||||
echo "Starte Deployment..."
|
echo "Starte Deployment für compliance-verification ..."
|
||||||
|
|
||||||
|
# Quellen prüfen
|
||||||
[ -d "$SRC_ROOT/app" ] || { echo "Quelle app fehlt: $SRC_ROOT/app"; exit 1; }
|
[ -d "$SRC_ROOT/app" ] || { echo "Quelle app fehlt: $SRC_ROOT/app"; exit 1; }
|
||||||
[ -d "$SRC_ROOT/images" ] || { echo "Quelle images fehlt: $SRC_ROOT/images"; exit 1; }
|
[ -d "$SRC_ROOT/images" ] || { echo "Quelle images fehlt: $SRC_ROOT/images"; exit 1; }
|
||||||
[ -d "$SRC_ROOT/styles" ] || { echo "Quelle styles fehlt: $SRC_ROOT/styles"; exit 1; }
|
[ -d "$SRC_ROOT/styles" ] || { echo "Quelle styles fehlt: $SRC_ROOT/styles"; exit 1; }
|
||||||
|
|
||||||
|
# Ziele prüfen
|
||||||
[ -d "$DST_ROOT/app" ] || { echo "Ziel app fehlt: $DST_ROOT/app"; exit 1; }
|
[ -d "$DST_ROOT/app" ] || { echo "Ziel app fehlt: $DST_ROOT/app"; exit 1; }
|
||||||
[ -d "$DST_ROOT/images" ] || { echo "Ziel images fehlt: $DST_ROOT/images"; exit 1; }
|
[ -d "$DST_ROOT/images" ] || { echo "Ziel images fehlt: $DST_ROOT/images"; exit 1; }
|
||||||
[ -d "$DST_ROOT/styles" ] || { echo "Ziel styles fehlt: $DST_ROOT/styles"; exit 1; }
|
[ -d "$DST_ROOT/styles" ] || { echo "Ziel styles fehlt: $DST_ROOT/styles"; exit 1; }
|
||||||
|
|
||||||
|
# Schutz: andere Projekte / DB dürfen nicht angefasst werden
|
||||||
|
[ -d "$DST_ROOT/app-unternehmen" ] && echo "Schutz aktiv: $DST_ROOT/app-unternehmen wird nicht angerührt."
|
||||||
|
[ -d "$DST_ROOT/unternehmen" ] && echo "Schutz aktiv: $DST_ROOT/unternehmen wird nicht angerührt."
|
||||||
|
[ -d "$DST_ROOT/db" ] && echo "Schutz aktiv: $DST_ROOT/db wird nicht angerührt."
|
||||||
|
|
||||||
echo "Synchronisiere app/ ..."
|
echo "Synchronisiere app/ ..."
|
||||||
rsync -av --delete \
|
rsync -av --delete \
|
||||||
--exclude '.DS_Store' \
|
--exclude '.DS_Store' \
|
||||||
@ -28,6 +33,9 @@ rsync -av --delete \
|
|||||||
--exclude 'styles/' \
|
--exclude 'styles/' \
|
||||||
--exclude 'files/' \
|
--exclude 'files/' \
|
||||||
--exclude 'Dockerfile.txt' \
|
--exclude 'Dockerfile.txt' \
|
||||||
|
--exclude 'app-unternehmen/' \
|
||||||
|
--exclude 'unternehmen/' \
|
||||||
|
--exclude 'db/' \
|
||||||
"$SRC_ROOT/app/" "$DST_ROOT/app/"
|
"$SRC_ROOT/app/" "$DST_ROOT/app/"
|
||||||
|
|
||||||
echo "Synchronisiere images/ ..."
|
echo "Synchronisiere images/ ..."
|
||||||
@ -43,9 +51,13 @@ rsync -av --delete \
|
|||||||
--exclude '._*' \
|
--exclude '._*' \
|
||||||
"$SRC_ROOT/styles/" "$DST_ROOT/styles/"
|
"$SRC_ROOT/styles/" "$DST_ROOT/styles/"
|
||||||
|
|
||||||
echo "files/ wird bewusst nicht angefasst."
|
echo "Diese Pfade werden bewusst NICHT angefasst:"
|
||||||
|
echo " - $DST_ROOT/files"
|
||||||
|
echo " - $DST_ROOT/app-unternehmen"
|
||||||
|
echo " - $DST_ROOT/unternehmen"
|
||||||
|
echo " - $DST_ROOT/db"
|
||||||
|
|
||||||
echo "Starte Container manuell neu ..."
|
echo "Starte Container manuell neu ..."
|
||||||
#ssh "${NAS_USER}@${NAS_HOST}" "/usr/bin/docker restart ${CONTAINER_NAME}"
|
# docker restart "${CONTAINER_NAME}"
|
||||||
|
|
||||||
echo "Deployment abgeschlossen."
|
echo "Deployment abgeschlossen."
|
||||||
@ -817,3 +817,121 @@ button {
|
|||||||
.progress-green {
|
.progress-green {
|
||||||
background: #2e7d32;
|
background: #2e7d32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ===============================
|
||||||
|
Home
|
||||||
|
=============================== */
|
||||||
|
.section {
|
||||||
|
margin: 40px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section.alt {
|
||||||
|
background: #f6f8fb;
|
||||||
|
padding: 30px;
|
||||||
|
border-radius: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
background: #fff;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 14px;
|
||||||
|
border: 1px solid #e3e8ef;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-actions {
|
||||||
|
margin-top: 20px;
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-section {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-group {
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-group label {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===============================
|
||||||
|
Footer
|
||||||
|
=============================== */
|
||||||
|
|
||||||
|
.site-footer {
|
||||||
|
margin-top: 60px;
|
||||||
|
padding: 20px 30px;
|
||||||
|
background: #0f172a;
|
||||||
|
color: #cbd5e1;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-inner {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-links {
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-links a {
|
||||||
|
color: #cbd5e1;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-links a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===============================
|
||||||
|
Impressum / Legal
|
||||||
|
=============================== */
|
||||||
|
|
||||||
|
.legal-section {
|
||||||
|
padding: 10px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-section h2 {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-section ul {
|
||||||
|
padding-left: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-footer {
|
||||||
|
margin-top: 40px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #64748b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.responsive-stack {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.responsive-stack {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user