🌟 🎉 Major Update:

This commit is contained in:
Till Tomczak 2025-06-01 23:41:02 +02:00
parent 62efe03887
commit 4042f07c00
228 changed files with 8598 additions and 1893 deletions

657
README.md
View File

@ -1,376 +1,395 @@
# MYP Reservation Platform
# MYP Druckerverwaltungssystem
Mercedes-Benz Werk 040 Berlin - 3D-Drucker Reservierungsplattform
**Manage Your Printer** - Mercedes-Benz Werk 040 Berlin
Vollständige 3D-Drucker Verwaltungsplattform mit Smart-Plug-Technologie
## 🎯 System-Übersicht
**MYP (Manage Your Printer)** ist ein System zur **zentralen Verwaltung und Steuerung von 3D-Druckern mittels Smart-Plug-Technologie**. Es digitalisiert den Reservierungsprozess für mehrere 3D-Drucker und ermögligt eine **automatisierte Schaltung der Drucker über WLAN-Steckdosen (TP-Link Tapo P110)**.
### 🔑 Kernfunktionen
#### **Benutzer- und Rechteverwaltung**
- **Registrierung, Login und Rollenkonzept** (Admin/Benutzer)
- **Administrierende** können Drucker und Nutzer verwalten
- **Standard-Benutzer** können Reservierungen anlegen und Druckjobs verwalten
#### **Drucker- und Auftragsmanagement**
- **Zentrales Reservierungssystem** für Zeitfenster-Buchungen
- **Automatische Drucker-Schaltung**: Einschalten zum Reservierungsstart, Ausschalten nach Ende
- **Herstellerunabhängig**: Keine direkte Kommunikation mit 3D-Druckern - ausschließlich Stromsteuerung über Smart-Plug-Steckdosen
- **Einfache Integration**: Keine Eingriffe in die Druckerhardware erforderlich
#### **Statistikerfassung**
- **Protokollierung** von Nutzungszeiten und abgeschlossenen Druckaufträgen
- **Auswertungen** (z.B. Gesamtdruckzeit pro Zeitraum)
- **Analytics-Dashboard** für Effizienzanalysen
#### **Offline-Fähigkeit & Kiosk-Modus**
- **Autonomer Betrieb** ohne Internetzugang nach Installation
- **Raspberry Pi Kiosk-Modus**: Vollbild-Dashboard vor Ort
- **Touch-Interface** für aktuelle Druckerbelegungen und Systemstatus
## 📋 Projektarchitektur
Dieses Repository enthält **zwei sich ergänzende Projektarbeiten** für die IHK-Abschlussprüfung:
### 🏗️ **Backend-System** (Till Tomczak) - **KERN-INFRASTRUKTUR**
- **Entwickler**: Till Tomczak
- **Fachrichtung**: Fachinformatiker für digitale Vernetzung
- **Technologie**: **Flask-basiertes Backend in Python** mit **SQLite-Datenbank**
- **Verantwortung**: Hardware-Integration, REST-APIs und cyber-physische Vernetzung
### 📊 **Frontend-System** (Torben Haack) - **BENUTZEROBERFLÄCHE & ANALYTICS**
- **Entwickler**: Torben Haack
- **Fachrichtung**: Fachinformatiker für Daten- und Prozessanalyse
- **Technologie**: **Next.js-basierte Webanwendung** mit erweiterten Analytics
- **Verantwortung**: Moderne Web-UI, Datenvisualisierung und Benutzerfreundlichkeit
## 🏗️ Technische Architektur
### Cyber-Physische Lösung
```
┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐
│ Frontend-Server │◄──►│ Backend-Server │◄──►│ Raspberry Pi │
│ (Port 3000) │ │ (Port 443/5000) │ │ (Smart-Plugs) │
│ Torben Haack │ │ Till Tomczak │ │ Till Tomczak │
│ │ │ │ │ │
│ • Next.js App │ │ • Flask REST-API │ │ • TP-Link Tapo P110 │
│ • Analytics UI │ │ • SQLite Database │ │ • Hardware Control │
│ • PWA-Features │ │ • Smart-Plug API │ │ • Kiosk Interface │
│ • HTTPS Client │ │ • HTTPS Server │ │ • Offline Operation │
│ • Export Functions │ │ • Session Management│ │ • Touch Interface │
└─────────────────────┘ └─────────────────────┘ └─────────────────────┘
```
### Kommunikations-Architektur
- **RESTful API**: Backend kommuniziert mit Frontend und externen Diensten
- **HTTPS-Verschlüsselung**: Selbstsignierte Zertifikate für sichere Übertragung
- **Progressive Web App (PWA)**: Offline-Funktionalität im Browser
- **Smart-Plug-Integration**: Lokale WLAN-Steuerung ohne Cloud-Abhängigkeit
## 🚀 Schnellstart
### MYP Control Center (Empfohlen)
Das zentrale Installationssystem für alle Komponenten:
### Backend-System (Hardware & APIs)
```bash
# Repository klonen
git clone <repository-url>
cd Projektarbeit-MYP
# Backend-Server starten (Till Tomczaks System)
cd backend
sudo ./setup.sh # Automatische Installation
python app.py # Oder für Development
# MYP Control Center starten
./myp_installer.sh
# Kiosk-Modus auf Raspberry Pi
sudo systemctl start myp-https.service
```
Das MYP Control Center bietet:
- **Schnellstart-Installationen** (Vollständig, Backend-Only, Entwicklung)
- **Produktions-Installer** (Integration der v3.2 install.sh Funktionalität)
- **Granulare Installation** (Einzelne Komponenten)
- **System & Wartung** (Tests, Status, Informationen)
### Direkter Produktions-Installer
Für schnelle Produktions-Deployments direkt im MYP Control Center → Option 4:
```bash
./myp_installer.sh
# → Wähle Option 4: Produktions-Installer
# → Backend installieren (Raspberry Pi)
# → Frontend installieren (Docker)
```
### Voraussetzungen
- **Backend (Raspberry Pi)**: Python 3.11, systemd
- **Frontend (m040tbaraspi001)**: Docker, Docker Compose
## 🌐 Zugriff
- **Frontend**: https://m040tbaraspi001.de040.corpintra.net
- **Backend API**: https://raspberrypi/api
## 🔧 Konfiguration
### Netzwerk
| Komponente | Hostname | IP | Port |
|------------|----------|----|----- |
| Frontend | m040tbaraspi001.de040.corpintra.net | 192.168.0.109 | 443 |
| Backend | raspberrypi | 192.168.0.105 | 443 |
### TLS-Zertifikate
Selbstsignierte Zertifikate werden automatisch generiert:
- Backend: `backend/app/certs/`
- Frontend: `frontend/certs/`
## 📊 Health Checks
```bash
# Backend
curl -k https://raspberrypi/api/test
# Frontend
curl -k https://m040tbaraspi001.de040.corpintra.net/health
```
## 🛠️ Entwicklung
### MYP Control Center (Entwicklungs-Setup)
```bash
./myp_installer.sh
# → Option 3: Entwicklungs-Setup
```
### MYP Kiosk-Modus (Produktions-bereit)
Das Backend bietet parallel zur API auch ein **vollständiges Web-Interface** für Kiosk-Betrieb:
```bash
./myp_installer.sh
# → Option 2: Backend-Only Installation (mit Kiosk Web Interface)
# oder
# → Option 5: Granulare Installation → Kiosk-Modus installieren
```
**Kiosk-Features:**
- ✅ **Web-Interface parallel zur API** - Kein separates Frontend nötig
- ✅ **Touch-optimierte Bedienung** - Ideal für Raspberry Pi Touchscreens
- ✅ **Automatischer Browser-Start** - Vollbild-Modus beim Boot
- ✅ **systemd Integration** - Service-basierte Kiosk-Verwaltung
- ✅ **Produktions-bereit** - SSL, Logging, Monitoring
**Kiosk URLs:**
- Hauptinterface: `https://raspberrypi/`
- Dashboard: `https://raspberrypi/dashboard`
- Drucker-Verwaltung: `https://raspberrypi/printers`
- Job-Verwaltung: `https://raspberrypi/jobs`
- Admin-Panel: `https://raspberrypi/admin`
### Manuelle Installation
#### Backend Debug-Modus
```bash
cd backend/app
python3.11 app.py --debug
```
#### Frontend Development
### Frontend-System (Web-Interface)
```bash
# Frontend-Server starten (Torben Haacks System)
cd frontend
npm run dev
pnpm install
pnpm db # Datenbank einrichten
pnpm dev # Development-Server
# Produktions-Deployment
pnpm build && pnpm start
```
#### Kiosk-Modus manuell starten
### Vollständiges System
```bash
# Backend starten
cd backend/app && python app.py
# Backend (API-Server)
cd backend && python app.py --host 0.0.0.0 --port 5000 &
# Kiosk-Browser starten (separates Terminal)
./backend/app/start_kiosk.sh
# Frontend (Web-Interface)
cd frontend && pnpm build && pnpm start &
```
## 📁 Projektstruktur
## 🌐 Systemzugriff
### Produktions-URLs
- **Web-Interface**: `http://localhost:3000` (Torben Haacks Frontend)
- **API-Backend**: `https://192.168.0.105:443/api` (Till Tomczaks APIs auf separatem Server)
- **Kiosk-Modus**: `https://192.168.0.105:443` (Lokales Touch-Interface)
### Standard-Anmeldedaten
- **Benutzername**: `admin`
- **Passwort**: `admin123`
### Netzwerk-Konfiguration
- **Backend-Server**: `192.168.0.105:443` (HTTPS)
- **Frontend-Server**: `localhost:3000` (HTTP Development)
- **SSL-Zertifikate**: Selbstsigniert (automatisch akzeptiert)
## 📁 Projektstruktur & Integration
```
Projektarbeit-MYP/
├── myp_installer.sh # 🎯 HAUPT-INSTALLER (Control Center)
├── backend/
│ ├── app/
│ │ ├── certs/ # TLS-Zertifikate
│ │ ├── database/ # SQLite-Datenbank
│ │ ├── logs/ # Anwendungslogs
│ │ └── app.py # Hauptanwendung
│ ├── myp.service # systemd Service
│ ├── requirements.txt # Python-Abhängigkeiten
│ └── legacy_setup_raspberry_pi.sh # Legacy Skript
├── frontend/
│ ├── certs/ # TLS-Zertifikate
│ ├── docker/
│ │ ├── caddy/
│ │ │ └── Caddyfile # Reverse Proxy Konfiguration
│ │ └── legacy_deploy.sh # Legacy Skript
│ ├── src/ # Next.js Anwendung
│ └── docker-compose.yml
├── scripts/
│ └── legacy_generate_certs.sh # Legacy Skript
├── archiv/
│ └── myp_installer_legacy.sh # Archivierte Version
└── docs/ # Dokumentation
├── backend/ # 🏗️ KERN-INFRASTRUKTUR (Till Tomczak)
│ ├── app.py # Flask REST-API Server
│ ├── models.py # SQLite-Datenbank & Business Logic
│ ├── utils/ # Smart-Plug Integration (TP-Link Tapo P110)
│ ├── templates/ # Kiosk-Mode Web-Interface
│ ├── static/ # PWA-Assets für Offline-Betrieb
│ └── systemd/ # Raspberry Pi Service-Integration
├──
├── frontend/ # 📊 WEB-INTERFACE (Torben Haack)
│ ├── src/app/ # Next.js Haupt-Anwendung
│ ├── src/components/ # React UI-Komponenten
│ ├── src/lib/api/ # Backend-REST-API-Integration
│ └── src/lib/analytics/ # Statistik-Algorithmen
├──
├── docs/ # 📚 Gemeinsame Dokumentation
└── README.md # Diese Datei
```
### Script-Status
## 🎯 Funktions-Aufgabenteilung
| Skript | Status | Verwendung |
|--------|--------|------------|
| `myp_installer.sh` | ✅ **AKTIV** | Haupt-Control-Center |
| `*legacy_*.sh` | 📦 Legacy | Historische Versionen |
| `archiv/myp_installer_legacy.sh` | 📦 Archiv | Alte Version 4.0 |
### Backend-Verantwortlichkeiten (Till Tomczak)
- ✅ **Smart-Plug-Steuerung**: TP-Link Tapo P110 WLAN-Steckdosen
- ✅ **Automatische Drucker-Schaltung**: Zeitgesteuerte Ein-/Ausschaltung
- ✅ **REST-API-Bereitstellung**: Vollständige API für alle Drucker-Operationen
- ✅ **Cyber-physische Vernetzung**: IT-System ↔ Hardware-Integration
- ✅ **SQLite-Datenbank**: Benutzer, Drucker, Jobs, Statistiken
- ✅ **HTTPS-Server**: Selbstsignierte Zertifikate und Session-Management
- ✅ **Raspberry Pi Integration**: Systemd-Services und Kiosk-Modus
- ✅ **Offline-Fähigkeit**: Autonomer Betrieb ohne Internet
## 🔒 Sicherheit
### Frontend-Verantwortlichkeiten (Torben Haack)
- ✅ **Moderne Web-UI**: React-basierte Benutzeroberfläche
- ✅ **Progressive Web App**: Offline-Funktionalität im Browser
- ✅ **Advanced Analytics**: Interaktive Charts und Datenvisualisierung
- ✅ **Reporting-System**: PDF/Excel-Export und automatisierte Berichte
- ✅ **Responsive Design**: Optimiert für Desktop, Tablet und Mobile
- ✅ **Backend-API-Integration**: Nahtlose REST-API-Anbindung
- ✅ **Statistik-Auswertungen**: Nutzungsanalysen und Trend-Analysen
- ✅ **Benutzerfreundlichkeit**: Intuitive Workflows für alle Stakeholder
- HTTPS-only (Port 443)
- Selbstsignierte TLS-Zertifikate
- HTTP → HTTPS Redirect
- Security Headers (HSTS, CSP, etc.)
## 🔗 API-Integration & Kommunikation
## 📝 Logs
### Backend-REST-Endpunkte (Till Tomczak)
```typescript
// Drucker-Management
GET /api/printers // Alle Drucker abrufen
POST /api/printers // Neuen Drucker hinzufügen
PUT /api/printers/{id} // Drucker aktualisieren
DELETE /api/printers/{id} // Drucker löschen
### Backend
// Reservierungs-Management
GET /api/jobs // Alle Reservierungen abrufen
POST /api/jobs // Neue Reservierung erstellen
PUT /api/jobs/{id}/finish // Reservierung beenden
DELETE /api/jobs/{id} // Reservierung abbrechen
// Smart-Plug-Steuerung (TP-Link Tapo P110)
POST /api/plugs/{id}/on // Drucker einschalten
POST /api/plugs/{id}/off // Drucker ausschalten
GET /api/plugs/{id}/status // Plug-Status abfragen
// Statistiken & Analytics
GET /api/stats // Nutzungsstatistiken
GET /api/reports // Report-Daten für Analytics
```
### Frontend-Integration (Torben Haack)
```typescript
// Backend-API Client - Konfiguriert für separaten Server
export class MYPApiClient {
constructor(baseURL: string = 'https://192.168.0.105:443/api') {
this.baseURL = baseURL;
}
async getPrinters() {
return fetch(`${this.baseURL}/printers`).then(r => r.json());
}
async getJobs() {
return fetch(`${this.baseURL}/jobs`).then(r => r.json());
}
async getStats() {
return fetch(`${this.baseURL}/stats`).then(r => r.json());
}
}
// API-Konfiguration mit Fallback-URLs
export const API_BASE_URL = {
primary: 'https://192.168.0.105:443',
fallbacks: [
'https://192.168.0.105',
'https://raspberrypi'
]
};
```
## 🖥️ Deployment-Szenarien
### Szenario 1: Separate Server (Empfohlen)
```bash
# systemd Journal
sudo journalctl -u myp.service -f
# Backend-Server (z.B. Raspberry Pi oder Linux-Server)
cd backend
sudo systemctl start myp-https.service
# Anwendungslogs
tail -f backend/app/logs/app/app.log
# Frontend-Server (z.B. Node.js-Server oder Cloud-Deployment)
cd frontend
npm run build && npm start
```
### Frontend
### Szenario 2: Docker-Deployment
```yaml
# docker-compose.yml
services:
backend:
build: ./backend
ports: ["5000:5000", "443:443"]
frontend:
build: ./frontend
ports: ["3000:3000"]
environment:
- NEXT_PUBLIC_API_URL=http://backend:5000/api
```
### Szenario 3: Raspberry Pi Kiosk (Lokal)
```bash
# Docker Logs
docker-compose logs -f
# Caddy Logs
docker-compose logs caddy
# Vollständige Kiosk-Installation
cd backend && sudo ./setup.sh
# Automatischer Start: Touch-Interface + Smart-Plug-Steuerung
```
### Kiosk-Modus
## 🔧 Konfiguration & Environment
### Backend-Konfiguration (.env)
```env
# Flask-Server Einstellungen
FLASK_HOST=0.0.0.0
FLASK_PORT=5000
SSL_ENABLED=true
DATABASE_URL=sqlite:///myp.db
# Smart-Plug Konfiguration (TP-Link Tapo P110)
TAPO_USERNAME=your-tapo-email
TAPO_PASSWORD=your-tapo-password
# Kiosk-Modus
KIOSK_MODE=true
OFFLINE_MODE=true
```
### Frontend-Konfiguration (.env.local)
```env
# Frontend-Server Einstellungen - Separater Backend-Server
NEXT_PUBLIC_API_URL=https://192.168.0.105:443
DATABASE_URL=file:./db/frontend.db
# SSL-Zertifikat Handling für selbstsignierte Zertifikate
NODE_TLS_REJECT_UNAUTHORIZED=0
# Analytics-Features
ENABLE_ADVANCED_ANALYTICS=true
CHART_REFRESH_INTERVAL=30000
```
## 📊 Features im Überblick
### Backend-Features (Till Tomczak) - Cyber-Physische Integration
- **TP-Link Tapo P110 Integration**: Lokale WLAN-Steckdosen-Steuerung
- **Automatische Zeitsteuerung**: Drucker Ein-/Ausschaltung nach Reservierung
- **Herstellerunabhängigkeit**: Keine direkten Drucker-Eingriffe erforderlich
- **Flask REST-APIs**: Vollständige CRUD-Operationen
- **SQLite-Datenbank**: Lokale Datenpersistenz ohne externe Abhängigkeiten
- **HTTPS-Verschlüsselung**: Selbstsignierte Zertifikate
- **Offline-Betrieb**: Vollständig autonomer Betrieb ohne Internet
- **Raspberry Pi Kiosk**: Touch-optimiertes Dashboard vor Ort
### Frontend-Features (Torben Haack) - Moderne Web-Oberfläche
- **Progressive Web App**: Offline-Funktionalität im Browser
- **React 18 + Next.js 14**: Moderne, performante Web-Technologien
- **Analytics-Dashboard**: Recharts-Visualisierungen für Nutzungsstatistiken
- **Responsive Design**: Optimiert für alle Endgeräte (Desktop/Tablet/Mobile)
- **Real-time Updates**: Live-Synchronisation mit Backend-APIs
- **Export-Funktionen**: PDF/Excel-Reports für Management-Analysen
- **Benutzerfreundlich**: Intuitive Workflows für alle Stakeholder
## 🛠️ Entwicklung
### Backend-Entwicklung (Till Tomczak)
```bash
# Backend Service
sudo systemctl status myp.service
# Kiosk-Browser Service
sudo systemctl status myp-kiosk-browser.service
# Kiosk-Browser Logs
sudo journalctl -u myp-kiosk-browser.service -f
cd backend
python -m venv venv
source venv/bin/activate # Linux/Mac
pip install -r requirements.txt
python app.py --debug
```
## 🔧 Services
### Backend Services
### Frontend-Entwicklung (Torben Haack)
```bash
# Backend starten/stoppen
sudo systemctl start myp.service
sudo systemctl stop myp.service
sudo systemctl restart myp.service
# Kiosk-Browser starten/stoppen (falls installiert)
sudo systemctl start myp-kiosk-browser.service
sudo systemctl stop myp-kiosk-browser.service
# Automatischen Start aktivieren/deaktivieren
sudo systemctl enable myp.service
sudo systemctl enable myp-kiosk-browser.service
cd frontend
pnpm install
pnpm db:migrate
pnpm dev
```
## 🆘 Troubleshooting
### MYP Control Center verwenden
### Integration testen
```bash
./myp_installer.sh
# → Option 6: Systemvoraussetzungen prüfen
# → Option 7: Anwendung starten
# Backend-APIs testen
curl http://localhost:5000/api/printers
# Frontend mit Backend-Integration
# Frontend auf :3000 konsumiert Backend-APIs von :5000
```
### Backend startet nicht
```bash
# Service Status prüfen
sudo systemctl status myp.service
## 📚 Dokumentation
# Logs prüfen
sudo journalctl -u myp.service --no-pager
### Backend-Dokumentation (Till Tomczak)
- [`backend/README.md`](backend/README.md) - Hardware-Setup & API-Dokumentation
- [`backend/docs/`](backend/docs/) - Raspberry Pi Konfiguration & Smart-Plug-Integration
# Zertifikate prüfen
ls -la backend/app/certs/
```
### Frontend-Dokumentation (Torben Haack)
- [`frontend/README.md`](frontend/README.md) - UI-Entwicklung & Analytics
- [`frontend/docs/`](frontend/docs/) - Component-Library & PWA-Features
### Frontend nicht erreichbar
```bash
# Container Status prüfen
docker-compose ps
### Gemeinsame Dokumentation
- [`docs/myp_documentation.md`](docs/myp_documentation.md) - Vollständige Projektdokumentation
- [`docs/DEPLOYMENT.md`](docs/DEPLOYMENT.md) - Production-Deployment-Guide
# Netzwerk prüfen
docker network ls
## 🤝 Projektphilosophie
# Zertifikate prüfen
ls -la frontend/certs/
```
### Cyber-Physische Vernetzung
MYP stellt eine **cyber-physische Lösung** dar, die **IT-System (Reservierungsplattform) und Hardware (Smart-Plugs und Drucker) eng vernetzt**. Das System überbrückt die digitale und physische Welt durch intelligente Automatisierung.
### Verbindungsprobleme
```bash
# DNS auflösen
nslookup raspberrypi
nslookup m040tbaraspi001.de040.corpintra.net
### Komplementäre Expertisen
- **Till Tomczak**: Spezialist für Hardware-Integration und cyber-physische Vernetzung
- **Torben Haack**: Spezialist für Frontend-Entwicklung und Datenanalyse
# Ports prüfen
netstat -tlnp | grep :443
```
### Gemeinsame Ziele
- **Digitalisierung**: Modernisierung des Reservierungsprozesses
- **Automatisierung**: Zeitgesteuerte Hardware-Steuerung ohne manuelle Eingriffe
- **Benutzerfreundlichkeit**: Intuitive Bedienung für alle Stakeholder
- **Effizienz**: Optimierte Ressourcennutzung und Energieeinsparung
## 📋 Version
## 👥 Entwicklerteam
- **Version**: 3.2-final
- **Control Center**: v4.0 mit v3.2 Integration
- **Build**: Production
- **Installer**: MYP Control Center
### Till Tomczak - **Backend-Infrastruktur & Hardware-Integration**
- **Cyber-Physische Systeme**: Smart-Plug-Integration und Hardware-Steuerung
- **System-Architektur**: Flask-APIs und SQLite-Datenbank-Design
- **DevOps**: Raspberry Pi Services und Produktions-Deployment
- **Offline-Systeme**: Autonomer Betrieb ohne Internet-Abhängigkeiten
## 👥 Support
### Torben Haack - **Frontend-Entwicklung & Analytics**
- **Progressive Web Apps**: Moderne Browser-Technologien und Offline-Features
- **User Interface**: React-Komponenten und responsive Design
- **Datenvisualisierung**: Charts, Dashboards und Analytics
- **API-Integration**: Nahtlose Backend-Anbindung und Real-time Updates
Bei Problemen verwenden Sie das MYP Control Center oder wenden Sie sich an das IT-Team des Mercedes-Benz Werk 040 Berlin.
## 📄 Lizenz
## 🖥️ Zwei-Server-Setup (Produktions-Architektur)
Dieses Projekt wurde für den internen Gebrauch bei Mercedes-Benz entwickelt.
Das MYP-System ist für eine **Zwei-Server-Architektur** optimiert:
---
### Server-Architektur
| Server | Hostname | Komponenten | URL |
|--------|----------|-------------|-----|
| **Frontend-Server** | `m040tbaraspi001.de040.corpintra.net` | Next.js + Docker + Caddy | `https://m040tbaraspi001.de040.corpintra.net` |
| **Backend-Server** | `raspberrypi` | Flask API + Web Interface + Kiosk | `https://raspberrypi` |
### 🚀 Server-spezifische Installation (Empfohlen)
Der `myp_installer.sh` erkennt automatisch den Server-Typ und bietet passende Installationsoptionen:
```bash
./myp_installer.sh
# Wählen Sie: "1. Server-spezifische Installation (Empfohlen)"
```
#### Frontend-Server (m040tbaraspi001)
```bash
# Automatische Erkennung: m040tbaraspi001.de040.corpintra.net
# Verfügbare Optionen:
# 1. Frontend installieren (Next.js + Docker)
# 2. Frontend Produktions-Deployment (Port 443 mit SSL)
# 3. Nur Docker & Dependencies installieren
```
#### Backend-Server (Raspberry Pi)
```bash
# Automatische Erkennung: raspberrypi
# Verfügbare Optionen:
# 1. Backend installieren (Flask API + Web Interface)
# 2. Kiosk-Modus installieren (Touch-Interface)
# 3. Produktions-Setup (Backend + Kiosk + Services)
# 4. Nur Python & Dependencies installieren
```
### 🔧 Manuelle Installation
#### Frontend-Server Setup
```bash
# Auf m040tbaraspi001.de040.corpintra.net
cd frontend/
npm install
docker-compose up -d
```
#### Backend-Server Setup
```bash
# Auf raspberrypi
cd backend/app/
python3.11 -m pip install -r requirements.txt
sudo systemctl start myp.service
sudo systemctl start myp-kiosk-browser.service # Optional: Kiosk-Modus
```
### 🌐 URLs & Zugriff
#### Frontend (m040tbaraspi001)
- **Haupt-URL**: `https://m040tbaraspi001.de040.corpintra.net`
- **Entwicklung**: `http://localhost:3000` (npm run dev)
- **Produktion**: `https://localhost:443` (Docker)
#### Backend (Raspberry Pi)
- **API**: `https://raspberrypi/api`
- **Web Interface**: `https://raspberrypi`
- **Kiosk-Modus**: `https://raspberrypi` (Vollbild-Touch-Interface)
### 🔗 Server-Kommunikation
Die Server kommunizieren über HTTPS:
- **Frontend → Backend**: `https://raspberrypi/api`
- **OAuth Callbacks**: `https://m040tbaraspi001.de040.corpintra.net/auth/login/callback`
- **Cross-Origin**: Automatisch konfiguriert für beide Domains
### 🛠️ Konfiguration
#### Frontend (.env.local)
```bash
# Backend-Verbindung
NEXT_PUBLIC_API_URL=https://raspberrypi
NEXT_PUBLIC_BACKEND_HOST=raspberrypi
# Frontend-URLs
NEXT_PUBLIC_FRONTEND_URL=https://m040tbaraspi001.de040.corpintra.net
NEXTAUTH_URL=https://m040tbaraspi001.de040.corpintra.net
```
#### Backend (config/settings.py)
```python
# Frontend-Verbindung
FRONTEND_URL = "https://m040tbaraspi001.de040.corpintra.net"
CORS_ORIGINS = ["https://m040tbaraspi001.de040.corpintra.net"]
# Kiosk-Konfiguration
KIOSK_MODE = True
KIOSK_AUTO_LOGIN = True
```
**Backend-System**: Till Tomczak (Cyber-Physische Vernetzung & Hardware-Integration)
**Frontend-System**: Torben Haack (Progressive Web App & Analytics)
**Architektur**: Microservices mit REST-API-Integration
**Technologie**: Flask + SQLite (Backend) + Next.js + React (Frontend)
**Hardware**: Raspberry Pi + TP-Link Tapo P110 Smart-Plugs
**Entwickelt für**: Mercedes-Benz Werk 040 Berlin MYP

