Title: Enhanced System Logs and UI Updates

🎉 New system logs have been implemented for improved monitoring and debugging capabilities. These include:

- admin.log
- admin_api.log
- app.log
- data_management.log
- drucker_steuerung.log
- energy_monitoring.log
- hardware_integration.log
- job_queue_system.log
- monitoring_analytics.log
- permissions.
This commit is contained in:
2025-06-20 00:41:55 +02:00
parent f9b5eafb76
commit 0fcf04833f
73 changed files with 1183 additions and 326 deletions

Binary file not shown.

View File

@ -660,10 +660,18 @@ def advanced_settings():
'time_window': 24
}
# Wartungs-Informationen für das Template
maintenance_info = {
'last_backup': 'Noch kein Backup erstellt',
'log_files_count': '12 Dateien',
'cache_size': '45.2 MB'
}
admin_logger.info(f"Template wird gerendert mit stats: {stats}")
return render_template('admin_advanced_settings.html',
stats=stats,
optimization_settings=optimization_settings,
maintenance_info=maintenance_info,
active_tab='system')
except Exception as e:
@ -689,9 +697,17 @@ def advanced_settings():
'time_window': 24
}
# Fallback-Wartungs-Informationen
maintenance_info = {
'last_backup': 'Fehler beim Laden',
'log_files_count': 'Unbekannt',
'cache_size': 'Unbekannt'
}
return render_template('admin_advanced_settings.html',
stats=stats,
optimization_settings=optimization_settings,
maintenance_info=maintenance_info,
active_tab='system')
@admin_blueprint.route("/system-health")

View File