151
backend/build-kiosk-css.ps1 Normal file
View File

@ -0,0 +1,151 @@
# MYP Platform - Kiosk CSS Build Script (PowerShell)
# Optimiert und minifiziert CSS für maximale Performance im Offline-Kiosk-Modus
Write-Host "Starte Kiosk CSS Build..." -ForegroundColor Green
# Erstelle Build-Verzeichnis
if (!(Test-Path "static\css\build")) {
New-Item -ItemType Directory -Path "static\css\build" -Force | Out-Null
}
# Prüfe ob Quelldateien existieren
if (!(Test-Path "static\css\kiosk-optimized.css")) {
Write-Host "FEHLER: static\css\kiosk-optimized.css nicht gefunden!" -ForegroundColor Red
exit 1
}
if (!(Test-Path "static\css\icons-minimal.css")) {
Write-Host "FEHLER: static\css\icons-minimal.css nicht gefunden!" -ForegroundColor Red
exit 1
}
if (!(Test-Path "static\css\critical-inline.css")) {
Write-Host "FEHLER: static\css\critical-inline.css nicht gefunden!" -ForegroundColor Red
exit 1
}
# Erstelle eine kombinierte CSS-Datei in korrekter Reihenfolge
Write-Host "Kombiniere CSS-Dateien..." -ForegroundColor Yellow
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$header = @"
/* MYP Platform - Kiosk Optimierte CSS Bundle */
/* Generiert am: $timestamp */
"@
# CSS-Dateien in optimaler Reihenfolge kombinieren
Write-Host "Lade kiosk-optimized.css..." -ForegroundColor Gray
$kioskCSS = Get-Content "static\css\kiosk-optimized.css" -Raw -Encoding UTF8
Write-Host "Lade icons-minimal.css..." -ForegroundColor Gray
$iconsCSS = Get-Content "static\css\icons-minimal.css" -Raw -Encoding UTF8
# Kombiniere CSS-Inhalte
$combinedCSS = $header + $kioskCSS + "`r`n`r`n" + $iconsCSS
# TailwindCSS mit aggressivem Purging bauen
Write-Host "Purge TailwindCSS..." -ForegroundColor Yellow
try {
$process = Start-Process "npx" -ArgumentList "tailwindcss", "-i", "static\css\input.css", "-o", "static\css\build\tailwind-purged.css", "--minify" -Wait -PassThru -NoNewWindow
if ($process.ExitCode -eq 0) {
Write-Host "TailwindCSS erfolgreich gebaut" -ForegroundColor Green
$tailwindCSS = Get-Content "static\css\build\tailwind-purged.css" -Raw -Encoding UTF8
$combinedCSS += "`r`n`r`n" + $tailwindCSS
} else {
Write-Host "TailwindCSS Build fehlgeschlagen, verwende ohne Tailwind" -ForegroundColor Yellow
}
} catch {
Write-Host "TailwindCSS Build fehlgeschlagen: $($_.Exception.Message)" -ForegroundColor Yellow
}
# Kombinierte CSS speichern
Write-Host "Speichere kombinierte CSS..." -ForegroundColor Gray
$combinedCSS | Out-File -FilePath "static\css\build\kiosk-combined.css" -Encoding UTF8
# CSS minifizieren (falls cssnano verfügbar)
Write-Host "Minifiziere CSS..." -ForegroundColor Yellow
try {
$process = Start-Process "npx" -ArgumentList "cssnano", "static\css\build\kiosk-combined.css", "static\css\build\kiosk-production.css", "--no-map" -Wait -PassThru -NoNewWindow
if ($process.ExitCode -eq 0) {
Write-Host "CSS erfolgreich minifiziert" -ForegroundColor Green
} else {
Write-Host "cssnano fehlgeschlagen, verwende unminifizierte Version" -ForegroundColor Yellow
Copy-Item "static\css\build\kiosk-combined.css" "static\css\build\kiosk-production.css"
}
} catch {
Write-Host "cssnano nicht verfügbar, verwende unminifizierte Version" -ForegroundColor Yellow
Copy-Item "static\css\build\kiosk-combined.css" "static\css\build\kiosk-production.css"
}
# Erstelle kritisches CSS für Inline-Verwendung
Write-Host "Erstelle kritisches CSS..." -ForegroundColor Yellow
Copy-Item "static\css\critical-inline.css" "static\css\build\critical.css"
# Erstelle eine Version ohne FontAwesome
Write-Host "Entferne FontAwesome-Abhängigkeiten..." -ForegroundColor Yellow
if (Test-Path "static\css\build\kiosk-production.css") {
$content = Get-Content "static\css\build\kiosk-production.css" | Where-Object { $_ -notmatch "fontawesome" }
$content | Out-File -FilePath "static\css\build\kiosk-no-fa.css" -Encoding UTF8
}
# Dateigröße-Analyse
Write-Host ""
Write-Host "Dateigröße-Analyse:" -ForegroundColor Cyan
if (Test-Path "static\css\build\critical.css") {
$criticalSize = (Get-Item "static\css\build\critical.css").Length
Write-Host "Critical CSS (inline): $criticalSize bytes"
}
if (Test-Path "static\css\build\kiosk-production.css") {
$kioskSize = (Get-Item "static\css\build\kiosk-production.css").Length
Write-Host "Kiosk Production CSS: $kioskSize bytes"
}
if (Test-Path "static\css\build\kiosk-no-fa.css") {
$noFaSize = (Get-Item "static\css\build\kiosk-no-fa.css").Length
Write-Host "Ohne FontAwesome: $noFaSize bytes"
}
# Vergleich mit Original-Dateien
if ((Test-Path "static\css\tailwind.min.css") -and (Test-Path "static\css\build\kiosk-production.css")) {
$originalSize = (Get-Item "static\css\tailwind.min.css").Length
$optimizedSize = (Get-Item "static\css\build\kiosk-production.css").Length
if ($originalSize -gt 0) {
$reduction = [math]::Round((1 - ($optimizedSize / $originalSize)) * 100, 1)
Write-Host "TailwindCSS Original: $originalSize bytes"
Write-Host "Größenreduktion: $reduction%" -ForegroundColor Green
}
}
# Cache-Busting Hash generieren
if (Test-Path "static\css\build\kiosk-production.css") {
$hash = (Get-FileHash "static\css\build\kiosk-production.css" -Algorithm SHA256).Hash.Substring(0, 8).ToLower()
Copy-Item "static\css\build\kiosk-production.css" "static\css\build\kiosk-$hash.css"
Write-Host ""
Write-Host "Build abgeschlossen!" -ForegroundColor Green
Write-Host ""
Write-Host "Generierte Dateien:" -ForegroundColor Cyan
Write-Host " • static\css\build\critical.css (inline verwenden)"
Write-Host " • static\css\build\kiosk-production.css (Haupt-CSS)"
Write-Host " • static\css\build\kiosk-$hash.css (mit Cache-Busting)"
Write-Host ""
Write-Host "HTML-Integration:" -ForegroundColor Cyan
Write-Host ' <style>/* Inhalt von critical.css hier einfügen */</style>'
Write-Host ' <link rel="stylesheet" href="/static/css/build/kiosk-production.css">'
Write-Host ""
Write-Host "Für maximale Performance: Service Worker entfernen und nur statische CSS verwenden" -ForegroundColor Blue
}
# Cleanup temporärer Dateien
if (Test-Path "static\css\build\kiosk-combined.css") {
Remove-Item "static\css\build\kiosk-combined.css"
}
if (Test-Path "static\css\build\tailwind-purged.css") {
Remove-Item "static\css\build\tailwind-purged.css"
}
Write-Host "Cleanup abgeschlossen" -ForegroundColor Green

View File

@ -0,0 +1,88 @@
#!/bin/bash
# MYP Platform - Kiosk CSS Build Script
# Optimiert und minifiziert CSS für maximale Performance im Offline-Kiosk-Modus
echo "🚀 Starte Kiosk CSS Build..."
# Erstelle Build-Verzeichnis
mkdir -p static/css/build
# Erstelle eine kombinierte CSS-Datei in korrekter Reihenfolge
echo "📦 Kombiniere CSS-Dateien..."
cat > static/css/build/kiosk-combined.css << 'EOF'
/* MYP Platform - Kiosk Optimierte CSS Bundle */
/* Generiert am: $(date) */
EOF
# CSS-Dateien in optimaler Reihenfolge kombinieren
cat static/css/kiosk-optimized.css >> static/css/build/kiosk-combined.css
echo "" >> static/css/build/kiosk-combined.css
cat static/css/icons-minimal.css >> static/css/build/kiosk-combined.css
# TailwindCSS mit aggressivem Purging bauen
echo "🎯 Purge TailwindCSS..."
npx tailwindcss -i static/css/input.css -o static/css/build/tailwind-purged.css --minify
# Kombiniere mit Tailwind
echo "" >> static/css/build/kiosk-combined.css
cat static/css/build/tailwind-purged.css >> static/css/build/kiosk-combined.css
# CSS minifizieren (falls cssnano verfügbar)
if command -v npx &> /dev/null; then
echo "🗜️ Minifiziere CSS..."
npx cssnano static/css/build/kiosk-combined.css static/css/build/kiosk-production.css --no-map
else
echo "⚠️ cssnano nicht verfügbar, verwende unminifizierte Version"
cp static/css/build/kiosk-combined.css static/css/build/kiosk-production.css
fi
# Erstelle kritisches CSS für Inline-Verwendung
echo "⚡ Erstelle kritisches CSS..."
cp static/css/critical-inline.css static/css/build/critical.css
# Erstelle eine Version ohne FontAwesome
echo "🚫 Entferne FontAwesome-Abhängigkeiten..."
grep -v "fontawesome" static/css/build/kiosk-production.css > static/css/build/kiosk-no-fa.css
# Dateigröße-Analyse
echo ""
echo "📊 Dateigröße-Analyse:"
echo "Critical CSS (inline): $(wc -c < static/css/build/critical.css) bytes"
echo "Kiosk Production CSS: $(wc -c < static/css/build/kiosk-production.css) bytes"
echo "Ohne FontAwesome: $(wc -c < static/css/build/kiosk-no-fa.css) bytes"
# Vergleich mit Original-Dateien
if [ -f "static/css/tailwind.min.css" ]; then
original_size=$(wc -c < static/css/tailwind.min.css)
optimized_size=$(wc -c < static/css/build/kiosk-production.css)
reduction=$((100 - (optimized_size * 100 / original_size)))
echo "TailwindCSS Original: $original_size bytes"
echo "Größenreduktion: $reduction%"
fi
# Cache-Busting Hash generieren
hash=$(sha256sum static/css/build/kiosk-production.css | cut -d' ' -f1 | cut -c1-8)
cp static/css/build/kiosk-production.css static/css/build/kiosk-$hash.css
echo ""
echo "✅ Build abgeschlossen!"
echo ""
echo "📁 Generierte Dateien:"
echo " • static/css/build/critical.css (inline verwenden)"
echo " • static/css/build/kiosk-production.css (Haupt-CSS)"
echo " • static/css/build/kiosk-$hash.css (mit Cache-Busting)"
echo ""
echo "🔧 HTML-Integration:"
echo ' <style>/* Inhalt von critical.css hier einfügen */</style>'
echo ' <link rel="stylesheet" href="/static/css/build/kiosk-production.css">'
echo ""
echo "💡 Für maximale Performance: Service Worker entfernen und nur statische CSS verwenden"
# Cleanup temporärer Dateien
rm -f static/css/build/kiosk-combined.css
rm -f static/css/build/tailwind-purged.css
echo "🧹 Cleanup abgeschlossen"

Binary file not shown.

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -87,3 +87,7 @@
2025-06-01 22:39:54 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert
2025-06-01 22:39:56 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert
2025-06-01 22:40:09 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert
2025-06-01 23:08:24 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert
2025-06-01 23:10:01 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert
2025-06-01 23:16:55 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert
2025-06-01 23:32:06 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert

View File

@ -2099,3 +2099,123 @@ WHERE jobs.status = ?) AS anon_1]
2025-06-01 22:40:14 - [app] app - [INFO] INFO - Job-Scheduler gestartet
2025-06-01 22:40:14 - [app] app - [INFO] INFO - Starte Debug-Server auf 0.0.0.0:5000 (HTTP)
2025-06-01 22:40:14 - [app] app - [INFO] INFO - Windows-Debug-Modus: Auto-Reload deaktiviert
2025-06-01 23:08:24 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db
2025-06-01 23:08:25 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O)
2025-06-01 23:08:25 - [app] app - [INFO] INFO - ✅ Timeout Force-Quit Manager geladen
2025-06-01 23:08:25 - [app] app - [INFO] INFO - ✅ Zentraler Shutdown-Manager initialisiert
2025-06-01 23:08:25 - [app] app - [INFO] INFO - 🔄 Starte Datenbank-Setup und Migrationen...
2025-06-01 23:08:25 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
2025-06-01 23:08:25 - [app] app - [INFO] INFO - ✅ JobOrder-Tabelle bereits vorhanden
2025-06-01 23:08:25 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt.
2025-06-01 23:08:25 - [app] app - [INFO] INFO - ✅ Datenbank-Setup und Migrationen erfolgreich abgeschlossen
2025-06-01 23:08:25 - [app] app - [INFO] INFO - 🖨️ Starte automatische Steckdosen-Initialisierung...
2025-06-01 23:08:29 - [app] app - [INFO] INFO - ✅ Steckdosen-Initialisierung: 0/2 Drucker erfolgreich
2025-06-01 23:08:29 - [app] app - [WARNING] WARNING - ⚠️ 2 Drucker konnten nicht initialisiert werden
2025-06-01 23:08:29 - [app] app - [INFO] INFO - 🔄 Debug-Modus: Queue Manager deaktiviert für Entwicklung
2025-06-01 23:08:29 - [app] app - [INFO] INFO - Job-Scheduler gestartet
2025-06-01 23:08:29 - [app] app - [INFO] INFO - Starte Debug-Server auf 0.0.0.0:5000 (HTTP)
2025-06-01 23:08:29 - [app] app - [INFO] INFO - Windows-Debug-Modus: Auto-Reload deaktiviert
2025-06-01 23:10:01 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db
2025-06-01 23:10:02 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O)
2025-06-01 23:10:02 - [app] app - [INFO] INFO - ✅ Timeout Force-Quit Manager geladen
2025-06-01 23:10:02 - [app] app - [INFO] INFO - ✅ Zentraler Shutdown-Manager initialisiert
2025-06-01 23:10:02 - [app] app - [INFO] INFO - 🔄 Starte Datenbank-Setup und Migrationen...
2025-06-01 23:10:02 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
2025-06-01 23:10:02 - [app] app - [INFO] INFO - ✅ JobOrder-Tabelle bereits vorhanden
2025-06-01 23:10:03 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt.
2025-06-01 23:10:03 - [app] app - [INFO] INFO - ✅ Datenbank-Setup und Migrationen erfolgreich abgeschlossen
2025-06-01 23:10:03 - [app] app - [INFO] INFO - 🖨️ Starte automatische Steckdosen-Initialisierung...
2025-06-01 23:10:07 - [app] app - [INFO] INFO - ✅ Steckdosen-Initialisierung: 0/2 Drucker erfolgreich
2025-06-01 23:10:07 - [app] app - [WARNING] WARNING - ⚠️ 2 Drucker konnten nicht initialisiert werden
2025-06-01 23:10:07 - [app] app - [INFO] INFO - 🔄 Debug-Modus: Queue Manager deaktiviert für Entwicklung
2025-06-01 23:10:07 - [app] app - [INFO] INFO - Job-Scheduler gestartet
2025-06-01 23:10:07 - [app] app - [INFO] INFO - Starte Debug-Server auf 0.0.0.0:5000 (HTTP)
2025-06-01 23:10:07 - [app] app - [INFO] INFO - Windows-Debug-Modus: Auto-Reload deaktiviert
2025-06-01 23:10:11 - [app] app - [INFO] INFO - Admin-Check für Funktion admin_page: User authenticated: True, User ID: 1, Is Admin: True
2025-06-01 23:10:11 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True
2025-06-01 23:16:55 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db
2025-06-01 23:16:56 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O)
2025-06-01 23:16:56 - [app] app - [INFO] INFO - ✅ Timeout Force-Quit Manager geladen
2025-06-01 23:16:56 - [app] app - [INFO] INFO - ✅ Zentraler Shutdown-Manager initialisiert
2025-06-01 23:16:56 - [app] app - [INFO] INFO - 🔄 Starte Datenbank-Setup und Migrationen...
2025-06-01 23:16:56 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
2025-06-01 23:16:56 - [app] app - [INFO] INFO - ✅ JobOrder-Tabelle bereits vorhanden
2025-06-01 23:16:56 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt.
2025-06-01 23:16:56 - [app] app - [INFO] INFO - ✅ Datenbank-Setup und Migrationen erfolgreich abgeschlossen
2025-06-01 23:16:56 - [app] app - [INFO] INFO - 🖨️ Starte automatische Steckdosen-Initialisierung...
2025-06-01 23:17:00 - [app] app - [INFO] INFO - ✅ Steckdosen-Initialisierung: 0/2 Drucker erfolgreich
2025-06-01 23:17:00 - [app] app - [WARNING] WARNING - ⚠️ 2 Drucker konnten nicht initialisiert werden
2025-06-01 23:17:00 - [app] app - [INFO] INFO - 🔄 Debug-Modus: Queue Manager deaktiviert für Entwicklung
2025-06-01 23:17:00 - [app] app - [INFO] INFO - Job-Scheduler gestartet
2025-06-01 23:17:00 - [app] app - [INFO] INFO - Starte Debug-Server auf 0.0.0.0:5000 (HTTP)
2025-06-01 23:17:00 - [app] app - [INFO] INFO - Windows-Debug-Modus: Auto-Reload deaktiviert
2025-06-01 23:17:28 - [app] app - [INFO] INFO - Admin-Check für Funktion admin_page: User authenticated: True, User ID: 1, Is Admin: True
2025-06-01 23:17:29 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True
2025-06-01 23:18:51 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:18:51 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:18:51 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:18:51 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:19:46 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:19:46 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:19:47 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:19:47 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:20:34 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:20:34 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:20:34 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:20:34 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:21:18 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:21:18 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:21:18 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:21:18 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:21:58 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:21:58 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:21:58 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:21:58 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:22:39 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:22:39 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:22:39 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:22:39 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:32:05 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db
2025-06-01 23:32:07 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O)
2025-06-01 23:32:07 - [app] app - [INFO] INFO - ✅ Timeout Force-Quit Manager geladen
2025-06-01 23:32:07 - [app] app - [INFO] INFO - ✅ Zentraler Shutdown-Manager initialisiert
2025-06-01 23:32:07 - [app] app - [INFO] INFO - 🔄 Starte Datenbank-Setup und Migrationen...
2025-06-01 23:32:07 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
2025-06-01 23:32:07 - [app] app - [INFO] INFO - ✅ JobOrder-Tabelle bereits vorhanden
2025-06-01 23:32:08 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt.
2025-06-01 23:32:08 - [app] app - [INFO] INFO - ✅ Datenbank-Setup und Migrationen erfolgreich abgeschlossen
2025-06-01 23:32:08 - [app] app - [INFO] INFO - 🖨️ Starte automatische Steckdosen-Initialisierung...
2025-06-01 23:32:12 - [app] app - [INFO] INFO - ✅ Steckdosen-Initialisierung: 0/2 Drucker erfolgreich
2025-06-01 23:32:12 - [app] app - [WARNING] WARNING - ⚠️ 2 Drucker konnten nicht initialisiert werden
2025-06-01 23:32:12 - [app] app - [INFO] INFO - 🔄 Debug-Modus: Queue Manager deaktiviert für Entwicklung
2025-06-01 23:32:12 - [app] app - [INFO] INFO - Job-Scheduler gestartet
2025-06-01 23:32:12 - [app] app - [INFO] INFO - Starte Debug-Server auf 0.0.0.0:5000 (HTTP)
2025-06-01 23:32:12 - [app] app - [INFO] INFO - Windows-Debug-Modus: Auto-Reload deaktiviert
2025-06-01 23:33:27 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:33:27 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:33:27 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:33:27 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:34:10 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:34:10 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:34:10 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:34:10 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:34:56 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:34:56 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:34:57 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:34:57 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:35:55 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:35:55 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:35:55 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:35:55 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:36:45 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:36:45 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:36:45 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:36:45 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:37:25 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:37:25 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:37:25 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:37:25 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:38:06 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:38:06 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:38:06 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:38:06 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}

View File

@ -91,3 +91,7 @@
2025-06-01 22:39:54 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation)
2025-06-01 22:39:56 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation)
2025-06-01 22:40:09 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation)
2025-06-01 23:08:24 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation)
2025-06-01 23:10:01 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation)
2025-06-01 23:16:55 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation)
2025-06-01 23:32:06 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation)

View File

@ -37,3 +37,4 @@
2025-06-01 19:09:10 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 16 Einträge für Zeitraum 2025-06-01 00:00:00 bis 2025-06-08 00:00:00
2025-06-01 21:14:20 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 16 Einträge für Zeitraum 2025-06-01 00:00:00 bis 2025-06-08 00:00:00
2025-06-01 21:14:43 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 16 Einträge für Zeitraum 2025-06-01 00:00:00 bis 2025-06-08 00:00:00
2025-06-01 23:32:26 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 16 Einträge für Zeitraum 2025-06-01 00:00:00 bis 2025-06-08 00:00:00

View File

@ -349,3 +349,19 @@
2025-06-01 22:40:10 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet
2025-06-01 22:40:10 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback)
2025-06-01 22:40:10 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server initialisiert (async_mode: threading)
2025-06-01 23:08:25 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet
2025-06-01 23:08:25 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet
2025-06-01 23:08:25 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback)
2025-06-01 23:08:25 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server initialisiert (async_mode: threading)
2025-06-01 23:10:02 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet
2025-06-01 23:10:02 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet
2025-06-01 23:10:02 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback)
2025-06-01 23:10:02 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server initialisiert (async_mode: threading)
2025-06-01 23:16:56 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet
2025-06-01 23:16:56 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet
2025-06-01 23:16:56 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback)
2025-06-01 23:16:56 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server initialisiert (async_mode: threading)
2025-06-01 23:32:07 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet
2025-06-01 23:32:07 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet
2025-06-01 23:32:07 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback)
2025-06-01 23:32:07 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server initialisiert (async_mode: threading)

View File

@ -87,3 +87,7 @@
2025-06-01 22:39:54 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet
2025-06-01 22:39:56 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet
2025-06-01 22:40:09 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet
2025-06-01 23:08:24 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet
2025-06-01 23:10:01 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet
2025-06-01 23:16:55 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet
2025-06-01 23:32:06 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet

View File

@ -84,3 +84,7 @@
2025-06-01 22:39:54 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand)
2025-06-01 22:39:57 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand)
2025-06-01 22:40:10 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand)
2025-06-01 23:08:25 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand)
2025-06-01 23:10:02 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand)
2025-06-01 23:16:56 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand)
2025-06-01 23:32:07 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand)

View File

@ -124,3 +124,6 @@ WHERE printers.id = ?]
2025-06-01 19:04:21 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 16 von 16 (Seite 1)
2025-06-01 21:14:21 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 16 von 16 (Seite 1)
2025-06-01 21:14:25 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 16 von 16 (Seite 1)
2025-06-01 23:10:14 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 16 von 16 (Seite 1)
2025-06-01 23:17:20 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 16 von 16 (Seite 1)
2025-06-01 23:32:17 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 16 von 16 (Seite 1)

View File

@ -172,3 +172,11 @@
2025-06-01 22:39:57 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
2025-06-01 22:40:10 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
2025-06-01 22:40:10 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
2025-06-01 23:08:25 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
2025-06-01 23:08:25 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
2025-06-01 23:10:02 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
2025-06-01 23:10:02 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
2025-06-01 23:16:56 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
2025-06-01 23:16:56 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
2025-06-01 23:32:07 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
2025-06-01 23:32:07 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet

View File

@ -172,3 +172,11 @@
2025-06-01 22:39:57 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
2025-06-01 22:40:10 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
2025-06-01 22:40:10 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
2025-06-01 23:08:25 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
2025-06-01 23:08:25 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
2025-06-01 23:10:02 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
2025-06-01 23:10:02 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
2025-06-01 23:16:56 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
2025-06-01 23:16:56 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
2025-06-01 23:32:07 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
2025-06-01 23:32:07 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt

View File

@ -86,3 +86,7 @@
2025-06-01 22:39:55 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
2025-06-01 22:39:57 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
2025-06-01 22:40:10 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
2025-06-01 23:08:25 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
2025-06-01 23:10:02 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
2025-06-01 23:16:56 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
2025-06-01 23:32:07 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert

View File

@ -2536,3 +2536,120 @@
2025-06-01 22:40:23 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 3/6: 192.168.0.100
2025-06-01 22:40:28 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 6/6: 192.168.0.105
2025-06-01 22:40:29 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 4/6: 192.168.0.101
2025-06-01 23:08:24 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
2025-06-01 23:08:24 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
2025-06-01 23:08:25 - [printer_monitor] printer_monitor - [INFO] INFO - 🚀 Starte Steckdosen-Initialisierung beim Programmstart...
2025-06-01 23:08:26 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Starte automatische Tapo-Steckdosenerkennung...
2025-06-01 23:08:26 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Teste 6 Standard-IPs aus der Konfiguration
2025-06-01 23:08:26 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 1/6: 192.168.0.103
2025-06-01 23:08:27 - [printer_monitor] printer_monitor - [WARNING] WARNING - ❌ Tapo P110 (192.168.0.103): Steckdose konnte nicht ausgeschaltet werden
2025-06-01 23:08:29 - [printer_monitor] printer_monitor - [WARNING] WARNING - ❌ Tapo P110 (192.168.0.104): Steckdose konnte nicht ausgeschaltet werden
2025-06-01 23:08:29 - [printer_monitor] printer_monitor - [INFO] INFO - 🎯 Steckdosen-Initialisierung abgeschlossen: 0/2 erfolgreich
2025-06-01 23:08:32 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 2/6: 192.168.0.104
2025-06-01 23:08:38 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 3/6: 192.168.0.100
2025-06-01 23:08:44 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 4/6: 192.168.0.101
2025-06-01 23:08:50 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 5/6: 192.168.0.102
2025-06-01 23:08:56 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 6/6: 192.168.0.105
2025-06-01 23:09:02 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Steckdosen-Erkennung abgeschlossen: 0/6 Steckdosen gefunden in 36.2s
2025-06-01 23:10:01 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
2025-06-01 23:10:01 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
2025-06-01 23:10:03 - [printer_monitor] printer_monitor - [INFO] INFO - 🚀 Starte Steckdosen-Initialisierung beim Programmstart...
2025-06-01 23:10:03 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Starte automatische Tapo-Steckdosenerkennung...
2025-06-01 23:10:03 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Teste 6 Standard-IPs aus der Konfiguration
2025-06-01 23:10:03 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 1/6: 192.168.0.103
2025-06-01 23:10:05 - [printer_monitor] printer_monitor - [WARNING] WARNING - ❌ Tapo P110 (192.168.0.103): Steckdose konnte nicht ausgeschaltet werden
2025-06-01 23:10:07 - [printer_monitor] printer_monitor - [WARNING] WARNING - ❌ Tapo P110 (192.168.0.104): Steckdose konnte nicht ausgeschaltet werden
2025-06-01 23:10:07 - [printer_monitor] printer_monitor - [INFO] INFO - 🎯 Steckdosen-Initialisierung abgeschlossen: 0/2 erfolgreich
2025-06-01 23:10:09 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 2/6: 192.168.0.104
2025-06-01 23:10:11 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
2025-06-01 23:10:11 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 2 aktiven Druckern...
2025-06-01 23:10:15 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
2025-06-01 23:10:15 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 2 aktiven Druckern...
2025-06-01 23:10:15 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 3/6: 192.168.0.100
2025-06-01 23:10:17 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
2025-06-01 23:10:17 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 2 aktiven Druckern...
2025-06-01 23:10:18 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
2025-06-01 23:10:18 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 2 aktiven Druckern...
2025-06-01 23:10:20 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.104): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:10:20 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.103): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:10:20 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Status-Update abgeschlossen für 2 Drucker
2025-06-01 23:10:21 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 4/6: 192.168.0.101
2025-06-01 23:10:24 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.104): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:10:24 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.103): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:10:24 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Status-Update abgeschlossen für 2 Drucker
2025-06-01 23:10:26 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.103): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:10:26 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.104): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:10:26 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Status-Update abgeschlossen für 2 Drucker
2025-06-01 23:10:27 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.104): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:10:27 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.103): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:10:27 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Status-Update abgeschlossen für 2 Drucker
2025-06-01 23:10:28 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 5/6: 192.168.0.102
2025-06-01 23:10:34 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 6/6: 192.168.0.105
2025-06-01 23:10:40 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Steckdosen-Erkennung abgeschlossen: 0/6 Steckdosen gefunden in 36.1s
2025-06-01 23:16:55 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
2025-06-01 23:16:55 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
2025-06-01 23:16:56 - [printer_monitor] printer_monitor - [INFO] INFO - 🚀 Starte Steckdosen-Initialisierung beim Programmstart...
2025-06-01 23:16:57 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Starte automatische Tapo-Steckdosenerkennung...
2025-06-01 23:16:57 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Teste 6 Standard-IPs aus der Konfiguration
2025-06-01 23:16:57 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 1/6: 192.168.0.103
2025-06-01 23:16:58 - [printer_monitor] printer_monitor - [WARNING] WARNING - ❌ Tapo P110 (192.168.0.103): Steckdose konnte nicht ausgeschaltet werden
2025-06-01 23:17:00 - [printer_monitor] printer_monitor - [WARNING] WARNING - ❌ Tapo P110 (192.168.0.104): Steckdose konnte nicht ausgeschaltet werden
2025-06-01 23:17:00 - [printer_monitor] printer_monitor - [INFO] INFO - 🎯 Steckdosen-Initialisierung abgeschlossen: 0/2 erfolgreich
2025-06-01 23:17:03 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 2/6: 192.168.0.104
2025-06-01 23:17:09 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 3/6: 192.168.0.100
2025-06-01 23:17:15 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 4/6: 192.168.0.101
2025-06-01 23:17:21 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
2025-06-01 23:17:21 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 2 aktiven Druckern...
2025-06-01 23:17:21 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 5/6: 192.168.0.102
2025-06-01 23:17:23 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
2025-06-01 23:17:23 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 2 aktiven Druckern...
2025-06-01 23:17:27 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 6/6: 192.168.0.105
2025-06-01 23:17:30 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.104): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:17:30 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.103): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:17:30 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Status-Update abgeschlossen für 2 Drucker
2025-06-01 23:17:32 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.103): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:17:32 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.104): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:17:32 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Status-Update abgeschlossen für 2 Drucker
2025-06-01 23:17:33 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Steckdosen-Erkennung abgeschlossen: 0/6 Steckdosen gefunden in 36.1s
2025-06-01 23:22:40 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
2025-06-01 23:22:40 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 2 aktiven Druckern...
2025-06-01 23:22:47 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
2025-06-01 23:22:47 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 2 aktiven Druckern...
2025-06-01 23:22:49 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.104): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:22:49 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.103): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:22:49 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Status-Update abgeschlossen für 2 Drucker
2025-06-01 23:32:06 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
2025-06-01 23:32:06 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
2025-06-01 23:32:08 - [printer_monitor] printer_monitor - [INFO] INFO - 🚀 Starte Steckdosen-Initialisierung beim Programmstart...
2025-06-01 23:32:08 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Starte automatische Tapo-Steckdosenerkennung...
2025-06-01 23:32:08 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Teste 6 Standard-IPs aus der Konfiguration
2025-06-01 23:32:08 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 1/6: 192.168.0.103
2025-06-01 23:32:10 - [printer_monitor] printer_monitor - [WARNING] WARNING - ❌ Tapo P110 (192.168.0.103): Steckdose konnte nicht ausgeschaltet werden
2025-06-01 23:32:12 - [printer_monitor] printer_monitor - [WARNING] WARNING - ❌ Tapo P110 (192.168.0.104): Steckdose konnte nicht ausgeschaltet werden
2025-06-01 23:32:12 - [printer_monitor] printer_monitor - [INFO] INFO - 🎯 Steckdosen-Initialisierung abgeschlossen: 0/2 erfolgreich
2025-06-01 23:32:13 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
2025-06-01 23:32:13 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 2 aktiven Druckern...
2025-06-01 23:32:14 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 2/6: 192.168.0.104
2025-06-01 23:32:16 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
2025-06-01 23:32:16 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 2 aktiven Druckern...
2025-06-01 23:32:20 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 3/6: 192.168.0.100
2025-06-01 23:32:22 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.104): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:32:22 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.103): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:32:22 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Status-Update abgeschlossen für 2 Drucker
2025-06-01 23:32:25 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.104): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:32:25 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.103): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:32:25 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Status-Update abgeschlossen für 2 Drucker
2025-06-01 23:32:26 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 4/6: 192.168.0.101
2025-06-01 23:32:32 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 5/6: 192.168.0.102
2025-06-01 23:32:38 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 6/6: 192.168.0.105
2025-06-01 23:32:44 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Steckdosen-Erkennung abgeschlossen: 0/6 Steckdosen gefunden in 36.1s
2025-06-01 23:37:25 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
2025-06-01 23:37:25 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 2 aktiven Druckern...
2025-06-01 23:37:34 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
2025-06-01 23:37:34 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 2 aktiven Druckern...
2025-06-01 23:37:34 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.103): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:37:34 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.104): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:37:34 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Status-Update abgeschlossen für 2 Drucker
2025-06-01 23:37:43 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.104): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:37:43 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.103): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:37:43 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Status-Update abgeschlossen für 2 Drucker

View File

@ -5056,3 +5056,131 @@
2025-06-01 21:14:47 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 21:14:47 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 21:14:47 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.41ms
2025-06-01 23:10:11 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:10:14 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check)
2025-06-01 23:10:15 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check)
2025-06-01 23:10:15 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:10:17 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:10:18 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:10:20 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:10:20 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9029.96ms
2025-06-01 23:10:24 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:10:24 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9041.46ms
2025-06-01 23:10:26 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:10:26 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9022.98ms
2025-06-01 23:10:27 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:10:27 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9032.41ms
2025-06-01 23:17:20 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check)
2025-06-01 23:17:21 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check)
2025-06-01 23:17:21 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:17:23 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:17:30 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:17:30 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9031.02ms
2025-06-01 23:17:32 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:17:32 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9018.02ms
2025-06-01 23:17:32 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:17:32 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:17:32 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.24ms
2025-06-01 23:17:33 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:17:33 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:17:33 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.33ms
2025-06-01 23:18:21 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:18:21 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:18:21 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.31ms
2025-06-01 23:18:51 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:18:51 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:18:51 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.45ms
2025-06-01 23:19:08 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:19:08 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:19:08 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.37ms
2025-06-01 23:19:15 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:19:15 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:19:15 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.27ms
2025-06-01 23:19:47 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:19:47 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:19:47 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.31ms
2025-06-01 23:20:04 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:20:04 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:20:04 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.41ms
2025-06-01 23:20:35 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:20:35 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:20:35 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.32ms
2025-06-01 23:20:48 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:20:48 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:20:48 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.27ms
2025-06-01 23:21:18 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:21:18 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:21:18 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.29ms
2025-06-01 23:21:27 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:21:27 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:21:27 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.49ms
2025-06-01 23:22:09 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:22:09 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:22:09 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.44ms
2025-06-01 23:22:40 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:22:47 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:22:49 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:22:49 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9004.42ms
2025-06-01 23:32:13 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:32:16 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check)
2025-06-01 23:32:16 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:32:17 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check)
2025-06-01 23:32:22 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:32:22 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9030.61ms
2025-06-01 23:32:25 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:32:25 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9035.13ms
2025-06-01 23:32:31 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check)
2025-06-01 23:32:31 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:32:31 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:32:31 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.35ms
2025-06-01 23:32:33 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:32:33 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:32:33 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.66ms
2025-06-01 23:32:35 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:32:35 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:32:35 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 2.22ms
2025-06-01 23:32:57 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:32:57 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:32:57 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.29ms
2025-06-01 23:33:27 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:33:27 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:33:27 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.34ms
2025-06-01 23:33:40 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:33:40 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:33:40 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.38ms
2025-06-01 23:34:10 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:34:10 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:34:10 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.34ms
2025-06-01 23:34:26 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:34:26 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:34:26 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.27ms
2025-06-01 23:34:57 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:34:57 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:34:57 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.33ms
2025-06-01 23:35:10 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:35:10 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:35:10 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.48ms
2025-06-01 23:35:55 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:35:55 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:35:55 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.51ms
2025-06-01 23:36:05 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:36:05 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:36:05 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.39ms
2025-06-01 23:36:45 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:36:45 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:36:45 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.25ms
2025-06-01 23:36:55 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:36:55 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:36:55 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.31ms
2025-06-01 23:37:25 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:37:34 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:37:34 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:37:34 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9033.19ms
2025-06-01 23:37:43 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:37:43 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9021.61ms
2025-06-01 23:38:06 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:38:06 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:38:06 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.30ms
2025-06-01 23:38:20 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:38:20 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:38:20 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.26ms

File diff suppressed because it is too large Load Diff

View File

@ -86,3 +86,7 @@
2025-06-01 22:39:55 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
2025-06-01 22:39:57 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
2025-06-01 22:40:10 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
2025-06-01 23:08:25 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
2025-06-01 23:10:02 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
2025-06-01 23:16:56 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
2025-06-01 23:32:07 - [security] security - [INFO] INFO - 🔒 Security System initialisiert

View File

@ -172,3 +172,7 @@
2025-06-01 22:39:55 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🏁 System wird beendet...
2025-06-01 22:39:57 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert
2025-06-01 22:40:10 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert
2025-06-01 23:08:25 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert
2025-06-01 23:10:02 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert
2025-06-01 23:16:56 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert
2025-06-01 23:32:07 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert

View File

@ -782,3 +782,39 @@
2025-06-01 22:40:10 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
2025-06-01 22:40:10 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
2025-06-01 22:40:10 - [startup] startup - [INFO] INFO - ==================================================
2025-06-01 23:08:25 - [startup] startup - [INFO] INFO - ==================================================
2025-06-01 23:08:25 - [startup] startup - [INFO] INFO - 🚀 MYP Platform Backend wird gestartet...
2025-06-01 23:08:25 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)]
2025-06-01 23:08:25 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32)
2025-06-01 23:08:25 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend
2025-06-01 23:08:25 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-01T23:08:25.318047
2025-06-01 23:08:25 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
2025-06-01 23:08:25 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
2025-06-01 23:08:25 - [startup] startup - [INFO] INFO - ==================================================
2025-06-01 23:10:02 - [startup] startup - [INFO] INFO - ==================================================
2025-06-01 23:10:02 - [startup] startup - [INFO] INFO - 🚀 MYP Platform Backend wird gestartet...
2025-06-01 23:10:02 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)]
2025-06-01 23:10:02 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32)
2025-06-01 23:10:02 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend
2025-06-01 23:10:02 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-01T23:10:02.765896
2025-06-01 23:10:02 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
2025-06-01 23:10:02 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
2025-06-01 23:10:02 - [startup] startup - [INFO] INFO - ==================================================
2025-06-01 23:16:56 - [startup] startup - [INFO] INFO - ==================================================
2025-06-01 23:16:56 - [startup] startup - [INFO] INFO - 🚀 MYP Platform Backend wird gestartet...
2025-06-01 23:16:56 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)]
2025-06-01 23:16:56 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32)
2025-06-01 23:16:56 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend
2025-06-01 23:16:56 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-01T23:16:56.191249
2025-06-01 23:16:56 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
2025-06-01 23:16:56 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
2025-06-01 23:16:56 - [startup] startup - [INFO] INFO - ==================================================
2025-06-01 23:32:07 - [startup] startup - [INFO] INFO - ==================================================
2025-06-01 23:32:07 - [startup] startup - [INFO] INFO - 🚀 MYP Platform Backend wird gestartet...
2025-06-01 23:32:07 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)]
2025-06-01 23:32:07 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32)
2025-06-01 23:32:07 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend
2025-06-01 23:32:07 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-01T23:32:07.643798
2025-06-01 23:32:07 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
2025-06-01 23:32:07 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
2025-06-01 23:32:07 - [startup] startup - [INFO] INFO - ==================================================

View File

@ -375,3 +375,19 @@
2025-06-01 22:40:09 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen)
2025-06-01 22:40:09 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet
2025-06-01 22:40:09 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
2025-06-01 23:08:24 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an...
2025-06-01 23:08:24 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen)
2025-06-01 23:08:24 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet
2025-06-01 23:08:24 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
2025-06-01 23:10:01 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an...
2025-06-01 23:10:01 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen)
2025-06-01 23:10:01 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet
2025-06-01 23:10:01 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
2025-06-01 23:16:55 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an...
2025-06-01 23:16:55 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen)
2025-06-01 23:16:55 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet
2025-06-01 23:16:55 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
2025-06-01 23:32:05 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an...
2025-06-01 23:32:05 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen)
2025-06-01 23:32:05 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet
2025-06-01 23:32:05 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet

View File

@ -0,0 +1,148 @@
MYP Platform - Performance Optimization Report
==============================================
CSS-Dateien (39):
- all.css: 106,394 Bytes
- all.min.css: 73,890 Bytes
- app-bundle.min.css: 8,714 Bytes
- brands.css: 19,852 Bytes
- brands.min.css: 14,574 Bytes
- caching-optimizations.css: 5,613 Bytes
- caching-optimizations.min.css: 3,565 Bytes
- components.css: 17,232 Bytes
- components.min.css: 13,062 Bytes
- critical-inline.css: 1,473 Bytes
- critical-inline.min.css: 1,399 Bytes
- fontawesome.css: 83,677 Bytes
- fontawesome.min.css: 56,777 Bytes
- glassmorphism.css: 6,211 Bytes
- glassmorphism.min.css: 4,715 Bytes
- input.css: 99,414 Bytes
- input.min.css: 76,568 Bytes
- main.min.css: 115 Bytes
- optimization-animations.css: 2,675 Bytes
- optimization-animations.min.css: 1,443 Bytes
- output.css: 248,934 Bytes
- output.min.css: 210,598 Bytes
- printers.css: 3,952 Bytes
- printers.min.css: 2,502 Bytes
- professional-theme.css: 24,631 Bytes
- professional-theme.min.css: 18,762 Bytes
- regular.css: 633 Bytes
- regular.min.css: 580 Bytes
- solid.css: 625 Bytes
- solid.min.css: 572 Bytes
- svg-with-js.css: 12,554 Bytes
- svg-with-js.min.css: 10,197 Bytes
- tailwind.min.css: 221,943 Bytes
- v4-font-face.css: 1,831 Bytes
- v4-font-face.min.css: 1,736 Bytes
- v4-shims.css: 38,514 Bytes
- v4-shims.min.css: 21,211 Bytes
- v5-font-face.css: 871 Bytes
- v5-font-face.min.css: 794 Bytes
JavaScript-Dateien (84):
- admin-guest-requests.js: 32,046 Bytes
- admin-guest-requests.min.js: 23,162 Bytes
- admin-panel.js: 42,961 Bytes
- admin-panel.min.js: 27,749 Bytes
- admin-unified.js: 56,717 Bytes
- admin-unified.min.js: 35,087 Bytes
- advanced-components.js: 29,859 Bytes
- advanced-components.min.js: 16,393 Bytes
- all.js: 1,627,440 Bytes
- all.min.js: 1,530,755 Bytes
- apexcharts.min.js: 524,387 Bytes
- auto-logout.js: 4,661 Bytes
- auto-logout.min.js: 3,099 Bytes
- brands.js: 510,493 Bytes
- brands.min.js: 499,125 Bytes
- chart-adapter.js: 8,486 Bytes
- chart-config.js: 9,767 Bytes
- chart-renderer.js: 10,396 Bytes
- chart.min.js: 181,743 Bytes
- charts.js: 13,704 Bytes
- charts.min.js: 7,671 Bytes
- conflict-detection.js: 38,929 Bytes
- conflict-detection.min.js: 15,853 Bytes
- core.min.js: 181,411 Bytes
- countdown-timer.js: 35,228 Bytes
- countdown-timer.min.js: 19,014 Bytes
- csp-violation-handler.js: 10,509 Bytes
- csp-violation-handler.min.js: 6,622 Bytes
- css-cache-manager.js: 3,454 Bytes
- css-cache-manager.min.js: 2,471 Bytes
- css-cache-service-worker.js: 10,648 Bytes
- css-cache-service-worker.min.js: 6,895 Bytes
- dark-mode-fix.js: 7,630 Bytes
- dark-mode-fix.min.js: 4,183 Bytes
- dark-mode.js: 11,717 Bytes
- dark-mode.min.js: 7,659 Bytes
- dashboard.js: 11,344 Bytes
- dashboard.min.js: 8,164 Bytes
- daygrid.min.js: 26,955 Bytes
- debug-fix.js: 7,419 Bytes
- debug-fix.min.js: 4,146 Bytes
- event-handlers.js: 16,020 Bytes
- event-handlers.min.js: 8,399 Bytes
- fontawesome.js: 106,548 Bytes
- fontawesome.min.js: 49,856 Bytes
- glassmorphism-notifications.js: 62,643 Bytes
- glassmorphism-notifications.min.js: 35,476 Bytes
- global-refresh-functions.js: 26,547 Bytes
- global-refresh-functions.min.js: 14,785 Bytes
- interaction.min.js: 35,636 Bytes
- job-manager.js: 31,172 Bytes
- job-manager.min.js: 16,598 Bytes
- jobs-safety-fix.js: 10,729 Bytes
- jobs-safety-fix.min.js: 5,270 Bytes
- list.min.js: 9,361 Bytes
- notifications.js: 26,568 Bytes
- notifications.min.js: 16,192 Bytes
- offline-app.js: 20,435 Bytes
- offline-app.min.js: 10,758 Bytes
- optimization-features.js: 33,307 Bytes
- optimization-features.min.js: 19,873 Bytes
- performance-service-worker.js: 10,657 Bytes
- performance-service-worker.min.js: 7,730 Bytes
- printer_monitor.js: 15,887 Bytes
- printer_monitor.min.js: 7,574 Bytes
- regular.js: 126,991 Bytes
- regular.min.js: 119,408 Bytes
- service-worker.js: 2,205 Bytes
- service-worker.min.js: 1,361 Bytes
- session-manager.js: 19,582 Bytes
- session-manager.min.js: 10,369 Bytes
- solid.js: 884,065 Bytes
- solid.min.js: 863,023 Bytes
- sw.js: 12,735 Bytes
- sw.min.js: 7,745 Bytes
- timegrid.min.js: 31,540 Bytes
- ui-components.js: 711 Bytes
- ui-components.min.js: 305 Bytes
- user-dropdown.js: 1 Bytes
- user-dropdown.min.js: 0 Bytes
- v4-shims.js: 35,459 Bytes
- v4-shims.min.js: 28,077 Bytes
- validation-fix.js: 9,064 Bytes
- validation-fix.min.js: 5,182 Bytes
Bilder (0):
Optimierungen durchgeführt:
✅ CSS-Minifizierung
✅ JavaScript-Minifizierung
✅ Gzip-Komprimierung
✅ WebP-Bildkonvertierung
✅ Critical CSS
✅ Service Worker
✅ PWA-Manifest
Empfohlene nächste Schritte:
1. Performance-optimiertes Template verwenden
2. Service Worker aktivieren
3. HTTP/2 Push für kritische Assets
4. CDN für statische Assets konfigurieren

Binary file not shown.

View File