@ -1388,3 +1388,53 @@
2025-06-20 00:32:10 - [admin] admin - [ERROR] ERROR - Fehler beim Laden des Admin-Dashboards: 'dict object' has no attribute 'online_printers'
2025-06-20 00:32:10 - [admin] admin - [INFO] INFO - Admin-Check für Funktion api_admin_live_stats: User authenticated: True, User ID: 1, Is Admin: True
2025-06-20 00:32:10 - [admin] admin - [INFO] INFO - Admin-Check für Funktion get_system_status_api: User authenticated: True, User ID: 1, Is Admin: True
2025-06-20 00:32:11 - [admin] admin - [INFO] INFO - System-Status abgerufen von admin
2025-06-20 00:32:24 - [admin] admin - [INFO] INFO - Admin-Check für Funktion get_system_status_api: User authenticated: True, User ID: 1, Is Admin: True
2025-06-20 00:32:25 - [admin] admin - [INFO] INFO - System-Status abgerufen von admin
2025-06-20 00:32:33 - [admin] admin - [INFO] INFO - Admin-Check für Funktion logs_overview: User authenticated: True, User ID: 1, Is Admin: True
2025-06-20 00:32:33 - [admin] admin - [INFO] INFO - Logs-Übersicht geladen von admin
2025-06-20 00:32:33 - [admin] admin - [ERROR] ERROR - Fehler beim Laden der Logs-Übersicht: 'dict object' has no attribute 'online_printers'
2025-06-20 00:32:33 - [admin] admin - [INFO] INFO - Admin-Check für Funktion api_admin_live_stats: User authenticated: True, User ID: 1, Is Admin: True
2025-06-20 00:32:33 - [admin] admin - [INFO] INFO - Admin-Check für Funktion get_system_status_api: User authenticated: True, User ID: 1, Is Admin: True
2025-06-20 00:32:34 - [admin] admin - [INFO] INFO - Admin-Check für Funktion get_logs_api: User authenticated: True, User ID: 1, Is Admin: True
2025-06-20 00:32:34 - [admin] admin - [INFO] INFO - Logs abgerufen: 0 Einträge, Level: all
2025-06-20 00:32:34 - [admin] admin - [INFO] INFO - System-Status abgerufen von admin
2025-06-20 00:32:34 - [admin] admin - [INFO] INFO - Admin-Check für Funktion get_logs_api: User authenticated: True, User ID: 1, Is Admin: True
2025-06-20 00:32:34 - [admin] admin - [INFO] INFO - Logs abgerufen: 0 Einträge, Level: all
2025-06-20 00:32:37 - [admin] admin - [INFO] INFO - Admin-Check für Funktion get_logs_api: User authenticated: True, User ID: 1, Is Admin: True
2025-06-20 00:32:37 - [admin] admin - [INFO] INFO - Logs abgerufen: 0 Einträge, Level: all
2025-06-20 00:32:40 - [admin] admin - [INFO] INFO - Admin-Check für Funktion get_logs_api: User authenticated: True, User ID: 1, Is Admin: True
2025-06-20 00:32:40 - [admin] admin - [INFO] INFO - Logs abgerufen: 0 Einträge, Level: all
2025-06-20 00:32:43 - [admin] admin - [INFO] INFO - Admin-Check für Funktion get_logs_api: User authenticated: True, User ID: 1, Is Admin: True
2025-06-20 00:32:43 - [admin] admin - [INFO] INFO - Logs abgerufen: 0 Einträge, Level: all
2025-06-20 00:32:44 - [admin] admin - [INFO] INFO - Admin-Check für Funktion advanced_settings: User authenticated: True, User ID: 1, Is Admin: True
2025-06-20 00:32:44 - [admin] admin - [INFO] INFO - Erweiterte Einstellungen werden geladen von admin
2025-06-20 00:32:44 - [admin] admin - [INFO] INFO - Template wird gerendert mit stats: {'total_users': 3, 'total_printers': 6, 'active_printers': 0, 'total_jobs': 0, 'pending_jobs': 0}
2025-06-20 00:32:44 - [admin] admin - [ERROR] ERROR - Fehler beim Laden der erweiterten Einstellungen: 'maintenance_info' is undefined
2025-06-20 00:32:44 - [admin] admin - [ERROR] ERROR - Traceback: Traceback (most recent call last):
File "/cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend/blueprints/admin_unified.py", line 664, in advanced_settings
return render_template('admin_advanced_settings.html',
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/core/.local/lib/python3.11/site-packages/flask/templating.py", line 152, in render_template
return _render(app, template, context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/core/.local/lib/python3.11/site-packages/flask/templating.py", line 133, in _render
rv = template.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/core/.local/lib/python3.11/site-packages/jinja2/environment.py", line 1301, in render
self.environment.handle_exception()
File "/home/core/.local/lib/python3.11/site-packages/jinja2/environment.py", line 936, in handle_exception
raise rewrite_traceback_stack(source=source)
File "/cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend/templates/admin_advanced_settings.html", line 1, in top-level template code
{% extends "base.html" %}
File "/cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend/templates/base.html", line 450, in top-level template code
{% block content %}{% endblock %}
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend/templates/admin_advanced_settings.html", line 532, in block 'content'
<span class="text-slate-900 dark:text-white font-semibold">{{ maintenance_info.last_backup }}</span>
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/core/.local/lib/python3.11/site-packages/jinja2/environment.py", line 485, in getattr
return getattr(obj, attribute)
^^^^^^^^^^^^^^^^^^^^^^^
jinja2.exceptions.UndefinedError: 'maintenance_info' is undefined

View File

@ -560,3 +560,4 @@
2025-06-20 00:30:01 - [admin_api] admin_api - [INFO] INFO - Live-Statistiken abgerufen von Admin admin
2025-06-20 00:31:52 - [admin_api] admin_api - [INFO] INFO - Live-Statistiken abgerufen von Admin admin
2025-06-20 00:32:10 - [admin_api] admin_api - [INFO] INFO - Live-Statistiken abgerufen von Admin admin
2025-06-20 00:32:33 - [admin_api] admin_api - [INFO] INFO - Live-Statistiken abgerufen von Admin admin

View File

@ -54748,3 +54748,253 @@ WHERE users.role = ?]
2025-06-20 00:32:10 - [app] app - [DEBUG] DEBUG - Response:
2025-06-20 00:32:10 - [app] app - [DEBUG] DEBUG - Response:
2025-06-20 00:32:10 - [app] app - [DEBUG] DEBUG - Request:
2025-06-20 00:32:11 - [app] app - [DEBUG] DEBUG - Response:
2025-06-20 00:32:24 - [app] app - [DEBUG] DEBUG - Request:
2025-06-20 00:32:25 - [app] app - [DEBUG] DEBUG - Response:
2025-06-20 00:32:33 - [app] app - [DEBUG] DEBUG - Request:
2025-06-20 00:32:33 - [app] app - [DEBUG] DEBUG - Response:
2025-06-20 00:32:33 - [app] app - [DEBUG] DEBUG - Request:
2025-06-20 00:32:33 - [app] app - [DEBUG] DEBUG - Request:
2025-06-20 00:32:33 - [app] app - [DEBUG] DEBUG - Response:
2025-06-20 00:32:33 - [app] app - [DEBUG] DEBUG - Response:
2025-06-20 00:32:33 - [app] app - [DEBUG] DEBUG - Request:
2025-06-20 00:32:34 - [app] app - [DEBUG] DEBUG - Request:
2025-06-20 00:32:34 - [app] app - [DEBUG] DEBUG - Response:
2025-06-20 00:32:34 - [app] app - [DEBUG] DEBUG - Response:
2025-06-20 00:32:34 - [app] app - [DEBUG] DEBUG - Request:
2025-06-20 00:32:34 - [app] app - [DEBUG] DEBUG - Response:
2025-06-20 00:32:37 - [app] app - [DEBUG] DEBUG - Request:
2025-06-20 00:32:37 - [app] app - [DEBUG] DEBUG - Response:
2025-06-20 00:32:40 - [app] app - [DEBUG] DEBUG - Request:
2025-06-20 00:32:40 - [app] app - [DEBUG] DEBUG - Response:
2025-06-20 00:32:43 - [app] app - [DEBUG] DEBUG - Request:
2025-06-20 00:32:43 - [app] app - [DEBUG] DEBUG - Response:
2025-06-20 00:32:44 - [app] app - [DEBUG] DEBUG - Request:
2025-06-20 00:32:44 - [app] app - [INFO] INFO - Locating template 'admin_advanced_settings.html':
1: trying loader of application '__main__'
class: jinja2.loaders.FileSystemLoader
encoding: 'utf-8'
followlinks: False
searchpath:
- /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend/templates
-> found ('/cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend/templates/admin_advanced_settings.html')
2025-06-20 00:32:44 - [app] app - [ERROR] ERROR - Unhandled Exception - ID:
2025-06-20 00:32:44 - [app] app - [ERROR] ERROR - URL:
2025-06-20 00:32:44 - [app] app - [ERROR] ERROR - Method:
2025-06-20 00:32:44 - [app] app - [ERROR] ERROR - User:
2025-06-20 00:32:44 - [app] app - [ERROR] ERROR - Exception Type:
2025-06-20 00:32:44 - [app] app - [ERROR] ERROR - Exception:
2025-06-20 00:32:44 - [app] app - [ERROR] ERROR - Traceback:
2025-06-20 00:32:44 - [app] app - [INFO] INFO - Locating template 'errors/500.html':
1: trying loader of application '__main__'
class: jinja2.loaders.FileSystemLoader
encoding: 'utf-8'
followlinks: False
searchpath:
- /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend/templates
-> found ('/cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend/templates/errors/500.html')
2025-06-20 00:32:44 - [app] app - [DEBUG] DEBUG - Response:
2025-06-20 00:32:45 - [app] app - [DEBUG] DEBUG - Request:
2025-06-20 00:32:45 - [app] app - [DEBUG] DEBUG - Response:
2025-06-20 00:33:05 - [app] app - [DEBUG] DEBUG - Request:
2025-06-20 00:33:05 - [app] app - [INFO] INFO - Locating template 'imprint.html':
1: trying loader of application '__main__'
class: jinja2.loaders.FileSystemLoader
encoding: 'utf-8'
followlinks: False
searchpath:
- /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend/templates
-> found ('/cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend/templates/imprint.html')
2025-06-20 00:33:05 - [app] app - [DEBUG] DEBUG - Response:
2025-06-20 00:33:06 - [app] app - [DEBUG] DEBUG - Request:
2025-06-20 00:33:06 - [app] app - [DEBUG] DEBUG - Response:
2025-06-20 00:33:36 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: backend/database/myp.db
2025-06-20 00:33:38 - [app] app - [INFO] INFO - [CONFIG] Erkannte Umgebung:
2025-06-20 00:33:38 - [app] app - [INFO] INFO - [CONFIG] Production-Modus:
2025-06-20 00:33:38 - [app] app - [INFO] INFO - [CONFIG] Verwende Development-Konfiguration
2025-06-20 00:33:38 - [app] app - [INFO] INFO - [DEVELOPMENT] Aktiviere Development-Konfiguration
2025-06-20 00:33:38 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Konfiguration aktiviert
2025-06-20 00:33:38 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Environment:
2025-06-20 00:33:38 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Debug Mode:
2025-06-20 00:33:38 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ SQL Echo:
2025-06-20 00:33:38 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O)
2025-06-20 00:33:38 - [app] app - [INFO] INFO - Admin-Berechtigungen beim Start korrigiert: erstellt, aktualisiert
2025-06-20 00:33:38 - [app] app - [INFO] INFO - [STARTUP] 🚀 Starte MYP -Umgebung
2025-06-20 00:33:38 - [app] app - [INFO] INFO - [STARTUP] 🏢
2025-06-20 00:33:38 - [app] app - [INFO] INFO - [STARTUP] 🔒 Air-Gapped:
2025-06-20 00:33:38 - [app] app - [INFO] INFO - [STARTUP] Initialisiere Datenbank...
2025-06-20 00:33:38 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
2025-06-20 00:33:38 - [app] app - [INFO] INFO - [STARTUP] ✅ Datenbank initialisiert
2025-06-20 00:33:38 - [app] app - [INFO] INFO - [STARTUP] Prüfe Initial-Admin...
2025-06-20 00:33:38 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt.
2025-06-20 00:33:38 - [app] app - [INFO] INFO - [STARTUP] ✅ Admin-Benutzer geprüft
2025-06-20 00:33:38 - [app] app - [INFO] INFO - [STARTUP] Initialisiere statische Drucker...
2025-06-20 00:33:38 - [app] app - [INFO] INFO - Drucker aktualisiert: Drucker 1 (192.168.0.100)
2025-06-20 00:33:38 - [app] app - [INFO] INFO - Drucker aktualisiert: Drucker 2 (192.168.0.101)
2025-06-20 00:33:38 - [app] app - [INFO] INFO - Drucker aktualisiert: Drucker 3 (192.168.0.102)
2025-06-20 00:33:38 - [app] app - [INFO] INFO - Drucker aktualisiert: Drucker 4 (192.168.0.103)
2025-06-20 00:33:38 - [app] app - [INFO] INFO - Drucker aktualisiert: Drucker 5 (192.168.0.104)
2025-06-20 00:33:38 - [app] app - [INFO] INFO - Drucker aktualisiert: Drucker 6 (192.168.0.106)
2025-06-20 00:33:38 - [app] app - [INFO] INFO - ✅ Statische Drucker-Initialisierung abgeschlossen: 0 erstellt, 6 aktualisiert
2025-06-20 00:33:38 - [app] app - [INFO] INFO - 📍 Alle Drucker sind für Standort 'TBA Marienfelde' konfiguriert
2025-06-20 00:33:38 - [app] app - [INFO] INFO - 🌐 IP-Bereich: 192.168.0.100-106 (außer .105)
2025-06-20 00:33:38 - [app] app - [INFO] INFO - [STARTUP] ✅ Statische Drucker konfiguriert
2025-06-20 00:33:38 - [app] app - [INFO] INFO - [STARTUP] Starte Queue Manager...
2025-06-20 00:33:38 - [app] app - [INFO] INFO - [STARTUP] ✅ Queue Manager gestartet
2025-06-20 00:33:38 - [app] app - [INFO] INFO - [STARTUP] Starte Job Scheduler...
2025-06-20 00:33:38 - [app] app - [INFO] INFO - [STARTUP] ✅ Job Scheduler gestartet
2025-06-20 00:33:38 - [app] app - [INFO] INFO - [STARTUP] 🌐 Server startet auf http://:
2025-06-20 00:33:39 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: backend/database/myp.db
2025-06-20 00:33:41 - [app] app - [INFO] INFO - [CONFIG] Erkannte Umgebung:
2025-06-20 00:33:41 - [app] app - [INFO] INFO - [CONFIG] Production-Modus:
2025-06-20 00:33:41 - [app] app - [INFO] INFO - [CONFIG] Verwende Development-Konfiguration
2025-06-20 00:33:41 - [app] app - [INFO] INFO - [DEVELOPMENT] Aktiviere Development-Konfiguration
2025-06-20 00:33:41 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Konfiguration aktiviert
2025-06-20 00:33:41 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Environment:
2025-06-20 00:33:41 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Debug Mode:
2025-06-20 00:33:41 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ SQL Echo:
2025-06-20 00:33:41 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O)
2025-06-20 00:33:41 - [app] app - [INFO] INFO - Admin-Berechtigungen beim Start korrigiert: erstellt, aktualisiert
2025-06-20 00:33:41 - [app] app - [INFO] INFO - [STARTUP] 🚀 Starte MYP -Umgebung
2025-06-20 00:33:41 - [app] app - [INFO] INFO - [STARTUP] 🏢
2025-06-20 00:33:41 - [app] app - [INFO] INFO - [STARTUP] 🔒 Air-Gapped:
2025-06-20 00:33:41 - [app] app - [INFO] INFO - [STARTUP] Initialisiere Datenbank...
2025-06-20 00:33:41 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
2025-06-20 00:33:41 - [app] app - [INFO] INFO - [STARTUP] ✅ Datenbank initialisiert
2025-06-20 00:33:41 - [app] app - [INFO] INFO - [STARTUP] Prüfe Initial-Admin...
2025-06-20 00:33:41 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt.
2025-06-20 00:33:41 - [app] app - [INFO] INFO - [STARTUP] ✅ Admin-Benutzer geprüft
2025-06-20 00:33:41 - [app] app - [INFO] INFO - [STARTUP] Initialisiere statische Drucker...
2025-06-20 00:33:41 - [app] app - [INFO] INFO - Drucker aktualisiert: Drucker 1 (192.168.0.100)
2025-06-20 00:33:41 - [app] app - [INFO] INFO - Drucker aktualisiert: Drucker 2 (192.168.0.101)
2025-06-20 00:33:41 - [app] app - [INFO] INFO - Drucker aktualisiert: Drucker 3 (192.168.0.102)
2025-06-20 00:33:41 - [app] app - [INFO] INFO - Drucker aktualisiert: Drucker 4 (192.168.0.103)
2025-06-20 00:33:41 - [app] app - [INFO] INFO - Drucker aktualisiert: Drucker 5 (192.168.0.104)
2025-06-20 00:33:41 - [app] app - [INFO] INFO - Drucker aktualisiert: Drucker 6 (192.168.0.106)
2025-06-20 00:33:41 - [app] app - [INFO] INFO - ✅ Statische Drucker-Initialisierung abgeschlossen: 0 erstellt, 6 aktualisiert
2025-06-20 00:33:41 - [app] app - [INFO] INFO - 📍 Alle Drucker sind für Standort 'TBA Marienfelde' konfiguriert
2025-06-20 00:33:41 - [app] app - [INFO] INFO - 🌐 IP-Bereich: 192.168.0.100-106 (außer .105)
2025-06-20 00:33:41 - [app] app - [INFO] INFO - [STARTUP] ✅ Statische Drucker konfiguriert
2025-06-20 00:33:41 - [app] app - [INFO] INFO - [STARTUP] Starte Queue Manager...
2025-06-20 00:33:41 - [app] app - [INFO] INFO - [STARTUP] ✅ Queue Manager gestartet
2025-06-20 00:33:41 - [app] app - [INFO] INFO - [STARTUP] Starte Job Scheduler...
2025-06-20 00:33:41 - [app] app - [INFO] INFO - [STARTUP] ✅ Job Scheduler gestartet
2025-06-20 00:33:41 - [app] app - [INFO] INFO - [STARTUP] 🌐 Server startet auf http://:
2025-06-20 00:33:43 - [app] app - [INFO] INFO - Locating template 'imprint.html':
1: trying loader of application '__main__'
class: jinja2.loaders.FileSystemLoader
encoding: 'utf-8'
followlinks: False
searchpath:
- /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend/templates
-> found ('/cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend/templates/imprint.html')
2025-06-20 00:33:43 - [app] app - [INFO] INFO - Locating template 'base.html':
1: trying loader of application '__main__'
class: jinja2.loaders.FileSystemLoader
encoding: 'utf-8'
followlinks: False
searchpath:
- /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend/templates
-> found ('/cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend/templates/base.html')
2025-06-20 00:33:43 - [app] app - [DEBUG] DEBUG - Response:
2025-06-20 00:33:43 - [app] app - [DEBUG] DEBUG - Request:
2025-06-20 00:33:43 - [app] app - [DEBUG] DEBUG - Response:
2025-06-20 00:33:47 - [app] app - [DEBUG] DEBUG - Request:
2025-06-20 00:33:47 - [app] app - [INFO] INFO - Locating template 'dashboard.html':
1: trying loader of application '__main__'
class: jinja2.loaders.FileSystemLoader
encoding: 'utf-8'
followlinks: False
searchpath:
- /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend/templates
-> found ('/cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend/templates/dashboard.html')
2025-06-20 00:33:48 - [app] app - [INFO] INFO - Locating template 'macros/ui_components.html':
1: trying loader of application '__main__'
class: jinja2.loaders.FileSystemLoader
encoding: 'utf-8'
followlinks: False
searchpath:
- /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend/templates
-> found ('/cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend/templates/macros/ui_components.html')
2025-06-20 00:33:48 - [app] app - [DEBUG] DEBUG - Response:
2025-06-20 00:33:48 - [app] app - [DEBUG] DEBUG - Request:
2025-06-20 00:33:48 - [app] app - [DEBUG] DEBUG - Response:
2025-06-20 00:34:18 - [app] app - [DEBUG] DEBUG - Request:
2025-06-20 00:34:18 - [app] app - [DEBUG] DEBUG - Response:
2025-06-20 00:34:44 - [app] app - [DEBUG] DEBUG - Request:
2025-06-20 00:34:47 - [app] app - [INFO] INFO - ✅ Steckdosen-Status geloggt: Drucker 1, Status: disconnected, Quelle: system
2025-06-20 00:34:47 - [app] app - [DEBUG] DEBUG - 📊 Auto-Status protokolliert: Drucker ->
2025-06-20 00:34:48 - [app] app - [DEBUG] DEBUG - Request:
2025-06-20 00:34:48 - [app] app - [DEBUG] DEBUG - Response:
2025-06-20 00:35:44 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: backend/database/myp.db
2025-06-20 00:35:45 - [app] app - [INFO] INFO - [CONFIG] Erkannte Umgebung:
2025-06-20 00:35:45 - [app] app - [INFO] INFO - [CONFIG] Production-Modus:
2025-06-20 00:35:45 - [app] app - [INFO] INFO - [CONFIG] Verwende Development-Konfiguration
2025-06-20 00:35:45 - [app] app - [INFO] INFO - [DEVELOPMENT] Aktiviere Development-Konfiguration
2025-06-20 00:35:45 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Konfiguration aktiviert
2025-06-20 00:35:45 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Environment:
2025-06-20 00:35:45 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Debug Mode:
2025-06-20 00:35:45 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ SQL Echo:
2025-06-20 00:35:45 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O)
2025-06-20 00:35:45 - [app] app - [INFO] INFO - Admin-Berechtigungen beim Start korrigiert: erstellt, aktualisiert
2025-06-20 00:35:45 - [app] app - [INFO] INFO - [STARTUP] 🚀 Starte MYP -Umgebung
2025-06-20 00:35:45 - [app] app - [INFO] INFO - [STARTUP] 🏢
2025-06-20 00:35:45 - [app] app - [INFO] INFO - [STARTUP] 🔒 Air-Gapped:
2025-06-20 00:35:45 - [app] app - [INFO] INFO - [STARTUP] Initialisiere Datenbank...
2025-06-20 00:35:45 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
2025-06-20 00:35:45 - [app] app - [INFO] INFO - [STARTUP] ✅ Datenbank initialisiert
2025-06-20 00:35:45 - [app] app - [INFO] INFO - [STARTUP] Prüfe Initial-Admin...
2025-06-20 00:35:45 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt.
2025-06-20 00:35:45 - [app] app - [INFO] INFO - [STARTUP] ✅ Admin-Benutzer geprüft
2025-06-20 00:35:45 - [app] app - [INFO] INFO - [STARTUP] Initialisiere statische Drucker...
2025-06-20 00:35:45 - [app] app - [INFO] INFO - Drucker aktualisiert: Drucker 1 (192.168.0.100)
2025-06-20 00:35:45 - [app] app - [INFO] INFO - Drucker aktualisiert: Drucker 2 (192.168.0.101)
2025-06-20 00:35:45 - [app] app - [INFO] INFO - Drucker aktualisiert: Drucker 3 (192.168.0.102)
2025-06-20 00:35:45 - [app] app - [INFO] INFO - Drucker aktualisiert: Drucker 4 (192.168.0.103)
2025-06-20 00:35:46 - [app] app - [INFO] INFO - Drucker aktualisiert: Drucker 5 (192.168.0.104)
2025-06-20 00:35:46 - [app] app - [INFO] INFO - Drucker aktualisiert: Drucker 6 (192.168.0.106)
2025-06-20 00:35:46 - [app] app - [INFO] INFO - ✅ Statische Drucker-Initialisierung abgeschlossen: 0 erstellt, 6 aktualisiert
2025-06-20 00:35:46 - [app] app - [INFO] INFO - 📍 Alle Drucker sind für Standort 'TBA Marienfelde' konfiguriert
2025-06-20 00:35:46 - [app] app - [INFO] INFO - 🌐 IP-Bereich: 192.168.0.100-106 (außer .105)
2025-06-20 00:35:46 - [app] app - [INFO] INFO - [STARTUP] ✅ Statische Drucker konfiguriert
2025-06-20 00:35:46 - [app] app - [INFO] INFO - [STARTUP] Starte Queue Manager...
2025-06-20 00:35:46 - [app] app - [INFO] INFO - [STARTUP] ✅ Queue Manager gestartet
2025-06-20 00:35:46 - [app] app - [INFO] INFO - [STARTUP] Starte Job Scheduler...
2025-06-20 00:35:46 - [app] app - [INFO] INFO - [STARTUP] ✅ Job Scheduler gestartet
2025-06-20 00:35:46 - [app] app - [INFO] INFO - [STARTUP] 🌐 Server startet auf http://:
2025-06-20 00:35:46 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: backend/database/myp.db
2025-06-20 00:35:48 - [app] app - [INFO] INFO - [CONFIG] Erkannte Umgebung:
2025-06-20 00:35:48 - [app] app - [INFO] INFO - [CONFIG] Production-Modus:
2025-06-20 00:35:48 - [app] app - [INFO] INFO - [CONFIG] Verwende Development-Konfiguration
2025-06-20 00:35:48 - [app] app - [INFO] INFO - [DEVELOPMENT] Aktiviere Development-Konfiguration
2025-06-20 00:35:48 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Konfiguration aktiviert
2025-06-20 00:35:48 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Environment:
2025-06-20 00:35:48 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Debug Mode:
2025-06-20 00:35:48 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ SQL Echo:
2025-06-20 00:35:48 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O)
2025-06-20 00:35:48 - [app] app - [INFO] INFO - Admin-Berechtigungen beim Start korrigiert: erstellt, aktualisiert
2025-06-20 00:35:48 - [app] app - [INFO] INFO - [STARTUP] 🚀 Starte MYP -Umgebung
2025-06-20 00:35:48 - [app] app - [INFO] INFO - [STARTUP] 🏢
2025-06-20 00:35:48 - [app] app - [INFO] INFO - [STARTUP] 🔒 Air-Gapped:
2025-06-20 00:35:48 - [app] app - [INFO] INFO - [STARTUP] Initialisiere Datenbank...
2025-06-20 00:35:48 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
2025-06-20 00:35:48 - [app] app - [INFO] INFO - [STARTUP] ✅ Datenbank initialisiert
2025-06-20 00:35:48 - [app] app - [INFO] INFO - [STARTUP] Prüfe Initial-Admin...
2025-06-20 00:35:48 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt.
2025-06-20 00:35:48 - [app] app - [INFO] INFO - [STARTUP] ✅ Admin-Benutzer geprüft
2025-06-20 00:35:48 - [app] app - [INFO] INFO - [STARTUP] Initialisiere statische Drucker...
2025-06-20 00:35:48 - [app] app - [INFO] INFO - Drucker aktualisiert: Drucker 1 (192.168.0.100)
2025-06-20 00:35:48 - [app] app - [INFO] INFO - Drucker aktualisiert: Drucker 2 (192.168.0.101)
2025-06-20 00:35:48 - [app] app - [INFO] INFO - Drucker aktualisiert: Drucker 3 (192.168.0.102)
2025-06-20 00:35:48 - [app] app - [INFO] INFO - Drucker aktualisiert: Drucker 4 (192.168.0.103)
2025-06-20 00:35:48 - [app] app - [INFO] INFO - Drucker aktualisiert: Drucker 5 (192.168.0.104)
2025-06-20 00:35:48 - [app] app - [INFO] INFO - Drucker aktualisiert: Drucker 6 (192.168.0.106)
2025-06-20 00:35:48 - [app] app - [INFO] INFO - ✅ Statische Drucker-Initialisierung abgeschlossen: 0 erstellt, 6 aktualisiert
2025-06-20 00:35:48 - [app] app - [INFO] INFO - 📍 Alle Drucker sind für Standort 'TBA Marienfelde' konfiguriert
2025-06-20 00:35:48 - [app] app - [INFO] INFO - 🌐 IP-Bereich: 192.168.0.100-106 (außer .105)
2025-06-20 00:35:48 - [app] app - [INFO] INFO - [STARTUP] ✅ Statische Drucker konfiguriert
2025-06-20 00:35:48 - [app] app - [INFO] INFO - [STARTUP] Starte Queue Manager...
2025-06-20 00:35:48 - [app] app - [INFO] INFO - [STARTUP] ✅ Queue Manager gestartet
2025-06-20 00:35:48 - [app] app - [INFO] INFO - [STARTUP] Starte Job Scheduler...
2025-06-20 00:35:48 - [app] app - [INFO] INFO - [STARTUP] ✅ Job Scheduler gestartet
2025-06-20 00:35:48 - [app] app - [INFO] INFO - [STARTUP] 🌐 Server startet auf http://:

View File

@ -871,3 +871,11 @@
2025-06-20 00:28:43 - [data_management] data_management - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
2025-06-20 00:28:45 - [data_management] data_management - [INFO] INFO - ✅ Data Management Module initialisiert
2025-06-20 00:28:45 - [data_management] data_management - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
2025-06-20 00:33:37 - [data_management] data_management - [INFO] INFO - ✅ Data Management Module initialisiert
2025-06-20 00:33:37 - [data_management] data_management - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
2025-06-20 00:33:40 - [data_management] data_management - [INFO] INFO - ✅ Data Management Module initialisiert
2025-06-20 00:33:40 - [data_management] data_management - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
2025-06-20 00:35:44 - [data_management] data_management - [INFO] INFO - ✅ Data Management Module initialisiert
2025-06-20 00:35:44 - [data_management] data_management - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
2025-06-20 00:35:47 - [data_management] data_management - [INFO] INFO - ✅ Data Management Module initialisiert
2025-06-20 00:35:47 - [data_management] data_management - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)

View File

@ -24,3 +24,7 @@
2025-06-20 00:00:12 - [drucker_steuerung] drucker_steuerung - [INFO] INFO - 🖨️ Drucker-Steuerungs-Blueprint (Backend-Kontrolle) geladen
2025-06-20 00:28:44 - [drucker_steuerung] drucker_steuerung - [INFO] INFO - 🖨️ Drucker-Steuerungs-Blueprint (Backend-Kontrolle) geladen
2025-06-20 00:28:45 - [drucker_steuerung] drucker_steuerung - [INFO] INFO - 🖨️ Drucker-Steuerungs-Blueprint (Backend-Kontrolle) geladen
2025-06-20 00:33:38 - [drucker_steuerung] drucker_steuerung - [INFO] INFO - 🖨️ Drucker-Steuerungs-Blueprint (Backend-Kontrolle) geladen
2025-06-20 00:33:41 - [drucker_steuerung] drucker_steuerung - [INFO] INFO - 🖨️ Drucker-Steuerungs-Blueprint (Backend-Kontrolle) geladen
2025-06-20 00:35:45 - [drucker_steuerung] drucker_steuerung - [INFO] INFO - 🖨️ Drucker-Steuerungs-Blueprint (Backend-Kontrolle) geladen
2025-06-20 00:35:48 - [drucker_steuerung] drucker_steuerung - [INFO] INFO - 🖨️ Drucker-Steuerungs-Blueprint (Backend-Kontrolle) geladen

View File

@ -731,3 +731,7 @@
2025-06-20 00:28:44 - [energy_monitoring] energy_monitoring - [INFO] INFO - ✅ Energiemonitoring-Blueprint initialisiert
2025-06-20 00:28:45 - [energy_monitoring] energy_monitoring - [INFO] INFO - ✅ Energiemonitoring-Blueprint initialisiert
2025-06-20 00:28:54 - [energy_monitoring] energy_monitoring - [INFO] INFO - 🔋 Energiemonitoring-Dashboard aufgerufen von admin
2025-06-20 00:33:38 - [energy_monitoring] energy_monitoring - [INFO] INFO - ✅ Energiemonitoring-Blueprint initialisiert
2025-06-20 00:33:41 - [energy_monitoring] energy_monitoring - [INFO] INFO - ✅ Energiemonitoring-Blueprint initialisiert
2025-06-20 00:35:45 - [energy_monitoring] energy_monitoring - [INFO] INFO - ✅ Energiemonitoring-Blueprint initialisiert
2025-06-20 00:35:48 - [energy_monitoring] energy_monitoring - [INFO] INFO - ✅ Energiemonitoring-Blueprint initialisiert

View File

@ -3421,3 +3421,9 @@
2025-06-20 00:29:04 - [hardware_integration] hardware_integration - [ERROR] ERROR - ❌ Fehler beim Prüfen von Steckdose 192.168.0.103: HTTPConnectionPool(host='192.168.1.101', port=3128): Read timed out. (read timeout=2)
2025-06-20 00:29:07 - [hardware_integration] hardware_integration - [ERROR] ERROR - ❌ Fehler beim Prüfen von Steckdose 192.168.0.104: HTTPConnectionPool(host='192.168.1.101', port=3128): Read timed out. (read timeout=2)
2025-06-20 00:29:09 - [hardware_integration] hardware_integration - [ERROR] ERROR - ❌ Fehler beim Prüfen von Steckdose 192.168.0.106: HTTPConnectionPool(host='192.168.1.101', port=3128): Read timed out. (read timeout=2)
2025-06-20 00:33:37 - [hardware_integration] hardware_integration - [INFO] INFO - 🚀 Hardware Integration (Backend-Kontrolle) erfolgreich geladen
2025-06-20 00:33:40 - [hardware_integration] hardware_integration - [INFO] INFO - 🚀 Hardware Integration (Backend-Kontrolle) erfolgreich geladen
2025-06-20 00:34:45 - [hardware_integration] hardware_integration - [INFO] INFO - 🎯 DruckerSteuerung initialisiert - BACKEND ÜBERNIMMT KONTROLLE
2025-06-20 00:34:47 - [hardware_integration] hardware_integration - [ERROR] ERROR - ❌ Fehler beim Prüfen von Steckdose 192.168.0.100: HTTPConnectionPool(host='192.168.1.101', port=3128): Read timed out. (read timeout=2)
2025-06-20 00:35:44 - [hardware_integration] hardware_integration - [INFO] INFO - 🚀 Hardware Integration (Backend-Kontrolle) erfolgreich geladen
2025-06-20 00:35:46 - [hardware_integration] hardware_integration - [INFO] INFO - 🚀 Hardware Integration (Backend-Kontrolle) erfolgreich geladen