@ -0,0 +1,31 @@
/* CRITICAL INLINE CSS - Sollte im HTML <head> stehen */
/* Nur die absolut notwendigen Styles für First Paint */
:root{--primary:#0073ce;--bg:#fafbfc;--surface:#fff;--text:#111827;--border:#e5e7eb;--shadow:0 2px 4px rgba(0,0,0,.05)}
*{box-sizing:border-box;margin:0;padding:0;contain:layout style}
body{font-family:system-ui,-apple-system,sans-serif;background:var(--bg);color:var(--text);line-height:1.5;text-rendering:optimizeSpeed;-webkit-font-smoothing:antialiased}
.header{background:var(--surface);border-bottom:1px solid var(--border);padding:1rem;position:sticky;top:0;z-index:1000}
.nav{display:flex;gap:1rem}
.nav-item{padding:.5rem 1rem;border-radius:6px;text-decoration:none;color:#6b7280;transition:background .1s}
.nav-item:hover{background:var(--bg);color:var(--text)}
.nav-item.active{background:var(--primary);color:#fff}
.container{max-width:1200px;margin:0 auto;padding:0 1rem}
.btn{background:var(--primary);color:#fff;border:none;border-radius:6px;padding:.75rem 1.5rem;font-weight:600;cursor:pointer;transition:background .1s}
.btn:hover{background:#005a9f}
.card{background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:1rem;box-shadow:var(--shadow)}
.flex{display:flex}
.grid{display:grid;gap:1rem}
.hidden{display:none}
.w-full{width:100%}
.text-center{text-align:center}
.p-4{padding:1rem}
.mb-4{margin-bottom:1rem}
.status{display:inline-block;padding:.25rem .75rem;border-radius:999px;font-size:.75rem;font-weight:600;text-transform:uppercase}
.status-online{background:#d1fae5;color:#065f46}
.status-offline{background:#fee2e2;color:#991b1b}
.status-printing{background:#dbeafe;color:#1e40af}
.input{background:var(--surface);border:1px solid var(--border);border-radius:6px;padding:.75rem;width:100%}
.input:focus{outline:none;border-color:var(--primary)}
@media (prefers-color-scheme:dark){:root{--bg:#1e293b;--surface:#334155;--text:#f8fafc;--border:#475569;--shadow:0 2px 4px rgba(0,0,0,.3)}}
@media (max-width:768px){.nav{flex-direction:column;gap:.5rem}}
@media (prefers-reduced-motion:reduce){*{transition:none!important}}

View File

@ -0,0 +1,498 @@
/* MYP Platform - Kiosk Optimierte CSS Bundle */
/* Generiert am: 2025-06-01 23:40:46 */
/**
* MYP Platform - Kiosk-Optimierte CSS
* Maximale Performance für Offline-Kiosk-Umgebung
* Keine Touch-Events, minimale Animationen, optimierte Rendering-Performance
*/
/* ===== CRITICAL INLINE STYLES (sollten im HTML-Head stehen) ===== */
:root {
/* Reduzierte Farbvariablen für bessere Performance */
--primary: #0073ce;
--primary-dark: #005a9f;
--bg: #fafbfc;
--surface: #ffffff;
--text: #111827;
--text-muted: #6b7280;
--border: #e5e7eb;
--shadow: 0 2px 4px rgba(0,0,0,0.05);
}
/* CSS Containment für bessere Performance */
* {
contain: layout style;
}
/* Basis-Reset ohne aufwendige Normalisierung */
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: system-ui, -apple-system, sans-serif;
background: var(--bg);
color: var(--text);
line-height: 1.5;
contain: layout style paint;
/* Optimiert für Kiosk-Rendering */
text-rendering: optimizeSpeed;
-webkit-font-smoothing: antialiased;
}
/* ===== LAYOUT OPTIMIERUNGEN ===== */
.header {
background: var(--surface);
border-bottom: 1px solid var(--border);
padding: 1rem;
contain: layout style;
}
.nav {
display: flex;
gap: 1rem;
contain: layout;
}
.nav-item {
padding: 0.5rem 1rem;
border-radius: 6px;
text-decoration: none;
color: var(--text-muted);
transition: background-color 0.1s ease; /* Minimale Transition */
}
.nav-item:hover {
background: var(--bg);
color: var(--text);
}
.nav-item.active {
background: var(--primary);
color: white;
}
/* ===== OPTIMIERTE KARTEN ===== */
.card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 8px;
padding: 1rem;
box-shadow: var(--shadow);
contain: layout style paint;
}
.card:hover {
transform: translateY(-1px); /* Minimaler Hover-Effekt */
}
/* ===== BUTTONS OHNE KOMPLEXE ANIMATIONEN ===== */
.btn {
background: var(--primary);
color: white;
border: none;
border-radius: 6px;
padding: 0.75rem 1.5rem;
font-weight: 600;
cursor: pointer;
transition: background-color 0.1s ease;
contain: layout style;
}
.btn:hover {
background: var(--primary-dark);
}
.btn-secondary {
background: var(--surface);
color: var(--text);
border: 1px solid var(--border);
}
.btn-secondary:hover {
background: var(--bg);
}
/* ===== INPUTS OPTIMIERT ===== */
.input {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 6px;
padding: 0.75rem;
width: 100%;
transition: border-color 0.1s ease;
contain: layout style;
}
.input:focus {
outline: none;
border-color: var(--primary);
}
/* ===== TABELLEN OHNE KOMPLEXE EFFEKTE ===== */
.table {
width: 100%;
border-collapse: collapse;
background: var(--surface);
border-radius: 8px;
overflow: hidden;
contain: layout;
}
.table th {
background: var(--bg);
padding: 1rem;
text-align: left;
font-weight: 600;
border-bottom: 1px solid var(--border);
}
.table td {
padding: 1rem;
border-bottom: 1px solid var(--border);
}
.table tr:hover {
background: var(--bg);
}
/* ===== STATUS BADGES VEREINFACHT ===== */
.status {
display: inline-block;
padding: 0.25rem 0.75rem;
border-radius: 999px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
}
.status-online { background: #d1fae5; color: #065f46; }
.status-offline { background: #fee2e2; color: #991b1b; }
.status-printing { background: #dbeafe; color: #1e40af; }
/* ===== GRID LAYOUTS OPTIMIERT ===== */
.grid {
display: grid;
gap: 1rem;
contain: layout;
}
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
/* ===== UTILITIES MINIMAL ===== */
.flex { display: flex; contain: layout; }
.flex-col { flex-direction: column; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-1 { gap: 0.25rem; }
.gap-2 { gap: 0.5rem; }
.gap-4 { gap: 1rem; }
.p-1 { padding: 0.25rem; }
.p-2 { padding: 0.5rem; }
.p-4 { padding: 1rem; }
.p-6 { padding: 1.5rem; }
.m-1 { margin: 0.25rem; }
.m-2 { margin: 0.5rem; }
.m-4 { margin: 1rem; }
.mb-2 { margin-bottom: 0.5rem; }
.mb-4 { margin-bottom: 1rem; }
.mb-6 { margin-bottom: 1.5rem; }
.text-sm { font-size: 0.875rem; }
.text-lg { font-size: 1.125rem; }
.text-xl { font-size: 1.25rem; }
.text-2xl { font-size: 1.5rem; }
.font-semibold { font-weight: 600; }
.font-bold { font-weight: 700; }
.text-center { text-align: center; }
.text-right { text-align: right; }
.w-full { width: 100%; }
.h-full { height: 100%; }
.rounded { border-radius: 6px; }
.rounded-lg { border-radius: 8px; }
.border { border: 1px solid var(--border); }
.border-t { border-top: 1px solid var(--border); }
.border-b { border-bottom: 1px solid var(--border); }
.bg-white { background: var(--surface); }
.bg-gray-50 { background: var(--bg); }
.text-gray-600 { color: var(--text-muted); }
.text-blue-600 { color: var(--primary); }
/* ===== DARK MODE MINIMAL ===== */
@media (prefers-color-scheme: dark) {
:root {
--bg: #1e293b;
--surface: #334155;
--text: #f8fafc;
--text-muted: #94a3b8;
--border: #475569;
--shadow: 0 2px 4px rgba(0,0,0,0.3);
}
}
/* ===== RESPONSIVE FÜR KIOSK-DISPLAYS ===== */
@media (max-width: 1024px) {
.grid-4 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
.grid-4,
.grid-3,
.grid-2 { grid-template-columns: 1fr; }
.nav {
flex-direction: column;
gap: 0.5rem;
}
}
/* ===== PERFORMANCE OPTIMIERUNGEN ===== */
/* Deaktivierung nicht benötigter Features für Kiosk */
* {
/* Keine Touch-Events */
touch-action: none;
-webkit-touch-callout: none;
-webkit-user-select: none;
user-select: none;
}
/* Nur notwendige Elemente selektierbar */
input,
textarea {
-webkit-user-select: text;
user-select: text;
touch-action: manipulation;
}
/* Optimierte Scrolling-Performance */
* {
-webkit-overflow-scrolling: touch;
scroll-behavior: smooth;
}
/* GPU-Acceleration nur wo nötig */
.card:hover,
.btn:hover {
will-change: transform;
}
/* Minimale Animationen für bessere Performance */
@media (prefers-reduced-motion: reduce) {
* {
transition: none !important;
animation: none !important;
}
}
/* Print-Optimierung (falls Kiosk drucken kann) */
@media print {
.nav,
.btn {
display: none;
}
.card {
box-shadow: none;
border: 1px solid #000;
}
}
/* ===== LAYOUT SHIFT PREVENTION ===== */
img {
height: auto;
max-width: 100%;
vertical-align: middle;
}
/* Container für stabile Layouts */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
contain: layout;
}
/* ===== KIOSK-SPEZIFISCHE OPTIMIERUNGEN ===== */
/* Vollbildmodus-Unterstützung */
html,
body {
height: 100%;
overflow-x: hidden;
}
/* Fokus-Management für Keyboard-Navigation */
:focus {
outline: 2px solid var(--primary);
outline-offset: 2px;
}
/* Kein Selection-Highlighting */
::selection {
background: transparent;
}
/* Optimierte Font-Loading */
@font-face {
font-family: 'system-ui';
font-display: swap;
}
/**
* Minimales Icon-Set für Kiosk-Modus
* SVG-basierte Icons als CSS-Pseudo-Elemente für beste Performance
* Ersetzt FontAwesome für deutlich kleinere Bundle-Größe
*/
/* Icon-Basis-Klasse */
.icon {
display: inline-block;
width: 1rem;
height: 1rem;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
vertical-align: middle;
}
.icon-lg { width: 1.5rem; height: 1.5rem; }
.icon-xl { width: 2rem; height: 2rem; }
/* ===== DRUCKER ICONS ===== */
.icon-printer {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z'/%3E%3C/svg%3E");
}
.icon-print {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z'/%3E%3C/svg%3E");
}
/* ===== STATUS ICONS ===== */
.icon-check {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/%3E%3C/svg%3E");
}
.icon-warning {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23f59e0b'%3E%3Cpath d='M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z'/%3E%3C/svg%3E");
}
.icon-error {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ef4444'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z'/%3E%3C/svg%3E");
}
.icon-offline {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%236b7280'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z'/%3E%3C/svg%3E");
}
/* ===== NAVIGATION ICONS ===== */
.icon-home {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z'/%3E%3C/svg%3E");
}
.icon-settings {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19.14,12.94c0.04-0.3,0.06-0.61,0.06-0.94c0-0.32-0.02-0.64-0.07-0.94l2.03-1.58c0.18-0.14,0.23-0.41,0.12-0.61 l-1.92-3.32c-0.12-0.22-0.37-0.29-0.59-0.22l-2.39,0.96c-0.5-0.38-1.03-0.7-1.62-0.94L14.4,2.81c-0.04-0.24-0.24-0.41-0.48-0.41 h-3.84c-0.24,0-0.43,0.17-0.47,0.41L9.25,5.35C8.66,5.59,8.12,5.92,7.63,6.29L5.24,5.33c-0.22-0.08-0.47,0-0.59,0.22L2.74,8.87 C2.62,9.08,2.66,9.34,2.86,9.48l2.03,1.58C4.84,11.36,4.8,11.69,4.8,12s0.02,0.64,0.07,0.94l-2.03,1.58 c-0.18,0.14-0.23,0.41-0.12,0.61l1.92,3.32c0.12,0.22,0.37,0.29,0.59,0.22l2.39-0.96c0.5,0.38,1.03,0.7,1.62,0.94l0.36,2.54 c0.05,0.24,0.24,0.41,0.48,0.41h3.84c0.24,0,0.44-0.17,0.47-0.41l0.36-2.54c0.59-0.24,1.13-0.56,1.62-0.94l2.39,0.96 c0.22,0.08,0.47,0,0.59-0.22l1.92-3.32c0.12-0.22,0.07-0.47-0.12-0.61L19.14,12.94z M12,15.6c-1.98,0-3.6-1.62-3.6-3.6 s1.62-3.6,3.6-3.6s3.6,1.62,3.6,3.6S13.98,15.6,12,15.6z'/%3E%3C/svg%3E");
}
.icon-users {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M16 4c0-1.11.89-2 2-2s2 .89 2 2-.89 2-2 2-2-.89-2-2zm4 18v-6h2.5l-2.54-7.63A3.012 3.012 0 0 0 16.43 6c-.68 0-1.3.27-1.77.72L12 8.5l-2.66-1.78C8.87 6.27 8.25 6 7.57 6c-1.31 0-2.42.83-2.83 2L2.5 16H5v6h2v-6h2v6h2zm-6.5-10.5c.83 0 1.5-.67 1.5-1.5s-.67-1.5-1.5-1.5S12 9.17 12 10s.67 1.5 1.5 1.5z'/%3E%3C/svg%3E");
}
.icon-dashboard {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z'/%3E%3C/svg%3E");
}
/* ===== ACTION ICONS ===== */
.icon-plus {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z'/%3E%3C/svg%3E");
}
.icon-edit {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z'/%3E%3C/svg%3E");
}
.icon-delete {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ef4444'%3E%3Cpath d='M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z'/%3E%3C/svg%3E");
}
.icon-refresh {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z'/%3E%3C/svg%3E");
}
/* ===== POWER/CONNECTION ICONS ===== */
.icon-power {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M13 3h-2v10h2V3zm4.83 2.17l-1.42 1.42C17.99 7.86 19 9.81 19 12c0 3.87-3.13 7-7 7s-7-3.13-7-7c0-2.19 1.01-4.14 2.58-5.42L6.17 5.17C4.23 6.82 3 9.26 3 12c0 4.97 4.03 9 9 9s9-4.03 9-9c0-2.74-1.23-5.18-3.17-6.83z'/%3E%3C/svg%3E");
}
.icon-wifi {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M1 9l2 2c4.97-4.97 13.03-4.97 18 0l2-2C16.93 2.93 7.07 2.93 1 9zm8 8l3 3 3-3c-1.65-1.66-4.34-1.66-6 0zm-4-4l2 2c2.76-2.76 7.24-2.76 10 0l2-2C15.14 9.14 8.87 9.14 5 13z'/%3E%3C/svg%3E");
}
/* ===== DOKUMENT ICONS ===== */
.icon-file {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z'/%3E%3C/svg%3E");
}
.icon-queue {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-1 9H9V9h10v2zm-4 4H9v-2h6v2zm4-8H9V5h10v2z'/%3E%3C/svg%3E");
}
/* ===== INFO ICONS ===== */
.icon-info {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%233b82f6'%3E%3Cpath d='M12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2M13,17H11V11H13M13,9H11V7H13'/%3E%3C/svg%3E");
}
.icon-time {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M16.2,16.2L11,13V7H12.5V12.2L17,14.7L16.2,16.2Z'/%3E%3C/svg%3E");
}
/* ===== ARROW ICONS ===== */
.icon-arrow-right {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z'/%3E%3C/svg%3E");
}
.icon-arrow-down {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z'/%3E%3C/svg%3E");
}
/* ===== HOVER-STATES ===== */
.btn:hover .icon,
.nav-item:hover .icon {
opacity: 0.8;
}
/* ===== DARK MODE ===== */
@media (prefers-color-scheme: dark) {
.icon-printer,
.icon-print,
.icon-home,
.icon-settings,
.icon-users,
.icon-dashboard,
.icon-plus,
.icon-edit,
.icon-refresh,
.icon-file,
.icon-queue,
.icon-time,
.icon-arrow-right,
.icon-arrow-down {
filter: brightness(2);
}
}
/* ===== RESPONSIVE ICON-SIZES ===== */
@media (max-width: 768px) {
.icon { width: 1.25rem; height: 1.25rem; }
.icon-lg { width: 1.75rem; height: 1.75rem; }
.icon-xl { width: 2.25rem; height: 2.25rem; }
}

View File

@ -0,0 +1,497 @@
/* MYP Platform - Kiosk Optimierte CSS Bundle */
/* Generiert am: 2025-06-01 23:40:46 */
/**
* MYP Platform - Kiosk-Optimierte CSS
* Maximale Performance für Offline-Kiosk-Umgebung
* Keine Touch-Events, minimale Animationen, optimierte Rendering-Performance
*/
/* ===== CRITICAL INLINE STYLES (sollten im HTML-Head stehen) ===== */
:root {
/* Reduzierte Farbvariablen für bessere Performance */
--primary: #0073ce;
--primary-dark: #005a9f;
--bg: #fafbfc;
--surface: #ffffff;
--text: #111827;
--text-muted: #6b7280;
--border: #e5e7eb;
--shadow: 0 2px 4px rgba(0,0,0,0.05);
}
/* CSS Containment für bessere Performance */
* {
contain: layout style;
}
/* Basis-Reset ohne aufwendige Normalisierung */
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: system-ui, -apple-system, sans-serif;
background: var(--bg);
color: var(--text);
line-height: 1.5;
contain: layout style paint;
/* Optimiert für Kiosk-Rendering */
text-rendering: optimizeSpeed;
-webkit-font-smoothing: antialiased;
}
/* ===== LAYOUT OPTIMIERUNGEN ===== */
.header {
background: var(--surface);
border-bottom: 1px solid var(--border);
padding: 1rem;
contain: layout style;
}
.nav {
display: flex;
gap: 1rem;
contain: layout;
}
.nav-item {
padding: 0.5rem 1rem;
border-radius: 6px;
text-decoration: none;
color: var(--text-muted);
transition: background-color 0.1s ease; /* Minimale Transition */
}
.nav-item:hover {
background: var(--bg);
color: var(--text);
}
.nav-item.active {
background: var(--primary);
color: white;
}
/* ===== OPTIMIERTE KARTEN ===== */
.card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 8px;
padding: 1rem;
box-shadow: var(--shadow);
contain: layout style paint;
}
.card:hover {
transform: translateY(-1px); /* Minimaler Hover-Effekt */
}
/* ===== BUTTONS OHNE KOMPLEXE ANIMATIONEN ===== */
.btn {
background: var(--primary);
color: white;
border: none;
border-radius: 6px;
padding: 0.75rem 1.5rem;
font-weight: 600;
cursor: pointer;
transition: background-color 0.1s ease;
contain: layout style;
}
.btn:hover {
background: var(--primary-dark);
}
.btn-secondary {
background: var(--surface);
color: var(--text);
border: 1px solid var(--border);
}
.btn-secondary:hover {
background: var(--bg);
}
/* ===== INPUTS OPTIMIERT ===== */
.input {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 6px;
padding: 0.75rem;
width: 100%;
transition: border-color 0.1s ease;
contain: layout style;
}
.input:focus {
outline: none;
border-color: var(--primary);
}
/* ===== TABELLEN OHNE KOMPLEXE EFFEKTE ===== */
.table {
width: 100%;
border-collapse: collapse;
background: var(--surface);
border-radius: 8px;
overflow: hidden;
contain: layout;
}
.table th {
background: var(--bg);
padding: 1rem;
text-align: left;
font-weight: 600;
border-bottom: 1px solid var(--border);
}
.table td {
padding: 1rem;
border-bottom: 1px solid var(--border);
}
.table tr:hover {
background: var(--bg);
}
/* ===== STATUS BADGES VEREINFACHT ===== */
.status {
display: inline-block;
padding: 0.25rem 0.75rem;
border-radius: 999px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
}
.status-online { background: #d1fae5; color: #065f46; }
.status-offline { background: #fee2e2; color: #991b1b; }
.status-printing { background: #dbeafe; color: #1e40af; }
/* ===== GRID LAYOUTS OPTIMIERT ===== */
.grid {
display: grid;
gap: 1rem;
contain: layout;
}
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
/* ===== UTILITIES MINIMAL ===== */
.flex { display: flex; contain: layout; }
.flex-col { flex-direction: column; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-1 { gap: 0.25rem; }
.gap-2 { gap: 0.5rem; }
.gap-4 { gap: 1rem; }
.p-1 { padding: 0.25rem; }
.p-2 { padding: 0.5rem; }
.p-4 { padding: 1rem; }
.p-6 { padding: 1.5rem; }
.m-1 { margin: 0.25rem; }
.m-2 { margin: 0.5rem; }
.m-4 { margin: 1rem; }
.mb-2 { margin-bottom: 0.5rem; }
.mb-4 { margin-bottom: 1rem; }
.mb-6 { margin-bottom: 1.5rem; }
.text-sm { font-size: 0.875rem; }
.text-lg { font-size: 1.125rem; }
.text-xl { font-size: 1.25rem; }
.text-2xl { font-size: 1.5rem; }
.font-semibold { font-weight: 600; }
.font-bold { font-weight: 700; }
.text-center { text-align: center; }
.text-right { text-align: right; }
.w-full { width: 100%; }
.h-full { height: 100%; }
.rounded { border-radius: 6px; }
.rounded-lg { border-radius: 8px; }
.border { border: 1px solid var(--border); }
.border-t { border-top: 1px solid var(--border); }
.border-b { border-bottom: 1px solid var(--border); }
.bg-white { background: var(--surface); }
.bg-gray-50 { background: var(--bg); }
.text-gray-600 { color: var(--text-muted); }
.text-blue-600 { color: var(--primary); }
/* ===== DARK MODE MINIMAL ===== */
@media (prefers-color-scheme: dark) {
:root {
--bg: #1e293b;
--surface: #334155;
--text: #f8fafc;
--text-muted: #94a3b8;
--border: #475569;
--shadow: 0 2px 4px rgba(0,0,0,0.3);
}
}
/* ===== RESPONSIVE FÜR KIOSK-DISPLAYS ===== */
@media (max-width: 1024px) {
.grid-4 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
.grid-4,
.grid-3,
.grid-2 { grid-template-columns: 1fr; }
.nav {
flex-direction: column;
gap: 0.5rem;
}
}
/* ===== PERFORMANCE OPTIMIERUNGEN ===== */
/* Deaktivierung nicht benötigter Features für Kiosk */
* {
/* Keine Touch-Events */
touch-action: none;
-webkit-touch-callout: none;
-webkit-user-select: none;
user-select: none;
}
/* Nur notwendige Elemente selektierbar */
input,
textarea {
-webkit-user-select: text;
user-select: text;
touch-action: manipulation;
}
/* Optimierte Scrolling-Performance */
* {
-webkit-overflow-scrolling: touch;
scroll-behavior: smooth;
}
/* GPU-Acceleration nur wo nötig */
.card:hover,
.btn:hover {
will-change: transform;
}
/* Minimale Animationen für bessere Performance */
@media (prefers-reduced-motion: reduce) {
* {
transition: none !important;
animation: none !important;
}
}
/* Print-Optimierung (falls Kiosk drucken kann) */
@media print {
.nav,
.btn {
display: none;
}
.card {
box-shadow: none;
border: 1px solid #000;
}
}
/* ===== LAYOUT SHIFT PREVENTION ===== */
img {
height: auto;
max-width: 100%;
vertical-align: middle;
}
/* Container für stabile Layouts */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
contain: layout;
}
/* ===== KIOSK-SPEZIFISCHE OPTIMIERUNGEN ===== */
/* Vollbildmodus-Unterstützung */
html,
body {
height: 100%;
overflow-x: hidden;
}
/* Fokus-Management für Keyboard-Navigation */
:focus {
outline: 2px solid var(--primary);
outline-offset: 2px;
}
/* Kein Selection-Highlighting */
::selection {
background: transparent;
}
/* Optimierte Font-Loading */
@font-face {
font-family: 'system-ui';
font-display: swap;
}
/**
* Minimales Icon-Set für Kiosk-Modus
* SVG-basierte Icons als CSS-Pseudo-Elemente für beste Performance
*/
/* Icon-Basis-Klasse */
.icon {
display: inline-block;
width: 1rem;
height: 1rem;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
vertical-align: middle;
}
.icon-lg { width: 1.5rem; height: 1.5rem; }
.icon-xl { width: 2rem; height: 2rem; }
/* ===== DRUCKER ICONS ===== */
.icon-printer {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z'/%3E%3C/svg%3E");
}
.icon-print {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z'/%3E%3C/svg%3E");
}
/* ===== STATUS ICONS ===== */
.icon-check {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/%3E%3C/svg%3E");
}
.icon-warning {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23f59e0b'%3E%3Cpath d='M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z'/%3E%3C/svg%3E");
}
.icon-error {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ef4444'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z'/%3E%3C/svg%3E");
}
.icon-offline {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%236b7280'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z'/%3E%3C/svg%3E");
}
/* ===== NAVIGATION ICONS ===== */
.icon-home {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z'/%3E%3C/svg%3E");
}
.icon-settings {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19.14,12.94c0.04-0.3,0.06-0.61,0.06-0.94c0-0.32-0.02-0.64-0.07-0.94l2.03-1.58c0.18-0.14,0.23-0.41,0.12-0.61 l-1.92-3.32c-0.12-0.22-0.37-0.29-0.59-0.22l-2.39,0.96c-0.5-0.38-1.03-0.7-1.62-0.94L14.4,2.81c-0.04-0.24-0.24-0.41-0.48-0.41 h-3.84c-0.24,0-0.43,0.17-0.47,0.41L9.25,5.35C8.66,5.59,8.12,5.92,7.63,6.29L5.24,5.33c-0.22-0.08-0.47,0-0.59,0.22L2.74,8.87 C2.62,9.08,2.66,9.34,2.86,9.48l2.03,1.58C4.84,11.36,4.8,11.69,4.8,12s0.02,0.64,0.07,0.94l-2.03,1.58 c-0.18,0.14-0.23,0.41-0.12,0.61l1.92,3.32c0.12,0.22,0.37,0.29,0.59,0.22l2.39-0.96c0.5,0.38,1.03,0.7,1.62,0.94l0.36,2.54 c0.05,0.24,0.24,0.41,0.48,0.41h3.84c0.24,0,0.44-0.17,0.47-0.41l0.36-2.54c0.59-0.24,1.13-0.56,1.62-0.94l2.39,0.96 c0.22,0.08,0.47,0,0.59-0.22l1.92-3.32c0.12-0.22,0.07-0.47-0.12-0.61L19.14,12.94z M12,15.6c-1.98,0-3.6-1.62-3.6-3.6 s1.62-3.6,3.6-3.6s3.6,1.62,3.6,3.6S13.98,15.6,12,15.6z'/%3E%3C/svg%3E");
}
.icon-users {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M16 4c0-1.11.89-2 2-2s2 .89 2 2-.89 2-2 2-2-.89-2-2zm4 18v-6h2.5l-2.54-7.63A3.012 3.012 0 0 0 16.43 6c-.68 0-1.3.27-1.77.72L12 8.5l-2.66-1.78C8.87 6.27 8.25 6 7.57 6c-1.31 0-2.42.83-2.83 2L2.5 16H5v6h2v-6h2v6h2zm-6.5-10.5c.83 0 1.5-.67 1.5-1.5s-.67-1.5-1.5-1.5S12 9.17 12 10s.67 1.5 1.5 1.5z'/%3E%3C/svg%3E");
}
.icon-dashboard {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z'/%3E%3C/svg%3E");
}
/* ===== ACTION ICONS ===== */
.icon-plus {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z'/%3E%3C/svg%3E");
}
.icon-edit {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z'/%3E%3C/svg%3E");
}
.icon-delete {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ef4444'%3E%3Cpath d='M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z'/%3E%3C/svg%3E");
}
.icon-refresh {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z'/%3E%3C/svg%3E");
}
/* ===== POWER/CONNECTION ICONS ===== */
.icon-power {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M13 3h-2v10h2V3zm4.83 2.17l-1.42 1.42C17.99 7.86 19 9.81 19 12c0 3.87-3.13 7-7 7s-7-3.13-7-7c0-2.19 1.01-4.14 2.58-5.42L6.17 5.17C4.23 6.82 3 9.26 3 12c0 4.97 4.03 9 9 9s9-4.03 9-9c0-2.74-1.23-5.18-3.17-6.83z'/%3E%3C/svg%3E");
}
.icon-wifi {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M1 9l2 2c4.97-4.97 13.03-4.97 18 0l2-2C16.93 2.93 7.07 2.93 1 9zm8 8l3 3 3-3c-1.65-1.66-4.34-1.66-6 0zm-4-4l2 2c2.76-2.76 7.24-2.76 10 0l2-2C15.14 9.14 8.87 9.14 5 13z'/%3E%3C/svg%3E");
}
/* ===== DOKUMENT ICONS ===== */
.icon-file {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z'/%3E%3C/svg%3E");
}
.icon-queue {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-1 9H9V9h10v2zm-4 4H9v-2h6v2zm4-8H9V5h10v2z'/%3E%3C/svg%3E");
}
/* ===== INFO ICONS ===== */
.icon-info {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%233b82f6'%3E%3Cpath d='M12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2M13,17H11V11H13M13,9H11V7H13'/%3E%3C/svg%3E");
}
.icon-time {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M16.2,16.2L11,13V7H12.5V12.2L17,14.7L16.2,16.2Z'/%3E%3C/svg%3E");
}
/* ===== ARROW ICONS ===== */
.icon-arrow-right {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z'/%3E%3C/svg%3E");
}
.icon-arrow-down {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z'/%3E%3C/svg%3E");
}
/* ===== HOVER-STATES ===== */
.btn:hover .icon,
.nav-item:hover .icon {
opacity: 0.8;
}
/* ===== DARK MODE ===== */
@media (prefers-color-scheme: dark) {
.icon-printer,
.icon-print,
.icon-home,
.icon-settings,
.icon-users,
.icon-dashboard,
.icon-plus,
.icon-edit,
.icon-refresh,
.icon-file,
.icon-queue,
.icon-time,
.icon-arrow-right,
.icon-arrow-down {
filter: brightness(2);
}
}
/* ===== RESPONSIVE ICON-SIZES ===== */
@media (max-width: 768px) {
.icon { width: 1.25rem; height: 1.25rem; }
.icon-lg { width: 1.75rem; height: 1.75rem; }
.icon-xl { width: 2.25rem; height: 2.25rem; }
}

View File

@ -0,0 +1,498 @@
/* MYP Platform - Kiosk Optimierte CSS Bundle */
/* Generiert am: 2025-06-01 23:40:46 */
/**
* MYP Platform - Kiosk-Optimierte CSS
* Maximale Performance für Offline-Kiosk-Umgebung
* Keine Touch-Events, minimale Animationen, optimierte Rendering-Performance
*/
/* ===== CRITICAL INLINE STYLES (sollten im HTML-Head stehen) ===== */
:root {
/* Reduzierte Farbvariablen für bessere Performance */
--primary: #0073ce;
--primary-dark: #005a9f;
--bg: #fafbfc;
--surface: #ffffff;
--text: #111827;
--text-muted: #6b7280;
--border: #e5e7eb;
--shadow: 0 2px 4px rgba(0,0,0,0.05);
}
/* CSS Containment für bessere Performance */
* {
contain: layout style;
}
/* Basis-Reset ohne aufwendige Normalisierung */
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: system-ui, -apple-system, sans-serif;
background: var(--bg);
color: var(--text);
line-height: 1.5;
contain: layout style paint;
/* Optimiert für Kiosk-Rendering */
text-rendering: optimizeSpeed;
-webkit-font-smoothing: antialiased;
}
/* ===== LAYOUT OPTIMIERUNGEN ===== */
.header {
background: var(--surface);
border-bottom: 1px solid var(--border);
padding: 1rem;
contain: layout style;
}
.nav {
display: flex;
gap: 1rem;
contain: layout;
}
.nav-item {
padding: 0.5rem 1rem;
border-radius: 6px;
text-decoration: none;
color: var(--text-muted);
transition: background-color 0.1s ease; /* Minimale Transition */
}
.nav-item:hover {
background: var(--bg);
color: var(--text);
}
.nav-item.active {
background: var(--primary);
color: white;
}
/* ===== OPTIMIERTE KARTEN ===== */
.card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 8px;
padding: 1rem;
box-shadow: var(--shadow);
contain: layout style paint;
}
.card:hover {
transform: translateY(-1px); /* Minimaler Hover-Effekt */
}
/* ===== BUTTONS OHNE KOMPLEXE ANIMATIONEN ===== */
.btn {
background: var(--primary);
color: white;
border: none;
border-radius: 6px;
padding: 0.75rem 1.5rem;
font-weight: 600;
cursor: pointer;
transition: background-color 0.1s ease;
contain: layout style;
}
.btn:hover {
background: var(--primary-dark);
}
.btn-secondary {
background: var(--surface);
color: var(--text);
border: 1px solid var(--border);
}
.btn-secondary:hover {
background: var(--bg);
}
/* ===== INPUTS OPTIMIERT ===== */
.input {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 6px;
padding: 0.75rem;
width: 100%;
transition: border-color 0.1s ease;
contain: layout style;
}
.input:focus {
outline: none;
border-color: var(--primary);
}
/* ===== TABELLEN OHNE KOMPLEXE EFFEKTE ===== */
.table {
width: 100%;
border-collapse: collapse;
background: var(--surface);
border-radius: 8px;
overflow: hidden;
contain: layout;
}
.table th {
background: var(--bg);
padding: 1rem;
text-align: left;
font-weight: 600;
border-bottom: 1px solid var(--border);
}
.table td {
padding: 1rem;
border-bottom: 1px solid var(--border);
}
.table tr:hover {
background: var(--bg);
}
/* ===== STATUS BADGES VEREINFACHT ===== */
.status {
display: inline-block;
padding: 0.25rem 0.75rem;
border-radius: 999px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
}
.status-online { background: #d1fae5; color: #065f46; }
.status-offline { background: #fee2e2; color: #991b1b; }
.status-printing { background: #dbeafe; color: #1e40af; }
/* ===== GRID LAYOUTS OPTIMIERT ===== */
.grid {
display: grid;
gap: 1rem;
contain: layout;
}
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
/* ===== UTILITIES MINIMAL ===== */
.flex { display: flex; contain: layout; }
.flex-col { flex-direction: column; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-1 { gap: 0.25rem; }
.gap-2 { gap: 0.5rem; }
.gap-4 { gap: 1rem; }
.p-1 { padding: 0.25rem; }
.p-2 { padding: 0.5rem; }
.p-4 { padding: 1rem; }
.p-6 { padding: 1.5rem; }
.m-1 { margin: 0.25rem; }
.m-2 { margin: 0.5rem; }
.m-4 { margin: 1rem; }
.mb-2 { margin-bottom: 0.5rem; }
.mb-4 { margin-bottom: 1rem; }
.mb-6 { margin-bottom: 1.5rem; }
.text-sm { font-size: 0.875rem; }
.text-lg { font-size: 1.125rem; }
.text-xl { font-size: 1.25rem; }
.text-2xl { font-size: 1.5rem; }
.font-semibold { font-weight: 600; }
.font-bold { font-weight: 700; }
.text-center { text-align: center; }
.text-right { text-align: right; }
.w-full { width: 100%; }
.h-full { height: 100%; }
.rounded { border-radius: 6px; }
.rounded-lg { border-radius: 8px; }
.border { border: 1px solid var(--border); }
.border-t { border-top: 1px solid var(--border); }
.border-b { border-bottom: 1px solid var(--border); }
.bg-white { background: var(--surface); }
.bg-gray-50 { background: var(--bg); }
.text-gray-600 { color: var(--text-muted); }
.text-blue-600 { color: var(--primary); }
/* ===== DARK MODE MINIMAL ===== */
@media (prefers-color-scheme: dark) {
:root {
--bg: #1e293b;
--surface: #334155;
--text: #f8fafc;
--text-muted: #94a3b8;
--border: #475569;
--shadow: 0 2px 4px rgba(0,0,0,0.3);
}
}
/* ===== RESPONSIVE FÜR KIOSK-DISPLAYS ===== */
@media (max-width: 1024px) {
.grid-4 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
.grid-4,
.grid-3,
.grid-2 { grid-template-columns: 1fr; }
.nav {
flex-direction: column;
gap: 0.5rem;
}
}
/* ===== PERFORMANCE OPTIMIERUNGEN ===== */
/* Deaktivierung nicht benötigter Features für Kiosk */
* {
/* Keine Touch-Events */
touch-action: none;
-webkit-touch-callout: none;
-webkit-user-select: none;
user-select: none;
}
/* Nur notwendige Elemente selektierbar */
input,
textarea {
-webkit-user-select: text;
user-select: text;
touch-action: manipulation;
}
/* Optimierte Scrolling-Performance */
* {
-webkit-overflow-scrolling: touch;
scroll-behavior: smooth;
}
/* GPU-Acceleration nur wo nötig */
.card:hover,
.btn:hover {
will-change: transform;
}
/* Minimale Animationen für bessere Performance */
@media (prefers-reduced-motion: reduce) {
* {
transition: none !important;
animation: none !important;
}
}
/* Print-Optimierung (falls Kiosk drucken kann) */
@media print {
.nav,
.btn {
display: none;
}
.card {
box-shadow: none;
border: 1px solid #000;
}
}
/* ===== LAYOUT SHIFT PREVENTION ===== */
img {
height: auto;
max-width: 100%;
vertical-align: middle;
}
/* Container für stabile Layouts */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
contain: layout;
}
/* ===== KIOSK-SPEZIFISCHE OPTIMIERUNGEN ===== */
/* Vollbildmodus-Unterstützung */
html,
body {
height: 100%;
overflow-x: hidden;
}
/* Fokus-Management für Keyboard-Navigation */
:focus {
outline: 2px solid var(--primary);
outline-offset: 2px;
}
/* Kein Selection-Highlighting */
::selection {
background: transparent;
}
/* Optimierte Font-Loading */
@font-face {
font-family: 'system-ui';
font-display: swap;
}
/**
* Minimales Icon-Set für Kiosk-Modus
* SVG-basierte Icons als CSS-Pseudo-Elemente für beste Performance
* Ersetzt FontAwesome für deutlich kleinere Bundle-Größe
*/
/* Icon-Basis-Klasse */
.icon {
display: inline-block;
width: 1rem;
height: 1rem;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
vertical-align: middle;
}
.icon-lg { width: 1.5rem; height: 1.5rem; }
.icon-xl { width: 2rem; height: 2rem; }
/* ===== DRUCKER ICONS ===== */
.icon-printer {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z'/%3E%3C/svg%3E");
}
.icon-print {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z'/%3E%3C/svg%3E");
}
/* ===== STATUS ICONS ===== */
.icon-check {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/%3E%3C/svg%3E");
}
.icon-warning {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23f59e0b'%3E%3Cpath d='M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z'/%3E%3C/svg%3E");
}
.icon-error {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ef4444'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z'/%3E%3C/svg%3E");
}
.icon-offline {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%236b7280'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z'/%3E%3C/svg%3E");
}
/* ===== NAVIGATION ICONS ===== */
.icon-home {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z'/%3E%3C/svg%3E");
}
.icon-settings {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19.14,12.94c0.04-0.3,0.06-0.61,0.06-0.94c0-0.32-0.02-0.64-0.07-0.94l2.03-1.58c0.18-0.14,0.23-0.41,0.12-0.61 l-1.92-3.32c-0.12-0.22-0.37-0.29-0.59-0.22l-2.39,0.96c-0.5-0.38-1.03-0.7-1.62-0.94L14.4,2.81c-0.04-0.24-0.24-0.41-0.48-0.41 h-3.84c-0.24,0-0.43,0.17-0.47,0.41L9.25,5.35C8.66,5.59,8.12,5.92,7.63,6.29L5.24,5.33c-0.22-0.08-0.47,0-0.59,0.22L2.74,8.87 C2.62,9.08,2.66,9.34,2.86,9.48l2.03,1.58C4.84,11.36,4.8,11.69,4.8,12s0.02,0.64,0.07,0.94l-2.03,1.58 c-0.18,0.14-0.23,0.41-0.12,0.61l1.92,3.32c0.12,0.22,0.37,0.29,0.59,0.22l2.39-0.96c0.5,0.38,1.03,0.7,1.62,0.94l0.36,2.54 c0.05,0.24,0.24,0.41,0.48,0.41h3.84c0.24,0,0.44-0.17,0.47-0.41l0.36-2.54c0.59-0.24,1.13-0.56,1.62-0.94l2.39,0.96 c0.22,0.08,0.47,0,0.59-0.22l1.92-3.32c0.12-0.22,0.07-0.47-0.12-0.61L19.14,12.94z M12,15.6c-1.98,0-3.6-1.62-3.6-3.6 s1.62-3.6,3.6-3.6s3.6,1.62,3.6,3.6S13.98,15.6,12,15.6z'/%3E%3C/svg%3E");
}
.icon-users {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M16 4c0-1.11.89-2 2-2s2 .89 2 2-.89 2-2 2-2-.89-2-2zm4 18v-6h2.5l-2.54-7.63A3.012 3.012 0 0 0 16.43 6c-.68 0-1.3.27-1.77.72L12 8.5l-2.66-1.78C8.87 6.27 8.25 6 7.57 6c-1.31 0-2.42.83-2.83 2L2.5 16H5v6h2v-6h2v6h2zm-6.5-10.5c.83 0 1.5-.67 1.5-1.5s-.67-1.5-1.5-1.5S12 9.17 12 10s.67 1.5 1.5 1.5z'/%3E%3C/svg%3E");
}
.icon-dashboard {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z'/%3E%3C/svg%3E");
}
/* ===== ACTION ICONS ===== */
.icon-plus {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z'/%3E%3C/svg%3E");
}
.icon-edit {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z'/%3E%3C/svg%3E");
}
.icon-delete {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ef4444'%3E%3Cpath d='M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z'/%3E%3C/svg%3E");
}
.icon-refresh {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z'/%3E%3C/svg%3E");
}
/* ===== POWER/CONNECTION ICONS ===== */
.icon-power {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M13 3h-2v10h2V3zm4.83 2.17l-1.42 1.42C17.99 7.86 19 9.81 19 12c0 3.87-3.13 7-7 7s-7-3.13-7-7c0-2.19 1.01-4.14 2.58-5.42L6.17 5.17C4.23 6.82 3 9.26 3 12c0 4.97 4.03 9 9 9s9-4.03 9-9c0-2.74-1.23-5.18-3.17-6.83z'/%3E%3C/svg%3E");
}
.icon-wifi {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M1 9l2 2c4.97-4.97 13.03-4.97 18 0l2-2C16.93 2.93 7.07 2.93 1 9zm8 8l3 3 3-3c-1.65-1.66-4.34-1.66-6 0zm-4-4l2 2c2.76-2.76 7.24-2.76 10 0l2-2C15.14 9.14 8.87 9.14 5 13z'/%3E%3C/svg%3E");
}
/* ===== DOKUMENT ICONS ===== */
.icon-file {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z'/%3E%3C/svg%3E");
}
.icon-queue {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-1 9H9V9h10v2zm-4 4H9v-2h6v2zm4-8H9V5h10v2z'/%3E%3C/svg%3E");
}
/* ===== INFO ICONS ===== */
.icon-info {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%233b82f6'%3E%3Cpath d='M12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2M13,17H11V11H13M13,9H11V7H13'/%3E%3C/svg%3E");
}
.icon-time {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M16.2,16.2L11,13V7H12.5V12.2L17,14.7L16.2,16.2Z'/%3E%3C/svg%3E");
}
/* ===== ARROW ICONS ===== */
.icon-arrow-right {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z'/%3E%3C/svg%3E");
}
.icon-arrow-down {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z'/%3E%3C/svg%3E");
}
/* ===== HOVER-STATES ===== */
.btn:hover .icon,
.nav-item:hover .icon {
opacity: 0.8;
}
/* ===== DARK MODE ===== */
@media (prefers-color-scheme: dark) {
.icon-printer,
.icon-print,
.icon-home,
.icon-settings,
.icon-users,
.icon-dashboard,
.icon-plus,
.icon-edit,
.icon-refresh,
.icon-file,
.icon-queue,
.icon-time,
.icon-arrow-right,
.icon-arrow-down {
filter: brightness(2);
}
}
/* ===== RESPONSIVE ICON-SIZES ===== */
@media (max-width: 768px) {
.icon { width: 1.25rem; height: 1.25rem; }
.icon-lg { width: 1.75rem; height: 1.75rem; }
.icon-xl { width: 2.25rem; height: 2.25rem; }
}

View File

@ -0,0 +1,288 @@
/**
* MYP Platform - CSS Caching-Optimierungen
* Performance-optimierte Styles für besseres Caching und schnellere Ladezeiten
*/
/* ===== KRITISCHE ABOVE-THE-FOLD STYLES ===== */
/* Diese Styles sollten inline im HTML-Head geladen werden */
.critical-header {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(8px);
position: sticky;
top: 0;
z-index: 1000;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}
.critical-nav {
display: flex;
align-items: center;
padding: 1rem;
max-width: 1200px;
margin: 0 auto;
}
.critical-logo {
font-weight: 700;
font-size: 1.25rem;
color: #0073ce;
}
.critical-main {
min-height: 100vh;
background: linear-gradient(135deg, #fafbfc 0%, #f5f7f9 100%);
}
/* ===== LAZY LOADING PLACEHOLDER ===== */
.lazy-placeholder {
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
background-size: 200% 100%;
animation: skeleton-loading 1.5s infinite ease-in-out;
border-radius: 4px;
}
@keyframes skeleton-loading {
0% {
background-position: 200% 0;
}
100% {
background-position: -200% 0;
}
}
.dark .lazy-placeholder {
background: linear-gradient(90deg, #374151 25%, #4b5563 50%, #374151 75%);
background-size: 200% 100%;
}
/* ===== PRELOAD HINTS ===== */
.preload-image {
content-visibility: auto;
contain-intrinsic-size: 300px 200px;
}
.preload-component {
content-visibility: auto;
contain-intrinsic-size: 100px;
}
/* ===== CACHE-OPTIMIERTE KOMPONENTEN ===== */
.cache-card {
background: rgba(255, 255, 255, 0.9);
border: 1px solid rgba(229, 231, 235, 0.5);
border-radius: 8px;
padding: 1rem;
margin-bottom: 1rem;
transition: transform 0.2s ease;
contain: layout style paint;
}
.cache-card:hover {
transform: translateY(-1px);
}
.cache-button {
background: #0073ce;
color: white;
border: none;
border-radius: 6px;
padding: 0.5rem 1rem;
font-weight: 600;
transition: background-color 0.2s ease;
contain: layout style;
}
.cache-button:hover {
background: #005a9f;
}
.cache-input {
background: rgba(255, 255, 255, 0.9);
border: 1px solid rgba(229, 231, 235, 0.8);
border-radius: 4px;
padding: 0.5rem;
transition: border-color 0.2s ease;
contain: layout style;
}
.cache-input:focus {
outline: none;
border-color: #0073ce;
box-shadow: 0 0 0 2px rgba(0, 115, 206, 0.1);
}
/* ===== LAYOUT SHIFT PREVENTION ===== */
.prevent-cls {
min-height: 200px; /* Prevent layout shift */
contain: layout;
}
.image-container {
aspect-ratio: 16/9;
overflow: hidden;
border-radius: 8px;
background: #f3f4f6;
}
.image-container img {
width: 100%;
height: 100%;
object-fit: cover;
transition: opacity 0.3s ease;
}
.image-container img[loading="lazy"] {
opacity: 0;
}
.image-container img[loading="lazy"].loaded {
opacity: 1;
}
/* ===== OPTIMIERTE TYPOGRAPHY ===== */
.text-heading {
font-weight: 700;
line-height: 1.2;
color: #111827;
contain: layout style;
}
.text-body {
line-height: 1.6;
color: #374151;
contain: layout style;
}
.text-muted {
color: #6b7280;
contain: layout style;
}
/* ===== DARK MODE CACHE OPTIMIZATIONS ===== */
.dark .cache-card {
background: rgba(30, 41, 59, 0.9);
border-color: rgba(100, 116, 139, 0.3);
}
.dark .cache-input {
background: rgba(30, 41, 59, 0.9);
border-color: rgba(100, 116, 139, 0.5);
color: #e2e8f0;
}
.dark .text-heading {
color: #f8fafc;
}
.dark .text-body {
color: #e2e8f0;
}
.dark .text-muted {
color: #94a3b8;
}
.dark .image-container {
background: #374151;
}
/* ===== RESPONSIVE OPTIMIZATIONS ===== */
@media (max-width: 768px) {
.critical-nav {
padding: 0.75rem;
}
.cache-card {
padding: 0.75rem;
margin-bottom: 0.75rem;
}
.cache-button {
padding: 0.75rem 1.25rem;
font-size: 0.875rem;
}
}
/* ===== PRINT OPTIMIZATIONS ===== */
@media print {
.critical-header,
.cache-button {
display: none;
}
.cache-card {
box-shadow: none;
border: 1px solid #000;
break-inside: avoid;
}
}
/* ===== GPU ACCELERATION HINTS ===== */
.gpu-accelerated {
transform: translateZ(0);
will-change: transform;
}
/* ===== EFFICIENT ANIMATIONS ===== */
.fade-in-optimized {
opacity: 0;
transform: translateY(10px);
transition: opacity 0.3s ease, transform 0.3s ease;
}
.fade-in-optimized.visible {
opacity: 1;
transform: translateY(0);
}
/* ===== CONTAINER QUERIES SUPPORT ===== */
@container (min-width: 300px) {
.cache-card {
display: grid;
grid-template-columns: 1fr auto;
gap: 1rem;
align-items: center;
}
}
/* ===== CONTENT VISIBILITY OPTIMIZATIONS ===== */
.auto-height {
content-visibility: auto;
contain-intrinsic-size: 0 200px;
}
.hidden-content {
content-visibility: hidden;
}
/* ===== REDUCED MOTION PREFERENCES ===== */
@media (prefers-reduced-motion: reduce) {
.fade-in-optimized,
.cache-card,
.cache-button,
.cache-input {
transition: none !important;
}
.lazy-placeholder {
animation: none !important;
background: #f0f0f0 !important;
}
}
/* ===== HIGH CONTRAST MODE ===== */
@media (prefers-contrast: high) {
.cache-card {
border-width: 2px;
border-color: #000;
}
.cache-button {
border: 2px solid #000;
}
.cache-input {
border-width: 2px;
border-color: #000;
}
}

Binary file not shown.

View File

@ -0,0 +1 @@
.critical-header{background:rgba(255,255,255,0.95);backdrop-filter:blur(8px);position:sticky;top:0;z-index:1000;box-shadow:0 2px 8px rgba(0,0,0,0.06)}.critical-nav{display:flex;align-items:center;padding:1rem;max-width:1200px;margin:0 auto}.critical-logo{font-weight:700;font-size:1.25rem;color:#0073ce}.critical-main{min-height:100vh;background:linear-gradient(135deg,#fafbfc 0,#f5f7f9 100%)}.lazy-placeholder{background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:skeleton-loading 1.5s infinite ease-in-out;border-radius:4px}@keyframes skeleton-loading{0%{background-position:200% 0}100%{background-position:-200% 0}}.dark .lazy-placeholder{background:linear-gradient(90deg,#374151 25%,#4b5563 50%,#374151 75%);background-size:200% 100%}.preload-image{content-visibility:auto;contain-intrinsic-size:300px 200px}.preload-component{content-visibility:auto;contain-intrinsic-size:100px}.cache-card{background:rgba(255,255,255,0.9);border:1px solid rgba(229,231,235,0.5);border-radius:8px;padding:1rem;margin-bottom:1rem;transition:transform .2s ease;contain:layout style paint}.cache-card:hover{transform:translateY(-1px)}.cache-button{background:#0073ce;color:white;border:0;border-radius:6px;padding:.5rem 1rem;font-weight:600;transition:background-color .2s ease;contain:layout style}.cache-button:hover{background:#005a9f}.cache-input{background:rgba(255,255,255,0.9);border:1px solid rgba(229,231,235,0.8);border-radius:4px;padding:.5rem;transition:border-color .2s ease;contain:layout style}.cache-input:focus{outline:0;border-color:#0073ce;box-shadow:0 0 0 2px rgba(0,115,206,0.1)}.prevent-cls{min-height:200px;contain:layout}.image-container{aspect-ratio:16/9;overflow:hidden;border-radius:8px;background:#f3f4f6}.image-container img{width:100%;height:100%;object-fit:cover;transition:opacity .3s ease}.image-container img[loading="lazy"]{opacity:0}.image-container img[loading="lazy"].loaded{opacity:1}.text-heading{font-weight:700;line-height:1.2;color:#111827;contain:layout style}.text-body{line-height:1.6;color:#374151;contain:layout style}.text-muted{color:#6b7280;contain:layout style}.dark .cache-card{background:rgba(30,41,59,0.9);border-color:rgba(100,116,139,0.3)}.dark .cache-input{background:rgba(30,41,59,0.9);border-color:rgba(100,116,139,0.5);color:#e2e8f0}.dark .text-heading{color:#f8fafc}.dark .text-body{color:#e2e8f0}.dark .text-muted{color:#94a3b8}.dark .image-container{background:#374151}@media(max-width:768px){.critical-nav{padding:.75rem}.cache-card{padding:.75rem;margin-bottom:.75rem}.cache-button{padding:.75rem 1.25rem;font-size:.875rem}}@media print{.critical-header,.cache-button{display:none}.cache-card{box-shadow:none;border:1px solid #000;break-inside:avoid}}.gpu-accelerated{transform:translateZ(0);will-change:transform}.fade-in-optimized{opacity:0;transform:translateY(10px);transition:opacity .3s ease,transform .3s ease}.fade-in-optimized.visible{opacity:1;transform:translateY(0)}@container(min-width:300px){.cache-card{display:grid;grid-template-columns:1fr auto;gap:1rem;align-items:center}}.auto-height{content-visibility:auto;contain-intrinsic-size:0 200px}.hidden-content{content-visibility:hidden}@media(prefers-reduced-motion:reduce){.fade-in-optimized,.cache-card,.cache-button,.cache-input{transition:none !important}.lazy-placeholder{animation:none !important;background:#f0f0f0 !important}}@media(prefers-contrast:high){.cache-card{border-width:2px;border-color:#000}.cache-button{border:2px solid #000}.cache-input{border-width:2px;border-color:#000}}

Binary file not shown.

Binary file not shown.

1
backend/static/css/components.min.css vendored Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -0,0 +1,31 @@
/* CRITICAL INLINE CSS - Sollte im HTML <head> stehen */
/* Nur die absolut notwendigen Styles für First Paint */
:root{--primary:#0073ce;--bg:#fafbfc;--surface:#fff;--text:#111827;--border:#e5e7eb;--shadow:0 2px 4px rgba(0,0,0,.05)}
*{box-sizing:border-box;margin:0;padding:0;contain:layout style}
body{font-family:system-ui,-apple-system,sans-serif;background:var(--bg);color:var(--text);line-height:1.5;text-rendering:optimizeSpeed;-webkit-font-smoothing:antialiased}
.header{background:var(--surface);border-bottom:1px solid var(--border);padding:1rem;position:sticky;top:0;z-index:1000}
.nav{display:flex;gap:1rem}
.nav-item{padding:.5rem 1rem;border-radius:6px;text-decoration:none;color:#6b7280;transition:background .1s}
.nav-item:hover{background:var(--bg);color:var(--text)}
.nav-item.active{background:var(--primary);color:#fff}
.container{max-width:1200px;margin:0 auto;padding:0 1rem}
.btn{background:var(--primary);color:#fff;border:none;border-radius:6px;padding:.75rem 1.5rem;font-weight:600;cursor:pointer;transition:background .1s}
.btn:hover{background:#005a9f}
.card{background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:1rem;box-shadow:var(--shadow)}
.flex{display:flex}
.grid{display:grid;gap:1rem}
.hidden{display:none}
.w-full{width:100%}
.text-center{text-align:center}
.p-4{padding:1rem}
.mb-4{margin-bottom:1rem}
.status{display:inline-block;padding:.25rem .75rem;border-radius:999px;font-size:.75rem;font-weight:600;text-transform:uppercase}
.status-online{background:#d1fae5;color:#065f46}
.status-offline{background:#fee2e2;color:#991b1b}
.status-printing{background:#dbeafe;color:#1e40af}
.input{background:var(--surface);border:1px solid var(--border);border-radius:6px;padding:.75rem;width:100%}
.input:focus{outline:none;border-color:var(--primary)}
@media (prefers-color-scheme:dark){:root{--bg:#1e293b;--surface:#334155;--text:#f8fafc;--border:#475569;--shadow:0 2px 4px rgba(0,0,0,.3)}}
@media (max-width:768px){.nav{flex-direction:column;gap:.5rem}}
@media (prefers-reduced-motion:reduce){*{transition:none!important}}

Binary file not shown.

View File

@ -0,0 +1 @@
*,*::before,*::after{box-sizing:border-box}body{margin:0;font-family:system-ui,-apple-system,sans-serif;line-height:1.6;color:#111827;background:#fafbfc}.critical-header{position:sticky;top:0;z-index:1000;background:rgba(255,255,255,0.95);backdrop-filter:blur(8px);border-bottom:1px solid #e5e7eb}.critical-nav{display:flex;align-items:center;justify-content:space-between;padding:1rem;max-width:1200px;margin:0 auto}.critical-logo{font-weight:700;font-size:1.25rem;color:#0073ce;text-decoration:none}.critical-main{min-height:100vh;padding:2rem 1rem}.critical-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:1.5rem;max-width:1200px;margin:0 auto}.critical-card{background:#fff;border:1px solid #e5e7eb;border-radius:8px;padding:1.5rem;box-shadow:0 1px 3px rgba(0,0,0,0.1)}.btn-primary{background:#0073ce;color:#fff;border:0;border-radius:6px;padding:.75rem 1.5rem;font-weight:600;cursor:pointer;text-decoration:none;display:inline-block}.loading{opacity:.6;pointer-events:none}.hidden{display:none}@media(max-width:768px){.critical-nav{padding:.75rem}.critical-main{padding:1rem}.critical-grid{grid-template-columns:1fr}.critical-card{padding:1rem}}@media(prefers-color-scheme:dark){body{background:#0f172a;color:#f8fafc}.critical-header{background:rgba(15,23,42,0.95);border-bottom-color:#334155}.critical-card{background:#1e293b;border-color:#334155;color:#f8fafc}}

Binary file not shown.

View File

@ -1,485 +1,255 @@
/* Enhanced Glassmorphism Effects for MYP Application */
/* Vereinfachte Glassmorphism-Effekte für MYP Application */
/* Base Glass Effects */
/* ===== BASIS GLASS EFFEKTE ===== */
.glass-base {
backdrop-filter: blur(24px) saturate(200%) brightness(115%);
-webkit-backdrop-filter: blur(24px) saturate(200%) brightness(115%);
border: 1px solid rgba(255, 255, 255, 0.25);
box-shadow:
0 25px 50px rgba(0, 0, 0, 0.12),
0 8px 16px rgba(0, 0, 0, 0.08),
inset 0 1px 0 rgba(255, 255, 255, 0.3);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
background: rgba(255, 255, 255, 0.85);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.3);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
transition: all 0.2s ease;
}
.glass-strong {
backdrop-filter: blur(28px) saturate(220%) brightness(125%);
-webkit-backdrop-filter: blur(28px) saturate(220%) brightness(125%);
box-shadow:
0 35px 70px rgba(0, 0, 0, 0.15),
0 12px 24px rgba(0, 0, 0, 0.1),
inset 0 1px 0 rgba(255, 255, 255, 0.4);
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.4);
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.12);
}
.glass-subtle {
backdrop-filter: blur(20px) saturate(180%) brightness(110%);
-webkit-backdrop-filter: blur(20px) saturate(180%) brightness(110%);
box-shadow:
0 15px 35px rgba(0, 0, 0, 0.08),
0 4px 8px rgba(0, 0, 0, 0.05),
inset 0 1px 0 rgba(255, 255, 255, 0.2);
background: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
/* Light Mode Glass */
.glass-light {
background: rgba(255, 255, 255, 0.85);
border: 1px solid rgba(255, 255, 255, 0.4);
box-shadow:
0 20px 40px rgba(0, 0, 0, 0.1),
0 8px 16px rgba(0, 115, 206, 0.05),
inset 0 1px 0 rgba(255, 255, 255, 0.6);
}
.glass-light-strong {
background: rgba(255, 255, 255, 0.75);
border: 1px solid rgba(255, 255, 255, 0.5);
box-shadow:
0 25px 50px rgba(0, 0, 0, 0.12),
0 10px 20px rgba(0, 115, 206, 0.08),
inset 0 1px 0 rgba(255, 255, 255, 0.7);
}
/* Light Mode Glass Premium */
.glass-light-premium {
background: linear-gradient(135deg,
rgba(255, 255, 255, 0.9) 0%,
rgba(248, 250, 252, 0.8) 50%,
rgba(255, 255, 255, 0.85) 100%);
border: 1px solid rgba(226, 232, 240, 0.6);
box-shadow:
0 25px 50px rgba(0, 0, 0, 0.08),
0 10px 20px rgba(0, 115, 206, 0.06),
inset 0 2px 0 rgba(255, 255, 255, 0.8),
inset 0 0 20px rgba(255, 255, 255, 0.3);
}
.glass-light-card {
background: linear-gradient(135deg,
rgba(255, 255, 255, 0.95) 0%,
rgba(250, 251, 252, 0.9) 100%);
border: 1px solid rgba(226, 232, 240, 0.4);
box-shadow:
0 20px 40px rgba(0, 0, 0, 0.06),
0 8px 16px rgba(0, 115, 206, 0.04),
inset 0 1px 0 rgba(255, 255, 255, 0.9);
}
/* Dark Mode Glass */
.glass-dark {
/* ===== DARK MODE GLASS ===== */
.dark .glass-base {
background: rgba(15, 23, 42, 0.8);
border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow:
0 25px 50px rgba(0, 0, 0, 0.4),
0 8px 16px rgba(0, 0, 0, 0.2),
inset 0 1px 0 rgba(255, 255, 255, 0.05);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
}
.glass-dark-strong {
.dark .glass-strong {
background: rgba(30, 41, 59, 0.85);
border: 1px solid rgba(255, 255, 255, 0.15);
box-shadow:
0 35px 70px rgba(0, 0, 0, 0.5),
0 12px 24px rgba(0, 0, 0, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.08);
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.4);
}
/* Interactive Glass Elements */
.glass-interactive {
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
cursor: pointer;
position: relative;
overflow: hidden;
.dark .glass-subtle {
background: rgba(15, 23, 42, 0.7);
border: 1px solid rgba(255, 255, 255, 0.08);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}
.glass-interactive::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg,
transparent,
rgba(255, 255, 255, 0.2),
transparent);
transition: left 0.6s ease;
z-index: 1;
}
.glass-interactive:hover {
transform: translateY(-3px) scale(1.01);
backdrop-filter: blur(32px) saturate(240%) brightness(130%);
-webkit-backdrop-filter: blur(32px) saturate(240%) brightness(130%);
box-shadow:
0 40px 80px rgba(0, 0, 0, 0.15),
0 16px 32px rgba(0, 115, 206, 0.1),
inset 0 1px 0 rgba(255, 255, 255, 0.4);
}
.glass-interactive:hover::before {
left: 100%;
}
.glass-interactive:active {
transform: translateY(-1px) scale(0.99);
transition: transform 0.1s ease;
}
/* Glass Navigation */
.glass-nav {
background: linear-gradient(135deg,
rgba(255, 255, 255, 0.9) 0%,
rgba(248, 250, 252, 0.85) 50%,
rgba(255, 255, 255, 0.9) 100%);
backdrop-filter: blur(24px) saturate(200%) brightness(115%);
-webkit-backdrop-filter: blur(24px) saturate(200%) brightness(115%);
border: 1px solid rgba(226, 232, 240, 0.5);
border-bottom: 1px solid rgba(203, 213, 225, 0.6);
box-shadow:
0 8px 32px rgba(0, 0, 0, 0.08),
0 4px 12px rgba(0, 115, 206, 0.05),
inset 0 1px 0 rgba(255, 255, 255, 0.8);
}
.dark .glass-nav {
background: rgba(15, 23, 42, 0.85);
border-color: rgba(51, 65, 85, 0.6);
border-bottom-color: rgba(71, 85, 105, 0.7);
box-shadow:
0 8px 32px rgba(0, 0, 0, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
/* Glass Cards */
/* ===== GLASS KARTEN ===== */
.glass-card {
background: linear-gradient(135deg,
rgba(255, 255, 255, 0.95) 0%,
rgba(250, 251, 252, 0.9) 100%);
backdrop-filter: blur(20px) saturate(180%) brightness(110%);
-webkit-backdrop-filter: blur(20px) saturate(180%) brightness(110%);
border: 1px solid rgba(229, 231, 235, 0.6);
border-radius: 16px;
box-shadow:
0 20px 40px rgba(0, 0, 0, 0.08),
0 8px 16px rgba(0, 115, 206, 0.04),
inset 0 1px 0 rgba(255, 255, 255, 0.9);
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(229, 231, 235, 0.5);
border-radius: 12px;
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.08);
padding: 1.5rem;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
overflow: hidden;
}
.glass-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 1px;
background: linear-gradient(90deg,
transparent 0%,
rgba(226, 232, 240, 0.8) 50%,
transparent 100%);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.glass-card:hover {
transform: translateY(-2px);
box-shadow:
0 25px 50px rgba(0, 0, 0, 0.12),
0 12px 24px rgba(0, 115, 206, 0.08),
inset 0 1px 0 rgba(255, 255, 255, 0.95);
transform: translateY(-1px);
box-shadow: 0 12px 20px rgba(0, 0, 0, 0.12);
}
.dark .glass-card {
background: rgba(30, 41, 59, 0.85);
border-color: rgba(100, 116, 139, 0.4);
box-shadow:
0 20px 40px rgba(0, 0, 0, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
border: 1px solid rgba(100, 116, 139, 0.3);
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.25);
}
.dark .glass-card:hover {
box-shadow:
0 25px 50px rgba(0, 0, 0, 0.4),
inset 0 1px 0 rgba(255, 255, 255, 0.15);
box-shadow: 0 12px 20px rgba(0, 0, 0, 0.35);
}
/* Glass Buttons */
/* ===== GLASS NAVIGATION ===== */
.glass-nav {
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(226, 232, 240, 0.4);
border-bottom: 1px solid rgba(203, 213, 225, 0.5);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
}
.dark .glass-nav {
background: rgba(15, 23, 42, 0.85);
border: 1px solid rgba(51, 65, 85, 0.5);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}
/* ===== GLASS BUTTONS ===== */
.glass-btn {
background: linear-gradient(135deg,
rgba(255, 255, 255, 0.9) 0%,
rgba(248, 250, 252, 0.8) 100%);
backdrop-filter: blur(16px) saturate(180%);
-webkit-backdrop-filter: blur(16px) saturate(180%);
border: 1px solid rgba(226, 232, 240, 0.6);
border-radius: 12px;
background: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
border: 1px solid rgba(226, 232, 240, 0.5);
border-radius: 8px;
padding: 0.75rem 1.5rem;
color: #0f172a;
font-weight: 600;
text-shadow: 0 1px 2px rgba(255, 255, 255, 0.8);
box-shadow:
0 4px 12px rgba(0, 0, 0, 0.08),
0 2px 4px rgba(0, 115, 206, 0.05),
inset 0 1px 0 rgba(255, 255, 255, 0.8);
transition: all 0.2s ease;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
transition: transform 0.2s ease, background 0.2s ease;
}
.glass-btn:hover {
transform: translateY(-1px);
background: linear-gradient(135deg,
rgba(255, 255, 255, 0.95) 0%,
rgba(248, 250, 252, 0.85) 100%);
box-shadow:
0 8px 20px rgba(0, 0, 0, 0.12),
0 4px 8px rgba(0, 115, 206, 0.08),
inset 0 1px 0 rgba(255, 255, 255, 0.9);
}
.glass-btn:active {
transform: translateY(0);
box-shadow:
0 2px 8px rgba(0, 0, 0, 0.1),
inset 0 1px 0 rgba(255, 255, 255, 0.7);
background: rgba(255, 255, 255, 0.9);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.glass-btn-primary {
background: linear-gradient(135deg,
rgba(0, 115, 206, 0.9) 0%,
rgba(0, 90, 159, 0.85) 100%);
background: rgba(0, 115, 206, 0.9);
color: white;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
box-shadow:
0 4px 12px rgba(0, 115, 206, 0.3),
0 2px 4px rgba(0, 115, 206, 0.2),
inset 0 1px 0 rgba(255, 255, 255, 0.2);
box-shadow: 0 2px 8px rgba(0, 115, 206, 0.2);
}
.glass-btn-primary:hover {
background: linear-gradient(135deg,
rgba(0, 115, 206, 0.95) 0%,
rgba(0, 90, 159, 0.9) 100%);
box-shadow:
0 8px 20px rgba(0, 115, 206, 0.4),
0 4px 8px rgba(0, 115, 206, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.3);
background: rgba(0, 115, 206, 0.95);
box-shadow: 0 4px 12px rgba(0, 115, 206, 0.3);
}
.dark .glass-btn {
background: rgba(30, 41, 59, 0.8);
color: #e2e8f0;
border-color: rgba(100, 116, 139, 0.6);
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
box-shadow:
0 4px 12px rgba(0, 0, 0, 0.2),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
border: 1px solid rgba(100, 116, 139, 0.5);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}
/* Glass Modals */
.dark .glass-btn:hover {
background: rgba(30, 41, 59, 0.9);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
}
/* ===== GLASS MODALS ===== */
.glass-modal {
background: linear-gradient(135deg,
rgba(255, 255, 255, 0.98) 0%,
rgba(248, 250, 252, 0.95) 50%,
rgba(255, 255, 255, 0.98) 100%);
backdrop-filter: blur(32px) saturate(220%) brightness(120%);
-webkit-backdrop-filter: blur(32px) saturate(220%) brightness(120%);
border: 1px solid rgba(226, 232, 240, 0.7);
border-radius: 20px;
box-shadow:
0 50px 100px rgba(0, 0, 0, 0.15),
0 20px 40px rgba(0, 115, 206, 0.08),
inset 0 2px 0 rgba(255, 255, 255, 0.9),
inset 0 0 40px rgba(255, 255, 255, 0.2);
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border: 1px solid rgba(226, 232, 240, 0.6);
border-radius: 16px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.12);
}
.dark .glass-modal {
background: rgba(15, 23, 42, 0.95);
border-color: rgba(51, 65, 85, 0.7);
box-shadow:
0 50px 100px rgba(0, 0, 0, 0.5),
inset 0 2px 0 rgba(255, 255, 255, 0.1);
border: 1px solid rgba(51, 65, 85, 0.6);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4);
}
/* Glass Form Elements */
/* ===== GLASS FORM ELEMENTE ===== */
.glass-input {
background: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border: 1px solid rgba(226, 232, 240, 0.6);
border-radius: 8px;
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
border: 1px solid rgba(226, 232, 240, 0.5);
border-radius: 6px;
padding: 0.75rem 1rem;
color: #0f172a;
box-shadow:
0 2px 8px rgba(0, 0, 0, 0.06),
inset 0 1px 0 rgba(255, 255, 255, 0.8);
transition: all 0.2s ease;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.glass-input:focus {
outline: none;
border-color: rgba(0, 115, 206, 0.6);
box-shadow:
0 4px 12px rgba(0, 115, 206, 0.15),
0 0 0 3px rgba(0, 115, 206, 0.1),
inset 0 1px 0 rgba(255, 255, 255, 0.9);
border-color: rgba(0, 115, 206, 0.5);
box-shadow: 0 2px 8px rgba(0, 115, 206, 0.1);
}
.dark .glass-input {
background: rgba(30, 41, 59, 0.8);
border-color: rgba(100, 116, 139, 0.6);
border: 1px solid rgba(100, 116, 139, 0.5);
color: #e2e8f0;
box-shadow:
0 2px 8px rgba(0, 0, 0, 0.2),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
}
/* Glass Dropdown */
.dark .glass-input:focus {
border-color: rgba(59, 130, 246, 0.5);
box-shadow: 0 2px 8px rgba(59, 130, 246, 0.15);
}
/* ===== GLASS DROPDOWN ===== */
.glass-dropdown {
background: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(24px) saturate(200%) brightness(120%);
-webkit-backdrop-filter: blur(24px) saturate(200%) brightness(120%);
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 12px;
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.25), 0 0 0 1px rgba(255, 255, 255, 0.1);
border-radius: 8px;
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
}
.dark .glass-dropdown {
background: rgba(0, 0, 0, 0.8);
border: 1px solid rgba(255, 255, 255, 0.15);
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.08);
background: rgba(15, 23, 42, 0.9);
border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
}
/* Animation for glass elements */
@keyframes glassFloat {
0%, 100% {
transform: translateY(0px);
}
50% {
transform: translateY(-2px);
}
}
.glass-float {
animation: glassFloat 3s ease-in-out infinite;
}
/* Glass overlay for backgrounds */
/* ===== UTILITY CLASSES ===== */
.glass-overlay {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.05) 100%);
backdrop-filter: blur(40px) saturate(200%);
-webkit-backdrop-filter: blur(40px) saturate(200%);
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
}
.dark .glass-overlay {
background: linear-gradient(135deg, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0.1) 100%);
background: rgba(0, 0, 0, 0.2);
}
/* Responsive glass effects */
/* ===== RESPONSIVE ANPASSUNGEN ===== */
@media (max-width: 768px) {
.glass-card {
padding: 1rem;
border-radius: 12px;
border-radius: 8px;
}
.glass-modal {
border-radius: 16px;
border-radius: 12px;
}
.glass-base,
.glass-strong,
.glass-subtle {
backdrop-filter: blur(6px);
-webkit-backdrop-filter: blur(6px);
}
}
/* High contrast mode adjustments */
/* ===== REDUZIERTE BEWEGUNG ===== */
@media (prefers-reduced-motion: reduce) {
.glass-card,
.glass-btn,
.glass-input {
transition: none !important;
}
}
/* ===== HOHER KONTRAST MODUS ===== */
@media (prefers-contrast: high) {
.glass-base,
.glass-strong,
.glass-card {
border-width: 2px;
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
}
}
/* Reduced motion support */
@media (prefers-reduced-motion: reduce) {
.glass-interactive,
.glass-btn,
.glass-card {
transition: none !important;
}
.glass-interactive::before {
display: none;
}
}
/* Glass Loading States */
.glass-loading {
position: relative;
overflow: hidden;
}
.glass-loading::after {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg,
transparent,
rgba(255, 255, 255, 0.3),
transparent);
animation: glass-shimmer 2s infinite;
}
.dark .glass-loading::after {
background: linear-gradient(90deg,
transparent,
rgba(255, 255, 255, 0.1),
transparent);
}
@keyframes glass-shimmer {
0% { left: -100%; }
100% { left: 100%; }
}
/* Premium Glow Effects for Light Mode */
.glass-glow {
position: relative;
}
.glass-glow::after {
content: '';
position: absolute;
top: -2px;
left: -2px;
right: -2px;
bottom: -2px;
background: linear-gradient(45deg,
rgba(0, 115, 206, 0.1),
rgba(0, 90, 159, 0.05),
rgba(0, 115, 206, 0.1));
border-radius: inherit;
z-index: -1;
opacity: 0;
transition: opacity 0.3s ease;
}
.glass-glow:hover::after {
opacity: 1;
}
.dark .glass-glow::after {
background: linear-gradient(45deg,
rgba(59, 130, 246, 0.2),
rgba(29, 78, 216, 0.1),
rgba(59, 130, 246, 0.2));
/* ===== PERFORMANCE OPTIMIERUNGEN ===== */
.glass-base,
.glass-strong,
.glass-subtle,
.glass-card,
.glass-btn,
.glass-modal {
will-change: transform;
}

Binary file not shown.

View File

@ -0,0 +1 @@
.glass-base{background:rgba(255,255,255,0.85);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,0.3);box-shadow:0 8px 20px rgba(0,0,0,0.1);transition:all .2s ease}.glass-strong{background:rgba(255,255,255,0.9);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,0.4);box-shadow:0 12px 24px rgba(0,0,0,0.12)}.glass-subtle{background:rgba(255,255,255,0.8);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(255,255,255,0.2);box-shadow:0 4px 12px rgba(0,0,0,0.08)}.dark .glass-base{background:rgba(15,23,42,0.8);border:1px solid rgba(255,255,255,0.1);box-shadow:0 8px 20px rgba(0,0,0,0.3)}.dark .glass-strong{background:rgba(30,41,59,0.85);border:1px solid rgba(255,255,255,0.15);box-shadow:0 12px 24px rgba(0,0,0,0.4)}.dark .glass-subtle{background:rgba(15,23,42,0.7);border:1px solid rgba(255,255,255,0.08);box-shadow:0 4px 12px rgba(0,0,0,0.2)}.glass-card{background:rgba(255,255,255,0.9);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);border:1px solid rgba(229,231,235,0.5);border-radius:12px;box-shadow:0 8px 16px rgba(0,0,0,0.08);padding:1.5rem;transition:transform .2s ease,box-shadow .2s ease}.glass-card:hover{transform:translateY(-1px);box-shadow:0 12px 20px rgba(0,0,0,0.12)}.dark .glass-card{background:rgba(30,41,59,0.85);border:1px solid rgba(100,116,139,0.3);box-shadow:0 8px 16px rgba(0,0,0,0.25)}.dark .glass-card:hover{box-shadow:0 12px 20px rgba(0,0,0,0.35)}.glass-nav{background:rgba(255,255,255,0.9);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid rgba(226,232,240,0.4);border-bottom:1px solid rgba(203,213,225,0.5);box-shadow:0 4px 12px rgba(0,0,0,0.06)}.dark .glass-nav{background:rgba(15,23,42,0.85);border:1px solid rgba(51,65,85,0.5);box-shadow:0 4px 12px rgba(0,0,0,0.2)}.glass-btn{background:rgba(255,255,255,0.8);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(226,232,240,0.5);border-radius:8px;padding:.75rem 1.5rem;color:#0f172a;font-weight:600;box-shadow:0 2px 8px rgba(0,0,0,0.06);transition:transform .2s ease,background .2s ease}.glass-btn:hover{transform:translateY(-1px);background:rgba(255,255,255,0.9);box-shadow:0 4px 12px rgba(0,0,0,0.1)}.glass-btn-primary{background:rgba(0,115,206,0.9);color:white;box-shadow:0 2px 8px rgba(0,115,206,0.2)}.glass-btn-primary:hover{background:rgba(0,115,206,0.95);box-shadow:0 4px 12px rgba(0,115,206,0.3)}.dark .glass-btn{background:rgba(30,41,59,0.8);color:#e2e8f0;border:1px solid rgba(100,116,139,0.5);box-shadow:0 2px 8px rgba(0,0,0,0.15)}.dark .glass-btn:hover{background:rgba(30,41,59,0.9);box-shadow:0 4px 12px rgba(0,0,0,0.25)}.glass-modal{background:rgba(255,255,255,0.95);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);border:1px solid rgba(226,232,240,0.6);border-radius:16px;box-shadow:0 20px 40px rgba(0,0,0,0.12)}.dark .glass-modal{background:rgba(15,23,42,0.95);border:1px solid rgba(51,65,85,0.6);box-shadow:0 20px 40px rgba(0,0,0,0.4)}.glass-input{background:rgba(255,255,255,0.8);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(226,232,240,0.5);border-radius:6px;padding:.75rem 1rem;color:#0f172a;box-shadow:0 2px 4px rgba(0,0,0,0.04);transition:border-color .2s ease,box-shadow .2s ease}.glass-input:focus{outline:0;border-color:rgba(0,115,206,0.5);box-shadow:0 2px 8px rgba(0,115,206,0.1)}.dark .glass-input{background:rgba(30,41,59,0.8);border:1px solid rgba(100,116,139,0.5);color:#e2e8f0;box-shadow:0 2px 4px rgba(0,0,0,0.15)}.dark .glass-input:focus{border-color:rgba(59,130,246,0.5);box-shadow:0 2px 8px rgba(59,130,246,0.15)}.glass-dropdown{background:rgba(255,255,255,0.9);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,0.3);border-radius:8px;box-shadow:0 8px 20px rgba(0,0,0,0.15)}.dark .glass-dropdown{background:rgba(15,23,42,0.9);border:1px solid rgba(255,255,255,0.1);box-shadow:0 8px 20px rgba(0,0,0,0.3)}.glass-overlay{background:rgba(255,255,255,0.1);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px)}.dark .glass-overlay{background:rgba(0,0,0,0.2)}@media(max-width:768px){.glass-card{padding:1rem;border-radius:8px}.glass-modal{border-radius:12px}.glass-base,.glass-strong,.glass-subtle{backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px)}}@media(prefers-reduced-motion:reduce){.glass-card,.glass-btn,.glass-input{transition:none !important}}@media(prefers-contrast:high){.glass-base,.glass-strong,.glass-card{border-width:2px;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}}.glass-base,.glass-strong,.glass-subtle,.glass-card,.glass-btn,.glass-modal{will-change:transform}

Binary file not shown.

View File

@ -0,0 +1,148 @@
/**
* Minimales Icon-Set für Kiosk-Modus
* SVG-basierte Icons als CSS-Pseudo-Elemente für beste Performance
* Ersetzt FontAwesome für deutlich kleinere Bundle-Größe
*/
/* Icon-Basis-Klasse */
.icon {
display: inline-block;
width: 1rem;
height: 1rem;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
vertical-align: middle;
}
.icon-lg { width: 1.5rem; height: 1.5rem; }
.icon-xl { width: 2rem; height: 2rem; }
/* ===== DRUCKER ICONS ===== */
.icon-printer {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z'/%3E%3C/svg%3E");
}
.icon-print {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z'/%3E%3C/svg%3E");
}
/* ===== STATUS ICONS ===== */
.icon-check {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/%3E%3C/svg%3E");
}
.icon-warning {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23f59e0b'%3E%3Cpath d='M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z'/%3E%3C/svg%3E");
}
.icon-error {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ef4444'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z'/%3E%3C/svg%3E");
}
.icon-offline {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%236b7280'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z'/%3E%3C/svg%3E");
}
/* ===== NAVIGATION ICONS ===== */
.icon-home {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z'/%3E%3C/svg%3E");
}
.icon-settings {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19.14,12.94c0.04-0.3,0.06-0.61,0.06-0.94c0-0.32-0.02-0.64-0.07-0.94l2.03-1.58c0.18-0.14,0.23-0.41,0.12-0.61 l-1.92-3.32c-0.12-0.22-0.37-0.29-0.59-0.22l-2.39,0.96c-0.5-0.38-1.03-0.7-1.62-0.94L14.4,2.81c-0.04-0.24-0.24-0.41-0.48-0.41 h-3.84c-0.24,0-0.43,0.17-0.47,0.41L9.25,5.35C8.66,5.59,8.12,5.92,7.63,6.29L5.24,5.33c-0.22-0.08-0.47,0-0.59,0.22L2.74,8.87 C2.62,9.08,2.66,9.34,2.86,9.48l2.03,1.58C4.84,11.36,4.8,11.69,4.8,12s0.02,0.64,0.07,0.94l-2.03,1.58 c-0.18,0.14-0.23,0.41-0.12,0.61l1.92,3.32c0.12,0.22,0.37,0.29,0.59,0.22l2.39-0.96c0.5,0.38,1.03,0.7,1.62,0.94l0.36,2.54 c0.05,0.24,0.24,0.41,0.48,0.41h3.84c0.24,0,0.44-0.17,0.47-0.41l0.36-2.54c0.59-0.24,1.13-0.56,1.62-0.94l2.39,0.96 c0.22,0.08,0.47,0,0.59-0.22l1.92-3.32c0.12-0.22,0.07-0.47-0.12-0.61L19.14,12.94z M12,15.6c-1.98,0-3.6-1.62-3.6-3.6 s1.62-3.6,3.6-3.6s3.6,1.62,3.6,3.6S13.98,15.6,12,15.6z'/%3E%3C/svg%3E");
}
.icon-users {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M16 4c0-1.11.89-2 2-2s2 .89 2 2-.89 2-2 2-2-.89-2-2zm4 18v-6h2.5l-2.54-7.63A3.012 3.012 0 0 0 16.43 6c-.68 0-1.3.27-1.77.72L12 8.5l-2.66-1.78C8.87 6.27 8.25 6 7.57 6c-1.31 0-2.42.83-2.83 2L2.5 16H5v6h2v-6h2v6h2zm-6.5-10.5c.83 0 1.5-.67 1.5-1.5s-.67-1.5-1.5-1.5S12 9.17 12 10s.67 1.5 1.5 1.5z'/%3E%3C/svg%3E");
}
.icon-dashboard {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z'/%3E%3C/svg%3E");
}
/* ===== ACTION ICONS ===== */
.icon-plus {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z'/%3E%3C/svg%3E");
}
.icon-edit {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z'/%3E%3C/svg%3E");
}
.icon-delete {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ef4444'%3E%3Cpath d='M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z'/%3E%3C/svg%3E");
}
.icon-refresh {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z'/%3E%3C/svg%3E");
}
/* ===== POWER/CONNECTION ICONS ===== */
.icon-power {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M13 3h-2v10h2V3zm4.83 2.17l-1.42 1.42C17.99 7.86 19 9.81 19 12c0 3.87-3.13 7-7 7s-7-3.13-7-7c0-2.19 1.01-4.14 2.58-5.42L6.17 5.17C4.23 6.82 3 9.26 3 12c0 4.97 4.03 9 9 9s9-4.03 9-9c0-2.74-1.23-5.18-3.17-6.83z'/%3E%3C/svg%3E");
}
.icon-wifi {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M1 9l2 2c4.97-4.97 13.03-4.97 18 0l2-2C16.93 2.93 7.07 2.93 1 9zm8 8l3 3 3-3c-1.65-1.66-4.34-1.66-6 0zm-4-4l2 2c2.76-2.76 7.24-2.76 10 0l2-2C15.14 9.14 8.87 9.14 5 13z'/%3E%3C/svg%3E");
}
/* ===== DOKUMENT ICONS ===== */
.icon-file {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z'/%3E%3C/svg%3E");
}
.icon-queue {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-1 9H9V9h10v2zm-4 4H9v-2h6v2zm4-8H9V5h10v2z'/%3E%3C/svg%3E");
}
/* ===== INFO ICONS ===== */
.icon-info {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%233b82f6'%3E%3Cpath d='M12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2M13,17H11V11H13M13,9H11V7H13'/%3E%3C/svg%3E");
}
.icon-time {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M16.2,16.2L11,13V7H12.5V12.2L17,14.7L16.2,16.2Z'/%3E%3C/svg%3E");
}
/* ===== ARROW ICONS ===== */
.icon-arrow-right {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z'/%3E%3C/svg%3E");
}
.icon-arrow-down {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z'/%3E%3C/svg%3E");
}
/* ===== HOVER-STATES ===== */
.btn:hover .icon,
.nav-item:hover .icon {
opacity: 0.8;
}
/* ===== DARK MODE ===== */
@media (prefers-color-scheme: dark) {
.icon-printer,
.icon-print,
.icon-home,
.icon-settings,
.icon-users,
.icon-dashboard,
.icon-plus,
.icon-edit,
.icon-refresh,
.icon-file,
.icon-queue,
.icon-time,
.icon-arrow-right,
.icon-arrow-down {
filter: brightness(2);
}
}
/* ===== RESPONSIVE ICON-SIZES ===== */
@media (max-width: 768px) {
.icon { width: 1.25rem; height: 1.25rem; }
.icon-lg { width: 1.75rem; height: 1.75rem; }
.icon-xl { width: 2.25rem; height: 2.25rem; }
}

Binary file not shown.

1
backend/static/css/input.min.css vendored Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -0,0 +1,346 @@
/**
* MYP Platform - Kiosk-Optimierte CSS
* Maximale Performance für Offline-Kiosk-Umgebung
* Keine Touch-Events, minimale Animationen, optimierte Rendering-Performance
*/
/* ===== CRITICAL INLINE STYLES (sollten im HTML-Head stehen) ===== */
:root {
/* Reduzierte Farbvariablen für bessere Performance */
--primary: #0073ce;
--primary-dark: #005a9f;
--bg: #fafbfc;
--surface: #ffffff;
--text: #111827;
--text-muted: #6b7280;
--border: #e5e7eb;
--shadow: 0 2px 4px rgba(0,0,0,0.05);
}
/* CSS Containment für bessere Performance */
* {
contain: layout style;
}
/* Basis-Reset ohne aufwendige Normalisierung */
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: system-ui, -apple-system, sans-serif;
background: var(--bg);
color: var(--text);
line-height: 1.5;
contain: layout style paint;
/* Optimiert für Kiosk-Rendering */
text-rendering: optimizeSpeed;
-webkit-font-smoothing: antialiased;
}
/* ===== LAYOUT OPTIMIERUNGEN ===== */
.header {
background: var(--surface);
border-bottom: 1px solid var(--border);
padding: 1rem;
contain: layout style;
}
.nav {
display: flex;
gap: 1rem;
contain: layout;
}
.nav-item {
padding: 0.5rem 1rem;
border-radius: 6px;
text-decoration: none;
color: var(--text-muted);
transition: background-color 0.1s ease; /* Minimale Transition */
}
.nav-item:hover {
background: var(--bg);
color: var(--text);
}
.nav-item.active {
background: var(--primary);
color: white;
}
/* ===== OPTIMIERTE KARTEN ===== */
.card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 8px;
padding: 1rem;
box-shadow: var(--shadow);
contain: layout style paint;
}
.card:hover {
transform: translateY(-1px); /* Minimaler Hover-Effekt */
}
/* ===== BUTTONS OHNE KOMPLEXE ANIMATIONEN ===== */
.btn {
background: var(--primary);
color: white;
border: none;
border-radius: 6px;
padding: 0.75rem 1.5rem;
font-weight: 600;
cursor: pointer;
transition: background-color 0.1s ease;
contain: layout style;
}
.btn:hover {
background: var(--primary-dark);
}
.btn-secondary {
background: var(--surface);
color: var(--text);
border: 1px solid var(--border);
}
.btn-secondary:hover {
background: var(--bg);
}
/* ===== INPUTS OPTIMIERT ===== */
.input {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 6px;
padding: 0.75rem;
width: 100%;
transition: border-color 0.1s ease;
contain: layout style;
}
.input:focus {
outline: none;
border-color: var(--primary);
}
/* ===== TABELLEN OHNE KOMPLEXE EFFEKTE ===== */
.table {
width: 100%;
border-collapse: collapse;
background: var(--surface);
border-radius: 8px;
overflow: hidden;
contain: layout;
}
.table th {
background: var(--bg);
padding: 1rem;
text-align: left;
font-weight: 600;
border-bottom: 1px solid var(--border);
}
.table td {
padding: 1rem;
border-bottom: 1px solid var(--border);
}
.table tr:hover {
background: var(--bg);
}
/* ===== STATUS BADGES VEREINFACHT ===== */
.status {
display: inline-block;
padding: 0.25rem 0.75rem;
border-radius: 999px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
}
.status-online { background: #d1fae5; color: #065f46; }
.status-offline { background: #fee2e2; color: #991b1b; }
.status-printing { background: #dbeafe; color: #1e40af; }
/* ===== GRID LAYOUTS OPTIMIERT ===== */
.grid {
display: grid;
gap: 1rem;
contain: layout;
}
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
/* ===== UTILITIES MINIMAL ===== */
.flex { display: flex; contain: layout; }
.flex-col { flex-direction: column; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-1 { gap: 0.25rem; }
.gap-2 { gap: 0.5rem; }
.gap-4 { gap: 1rem; }
.p-1 { padding: 0.25rem; }
.p-2 { padding: 0.5rem; }
.p-4 { padding: 1rem; }
.p-6 { padding: 1.5rem; }
.m-1 { margin: 0.25rem; }
.m-2 { margin: 0.5rem; }
.m-4 { margin: 1rem; }
.mb-2 { margin-bottom: 0.5rem; }
.mb-4 { margin-bottom: 1rem; }
.mb-6 { margin-bottom: 1.5rem; }
.text-sm { font-size: 0.875rem; }
.text-lg { font-size: 1.125rem; }
.text-xl { font-size: 1.25rem; }
.text-2xl { font-size: 1.5rem; }
.font-semibold { font-weight: 600; }
.font-bold { font-weight: 700; }
.text-center { text-align: center; }
.text-right { text-align: right; }
.w-full { width: 100%; }
.h-full { height: 100%; }
.rounded { border-radius: 6px; }
.rounded-lg { border-radius: 8px; }
.border { border: 1px solid var(--border); }
.border-t { border-top: 1px solid var(--border); }
.border-b { border-bottom: 1px solid var(--border); }
.bg-white { background: var(--surface); }
.bg-gray-50 { background: var(--bg); }
.text-gray-600 { color: var(--text-muted); }
.text-blue-600 { color: var(--primary); }
/* ===== DARK MODE MINIMAL ===== */
@media (prefers-color-scheme: dark) {
:root {
--bg: #1e293b;
--surface: #334155;
--text: #f8fafc;
--text-muted: #94a3b8;
--border: #475569;
--shadow: 0 2px 4px rgba(0,0,0,0.3);
}
}
/* ===== RESPONSIVE FÜR KIOSK-DISPLAYS ===== */
@media (max-width: 1024px) {
.grid-4 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
.grid-4,
.grid-3,
.grid-2 { grid-template-columns: 1fr; }
.nav {
flex-direction: column;
gap: 0.5rem;
}
}
/* ===== PERFORMANCE OPTIMIERUNGEN ===== */
/* Deaktivierung nicht benötigter Features für Kiosk */
* {
/* Keine Touch-Events */
touch-action: none;
-webkit-touch-callout: none;
-webkit-user-select: none;
user-select: none;
}
/* Nur notwendige Elemente selektierbar */
input,
textarea {
-webkit-user-select: text;
user-select: text;
touch-action: manipulation;
}
/* Optimierte Scrolling-Performance */
* {
-webkit-overflow-scrolling: touch;
scroll-behavior: smooth;
}
/* GPU-Acceleration nur wo nötig */
.card:hover,
.btn:hover {
will-change: transform;
}
/* Minimale Animationen für bessere Performance */
@media (prefers-reduced-motion: reduce) {
* {
transition: none !important;
animation: none !important;
}
}
/* Print-Optimierung (falls Kiosk drucken kann) */
@media print {
.nav,
.btn {
display: none;
}
.card {
box-shadow: none;
border: 1px solid #000;
}
}
/* ===== LAYOUT SHIFT PREVENTION ===== */
img {
height: auto;
max-width: 100%;
vertical-align: middle;
}
/* Container für stabile Layouts */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
contain: layout;
}
/* ===== KIOSK-SPEZIFISCHE OPTIMIERUNGEN ===== */
/* Vollbildmodus-Unterstützung */
html,
body {
height: 100%;
overflow-x: hidden;
}
/* Fokus-Management für Keyboard-Navigation */
:focus {
outline: 2px solid var(--primary);
outline-offset: 2px;
}
/* Kein Selection-Highlighting */
::selection {
background: transparent;
}
/* Optimierte Font-Loading */
@font-face {
font-family: 'system-ui';
font-display: swap;
}

View File

@ -1,100 +1,27 @@
/**
* MYP Platform - Optimierungs-Animationen
* Belohnende und motivierende Animationen für Auto-Optimierung
* MYP Platform - Optimierte einfache Animationen
* Reduzierte, performante Animationen für bessere User Experience
*/
/* ===== MODAL FADE-IN ANIMATION ===== */
/* ===== EINFACHE FADE-IN ANIMATION ===== */
@keyframes fade-in {
from {
opacity: 0;
backdrop-filter: blur(0px);
}
to {
opacity: 1;
backdrop-filter: blur(8px);
}
}
.animate-fade-in {
animation: fade-in 0.3s ease-out;
animation: fade-in 0.2s ease-out;
}
/* ===== BOUNCE-IN ANIMATION ===== */
@keyframes bounce-in {
0% {
opacity: 0;
transform: scale(0.3) translateY(-50px);
}
50% {
opacity: 1;
transform: scale(1.05) translateY(0);
}
70% {
transform: scale(0.95);
}
100% {
opacity: 1;
transform: scale(1);
}
}
.animate-bounce-in {
animation: bounce-in 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
/* ===== PULSE-SCALE ANIMATION ===== */
@keyframes pulse-scale {
0%, 100% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
}
.animate-pulse-scale {
animation: pulse-scale 3s infinite ease-in-out;
}
/* ===== FLOATING ANIMATIONS ===== */
@keyframes float {
0%, 100% {
transform: translateY(0px) rotate(0deg);
}
33% {
transform: translateY(-15px) rotate(5deg);
}
66% {
transform: translateY(-5px) rotate(-3deg);
}
}
@keyframes float-delay {
0%, 100% {
transform: translateY(0px) rotate(0deg);
}
33% {
transform: translateY(-10px) rotate(-5deg);
}
66% {
transform: translateY(-8px) rotate(3deg);
}
}
.animate-float {
animation: float 4s infinite ease-in-out;
}
.animate-float-delay {
animation: float-delay 4s infinite ease-in-out;
animation-delay: 1.5s;
}
/* ===== SLIDE-UP ANIMATIONS ===== */
/* ===== EINFACHE SLIDE-UP ANIMATION ===== */
@keyframes slide-up {
from {
opacity: 0;
transform: translateY(30px);
transform: translateY(15px);
}
to {
opacity: 1;
@ -103,239 +30,105 @@
}
.animate-slide-up {
animation: slide-up 0.6s ease-out;
animation: slide-up 0.3s ease-out;
}
.animate-slide-up-delay {
animation: slide-up 0.6s ease-out;
animation-delay: 0.2s;
animation: slide-up 0.3s ease-out;
animation-delay: 0.1s;
animation-fill-mode: both;
}
.animate-slide-up-delay-2 {
animation: slide-up 0.6s ease-out;
animation-delay: 0.4s;
animation: slide-up 0.3s ease-out;
animation-delay: 0.2s;
animation-fill-mode: both;
}
.animate-slide-up-delay-3 {
animation: slide-up 0.6s ease-out;
animation-delay: 0.6s;
animation-fill-mode: both;
/* ===== EINFACHER HOVER-EFFEKT ===== */
.animate-hover-lift {
transition: transform 0.2s ease;
}
/* ===== COUNT-UP ANIMATION ===== */
@keyframes count-up {
from {
opacity: 0;
transform: scale(0.5) rotate(-10deg);
}
50% {
opacity: 1;
transform: scale(1.2) rotate(5deg);
}
to {
opacity: 1;
transform: scale(1) rotate(0deg);
}
.animate-hover-lift:hover {
transform: translateY(-2px);
}
.animate-count-up {
animation: count-up 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275);
animation-delay: 0.3s;
animation-fill-mode: both;
}
/* ===== GLOW ANIMATION ===== */
@keyframes glow {
0%, 100% {
box-shadow: 0 0 5px rgba(59, 130, 246, 0.5),
0 0 10px rgba(59, 130, 246, 0.3),
0 0 15px rgba(59, 130, 246, 0.1);
}
50% {
box-shadow: 0 0 20px rgba(59, 130, 246, 0.8),
0 0 30px rgba(59, 130, 246, 0.6),
0 0 40px rgba(59, 130, 246, 0.4);
}
}
.animate-glow {
animation: glow 3s infinite ease-in-out;
}
/* ===== KONFETTI ANIMATION ===== */
.confetti-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
pointer-events: none;
}
.confetti-piece {
position: absolute;
width: 8px;
height: 8px;
top: -10px;
border-radius: 2px;
animation: confetti-fall linear infinite;
}
@keyframes confetti-fall {
/* ===== EINFACHE SUCCESS ANIMATION ===== */
@keyframes simple-success {
0% {
transform: translateY(-100vh) rotate(0deg);
opacity: 1;
opacity: 0;
transform: scale(0.9);
}
100% {
transform: translateY(120vh) rotate(720deg);
opacity: 0;
}
}
/* ===== ERFOLGS-BADGE SPEZIAL-ANIMATIONEN ===== */
@keyframes star-twinkle {
0%, 100% {
opacity: 0.6;
opacity: 1;
transform: scale(1);
}
50% {
}
.animate-success {
animation: simple-success 0.3s ease-out;
}
/* ===== EINFACHER PULSE FÜR LOADING ===== */
@keyframes simple-pulse {
0%, 100% {
opacity: 1;
transform: scale(1.2);
}
}
.badge-star {
animation: star-twinkle 1.5s infinite ease-in-out;
}
/* ===== LOADING SPINNER IMPROVEMENTS ===== */
@keyframes spinner-glow {
0% {
filter: drop-shadow(0 0 5px rgba(59, 130, 246, 0.5));
}
50% {
filter: drop-shadow(0 0 15px rgba(59, 130, 246, 0.8));
}
100% {
filter: drop-shadow(0 0 5px rgba(59, 130, 246, 0.5));
opacity: 0.6;
}
}
#optimization-loader .animate-spin {
animation: spin 1s linear infinite, spinner-glow 2s ease-in-out infinite;
.animate-pulse-simple {
animation: simple-pulse 2s infinite ease-in-out;
}
/* ===== DARK MODE OPTIMIERUNGEN ===== */
@media (prefers-color-scheme: dark) {
.animate-glow {
animation: glow-dark 2s infinite ease-in-out;
}
@keyframes glow-dark {
0%, 100% {
box-shadow: 0 0 5px rgba(96, 165, 250, 0.5),
0 0 10px rgba(96, 165, 250, 0.3),
0 0 15px rgba(96, 165, 250, 0.1);
}
50% {
box-shadow: 0 0 20px rgba(96, 165, 250, 0.8),
0 0 30px rgba(96, 165, 250, 0.6),
0 0 40px rgba(96, 165, 250, 0.4);
}
}
/* ===== EINFACHER PROGRESS BAR ===== */
.progress-fill {
transition: width 1s ease-out;
}
/* ===== PERFORMANCE OPTIMIERUNGEN ===== */
.animate-bounce-in,
.animate-fade-in,
.animate-slide-up,
.animate-slide-up-delay,
.animate-slide-up-delay-2,
.animate-slide-up-delay-3 {
.animate-slide-up-delay-2 {
will-change: transform, opacity;
}
.animate-pulse-scale,
.animate-float,
.animate-float-delay {
.animate-hover-lift {
will-change: transform;
}
.animate-glow {
will-change: box-shadow;
/* ===== UTILITY CLASSES ===== */
.animate-smooth {
transition: all 0.2s ease;
}
.animate-smooth-fast {
transition: all 0.1s ease;
}
/* ===== RESPONSIVE ANPASSUNGEN ===== */
@media (max-width: 768px) {
.confetti-piece {
width: 6px;
height: 6px;
.animate-fade-in,
.animate-slide-up,
.animate-slide-up-delay,
.animate-slide-up-delay-2 {
animation-duration: 0.2s;
}
}
/* ===== REDUZIERTE BEWEGUNG UNTERSTÜTZUNG ===== */
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
#optimization-reward-modal .text-8xl {
font-size: 4rem;
}
#optimization-reward-modal .max-w-md {
max-width: 90vw;
}
}
/* ===== BUTTON HOVER VERBESSERUNGEN ===== */
button:hover .badge-star {
animation-duration: 0.8s;
}
/* ===== ZUSÄTZLICHE UTILITY CLASSES ===== */
.animate-shake {
animation: shake 0.5s ease-in-out;
}
@keyframes shake {
0%, 100% { transform: translateX(0); }
10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
20%, 40%, 60%, 80% { transform: translateX(5px); }
}
.animate-heartbeat {
animation: heartbeat 1.5s infinite;
}
@keyframes heartbeat {
0%, 100% { transform: scale(1); }
14% { transform: scale(1.1); }
28% { transform: scale(1); }
42% { transform: scale(1.1); }
70% { transform: scale(1); }
}
/* ===== PROGRESS BAR ANIMATION ===== */
.progress-fill {
animation: progress-grow 2s ease-out;
}
@keyframes progress-grow {
from {
width: 0%;
}
to {
width: var(--progress-width, 100%);
}
}
/* ===== SUCCESS CHECKMARK ANIMATION ===== */
.success-checkmark {
animation: checkmark-draw 0.8s ease-out;
}
@keyframes checkmark-draw {
0% {
stroke-dasharray: 0 100;
}
100% {
stroke-dasharray: 100 0;
.animate-hover-lift:hover {
transform: none;
}
}

Binary file not shown.

View File

@ -0,0 +1 @@
@keyframes fade-in{from{opacity:0}to{opacity:1}}.animate-fade-in{animation:fade-in .2s ease-out}@keyframes slide-up{from{opacity:0;transform:translateY(15px)}to{opacity:1;transform:translateY(0)}}.animate-slide-up{animation:slide-up .3s ease-out}.animate-slide-up-delay{animation:slide-up .3s ease-out;animation-delay:.1s;animation-fill-mode:both}.animate-slide-up-delay-2{animation:slide-up .3s ease-out;animation-delay:.2s;animation-fill-mode:both}.animate-hover-lift{transition:transform .2s ease}.animate-hover-lift:hover{transform:translateY(-2px)}@keyframes simple-success{0%{opacity:0;transform:scale(0.9)}100%{opacity:1;transform:scale(1)}}.animate-success{animation:simple-success .3s ease-out}@keyframes simple-pulse{0%,100%{opacity:1}50%{opacity:.6}}.animate-pulse-simple{animation:simple-pulse 2s infinite ease-in-out}.progress-fill{transition:width 1s ease-out}.animate-fade-in,.animate-slide-up,.animate-slide-up-delay,.animate-slide-up-delay-2{will-change:transform,opacity}.animate-hover-lift{will-change:transform}.animate-smooth{transition:all .2s ease}.animate-smooth-fast{transition:all .1s ease}@media(max-width:768px){.animate-fade-in,.animate-slide-up,.animate-slide-up-delay,.animate-slide-up-delay-2{animation-duration:.2s}}@media(prefers-reduced-motion:reduce){*{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.01ms !important}.animate-hover-lift:hover{transform:none}}

Binary file not shown.

Binary file not shown.

1
backend/static/css/output.min.css vendored Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

1
backend/static/css/printers.min.css vendored Normal file
View File

@ -0,0 +1 @@
.filter-btn{transition:all .2s ease-in-out}.filter-btn.active{background-color:white;box-shadow:0 1px 3px 0 rgba(0,0,0,0.1),0 1px 2px 0 rgba(0,0,0,0.06);color:#374151}.dark .filter-btn.active{background-color:#475569;color:#f1f5f9}.printer-card-online{background:linear-gradient(135deg,#f0fdf4 0,#fff 100%);border-color:#bbf7d0;box-shadow:0 1px 3px 0 rgba(34,197,94,0.1),0 1px 2px 0 rgba(34,197,94,0.06)}.dark .printer-card-online{background:linear-gradient(135deg,rgba(34,197,94,0.1) 0,#1e293b 100%);border-color:#166534;box-shadow:0 1px 3px 0 rgba(34,197,94,0.2),0 1px 2px 0 rgba(34,197,94,0.1)}.printer-card-online:hover{box-shadow:0 4px 6px -1px rgba(34,197,94,0.2),0 2px 4px -1px rgba(34,197,94,0.1)}.dark .printer-card-online:hover{box-shadow:0 4px 6px -1px rgba(34,197,94,0.3),0 2px 4px -1px rgba(34,197,94,0.2)}.online-indicator{animation:pulse-green 2s cubic-bezier(0.4,0,0.6,1) infinite}@keyframes pulse-green{0%,100%{opacity:1;box-shadow:0 0 0 0 rgba(34,197,94,0.7)}50%{opacity:.8;box-shadow:0 0 0 4px rgba(34,197,94,0)}}.status-count-change{animation:count-change .5s ease-in-out}@keyframes count-change{0%{transform:scale(1)}50%{transform:scale(1.1)}100%{transform:scale(1)}}.auto-refresh-active{background:linear-gradient(45deg,#10b981,#059669);animation:gradient-shift 3s ease-in-out infinite}@keyframes gradient-shift{0%,100%{background-position:0 50%}50%{background-position:100% 50%}}.printer-card{transition:all .3s cubic-bezier(0.4,0,0.2,1)}.printer-card:hover{transform:translateY(-2px)}.live-update-spinner{animation:spin 1s linear infinite}@keyframes spin{from{transform:rotate(0)}to{transform:rotate(360deg)}}@media(max-width:640px){.filter-btn{padding:.375rem .75rem;font-size:.75rem}.status-overview{flex-direction:column;gap:.5rem}.printer-card{padding:1rem}}.dark .printer-card{background-color:#1e293b;border-color:#334155}.dark .printer-card:hover{background-color:#334155}.filter-btn:focus{outline:2px solid #3b82f6;outline-offset:2px}.printer-card:focus-within{outline:2px solid #3b82f6;outline-offset:2px}@media print{.filter-btn,.auto-refresh-btn,.printer-detail-btn,.delete-printer-btn{display:none}.printer-card{break-inside:avoid;box-shadow:none;border:1px solid #000}}@media(prefers-contrast:high){.printer-card-online{border:2px solid #059669}.online-indicator{border:1px solid #000}}@media(prefers-reduced-motion:reduce){.online-indicator,.auto-refresh-active,.live-update-spinner{animation:none}.printer-card{transition:none}.printer-card:hover{transform:none}}

Binary file not shown.

View File

@ -1,12 +1,11 @@
/**
* Mercedes-Benz MYP Platform - Erweiterte Professional Theme
* Verbesserte Light/Dark Mode Implementierung mit optimierten Kontrasten
* OPTIMIERT: Light Mode deutlich verbessert für bessere Lesbarkeit
* Mercedes-Benz MYP Platform - Optimierte Professional Theme
* Vereinfachte Light/Dark Mode Implementierung für bessere Performance
*/
/* Globale CSS-Variablen für konsistente Theming */
:root {
/* Mercedes-Benz Markenfarben - Erweitert */
/* Mercedes-Benz Markenfarben */
--mb-primary: #0073ce;
--mb-primary-dark: #005a9f;
--mb-secondary: #64748b;
@ -14,32 +13,22 @@
--mb-black: #000000;
--mb-silver: #c0c0c0;
/* Light Mode Farbpalette - DEUTLICH VERBESSERT für optimale Lesbarkeit */
/* Light Mode Farbpalette */
--light-bg-primary: #ffffff;
--light-bg-secondary: #fafbfc;
--light-bg-tertiary: #f3f5f7;
--light-bg-accent: #fbfcfd;
--light-surface: #ffffff;
--light-surface-hover: #fafbfc;
--light-surface-active: #f3f5f7;
--light-text-primary: #111827; /* Deutlich verstärkter Kontrast */
--light-text-secondary: #374151; /* Erhöhter Kontrast für bessere Lesbarkeit */
--light-text-muted: #6b7280; /* Optimierter Muted-Text, immer noch lesbar */
--light-text-primary: #111827;
--light-text-secondary: #374151;
--light-text-muted: #6b7280;
--light-text-accent: #0073ce;
--light-border: #e5e7eb; /* Sichtbarere aber elegante Borders */
--light-border: #e5e7eb;
--light-border-strong: #d1d5db;
--light-border-accent: #0073ce15; /* Subtilerer Accent-Border */
--light-shadow: rgba(0, 0, 0, 0.04); /* Sanftere, natürlichere Schatten */
--light-shadow: rgba(0, 0, 0, 0.04);
--light-shadow-strong: rgba(0, 0, 0, 0.08);
--light-shadow-accent: rgba(0, 115, 206, 0.08);
/* Neue Light Mode Gradients - VERBESSERT für sanftere, harmonischere Optik */
--light-gradient-primary: linear-gradient(135deg, #ffffff 0%, #fafbfc 25%, #f8fafc 75%, #f3f5f7 100%);
--light-gradient-card: linear-gradient(135deg, #ffffff 0%, #fdfdfe 50%, #fafbfc 100%);
--light-gradient-hero: linear-gradient(135deg, #fafbfc 0%, #f5f7f9 30%, #f0f3f6 70%, #f8fafc 100%);
--light-gradient-accent: linear-gradient(135deg, #0073ce 0%, #005a9f 100%);
/* Dark Mode Farbpalette - UNVERÄNDERT (bereits perfekt) */
/* Dark Mode Farbpalette */
--dark-bg-primary: #0f172a;
--dark-bg-secondary: #1e293b;
--dark-bg-tertiary: #334155;
@ -54,118 +43,81 @@
--dark-shadow-strong: rgba(0, 0, 0, 0.5);
}
/* Professionelle Hero-Header Stile - VERBESSERT für Light Mode */
/* Vereinfachte Hero-Header */
.professional-hero {
position: relative;
overflow: hidden;
border-radius: 1.5rem;
border-radius: 1rem;
margin: 1.5rem;
margin-bottom: 2rem;
background: var(--light-gradient-hero);
background: var(--light-bg-secondary);
border: 1px solid var(--light-border);
box-shadow:
0 8px 25px var(--light-shadow),
0 4px 12px rgba(0, 115, 206, 0.03),
inset 0 1px 0 rgba(255, 255, 255, 0.9);
transition: all 0.3s ease;
box-shadow: 0 4px 12px var(--light-shadow);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.professional-hero:hover {
transform: translateY(-1px);
box-shadow:
0 12px 35px var(--light-shadow-strong),
0 6px 16px var(--light-shadow-accent),
inset 0 1px 0 rgba(255, 255, 255, 0.95);
box-shadow: 0 8px 20px var(--light-shadow-strong);
}
.dark .professional-hero {
background: linear-gradient(135deg, var(--dark-bg-primary) 0%, var(--dark-bg-secondary) 100%);
background: var(--dark-bg-secondary);
border: 1px solid var(--dark-border);
box-shadow: 0 20px 40px var(--dark-shadow-strong);
box-shadow: 0 8px 20px var(--dark-shadow);
}
.professional-hero::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(45deg, transparent 30%, rgba(255, 255, 255, 0.06) 50%, transparent 70%);
opacity: 0.6;
}
.dark .professional-hero::before {
background: linear-gradient(45deg, transparent 30%, rgba(255, 255, 255, 0.05) 50%, transparent 70%);
opacity: 0.3;
}
/* Hero Pattern Overlay - OPTIMIERT */
.hero-pattern {
background-image:
radial-gradient(circle at 20% 20%, var(--light-border) 0.8px, transparent 0.8px),
radial-gradient(circle at 80% 80%, var(--light-border) 0.8px, transparent 0.8px);
background-size: 48px 48px;
background-position: 0 0, 24px 24px;
}
.dark .hero-pattern {
background-image:
radial-gradient(circle at 20% 20%, var(--dark-border) 1px, transparent 1px),
radial-gradient(circle at 80% 80%, var(--dark-border) 1px, transparent 1px);
}
/* Professionelle Container - VERBESSERT */
/* Vereinfachte Container */
.professional-container {
background: var(--light-surface);
border: 1px solid var(--light-border);
border-radius: 1rem;
box-shadow: 0 4px 20px var(--light-shadow);
backdrop-filter: blur(16px);
transition: all 0.3s ease;
border-radius: 0.75rem;
box-shadow: 0 2px 8px var(--light-shadow);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.dark .professional-container {
background: var(--dark-surface);
border: 1px solid var(--dark-border);
box-shadow: 0 10px 30px var(--dark-shadow);
box-shadow: 0 4px 12px var(--dark-shadow);
}
.professional-container:hover {
transform: translateY(-2px);
box-shadow: 0 8px 30px var(--light-shadow-strong);
transform: translateY(-1px);
box-shadow: 0 4px 16px var(--light-shadow-strong);
}
.dark .professional-container:hover {
box-shadow: 0 20px 40px var(--dark-shadow-strong);
box-shadow: 0 8px 20px var(--dark-shadow-strong);
}
/* Mercedes-Benz Glassmorphism Effekt - OPTIMIERT für Light Mode */
/* Vereinfachte Glassmorphism-Effekte */
.mb-glass {
background: rgba(255, 255, 255, 0.94);
backdrop-filter: blur(16px) saturate(180%);
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(8px);
border: 1px solid rgba(229, 231, 235, 0.4);
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.04);
transition: all 0.3s ease;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
transition: transform 0.2s ease, background 0.2s ease;
}
.dark .mb-glass {
background: rgba(15, 23, 42, 0.9);
background: rgba(15, 23, 42, 0.85);
border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
}
.mb-glass:hover {
background: rgba(255, 255, 255, 0.97);
background: rgba(255, 255, 255, 0.95);
transform: translateY(-1px);
box-shadow: 0 8px 28px rgba(0, 0, 0, 0.06);
}
.dark .mb-glass:hover {
background: rgba(15, 23, 42, 0.95);
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.4);
background: rgba(15, 23, 42, 0.9);
}
/* Professional Buttons - VERBESSERT */
/* Vereinfachte Buttons */
.btn-professional {
background: var(--light-gradient-accent);
background: linear-gradient(135deg, var(--mb-primary) 0%, var(--mb-primary-dark) 100%);
color: white;
border: none;
border-radius: 0.5rem;
@ -174,73 +126,50 @@
font-size: 0.875rem;
text-transform: uppercase;
letter-spacing: 0.025em;
transition: all 0.2s ease;
box-shadow:
0 2px 8px rgba(0, 115, 206, 0.2),
0 1px 3px rgba(0, 115, 206, 0.08);
position: relative;
overflow: hidden;
}
.btn-professional::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
transition: left 0.5s ease;
transition: transform 0.2s ease, box-shadow 0.2s ease;
box-shadow: 0 2px 8px rgba(0, 115, 206, 0.2);
}
.btn-professional:hover {
transform: translateY(-1px);
box-shadow:
0 4px 15px rgba(0, 115, 206, 0.25),
0 2px 8px rgba(0, 115, 206, 0.15);
}
.btn-professional:hover::before {
left: 100%;
box-shadow: 0 4px 12px rgba(0, 115, 206, 0.3);
}
.btn-professional:active {
transform: translateY(0);
}
/* Secondary Button Style - VERBESSERT */
/* Secondary Button */
.btn-secondary-professional {
background: var(--light-surface);
color: var(--light-text-primary);
border: 1px solid var(--light-border-strong);
border-radius: 0.75rem;
padding: 0.75rem 1.75rem;
border-radius: 0.5rem;
padding: 0.75rem 1.5rem;
font-weight: 600;
font-size: 0.875rem;
transition: all 0.3s ease;
box-shadow: 0 2px 8px var(--light-shadow);
transition: all 0.2s ease;
box-shadow: 0 1px 4px var(--light-shadow);
}
.dark .btn-secondary-professional {
background: var(--dark-surface);
color: var(--dark-text-primary);
border-color: var(--dark-border-strong);
box-shadow: 0 4px 15px var(--dark-shadow);
box-shadow: 0 2px 8px var(--dark-shadow);
}
.btn-secondary-professional:hover {
background: var(--light-surface-hover);
border-color: var(--mb-primary);
transform: translateY(-1px);
box-shadow: 0 4px 15px var(--light-shadow-strong);
}
.dark .btn-secondary-professional:hover {
background: var(--dark-surface-hover);
box-shadow: 0 8px 25px var(--dark-shadow);
}
/* Professional Input Fields - VERBESSERT */
/* Vereinfachte Input Fields */
.input-professional {
background: var(--light-surface);
border: 1px solid var(--light-border);
@ -248,20 +177,20 @@
padding: 0.75rem 1rem;
color: var(--light-text-primary);
font-size: 0.875rem;
transition: all 0.3s ease;
box-shadow: 0 1px 6px var(--light-shadow);
transition: border-color 0.2s ease, box-shadow 0.2s ease;
box-shadow: 0 1px 4px var(--light-shadow);
}
.dark .input-professional {
background: var(--dark-surface);
border-color: var(--dark-border);
color: var(--dark-text-primary);
box-shadow: 0 2px 8px var(--dark-shadow);
box-shadow: 0 2px 4px var(--dark-shadow);
}
.input-professional:focus {
border-color: var(--mb-primary);
box-shadow: 0 0 0 3px rgba(0, 115, 206, 0.06);
box-shadow: 0 0 0 3px rgba(0, 115, 206, 0.1);
transform: translateY(-1px);
}
@ -273,77 +202,51 @@
color: var(--dark-text-muted);
}
/* Professional Cards - VERBESSERT */
/* Vereinfachte Cards */
.card-professional {
background: var(--light-gradient-card);
background: var(--light-surface);
border: 1px solid var(--light-border);
border-radius: 0.75rem;
padding: 1.5rem;
box-shadow:
0 2px 12px var(--light-shadow),
0 1px 4px rgba(0, 115, 206, 0.02),
inset 0 1px 0 rgba(255, 255, 255, 0.8);
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.card-professional::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 1px;
background: var(--light-gradient-accent);
opacity: 0;
transition: opacity 0.3s ease;
box-shadow: 0 2px 8px var(--light-shadow);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.card-professional:hover {
transform: translateY(-2px);
box-shadow:
0 8px 25px var(--light-shadow-strong),
0 4px 12px var(--light-shadow-accent),
inset 0 1px 0 rgba(255, 255, 255, 0.9);
}
.card-professional:hover::before {
opacity: 1;
box-shadow: 0 4px 16px var(--light-shadow-strong);
}
.dark .card-professional {
background: var(--dark-surface);
border-color: var(--dark-border);
box-shadow: 0 4px 15px var(--dark-shadow);
box-shadow: 0 4px 12px var(--dark-shadow);
}
/* Professional Statistics Cards - VERBESSERT */
/* Vereinfachte Statistics Cards */
.stat-card {
background: var(--light-surface);
border: 1px solid var(--light-border);
border-radius: 0.75rem;
padding: 1.5rem;
text-align: center;
transition: all 0.3s ease;
box-shadow: 0 2px 12px var(--light-shadow);
position: relative;
overflow: hidden;
transition: transform 0.2s ease, box-shadow 0.2s ease;
box-shadow: 0 2px 8px var(--light-shadow);
}
.dark .stat-card {
background: var(--dark-surface);
border-color: var(--dark-border);
box-shadow: 0 4px 15px var(--dark-shadow);
box-shadow: 0 4px 12px var(--dark-shadow);
}
.stat-card:hover {
transform: translateY(-1px) scale(1.01);
box-shadow: 0 6px 20px var(--light-shadow-strong);
transform: translateY(-1px);
box-shadow: 0 4px 16px var(--light-shadow-strong);
}
.dark .stat-card:hover {
box-shadow: 0 8px 30px var(--dark-shadow-strong);
box-shadow: 0 8px 20px var(--dark-shadow-strong);
}
.stat-number {
@ -370,7 +273,7 @@
color: var(--dark-text-muted);
}
/* Professional Status Badges */
/* Vereinfachte Status Badges */
.status-professional {
display: inline-flex;
align-items: center;
@ -381,121 +284,61 @@
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
transition: all 0.2s ease;
transition: transform 0.2s ease;
border: 1px solid transparent;
}
.status-professional:hover {
transform: scale(1.05);
transform: scale(1.02);
}
/* Verbesserte Status Indicators */
/* Status Indicators */
.status-online {
background: linear-gradient(135deg, #ecfdf5 0%, #d1fae5 100%);
background: #ecfdf5;
color: #065f46;
border: 1px solid rgba(16, 185, 129, 0.2);
box-shadow: 0 2px 8px rgba(16, 185, 129, 0.1);
}
.dark .status-online {
background: linear-gradient(135deg, rgba(16, 185, 129, 0.15) 0%, rgba(16, 185, 129, 0.05) 100%);
background: rgba(16, 185, 129, 0.15);
color: #10b981;
border-color: rgba(16, 185, 129, 0.3);
}
.status-offline {
background: linear-gradient(135deg, #fef2f2 0%, #fecaca 100%);
background: #fef2f2;
color: #991b1b;
border: 1px solid rgba(239, 68, 68, 0.2);
box-shadow: 0 2px 8px rgba(239, 68, 68, 0.1);
}
.dark .status-offline {
background: linear-gradient(135deg, rgba(239, 68, 68, 0.15) 0%, rgba(239, 68, 68, 0.05) 100%);
background: rgba(239, 68, 68, 0.15);
color: #ef4444;
border-color: rgba(239, 68, 68, 0.3);
}
.status-printing {
background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
background: #eff6ff;
color: #1d4ed8;
border: 1px solid rgba(59, 130, 246, 0.2);
box-shadow: 0 2px 8px rgba(59, 130, 246, 0.1);
}
.dark .status-printing {
background: linear-gradient(135deg, rgba(59, 130, 246, 0.15) 0%, rgba(59, 130, 246, 0.05) 100%);
background: rgba(59, 130, 246, 0.15);
color: #3b82f6;
border-color: rgba(59, 130, 246, 0.3);
}
.status-maintenance {
background: linear-gradient(135deg, #faf5ff 0%, #ede9fe 100%);
color: #6b21a8;
border: 1px solid rgba(139, 92, 246, 0.2);
box-shadow: 0 2px 8px rgba(139, 92, 246, 0.1);
}
.dark .status-maintenance {
background: linear-gradient(135deg, rgba(139, 92, 246, 0.15) 0%, rgba(139, 92, 246, 0.05) 100%);
color: #8b5cf6;
border-color: rgba(139, 92, 246, 0.3);
}
.status-pending {
background: linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%);
color: #92400e;
border: 1px solid rgba(251, 191, 36, 0.2);
box-shadow: 0 2px 8px rgba(251, 191, 36, 0.1);
}
.dark .status-pending {
background: linear-gradient(135deg, rgba(251, 191, 36, 0.15) 0%, rgba(251, 191, 36, 0.05) 100%);
color: #fbbf24;
border-color: rgba(251, 191, 36, 0.3);
}
.status-approved {
background: linear-gradient(135deg, #ecfdf5 0%, #a7f3d0 100%);
color: #065f46;
border: 1px solid rgba(16, 185, 129, 0.3);
box-shadow: 0 2px 8px rgba(16, 185, 129, 0.15);
}
.dark .status-approved {
background: linear-gradient(135deg, rgba(16, 185, 129, 0.2) 0%, rgba(16, 185, 129, 0.1) 100%);
color: #10b981;
}
.status-denied {
background: linear-gradient(135deg, #fef2f2 0%, #fca5a5 100%);
color: #991b1b;
border: 1px solid rgba(239, 68, 68, 0.3);
box-shadow: 0 2px 8px rgba(239, 68, 68, 0.15);
}
.dark .status-denied {
background: linear-gradient(135deg, rgba(239, 68, 68, 0.2) 0%, rgba(239, 68, 68, 0.1) 100%);
color: #ef4444;
}
/* Professional Typography */
/* Vereinfachte Typography */
.title-professional {
background: linear-gradient(135deg, var(--light-text-primary) 0%, var(--light-text-accent) 50%, var(--light-text-secondary) 100%);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
color: var(--light-text-primary);
font-weight: 700;
letter-spacing: -0.025em;
line-height: 1.1;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.dark .title-professional {
background: linear-gradient(135deg, var(--dark-text-primary) 0%, var(--dark-text-secondary) 100%);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
color: var(--dark-text-primary);
}
.subtitle-professional {
@ -512,21 +355,17 @@
/* Professional Navigation */
.nav-professional {
background: var(--light-gradient-card);
background: var(--light-bg-secondary);
border: 1px solid var(--light-border);
border-radius: 1rem;
border-radius: 0.75rem;
padding: 0.5rem;
box-shadow:
0 4px 15px var(--light-shadow),
0 2px 8px rgba(0, 115, 206, 0.05),
inset 0 1px 0 rgba(255, 255, 255, 0.6);
backdrop-filter: blur(20px);
box-shadow: 0 2px 8px var(--light-shadow);
}
.dark .nav-professional {
background: var(--dark-surface);
background: var(--dark-bg-secondary);
border-color: var(--dark-border);
box-shadow: 0 4px 15px var(--dark-shadow);
box-shadow: 0 4px 12px var(--dark-shadow);
}
.nav-item-professional {
@ -563,8 +402,8 @@
background: linear-gradient(135deg, rgba(0, 115, 206, 0.1) 0%, rgba(0, 115, 206, 0.05) 100%);
color: var(--mb-primary);
font-weight: 600;
border: 1px solid var(--light-border-accent);
box-shadow: 0 2px 8px var(--light-shadow-accent);
border: 1px solid var(--light-border-strong);
box-shadow: 0 2px 8px var(--light-shadow);
}
.dark .nav-item-professional.active {
@ -575,23 +414,20 @@
.table-professional {
width: 100%;
border-collapse: collapse;
background: var(--light-gradient-card);
border-radius: 1rem;
background: var(--light-bg-secondary);
border-radius: 0.75rem;
overflow: hidden;
box-shadow:
0 4px 20px var(--light-shadow),
0 2px 8px rgba(0, 115, 206, 0.05),
inset 0 1px 0 rgba(255, 255, 255, 0.6);
box-shadow: 0 2px 8px var(--light-shadow);
border: 1px solid var(--light-border);
}
.dark .table-professional {
background: var(--dark-surface);
box-shadow: 0 4px 20px var(--dark-shadow);
background: var(--dark-bg-secondary);
box-shadow: 0 4px 12px var(--dark-shadow);
}
.table-professional th {
background: linear-gradient(135deg, var(--light-bg-secondary) 0%, var(--light-bg-tertiary) 100%);
background: linear-gradient(135deg, var(--light-bg-tertiary) 0%, var(--light-bg-secondary) 100%);
color: var(--light-text-primary);
font-weight: 600;
text-align: left;
@ -611,7 +447,7 @@
}
.dark .table-professional th {
background: var(--dark-bg-secondary);
background: var(--dark-bg-tertiary);
color: var(--dark-text-primary);
border-bottom-color: var(--dark-border);
}
@ -723,7 +559,7 @@
/* Background Gradients für verschiedene Seiten */
.bg-professional {
background: var(--light-gradient-primary);
background: var(--light-bg-secondary);
min-height: 100vh;
position: relative;
}

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More