View File

@ -1684,3 +1684,19 @@
2025-06-20 00:28:45 - [job_queue_system] job_queue_system - [INFO] INFO - ✅ Job & Queue System Module initialisiert
2025-06-20 00:28:45 - [job_queue_system] job_queue_system - [INFO] INFO - 📊 MASSIVE Konsolidierung: 4 Dateien → 1 Datei (75% Reduktion)
2025-06-20 00:28:46 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestartet (Legacy-Kompatibilität)
2025-06-20 00:33:18 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestoppt (Legacy-Kompatibilität)
2025-06-20 00:33:18 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestoppt (Legacy-Kompatibilität)
2025-06-20 00:33:37 - [job_queue_system] job_queue_system - [INFO] INFO - ✅ Job & Queue System Module initialisiert
2025-06-20 00:33:37 - [job_queue_system] job_queue_system - [INFO] INFO - 📊 MASSIVE Konsolidierung: 4 Dateien → 1 Datei (75% Reduktion)
2025-06-20 00:33:38 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestartet (Legacy-Kompatibilität)
2025-06-20 00:33:40 - [job_queue_system] job_queue_system - [INFO] INFO - ✅ Job & Queue System Module initialisiert
2025-06-20 00:33:40 - [job_queue_system] job_queue_system - [INFO] INFO - 📊 MASSIVE Konsolidierung: 4 Dateien → 1 Datei (75% Reduktion)
2025-06-20 00:33:41 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestartet (Legacy-Kompatibilität)
2025-06-20 00:34:49 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestoppt (Legacy-Kompatibilität)
2025-06-20 00:34:49 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestoppt (Legacy-Kompatibilität)
2025-06-20 00:35:44 - [job_queue_system] job_queue_system - [INFO] INFO - ✅ Job & Queue System Module initialisiert
2025-06-20 00:35:44 - [job_queue_system] job_queue_system - [INFO] INFO - 📊 MASSIVE Konsolidierung: 4 Dateien → 1 Datei (75% Reduktion)
2025-06-20 00:35:46 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestartet (Legacy-Kompatibilität)
2025-06-20 00:35:47 - [job_queue_system] job_queue_system - [INFO] INFO - ✅ Job & Queue System Module initialisiert
2025-06-20 00:35:47 - [job_queue_system] job_queue_system - [INFO] INFO - 📊 MASSIVE Konsolidierung: 4 Dateien → 1 Datei (75% Reduktion)
2025-06-20 00:35:48 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestartet (Legacy-Kompatibilität)

View File

@ -861,3 +861,11 @@
2025-06-20 00:28:44 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - 📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
2025-06-20 00:28:45 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - ✅ Monitoring & Analytics Module initialisiert
2025-06-20 00:28:45 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - 📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
2025-06-20 00:33:38 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - ✅ Monitoring & Analytics Module initialisiert
2025-06-20 00:33:38 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - 📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
2025-06-20 00:33:41 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - ✅ Monitoring & Analytics Module initialisiert
2025-06-20 00:33:41 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - 📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
2025-06-20 00:35:45 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - ✅ Monitoring & Analytics Module initialisiert
2025-06-20 00:35:45 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - 📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
2025-06-20 00:35:48 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - ✅ Monitoring & Analytics Module initialisiert
2025-06-20 00:35:48 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - 📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)

View File

@ -435,3 +435,7 @@ WHERE users.role = ?]
2025-06-20 00:00:12 - [permissions] permissions - [INFO] INFO - Admin-Berechtigungen korrigiert: 0 erstellt, 0 aktualisiert
2025-06-20 00:28:44 - [permissions] permissions - [INFO] INFO - Admin-Berechtigungen korrigiert: 0 erstellt, 0 aktualisiert
2025-06-20 00:28:45 - [permissions] permissions - [INFO] INFO - Admin-Berechtigungen korrigiert: 0 erstellt, 0 aktualisiert
2025-06-20 00:33:38 - [permissions] permissions - [INFO] INFO - Admin-Berechtigungen korrigiert: 0 erstellt, 0 aktualisiert
2025-06-20 00:33:41 - [permissions] permissions - [INFO] INFO - Admin-Berechtigungen korrigiert: 0 erstellt, 0 aktualisiert
2025-06-20 00:35:45 - [permissions] permissions - [INFO] INFO - Admin-Berechtigungen korrigiert: 0 erstellt, 0 aktualisiert
2025-06-20 00:35:48 - [permissions] permissions - [INFO] INFO - Admin-Berechtigungen korrigiert: 0 erstellt, 0 aktualisiert

View File

@ -2483,3 +2483,15 @@
2025-06-20 00:28:45 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
2025-06-20 00:28:46 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
2025-06-20 00:28:46 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
2025-06-20 00:33:37 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
2025-06-20 00:33:38 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
2025-06-20 00:33:38 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
2025-06-20 00:33:40 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
2025-06-20 00:33:41 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
2025-06-20 00:33:41 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
2025-06-20 00:35:44 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
2025-06-20 00:35:46 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
2025-06-20 00:35:46 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
2025-06-20 00:35:46 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
2025-06-20 00:35:48 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
2025-06-20 00:35:48 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet

View File

@ -1301,3 +1301,15 @@
2025-06-20 00:28:45 - [security_suite] security_suite - [INFO] INFO - ✅ Security Suite Module initialisiert
2025-06-20 00:28:45 - [security_suite] security_suite - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
2025-06-20 00:28:45 - [security_suite] security_suite - [INFO] INFO - 🔒 Security Suite initialisiert
2025-06-20 00:33:37 - [security_suite] security_suite - [INFO] INFO - ✅ Security Suite Module initialisiert
2025-06-20 00:33:37 - [security_suite] security_suite - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
2025-06-20 00:33:38 - [security_suite] security_suite - [INFO] INFO - 🔒 Security Suite initialisiert
2025-06-20 00:33:40 - [security_suite] security_suite - [INFO] INFO - ✅ Security Suite Module initialisiert
2025-06-20 00:33:40 - [security_suite] security_suite - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
2025-06-20 00:33:41 - [security_suite] security_suite - [INFO] INFO - 🔒 Security Suite initialisiert
2025-06-20 00:35:44 - [security_suite] security_suite - [INFO] INFO - ✅ Security Suite Module initialisiert
2025-06-20 00:35:44 - [security_suite] security_suite - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
2025-06-20 00:35:45 - [security_suite] security_suite - [INFO] INFO - 🔒 Security Suite initialisiert
2025-06-20 00:35:47 - [security_suite] security_suite - [INFO] INFO - ✅ Security Suite Module initialisiert
2025-06-20 00:35:47 - [security_suite] security_suite - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
2025-06-20 00:35:48 - [security_suite] security_suite - [INFO] INFO - 🔒 Security Suite initialisiert

View File

@ -3429,3 +3429,31 @@
2025-06-20 00:28:45 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
2025-06-20 00:28:45 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-20T00:28:45.863372
2025-06-20 00:28:45 - [startup] startup - [INFO] INFO - ==================================================
2025-06-20 00:33:38 - [startup] startup - [INFO] INFO - ==================================================
2025-06-20 00:33:38 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
2025-06-20 00:33:38 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
2025-06-20 00:33:38 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
2025-06-20 00:33:38 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
2025-06-20 00:33:38 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-20T00:33:38.177963
2025-06-20 00:33:38 - [startup] startup - [INFO] INFO - ==================================================
2025-06-20 00:33:41 - [startup] startup - [INFO] INFO - ==================================================
2025-06-20 00:33:41 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
2025-06-20 00:33:41 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
2025-06-20 00:33:41 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
2025-06-20 00:33:41 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
2025-06-20 00:33:41 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-20T00:33:41.286656
2025-06-20 00:33:41 - [startup] startup - [INFO] INFO - ==================================================
2025-06-20 00:35:45 - [startup] startup - [INFO] INFO - ==================================================
2025-06-20 00:35:45 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
2025-06-20 00:35:45 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
2025-06-20 00:35:45 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
2025-06-20 00:35:45 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
2025-06-20 00:35:45 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-20T00:35:45.472279
2025-06-20 00:35:45 - [startup] startup - [INFO] INFO - ==================================================
2025-06-20 00:35:48 - [startup] startup - [INFO] INFO - ==================================================
2025-06-20 00:35:48 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
2025-06-20 00:35:48 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
2025-06-20 00:35:48 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
2025-06-20 00:35:48 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
2025-06-20 00:35:48 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-20T00:35:48.069796
2025-06-20 00:35:48 - [startup] startup - [INFO] INFO - ==================================================

View File

@ -1111,3 +1111,11 @@
2025-06-20 00:28:43 - [utilities_collection] utilities_collection - [INFO] INFO - 🚨 ALLERLETZTE MEGA-Konsolidierung: 12+ Dateien → 1 Datei (90%+ Reduktion)
2025-06-20 00:28:45 - [utilities_collection] utilities_collection - [INFO] INFO - ✅ Utilities Collection initialisiert
2025-06-20 00:28:45 - [utilities_collection] utilities_collection - [INFO] INFO - 🚨 ALLERLETZTE MEGA-Konsolidierung: 12+ Dateien → 1 Datei (90%+ Reduktion)
2025-06-20 00:33:36 - [utilities_collection] utilities_collection - [INFO] INFO - ✅ Utilities Collection initialisiert
2025-06-20 00:33:36 - [utilities_collection] utilities_collection - [INFO] INFO - 🚨 ALLERLETZTE MEGA-Konsolidierung: 12+ Dateien → 1 Datei (90%+ Reduktion)
2025-06-20 00:33:39 - [utilities_collection] utilities_collection - [INFO] INFO - ✅ Utilities Collection initialisiert
2025-06-20 00:33:39 - [utilities_collection] utilities_collection - [INFO] INFO - 🚨 ALLERLETZTE MEGA-Konsolidierung: 12+ Dateien → 1 Datei (90%+ Reduktion)
2025-06-20 00:35:44 - [utilities_collection] utilities_collection - [INFO] INFO - ✅ Utilities Collection initialisiert
2025-06-20 00:35:44 - [utilities_collection] utilities_collection - [INFO] INFO - 🚨 ALLERLETZTE MEGA-Konsolidierung: 12+ Dateien → 1 Datei (90%+ Reduktion)
2025-06-20 00:35:46 - [utilities_collection] utilities_collection - [INFO] INFO - ✅ Utilities Collection initialisiert
2025-06-20 00:35:46 - [utilities_collection] utilities_collection - [INFO] INFO - 🚨 ALLERLETZTE MEGA-Konsolidierung: 12+ Dateien → 1 Datei (90%+ Reduktion)

File diff suppressed because one or more lines are too long

View File

@ -1083,6 +1083,208 @@ class AdminDashboard {
}
}
// ===== DIREKTE BENUTZERVERWALTUNGS-FUNKTIONEN =====
async updateUserRole(userId, newRole) {
try {
const response = await fetch(`${this.apiBaseUrl}/api/admin/users/${userId}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': this.csrfToken
},
body: JSON.stringify({ role: newRole })
});
const data = await response.json();
if (data.success) {
this.showNotification(`✅ Rolle erfolgreich aktualisiert`, 'success');
// Seite nach kurzer Zeit neu laden
setTimeout(() => window.location.reload(), 1000);
} else {
this.showNotification(`❌ Fehler: ${data.error}`, 'error');
// Rolle zurücksetzen bei Fehler
const selectElement = document.querySelector(`select[data-user-id="${userId}"]`);
if (selectElement) {
selectElement.value = selectElement.value === 'admin' ? 'user' : 'admin';
}
}
} catch (error) {
console.error('Fehler beim Aktualisieren der Rolle:', error);
this.showNotification('❌ Fehler beim Aktualisieren der Rolle', 'error');
}
}
async toggleUserStatus(userId, isActive) {
try {
const response = await fetch(`${this.apiBaseUrl}/api/admin/users/${userId}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': this.csrfToken
},
body: JSON.stringify({ active: isActive })
});
const data = await response.json();
if (data.success) {
const statusText = isActive ? 'aktiviert' : 'deaktiviert';
this.showNotification(`✅ Benutzer erfolgreich ${statusText}`, 'success');
// Status-Text visuell aktualisieren
const row = document.querySelector(`tr[data-user-id="${userId}"]`);
const statusSpan = row.querySelector('.status-toggle + span');
if (statusSpan) {
statusSpan.textContent = isActive ? 'Aktiv' : 'Inaktiv';
statusSpan.className = `ml-2 text-xs ${isActive ? 'text-green-700 dark:text-green-400' : 'text-red-700 dark:text-red-400'}`;
}
} else {
this.showNotification(`❌ Fehler: ${data.error}`, 'error');
// Checkbox zurücksetzen
const checkbox = document.querySelector(`input[data-user-id="${userId}"].status-toggle`);
if (checkbox) checkbox.checked = !isActive;
}
} catch (error) {
console.error('Fehler beim Ändern des Status:', error);
this.showNotification('❌ Fehler beim Ändern des Status', 'error');
}
}
async updateUserPermission(userId, permission, isEnabled) {
try {
const permissionData = {
[permission]: isEnabled
};
const response = await fetch(`${this.apiBaseUrl}/api/admin/users/${userId}/permissions`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': this.csrfToken
},
body: JSON.stringify(permissionData)
});
const data = await response.json();
if (data.success) {
const permissionNames = {
'can_start_jobs': 'Jobs starten',
'needs_approval': 'Genehmigung erforderlich',
'can_approve_jobs': 'Jobs genehmigen'
};
const actionText = isEnabled ? 'aktiviert' : 'deaktiviert';
this.showNotification(`${permissionNames[permission]} ${actionText}`, 'success');
} else {
this.showNotification(`❌ Fehler: ${data.error}`, 'error');
// Checkbox zurücksetzen
const checkbox = document.querySelector(`input[data-user-id="${userId}"][data-permission="${permission}"]`);
if (checkbox) checkbox.checked = !isEnabled;
}
} catch (error) {
console.error('Fehler beim Aktualisieren der Berechtigung:', error);
this.showNotification('❌ Fehler beim Aktualisieren der Berechtigung', 'error');
}
}
async resetUserPassword(userId, userName) {
if (!confirm(`🔑 Möchten Sie das Passwort für "${userName}" wirklich zurücksetzen?\n\nDem Benutzer wird ein neues temporäres Passwort zugewiesen.`)) {
return;
}
try {
// Temporäres Passwort generieren
const tempPassword = this.generateTempPassword();
const response = await fetch(`${this.apiBaseUrl}/api/admin/users/${userId}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': this.csrfToken
},
body: JSON.stringify({ password: tempPassword })
});
const data = await response.json();
if (data.success) {
// Passwort-Modal anzeigen
this.showPasswordResetModal(userName, tempPassword);
} else {
this.showNotification(`❌ Fehler: ${data.error}`, 'error');
}
} catch (error) {
console.error('Fehler beim Zurücksetzen des Passworts:', error);
this.showNotification('❌ Fehler beim Zurücksetzen des Passworts', 'error');
}
}
generateTempPassword() {
const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789';
let password = '';
for (let i = 0; i < 12; i++) {
password += chars.charAt(Math.floor(Math.random() * chars.length));
}
return password;
}
showPasswordResetModal(userName, tempPassword) {
const modalHtml = `
<div id="password-reset-modal" class="fixed inset-0 bg-black/60 backdrop-blur-sm z-50 flex items-center justify-center p-4">
<div class="bg-white dark:bg-slate-800 rounded-2xl p-8 max-w-md w-full shadow-2xl">
<div class="text-center mb-6">
<div class="w-16 h-16 bg-green-100 dark:bg-green-900/30 rounded-full flex items-center justify-center mx-auto mb-4">
<svg class="w-8 h-8 text-green-600 dark:text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"/>
</svg>
</div>
<h3 class="text-2xl font-bold text-slate-900 dark:text-white">Passwort zurückgesetzt</h3>
<p class="text-slate-600 dark:text-slate-400 mt-2">Neues temporäres Passwort für <strong>${userName}</strong></p>
</div>
<div class="bg-slate-50 dark:bg-slate-700 rounded-xl p-4 mb-6">
<div class="flex items-center justify-between">
<div class="font-mono text-lg font-bold text-slate-900 dark:text-white">${tempPassword}</div>
<button onclick="navigator.clipboard.writeText('${tempPassword}'); this.innerHTML='✓ Kopiert'"
class="px-3 py-1 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors text-sm">
Kopieren
</button>
</div>
</div>
<div class="bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-xl p-4 mb-6">
<p class="text-sm text-yellow-800 dark:text-yellow-200">
<strong>Wichtig:</strong> Teilen Sie dieses Passwort sicher mit dem Benutzer mit und bitten Sie ihn, es sofort zu ändern.
</p>
</div>
<button onclick="document.getElementById('password-reset-modal').remove()"
class="w-full px-6 py-3 bg-green-500 text-white rounded-xl hover:bg-green-600 transition-colors font-medium">
Verstanden
</button>
</div>
</div>
`;
document.body.insertAdjacentHTML('beforeend', modalHtml);
}
async impersonateUser(userId, userName) {
if (!confirm(`👤 Möchten Sie sich als "${userName}" anmelden?\n\nSie können jederzeit zur Admin-Ansicht zurückkehren.`)) {
return;
}
try {
// Impersonation-API implementieren falls gewünscht
this.showNotification('🚧 Impersonation-Feature wird implementiert...', 'info');
} catch (error) {
console.error('Fehler bei der Benutzer-Impersonation:', error);
this.showNotification('❌ Fehler bei der Benutzer-Impersonation', 'error');
}
}
editUser(userId) {
console.log(`✏️ Benutzer ${userId} wird bearbeitet`);
this.showUserModal(userId);

View File

@ -358,80 +358,234 @@ document.addEventListener('DOMContentLoaded', function() {
{% if active_tab == 'users' %}
<!-- Benutzer Tab -->
<div class="p-12">
<div class="flex items-center justify-between mb-6">
<h2 class="text-2xl font-bold text-slate-900 dark:text-white">Benutzerverwaltung</h2>
<button id="add-user-btn" class="inline-flex items-center px-4 py-2 bg-gradient-to-r from-blue-500 to-blue-600 text-white rounded-xl hover:from-blue-600 hover:to-blue-700 transition-all duration-300 shadow-lg hover:shadow-xl">
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"/>
</svg>
Neuer Benutzer
</button>
<div class="p-8">
<!-- Header mit Statistiken -->
<div class="flex items-center justify-between mb-8">
<div>
<h2 class="text-3xl font-bold text-slate-900 dark:text-white mb-2">Granulare Benutzerverwaltung</h2>
<p class="text-slate-600 dark:text-slate-400">Verwalten Sie Benutzer und deren Berechtigungen direkt im Admin Panel</p>
</div>
<div class="flex items-center space-x-4">
<div class="bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-xl px-4 py-2">
<div class="text-sm text-blue-600 dark:text-blue-400">Benutzer gesamt</div>
<div class="text-2xl font-bold text-blue-800 dark:text-blue-300">{{ users|length }}</div>
</div>
<button id="add-user-btn" class="inline-flex items-center px-6 py-3 bg-gradient-to-r from-blue-500 to-blue-600 text-white rounded-xl hover:from-blue-600 hover:to-blue-700 transition-all duration-300 shadow-lg hover:shadow-xl">
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"/>
</svg>
Neuer Benutzer
</button>
</div>
</div>
<!-- Filter und Suche -->
<div class="bg-slate-50 dark:bg-slate-800/50 rounded-xl p-6 mb-8">
<div class="flex flex-wrap items-center justify-between gap-4">
<div class="flex items-center space-x-4">
<div>
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">Suche</label>
<input type="text" id="user-search" placeholder="Benutzer suchen..."
class="px-4 py-2 border border-slate-300 dark:border-slate-600 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent dark:bg-slate-700 dark:text-white">
</div>
<div>
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">Rolle</label>
<select id="role-filter" class="px-4 py-2 border border-slate-300 dark:border-slate-600 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent dark:bg-slate-700 dark:text-white">
<option value="">Alle Rollen</option>
<option value="admin">Administrator</option>
<option value="user">Benutzer</option>
</select>
</div>
<div>
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">Status</label>
<select id="status-filter" class="px-4 py-2 border border-slate-300 dark:border-slate-600 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent dark:bg-slate-700 dark:text-white">
<option value="">Alle Status</option>
<option value="active">Aktiv</option>
<option value="inactive">Inaktiv</option>
</select>
</div>
</div>
<div class="flex items-center space-x-2">
<button id="bulk-actions-btn" class="px-4 py-2 bg-slate-200 dark:bg-slate-600 text-slate-700 dark:text-slate-300 rounded-lg hover:bg-slate-300 dark:hover:bg-slate-500 transition-colors">
Massenaktionen
</button>
<button id="export-users-btn" class="px-4 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 transition-colors">
Export
</button>
</div>
</div>
</div>
<!-- Benutzer Tabelle -->
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-slate-200 dark:divide-slate-700">
<thead class="bg-slate-50 dark:bg-slate-900/50">
<tr>
<th class="px-6 py-3 text-left text-xs font-medium text-slate-500 dark:text-slate-400 uppercase tracking-wider">Benutzer</th>
<th class="px-6 py-3 text-left text-xs font-medium text-slate-500 dark:text-slate-400 uppercase tracking-wider">E-Mail</th>
<th class="px-6 py-3 text-left text-xs font-medium text-slate-500 dark:text-slate-400 uppercase tracking-wider">Rolle</th>
<th class="px-6 py-3 text-left text-xs font-medium text-slate-500 dark:text-slate-400 uppercase tracking-wider">Status</th>
<th class="px-6 py-3 text-left text-xs font-medium text-slate-500 dark:text-slate-400 uppercase tracking-wider">Letzte Aktivität</th>
<th class="px-6 py-3 text-left text-xs font-medium text-slate-500 dark:text-slate-400 uppercase tracking-wider">Aktionen</th>
</tr>
</thead>
<tbody class="bg-white dark:bg-slate-800/50 divide-y divide-slate-200 dark:divide-slate-700">
<!-- Erweiterte Benutzer-Management-Tabelle -->
<div class="bg-white dark:bg-slate-800 rounded-xl shadow-lg overflow-hidden">
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-slate-200 dark:divide-slate-700">
<thead class="bg-slate-50 dark:bg-slate-900/50">
<tr>
<th class="px-6 py-4 text-left">
<input type="checkbox" id="select-all-users" class="rounded border-slate-300 text-blue-600 focus:ring-blue-500">
</th>
<th class="px-6 py-4 text-left text-xs font-medium text-slate-500 dark:text-slate-400 uppercase tracking-wider">Benutzer</th>
<th class="px-6 py-4 text-left text-xs font-medium text-slate-500 dark:text-slate-400 uppercase tracking-wider">Kontakt</th>
<th class="px-6 py-4 text-left text-xs font-medium text-slate-500 dark:text-slate-400 uppercase tracking-wider">Rolle & Status</th>
<th class="px-6 py-4 text-left text-xs font-medium text-slate-500 dark:text-slate-400 uppercase tracking-wider">Berechtigungen</th>
<th class="px-6 py-4 text-left text-xs font-medium text-slate-500 dark:text-slate-400 uppercase tracking-wider">Aktivität</th>
<th class="px-6 py-4 text-left text-xs font-medium text-slate-500 dark:text-slate-400 uppercase tracking-wider">Schnellaktionen</th>
</tr>
</thead>
<tbody class="bg-white dark:bg-slate-800 divide-y divide-slate-200 dark:divide-slate-700" id="users-table-body">
{% for user in users %}
<tr class="hover:bg-slate-50 dark:hover:bg-slate-700/50 transition-colors duration-200">
<tr class="hover:bg-slate-50 dark:hover:bg-slate-700/50 transition-colors duration-200" data-user-id="{{ user.id }}">
<!-- Checkbox -->
<td class="px-6 py-4 whitespace-nowrap">
<input type="checkbox" class="user-checkbox rounded border-slate-300 text-blue-600 focus:ring-blue-500" value="{{ user.id }}">
</td>
<!-- Benutzer Info -->
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
<div class="flex-shrink-0 h-10 w-10">
<div class="h-10 w-10 rounded-full bg-gradient-to-br from-blue-500 to-purple-600 flex items-center justify-center text-white font-semibold">
<div class="flex-shrink-0 h-12 w-12">
<div class="h-12 w-12 rounded-full bg-gradient-to-br from-blue-500 to-purple-600 flex items-center justify-center text-white font-semibold text-lg">
{{ user.username[0].upper() }}
</div>
</div>
<div class="ml-4">
<div class="text-sm font-medium text-slate-900 dark:text-white">{{ user.username }}</div>
<div class="text-sm text-slate-500 dark:text-slate-400">{{ user.name or 'Kein Name' }}</div>
{% if user.department %}
<div class="text-xs text-slate-400 dark:text-slate-500">{{ user.department }}</div>
{% endif %}
</div>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-slate-900 dark:text-white">{{ user.email }}</td>
<!-- Kontakt -->
<td class="px-6 py-4 whitespace-nowrap">
<span class="inline-flex px-2 py-1 text-xs font-semibold rounded-full {{ 'bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200' if user.is_admin else 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200' }}">
{{ 'Administrator' if user.is_admin else 'Benutzer' }}
</span>
<div class="text-sm text-slate-900 dark:text-white">{{ user.email }}</div>
{% if user.phone %}
<div class="text-sm text-slate-500 dark:text-slate-400">{{ user.phone }}</div>
{% endif %}
</td>
<!-- Rolle & Status -->
<td class="px-6 py-4 whitespace-nowrap">
<span class="inline-flex items-center px-2 py-1 text-xs font-semibold rounded-full {{ 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200' if user.is_active else 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200' }}">
<span class="w-2 h-2 mr-1 rounded-full {{ 'bg-green-400' if user.is_active else 'bg-red-400' }}"></span>
{{ 'Aktiv' if user.is_active else 'Inaktiv' }}
</span>
<div class="space-y-2">
<!-- Rolle -->
<div>
<select class="role-select text-xs px-2 py-1 rounded-full border-0 {{ 'bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200' if user.is_admin else 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200' }}"
data-user-id="{{ user.id }}" onchange="updateUserRole({{ user.id }}, this.value)">
<option value="user" {{ 'selected' if not user.is_admin else '' }}>Benutzer</option>
<option value="admin" {{ 'selected' if user.is_admin else '' }}>Administrator</option>
</select>
</div>
<!-- Status Toggle -->
<div>
<label class="inline-flex items-center">
<input type="checkbox" class="status-toggle rounded border-slate-300 text-green-600 focus:ring-green-500"
data-user-id="{{ user.id }}" {{ 'checked' if user.active else '' }}
onchange="toggleUserStatus({{ user.id }}, this.checked)">
<span class="ml-2 text-xs {{ 'text-green-700 dark:text-green-400' if user.active else 'text-red-700 dark:text-red-400' }}">
{{ 'Aktiv' if user.active else 'Inaktiv' }}
</span>
</label>
</div>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-slate-500 dark:text-slate-400">
{{ user.last_login | format_datetime if user.last_login else 'Nie' }}
<!-- Granulare Berechtigungen -->
<td class="px-6 py-4 whitespace-nowrap">
{% if user.is_admin %}
<div class="inline-flex items-center px-3 py-1 rounded-full text-xs font-medium bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200">
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 3l14 9-14 9V3z"/>
</svg>
Alle Rechte
</div>
{% else %}
<div class="space-y-2">
<!-- Jobs starten -->
<div class="flex items-center">
<input type="checkbox" class="permission-toggle rounded border-slate-300 text-blue-600 focus:ring-blue-500"
data-user-id="{{ user.id }}" data-permission="can_start_jobs"
{{ 'checked' if user.permissions and user.permissions.can_start_jobs else '' }}
onchange="updateUserPermission({{ user.id }}, 'can_start_jobs', this.checked)">
<span class="ml-2 text-xs text-slate-600 dark:text-slate-400">Jobs starten</span>
</div>
<!-- Genehmigung erforderlich -->
<div class="flex items-center">
<input type="checkbox" class="permission-toggle rounded border-slate-300 text-yellow-600 focus:ring-yellow-500"
data-user-id="{{ user.id }}" data-permission="needs_approval"
{{ 'checked' if user.permissions and user.permissions.needs_approval else '' }}
onchange="updateUserPermission({{ user.id }}, 'needs_approval', this.checked)">
<span class="ml-2 text-xs text-slate-600 dark:text-slate-400">Benötigt Genehmigung</span>
</div>
<!-- Jobs genehmigen -->
<div class="flex items-center">
<input type="checkbox" class="permission-toggle rounded border-slate-300 text-green-600 focus:ring-green-500"
data-user-id="{{ user.id }}" data-permission="can_approve_jobs"
{{ 'checked' if user.permissions and user.permissions.can_approve_jobs else '' }}
onchange="updateUserPermission({{ user.id }}, 'can_approve_jobs', this.checked)">
<span class="ml-2 text-xs text-slate-600 dark:text-slate-400">Jobs genehmigen</span>
</div>
</div>
{% endif %}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
<div class="flex space-x-2">
<button class="edit-user-btn text-blue-600 hover:text-blue-900 dark:text-blue-400 dark:hover:text-blue-300 transition-colors" data-user-id="{{ user.id }}" title="Benutzer bearbeiten">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<!-- Aktivität -->
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-slate-900 dark:text-white">
{% if user.last_login %}
Letzte Anmeldung:
<div class="text-xs text-slate-500 dark:text-slate-400">{{ user.last_login.strftime('%d.%m.%Y %H:%M') if user.last_login else 'Nie' }}</div>
{% else %}
<span class="text-slate-500 dark:text-slate-400">Nie angemeldet</span>
{% endif %}
</div>
{% if user.last_activity %}
<div class="text-xs text-slate-400 dark:text-slate-500 mt-1">
Aktivität: {{ user.last_activity.strftime('%d.%m.%Y %H:%M') }}
</div>
{% endif %}
</td>
<!-- Schnellaktionen -->
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center space-x-2">
<!-- Benutzer bearbeiten -->
<button class="edit-user-btn text-blue-600 hover:text-blue-900 dark:text-blue-400 dark:hover:text-blue-300 transition-colors p-1 rounded"
data-user-id="{{ user.id }}" title="Benutzer bearbeiten">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
</svg>
</button>
{% if not user.is_admin %}
<button class="permissions-user-btn text-green-600 hover:text-green-900 dark:text-green-400 dark:hover:text-green-300 transition-colors" data-user-id="{{ user.id }}" data-user-name="{{ user.username }}" title="Berechtigungen verwalten">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/>
<!-- Passwort zurücksetzen -->
<button class="reset-password-btn text-orange-600 hover:text-orange-900 dark:text-orange-400 dark:hover:text-orange-300 transition-colors p-1 rounded"
data-user-id="{{ user.id }}" data-user-name="{{ user.username }}" title="Passwort zurücksetzen">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"/>
</svg>
</button>
<!-- Als Benutzer anmelden (Impersonation) -->
{% if not user.is_admin and current_user.is_admin %}
<button class="impersonate-user-btn text-purple-600 hover:text-purple-900 dark:text-purple-400 dark:hover:text-purple-300 transition-colors p-1 rounded"
data-user-id="{{ user.id }}" data-user-name="{{ user.username }}" title="Als Benutzer anmelden">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
</svg>
</button>
{% endif %}
<button class="delete-user-btn text-red-600 hover:text-red-900 dark:text-red-400 dark:hover:text-red-300 transition-colors" data-user-id="{{ user.id }}" data-user-name="{{ user.username }}" title="Benutzer löschen">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<!-- Benutzer löschen -->
{% if user.id != current_user.id %}
<button class="delete-user-btn text-red-600 hover:text-red-900 dark:text-red-400 dark:hover:text-red-300 transition-colors p-1 rounded"
data-user-id="{{ user.id }}" data-user-name="{{ user.username }}" title="Benutzer löschen">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
</svg>
</button>
{% endif %}
</div>
</td>
</tr>

View File

@ -1,300 +1,374 @@
{% extends "base.html" %}
{% block title %}Impressum - Mercedes-Benz MYP{% endblock %}
{% block extra_css %}
<style>
body {
background: var(--bg-primary);
}
.clean-card {
background: var(--bg-card);
border: 1px solid var(--border-primary);
border-radius: 12px;
padding: 2rem;
margin-bottom: 2rem;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.hero-section {
background: linear-gradient(135deg, var(--mb-black) 0%, var(--mb-primary) 100%);
color: white;
padding: 4rem 0;
margin-bottom: 3rem;
}
.mercedes-logo {
width: 60px;
height: 60px;
background: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 1.5rem;
}
.info-table {
width: 100%;
border-collapse: collapse;
}
.info-table td {
padding: 0.75rem 0;
border-bottom: 1px solid var(--border-primary);
vertical-align: top;
}
.info-table td:first-child {
font-weight: 600;
color: var(--text-secondary);
width: 140px;
padding-right: 1rem;
}
.info-table td:last-child {
color: var(--text-primary);
}
.info-table tr:last-child td {
border-bottom: none;
}
.section-title {
font-size: 1.5rem;
font-weight: 700;
color: var(--text-primary);
margin-bottom: 1.5rem;
border-bottom: 2px solid var(--mb-primary);
padding-bottom: 0.5rem;
}
.link-style {
color: var(--mb-primary);
text-decoration: none;
font-weight: 500;
}
.link-style:hover {
text-decoration: underline;
}
.project-box {
background: linear-gradient(135deg, rgba(0, 115, 206, 0.05) 0%, rgba(0, 115, 206, 0.1) 100%);
border-left: 4px solid var(--mb-primary);
padding: 1.5rem;
border-radius: 0 8px 8px 0;
margin: 2rem 0;
}
.nav-buttons {
display: flex;
gap: 1rem;
flex-wrap: wrap;
justify-content: center;
margin-top: 2rem;
}
@media (max-width: 768px) {
.hero-section {
padding: 2rem 0;
}
.clean-card {
padding: 1.5rem;
margin-bottom: 1.5rem;
}
.info-table td:first-child {
width: 120px;
font-size: 0.9rem;
}
.nav-buttons {
flex-direction: column;
align-items: center;
}
}
</style>
{% endblock %}
{% block title %}Impressum - Mercedes-Benz TBA Marienfelde{% endblock %}
{% block content %}
<!-- Simple Hero -->
<div class="hero-section">
<div class="container mx-auto px-6 text-center">
<div class="mercedes-logo">
<svg class="w-8 h-8 text-black" fill="currentColor" viewBox="0 0 80 80">
<path d="M58.6,4.5C53,1.6,46.7,0,40,0c-6.7,0-13,1.6-18.6,4.5v0C8.7,11.2,0,24.6,0,40c0,15.4,8.7,28.8,21.5,35.5C27,78.3,33.3,80,40,80c6.7,0,12.9-1.7,18.5-4.6C71.3,68.8,80,55.4,80,40C80,24.6,71.3,11.2,58.6,4.5z M4,40c0-13.1,7-24.5,17.5-30.9v0C26.6,6,32.5,4.2,39,4l-4.5,32.7L21.5,46.8v0L8.3,57.1C5.6,52,4,46.2,4,40z M58.6,70.8C53.1,74.1,46.8,76,40,76c-6.8,0-13.2-1.9-18.6-5.2c-4.9-2.9-8.9-6.9-11.9-11.7l11.9-4.9v0L40,46.6l18.6,7.5v0l12,4.9C67.6,63.9,63.4,67.9,58.6,70.8z M58.6,46.8L58.6,46.8l-12.9-10L41.1,4c6.3,0.2,12.3,2,17.4,5.1v0C69,15.4,76,26.9,76,40c0,6.2-1.5,12-4.3,17.1L58.6,46.8z"/>
</svg>
</div>
<h1 class="text-4xl font-bold mb-4">Impressum</h1>
<p class="text-xl opacity-90">Rechtliche Angaben gemäß § 5 TMG</p>
</div>
</div>
<div class="container mx-auto px-6 max-w-4xl pb-12">
<!-- Modernes Admin Panel Design für Impressum -->
<div class="min-h-screen">
<!-- Anbieter -->
<div class="clean-card">
<h2 class="section-title">Anbieter</h2>
<!-- Hero Header mit Gradient Background (nach Admin-Vorbild) -->
<div class="relative overflow-hidden bg-gradient-to-r from-slate-900 via-blue-900 to-indigo-900 text-white rounded-3xl mx-4 mt-4">
<div class="absolute inset-0 bg-black/20"></div>
<div class="absolute inset-0 bg-gradient-to-r from-transparent via-white/5 to-transparent"></div>
<div class="grid md:grid-cols-2 gap-8">
<div>
<table class="info-table">
<tr>
<td>Unternehmen</td>
<td>Mercedes-Benz AG</td>
</tr>
<tr>
<td>Abteilung</td>
<td>Technische Berufsausbildung (TBA)</td>
</tr>
<tr>
<td>Standort</td>
<td>Marienfelde, Berlin</td>
</tr>
<tr>
<td>Bereich</td>
<td>Digitale Fertigung & 3D-Druck</td>
</tr>
</table>
</div>
<div>
<table class="info-table">
<tr>
<td>Adresse</td>
<td>
Daimlerstraße 1<br>
12277 Berlin<br>
Deutschland
</td>
</tr>
<tr>
<td>Website</td>
<td><a href="https://www.mercedes-benz.com" target="_blank" class="link-style">mercedes-benz.com</a></td>
</tr>
<tr>
<td>Telefon</td>
<td><a href="tel:+493075668000" class="link-style">+49 (0) 30 7566-8000</a></td>
</tr>
</table>
<!-- Live Status Indicator -->
<div class="absolute top-4 right-4 flex items-center space-x-2">
<div class="bg-white/10 backdrop-blur-sm border border-white/20 rounded-full px-3 py-1">
<span class="text-sm font-medium">Rechtliche Angaben</span>
</div>
</div>
</div>
<!-- Projektverantwortlicher -->
<div class="clean-card">
<h2 class="section-title">Projektverantwortlicher</h2>
<div class="grid md:grid-cols-2 gap-8">
<div>
<table class="info-table">
<tr>
<td>Name</td>
<td>Till Tomczak</td>
</tr>
<tr>
<td>Position</td>
<td>Fachinformatiker für digitale Vernetzung</td>
</tr>
<tr>
<td>Projekt</td>
<td>IHK-Projektarbeit: MYP System</td>
</tr>
<tr>
<td>Status</td>
<td>Auszubildender</td>
</tr>
</table>
</div>
<div>
<table class="info-table">
<tr>
<td>E-Mail</td>
<td><a href="mailto:till.tomczak@mercedes-benz.com" class="link-style">till.tomczak@mercedes-benz.com</a></td>
</tr>
<tr>
<td>Ausbildung</td>
<td>Mercedes-Benz AG - TBA Marienfelde</td>
</tr>
<tr>
<td>Zweck</td>
<td>Interne Systemschulung & 3D-Druck Management</td>
</tr>
</table>
</div>
<!-- Animated Background Pattern -->
<div class="absolute inset-0 opacity-10 rounded-3xl overflow-hidden">
<div class="absolute inset-0" style="background-image: radial-gradient(circle at 25% 25%, white 2px, transparent 2px), radial-gradient(circle at 75% 75%, white 2px, transparent 2px); background-size: 50px 50px;"></div>
</div>
</div>
<!-- Projekt Info -->
<div class="project-box">
<h3 class="text-xl font-bold mb-3" style="color: var(--text-primary);">MYP Platform - Das Projekt</h3>
<p style="color: var(--text-secondary);">
Das <strong>MYP System (Manage Your Printers)</strong> wurde als IHK-Projektarbeit für die Ausbildung zum
Fachinformatiker für digitale Vernetzung entwickelt. Es dient der zentralen Verwaltung von 3D-Druckern
in der Mercedes-Benz TBA Marienfelde mit Smart-Plug-Integration und Energiemonitoring.
</p>
</div>
<!-- Rechtliche Angaben -->
<div class="clean-card">
<h2 class="section-title">Rechtliche Angaben</h2>
<div class="grid md:grid-cols-2 gap-8">
<div>
<table class="info-table">
<tr>
<td>Registergericht</td>
<td>Amtsgericht Stuttgart</td>
</tr>
<tr>
<td>Handelsregister</td>
<td>HRB 19360</td>
</tr>
<tr>
<td>USt-IdNr.</td>
<td>DE811944017</td>
</tr>
<tr>
<td>Steuernummer</td>
<td>99073/00159</td>
</tr>
</table>
</div>
<div>
<h4 class="font-semibold mb-3" style="color: var(--text-primary);">Vorstand Mercedes-Benz AG</h4>
<div style="color: var(--text-secondary);">
<p>Ola Källenius <span style="color: var(--text-muted);">(Vorsitzender)</span></p>
<p>Jörg Burzer</p>
<p>Renata Jungo Brüngger</p>
<p>Sabine Kohleisen</p>
<p>Harald Wilhelm</p>
<div class="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
<div class="text-center">
<!-- Mercedes-Benz Logo -->
<div class="inline-flex items-center justify-center w-20 h-20 bg-white/10 backdrop-blur-sm rounded-full mb-6 border border-white/20">
<svg class="w-10 h-10 text-white" viewBox="0 0 80 80" fill="currentColor">
<path d="M58.6,4.5C53,1.6,46.7,0,40,0c-6.7,0-13,1.6-18.6,4.5v0C8.7,11.2,0,24.6,0,40c0,15.4,8.7,28.8,21.5,35.5
C27,78.3,33.3,80,40,80c6.7,0,12.9-1.7,18.5-4.6C71.3,68.8,80,55.4,80,40C80,24.6,71.3,11.2,58.6,4.5z M4,40
c0-13.1,7-24.5,17.5-30.9v0C26.6,6,32.5,4.2,39,4l-4.5,32.7L21.5,46.8v0L8.3,57.1C5.6,52,4,46.2,4,40z M58.6,70.8
C53.1,74.1,46.8,76,40,76c-6.8,0-13.2-1.9-18.6-5.2c-4.9-2.9-8.9-6.9-11.9-11.7l11.9-4.9v0L40,46.6l18.6,7.5v0l12,4.9
C67.6,63.9,63.4,67.9,58.6,70.8z M58.6,46.8L58.6,46.8l-12.9-10L41.1,4c6.3,0.2,12.3,2,17.4,5.1v0C69,15.4,76,26.9,76,40
c0,6.2-1.5,12-4.3,17.1L58.6,46.8z"/>
</svg>
</div>
<h1 class="text-5xl md:text-6xl font-bold mb-4 tracking-tight">
<span class="bg-gradient-to-r from-white to-blue-200 bg-clip-text text-transparent">
Impressum
</span>
</h1>
<p class="text-xl md:text-2xl text-blue-100 max-w-3xl mx-auto leading-relaxed">
Rechtliche Angaben gemäß § 5 TMG für das MYP System der TBA Marienfelde
</p>
<!-- Real-Time Quick Actions -->
<div class="flex flex-wrap justify-center gap-4 mt-8">
<button class="inline-flex items-center px-6 py-3 bg-white/10 backdrop-blur-sm border border-white/20 rounded-xl text-white hover:bg-white/20 transition-all duration-300 hover:scale-105">
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/>
</svg>
DSGVO Konform
</button>
<button class="inline-flex items-center px-6 py-3 bg-white/10 backdrop-blur-sm border border-white/20 rounded-xl text-white hover:bg-white/20 transition-all duration-300 hover:scale-105">
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.746 0 3.332.477 4.5 1.253v13C20.832 18.477 19.246 18 17.5 18c-1.746 0-3.332.477-4.5 1.253"/>
</svg>
§ 5 TMG
</button>
</div>
</div>
</div>
</div>
<!-- Navigation -->
<div class="clean-card">
<div class="nav-buttons">
<a href="{{ url_for('index') }}" class="btn-primary">Zur Startseite</a>
<a href="{{ url_for('legal.privacy') }}" class="btn-success">Datenschutz</a>
<a href="{{ url_for('legal.legal') }}" class="btn-secondary">Rechtliche Hinweise</a>
{% if current_user.is_authenticated %}
<a href="{{ url_for('dashboard') }}" class="btn-secondary">Dashboard</a>
{% endif %}
<!-- Content Grid mit Glassmorphism Cards -->
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
<!-- Anbieter Section -->
<div class="bg-white/60 dark:bg-slate-900/60 backdrop-blur-xl border border-slate-200/50 dark:border-slate-700/50 rounded-3xl p-8 mb-8 shadow-xl">
<div class="flex items-center mb-6">
<div class="w-12 h-12 bg-gradient-to-r from-blue-500 to-indigo-600 rounded-xl flex items-center justify-center mr-4">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-4m-5 0H9m0 0H5m4 0V9a2 2 0 012-2h2a2 2 0 012 2v12"/>
</svg>
</div>
<h2 class="text-3xl font-bold text-slate-900 dark:text-white">Anbieter</h2>
</div>
<div class="grid md:grid-cols-2 gap-8">
<div class="space-y-6">
<div class="bg-white/40 dark:bg-slate-800/40 backdrop-blur-sm rounded-2xl p-6 border border-slate-200/30 dark:border-slate-700/30">
<h3 class="text-lg font-semibold text-slate-900 dark:text-white mb-4">Unternehmen</h3>
<div class="space-y-3">
<div class="flex justify-between items-center">
<span class="text-slate-600 dark:text-slate-400">Firma:</span>
<span class="font-medium text-slate-900 dark:text-white">Mercedes-Benz AG</span>
</div>
<div class="flex justify-between items-center">
<span class="text-slate-600 dark:text-slate-400">Abteilung:</span>
<span class="font-medium text-slate-900 dark:text-white">TBA Marienfelde</span>
</div>
<div class="flex justify-between items-center">
<span class="text-slate-600 dark:text-slate-400">Bereich:</span>
<span class="font-medium text-slate-900 dark:text-white">3D-Druck Management</span>
</div>
</div>
</div>
</div>
<div class="space-y-6">
<div class="bg-white/40 dark:bg-slate-800/40 backdrop-blur-sm rounded-2xl p-6 border border-slate-200/30 dark:border-slate-700/30">
<h3 class="text-lg font-semibold text-slate-900 dark:text-white mb-4">Kontakt</h3>
<div class="space-y-3">
<div class="flex justify-between items-center">
<span class="text-slate-600 dark:text-slate-400">Adresse:</span>
<div class="text-right">
<div class="font-medium text-slate-900 dark:text-white">Daimlerstraße 1</div>
<div class="font-medium text-slate-900 dark:text-white">12277 Berlin</div>
</div>
</div>
<div class="flex justify-between items-center">
<span class="text-slate-600 dark:text-slate-400">Website:</span>
<a href="https://www.mercedes-benz.com" target="_blank" class="font-medium text-blue-600 dark:text-blue-400 hover:underline">mercedes-benz.com</a>
</div>
<div class="flex justify-between items-center">
<span class="text-slate-600 dark:text-slate-400">Telefon:</span>
<a href="tel:+493075668000" class="font-medium text-blue-600 dark:text-blue-400 hover:underline">+49 (0) 30 7566-8000</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Footer -->
<div class="text-center py-6" style="color: var(--text-muted);">
<p class="text-sm">
Letzte Aktualisierung: 19.06.2025 | Mercedes-Benz AG TBA Marienfelde | MYP Platform v3.0.0
</p>
<!-- Projektverantwortlicher Section -->
<div class="bg-white/60 dark:bg-slate-900/60 backdrop-blur-xl border border-slate-200/50 dark:border-slate-700/50 rounded-3xl p-8 mb-8 shadow-xl">
<div class="flex items-center mb-6">
<div class="w-12 h-12 bg-gradient-to-r from-emerald-500 to-teal-600 rounded-xl flex items-center justify-center mr-4">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
</svg>
</div>
<h2 class="text-3xl font-bold text-slate-900 dark:text-white">Projektverantwortlicher</h2>
</div>
<div class="grid md:grid-cols-2 gap-8">
<div class="space-y-6">
<div class="bg-white/40 dark:bg-slate-800/40 backdrop-blur-sm rounded-2xl p-6 border border-slate-200/30 dark:border-slate-700/30">
<h3 class="text-lg font-semibold text-slate-900 dark:text-white mb-4">Person</h3>
<div class="space-y-3">
<div class="flex justify-between items-center">
<span class="text-slate-600 dark:text-slate-400">Name:</span>
<span class="font-medium text-slate-900 dark:text-white">Till Tomczak</span>
</div>
<div class="flex justify-between items-center">
<span class="text-slate-600 dark:text-slate-400">Position:</span>
<span class="font-medium text-slate-900 dark:text-white">Fachinformatiker</span>
</div>
<div class="flex justify-between items-center">
<span class="text-slate-600 dark:text-slate-400">Status:</span>
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-blue-100 dark:bg-blue-900/30 text-blue-800 dark:text-blue-200">
Auszubildender
</span>
</div>
</div>
</div>
</div>
<div class="space-y-6">
<div class="bg-white/40 dark:bg-slate-800/40 backdrop-blur-sm rounded-2xl p-6 border border-slate-200/30 dark:border-slate-700/30">
<h3 class="text-lg font-semibold text-slate-900 dark:text-white mb-4">Projekt</h3>
<div class="space-y-3">
<div class="flex justify-between items-center">
<span class="text-slate-600 dark:text-slate-400">E-Mail:</span>
<a href="mailto:till.tomczak@mercedes-benz.com" class="font-medium text-blue-600 dark:text-blue-400 hover:underline">till.tomczak@mercedes-benz.com</a>
</div>
<div class="flex justify-between items-center">
<span class="text-slate-600 dark:text-slate-400">Projekt:</span>
<span class="font-medium text-slate-900 dark:text-white">IHK-Projektarbeit</span>
</div>
<div class="flex justify-between items-center">
<span class="text-slate-600 dark:text-slate-400">Zweck:</span>
<span class="font-medium text-slate-900 dark:text-white">3D-Druck Management</span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- MYP Projekt Highlight -->
<div class="bg-gradient-to-r from-blue-50 via-indigo-50 to-purple-50 dark:from-slate-900 dark:via-blue-900/20 dark:to-indigo-900/20 rounded-3xl p-8 mb-8 border border-blue-200/50 dark:border-blue-700/30 relative overflow-hidden">
<div class="absolute inset-0 bg-gradient-to-r from-blue-500/10 to-indigo-500/10 dark:from-blue-400/5 dark:to-indigo-400/5"></div>
<div class="relative">
<div class="flex items-center mb-6">
<div class="w-16 h-16 bg-gradient-to-r from-blue-600 to-indigo-600 rounded-2xl flex items-center justify-center mr-6">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19.428 15.428a2 2 0 00-1.022-.547l-2.387-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z"/>
</svg>
</div>
<div>
<h2 class="text-3xl font-bold text-slate-900 dark:text-white mb-2">MYP Platform</h2>
<p class="text-lg text-slate-600 dark:text-slate-400">Manage Your Printers - 3D-Druck Management System</p>
</div>
</div>
<div class="prose prose-lg max-w-none">
<p class="text-slate-700 dark:text-slate-300 leading-relaxed">
Das <strong class="text-slate-900 dark:text-white">MYP System (Manage Your Printers)</strong> wurde als IHK-Projektarbeit für die Ausbildung zum
Fachinformatiker für digitale Vernetzung entwickelt. Es dient der zentralen Verwaltung von 3D-Druckern
in der Mercedes-Benz TBA Marienfelde mit Smart-Plug-Integration, Energiemonitoring und modernem Dashboard.
</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mt-8">
<div class="flex items-center space-x-3 bg-white/50 dark:bg-slate-800/50 backdrop-blur-sm rounded-xl p-4">
<div class="w-10 h-10 bg-green-500 rounded-lg flex items-center justify-center">
<svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</div>
<div>
<div class="font-semibold text-slate-900 dark:text-white">Smart Integration</div>
<div class="text-sm text-slate-600 dark:text-slate-400">TP-Link Tapo Steuerung</div>
</div>
</div>
<div class="flex items-center space-x-3 bg-white/50 dark:bg-slate-800/50 backdrop-blur-sm rounded-xl p-4">
<div class="w-10 h-10 bg-blue-500 rounded-lg flex items-center justify-center">
<svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/>
</svg>
</div>
<div>
<div class="font-semibold text-slate-900 dark:text-white">Energy Monitor</div>
<div class="text-sm text-slate-600 dark:text-slate-400">Echtzeit Verbrauch</div>
</div>
</div>
<div class="flex items-center space-x-3 bg-white/50 dark:bg-slate-800/50 backdrop-blur-sm rounded-xl p-4">
<div class="w-10 h-10 bg-purple-500 rounded-lg flex items-center justify-center">
<svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 100-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 100-4m0 4v2m0-6V4"/>
</svg>
</div>
<div>
<div class="font-semibold text-slate-900 dark:text-white">Modern Dashboard</div>
<div class="text-sm text-slate-600 dark:text-slate-400">Real-Time Updates</div>
</div>
</div>
</div>
</div>
</div>
<!-- Rechtliche Angaben Section -->
<div class="bg-white/60 dark:bg-slate-900/60 backdrop-blur-xl border border-slate-200/50 dark:border-slate-700/50 rounded-3xl p-8 mb-8 shadow-xl">
<div class="flex items-center mb-6">
<div class="w-12 h-12 bg-gradient-to-r from-amber-500 to-orange-600 rounded-xl flex items-center justify-center mr-4">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/>
</svg>
</div>
<h2 class="text-3xl font-bold text-slate-900 dark:text-white">Rechtliche Angaben</h2>
</div>
<div class="grid md:grid-cols-2 gap-8">
<div class="space-y-6">
<div class="bg-white/40 dark:bg-slate-800/40 backdrop-blur-sm rounded-2xl p-6 border border-slate-200/30 dark:border-slate-700/30">
<h3 class="text-lg font-semibold text-slate-900 dark:text-white mb-4">Handelsregister</h3>
<div class="space-y-3">
<div class="flex justify-between items-center">
<span class="text-slate-600 dark:text-slate-400">Registergericht:</span>
<span class="font-medium text-slate-900 dark:text-white">Amtsgericht Stuttgart</span>
</div>
<div class="flex justify-between items-center">
<span class="text-slate-600 dark:text-slate-400">Handelsregister:</span>
<span class="font-medium text-slate-900 dark:text-white">HRB 19360</span>
</div>
<div class="flex justify-between items-center">
<span class="text-slate-600 dark:text-slate-400">USt-IdNr.:</span>
<span class="font-medium text-slate-900 dark:text-white">DE811944017</span>
</div>
<div class="flex justify-between items-center">
<span class="text-slate-600 dark:text-slate-400">Steuernummer:</span>
<span class="font-medium text-slate-900 dark:text-white">99073/00159</span>
</div>
</div>
</div>
</div>
<div class="space-y-6">
<div class="bg-white/40 dark:bg-slate-800/40 backdrop-blur-sm rounded-2xl p-6 border border-slate-200/30 dark:border-slate-700/30">
<h3 class="text-lg font-semibold text-slate-900 dark:text-white mb-4">Vorstand Mercedes-Benz AG</h3>
<div class="space-y-2">
<div class="flex items-center justify-between">
<span class="font-medium text-slate-900 dark:text-white">Ola Källenius</span>
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-blue-100 dark:bg-blue-900/30 text-blue-800 dark:text-blue-200">
Vorsitzender
</span>
</div>
<div class="text-slate-700 dark:text-slate-300">Jörg Burzer</div>
<div class="text-slate-700 dark:text-slate-300">Renata Jungo Brüngger</div>
<div class="text-slate-700 dark:text-slate-300">Sabine Kohleisen</div>
<div class="text-slate-700 dark:text-slate-300">Harald Wilhelm</div>
</div>
</div>
</div>
</div>
</div>
<!-- Navigation Actions -->
<div class="bg-white/60 dark:bg-slate-900/60 backdrop-blur-xl border border-slate-200/50 dark:border-slate-700/50 rounded-3xl p-8 mb-8 shadow-xl">
<div class="flex items-center mb-6">
<div class="w-12 h-12 bg-gradient-to-r from-violet-500 to-purple-600 rounded-xl flex items-center justify-center mr-4">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"/>
</svg>
</div>
<h2 class="text-3xl font-bold text-slate-900 dark:text-white">Navigation</h2>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<a href="{{ url_for('index') }}" class="inline-flex items-center justify-center px-6 py-3 bg-white/10 backdrop-blur-sm border border-white/20 rounded-xl text-slate-900 dark:text-white hover:bg-white/20 dark:hover:bg-slate-700/50 transition-all duration-300 hover:scale-105 group">
<svg class="w-5 h-5 mr-2 group-hover:scale-110 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"/>
</svg>
Startseite
</a>
<a href="{{ url_for('legal.privacy') }}" class="inline-flex items-center justify-center px-6 py-3 bg-white/10 backdrop-blur-sm border border-white/20 rounded-xl text-slate-900 dark:text-white hover:bg-white/20 dark:hover:bg-slate-700/50 transition-all duration-300 hover:scale-105 group">
<svg class="w-5 h-5 mr-2 group-hover:scale-110 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"/>
</svg>
Datenschutz
</a>
<a href="{{ url_for('legal.legal') }}" class="inline-flex items-center justify-center px-6 py-3 bg-white/10 backdrop-blur-sm border border-white/20 rounded-xl text-slate-900 dark:text-white hover:bg-white/20 dark:hover:bg-slate-700/50 transition-all duration-300 hover:scale-105 group">
<svg class="w-5 h-5 mr-2 group-hover:scale-110 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.746 0 3.332.477 4.5 1.253v13C20.832 18.477 19.246 18 17.5 18c-1.746 0-3.332.477-4.5 1.253"/>
</svg>
Rechtliches
</a>
{% if current_user.is_authenticated %}
<a href="{{ url_for('dashboard') }}" class="inline-flex items-center justify-center px-6 py-3 bg-white/10 backdrop-blur-sm border border-white/20 rounded-xl text-slate-900 dark:text-white hover:bg-white/20 dark:hover:bg-slate-700/50 transition-all duration-300 hover:scale-105 group">
<svg class="w-5 h-5 mr-2 group-hover:scale-110 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
</svg>
Dashboard
</a>
{% endif %}
</div>
</div>
<!-- Footer mit Live Update -->
<div class="text-center py-8 border-t border-slate-200/50 dark:border-slate-700/50">
<div class="bg-white/30 dark:bg-slate-800/30 backdrop-blur-sm rounded-2xl p-6 inline-block">
<div class="flex items-center justify-center space-x-4 text-slate-600 dark:text-slate-400">
<div class="flex items-center space-x-2">
<div class="w-2 h-2 bg-green-400 rounded-full animate-pulse"></div>
<span class="text-sm font-medium">Live System</span>
</div>
<div class="w-px h-4 bg-slate-300 dark:bg-slate-600"></div>
<div class="text-sm">
Letzte Aktualisierung: <span class="font-medium">19.06.2025</span>
</div>
<div class="w-px h-4 bg-slate-300 dark:bg-slate-600"></div>
<div class="text-sm">
Mercedes-Benz AG TBA Marienfelde
</div>
<div class="w-px h-4 bg-slate-300 dark:bg-slate-600"></div>
<div class="text-sm">
MYP Platform <span class="font-mono font-semibold">v3.0.0</span>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}