"Update database files and scripts for Raspberry Pi installation"

This commit is contained in:
2025-05-29 16:20:43 +02:00
parent 1ee91cec0a
commit 97538039c1
7 changed files with 294 additions and 354 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -241,7 +241,7 @@ chown "$APP_USER:$APP_USER" "$APP_DIR/.env"
# Erstelle Kiosk-Skript (nach offizieller Anleitung) # Erstelle Kiosk-Skript (nach offizieller Anleitung)
log "Erstelle Kiosk-Skript..." log "Erstelle Kiosk-Skript..."
cat > "/home/$KIOSK_USER/kiosk.sh" << EOF cat > "$KIOSK_HOME/kiosk.sh" << EOF
#!/bin/bash #!/bin/bash
# Warte auf System-Bereitschaft # Warte auf System-Bereitschaft
@@ -259,8 +259,8 @@ xset -dpms
unclutter -idle 0.5 -root & unclutter -idle 0.5 -root &
# Bereinige Chromium-Präferenzen (verhindert Crash-Warnungen) # Bereinige Chromium-Präferenzen (verhindert Crash-Warnungen)
sed -i 's/"exited_cleanly":false/"exited_cleanly":true/' /home/$KIOSK_USER/.config/chromium/Default/Preferences 2>/dev/null || true sed -i 's/"exited_cleanly":false/"exited_cleanly":true/' $KIOSK_HOME/.config/chromium/Default/Preferences 2>/dev/null || true
sed -i 's/"exit_type":"Crashed"/"exit_type":"Normal"/' /home/$KIOSK_USER/.config/chromium/Default/Preferences 2>/dev/null || true sed -i 's/"exit_type":"Crashed"/"exit_type":"Normal"/' $KIOSK_HOME/.config/chromium/Default/Preferences 2>/dev/null || true
# Warte auf Netzwerk und Anwendung # Warte auf Netzwerk und Anwendung
while ! curl -s http://localhost > /dev/null; do while ! curl -s http://localhost > /dev/null; do
@@ -304,12 +304,12 @@ done
# done # done
EOF EOF
chmod +x "/home/$KIOSK_USER/kiosk.sh" chmod +x "$KIOSK_HOME/kiosk.sh"
chown "$KIOSK_USER:$KIOSK_USER" "/home/$KIOSK_USER/kiosk.sh" chown "$KIOSK_USER:$KIOSK_USER" "$KIOSK_HOME/kiosk.sh"
# Konfiguriere LightDM für automatischen Login (nach offizieller Anleitung) # Konfiguriere LightDM für automatischen Login (nach offizieller Anleitung)
log "Konfiguriere automatischen Login..." log "Konfiguriere automatischen Login..."
cat > "/etc/lightdm/lightdm.conf" << EOF cat > "$LIGHTDM_CONF" << EOF
[Seat:*] [Seat:*]
autologin-user=$KIOSK_USER autologin-user=$KIOSK_USER
autologin-user-timeout=0 autologin-user-timeout=0
@@ -319,17 +319,17 @@ EOF
# Erstelle Openbox-Konfiguration für Kiosk-Benutzer # Erstelle Openbox-Konfiguration für Kiosk-Benutzer
log "Konfiguriere Openbox für Kiosk-Modus..." log "Konfiguriere Openbox für Kiosk-Modus..."
mkdir -p "/home/$KIOSK_USER/.config/openbox" mkdir -p "$KIOSK_HOME/.config/openbox"
cat > "/home/$KIOSK_USER/.config/openbox/autostart" << EOF cat > "$KIOSK_HOME/.config/openbox/autostart" << EOF
# Starte Kiosk-Anwendung automatisch # Starte Kiosk-Anwendung automatisch
/home/$KIOSK_USER/kiosk.sh & $KIOSK_HOME/kiosk.sh &
EOF EOF
chown -R "$KIOSK_USER:$KIOSK_USER" "/home/$KIOSK_USER/.config" chown -R "$KIOSK_USER:$KIOSK_USER" "$KIOSK_HOME/.config"
# Erstelle Systemd-Service für die Anwendung # Erstelle Systemd-Service für die Anwendung
log "Erstelle Systemd-Service für Anwendung..." log "Erstelle Systemd-Service für Anwendung..."
cat > "/etc/systemd/system/$SERVICE_NAME.service" << EOF cat > "$SYSTEMD_DIR/$SERVICE_NAME.service" << EOF
[Unit] [Unit]
Description=MYP Druckerverwaltung Flask Application Description=MYP Druckerverwaltung Flask Application
After=network.target After=network.target
@@ -352,7 +352,7 @@ EOF
# Erstelle Systemd-Service für Kiosk (nach offizieller Anleitung) # Erstelle Systemd-Service für Kiosk (nach offizieller Anleitung)
log "Erstelle Systemd-Service für Kiosk..." log "Erstelle Systemd-Service für Kiosk..."
cat > "/etc/systemd/system/$KIOSK_SERVICE_NAME.service" << EOF cat > "$SYSTEMD_DIR/$KIOSK_SERVICE_NAME.service" << EOF
[Unit] [Unit]
Description=MYP Chromium Kiosk Description=MYP Chromium Kiosk
Wants=graphical.target Wants=graphical.target
@@ -360,9 +360,9 @@ After=graphical.target $SERVICE_NAME.service
[Service] [Service]
Environment=DISPLAY=:0.0 Environment=DISPLAY=:0.0
Environment=XAUTHORITY=/home/$KIOSK_USER/.Xauthority Environment=XAUTHORITY=$KIOSK_HOME/.Xauthority
Type=simple Type=simple
ExecStart=/bin/bash /home/$KIOSK_USER/kiosk.sh ExecStart=/bin/bash $KIOSK_HOME/kiosk.sh
Restart=on-abort Restart=on-abort
User=$KIOSK_USER User=$KIOSK_USER
Group=$KIOSK_USER Group=$KIOSK_USER
@@ -373,7 +373,7 @@ EOF
# Nginx-Konfiguration # Nginx-Konfiguration
log "Konfiguriere Nginx..." log "Konfiguriere Nginx..."
cat > "/etc/nginx/sites-available/myp-druckerverwaltung" << EOF cat > "$NGINX_SITES_AVAILABLE/myp-druckerverwaltung" << EOF
server { server {
listen 80 default_server; listen 80 default_server;
listen [::]:80 default_server; listen [::]:80 default_server;
@@ -403,12 +403,12 @@ server {
EOF EOF
# Aktiviere Nginx-Site # Aktiviere Nginx-Site
rm -f /etc/nginx/sites-enabled/default rm -f $NGINX_SITES_ENABLED/default
ln -sf /etc/nginx/sites-available/myp-druckerverwaltung /etc/nginx/sites-enabled/ ln -sf $NGINX_SITES_AVAILABLE/myp-druckerverwaltung $NGINX_SITES_ENABLED/
# Erstelle Wartungsskript # Erstelle Wartungsskript
log "Erstelle Wartungsskript..." log "Erstelle Wartungsskript..."
cat > "/usr/local/bin/myp-maintenance" << 'EOF' cat > "$LOCAL_BIN/myp-maintenance" << 'EOF'
#!/bin/bash #!/bin/bash
# MYP Druckerverwaltung Wartungsskript # MYP Druckerverwaltung Wartungsskript
@@ -452,7 +452,7 @@ case "$1" in
;; ;;
update) update)
echo "Aktualisiere MYP Druckerverwaltung..." echo "Aktualisiere MYP Druckerverwaltung..."
cd /opt/myp-druckerverwaltung cd $APP_DIR
sudo -u myp git pull || echo "Git pull nicht möglich - lokale Installation" sudo -u myp git pull || echo "Git pull nicht möglich - lokale Installation"
# Aktualisiere Python-Dependencies # Aktualisiere Python-Dependencies
@@ -481,50 +481,50 @@ case "$1" in
esac esac
EOF EOF
chmod +x /usr/local/bin/myp-maintenance chmod +x $LOCAL_BIN/myp-maintenance
# Erstelle Backup-Skript # Erstelle Backup-Skript
log "Erstelle Backup-Skript..." log "Erstelle Backup-Skript..."
cat > "/usr/local/bin/myp-backup" << 'EOF' cat > "$LOCAL_BIN/myp-backup" << EOF
#!/bin/bash #!/bin/bash
BACKUP_DIR="/opt/myp-backups" BACKUP_DIR="$BACKUP_DIR"
DATE=$(date +%Y%m%d_%H%M%S) DATE=\$(date +%Y%m%d_%H%M%S)
APP_DIR="/opt/myp-druckerverwaltung" APP_DIR="$APP_DIR"
mkdir -p "$BACKUP_DIR" mkdir -p "\$BACKUP_DIR"
echo "Erstelle Backup: $DATE" echo "Erstelle Backup: \$DATE"
# Stoppe Anwendung # Stoppe Anwendung
systemctl stop myp-druckerverwaltung systemctl stop myp-druckerverwaltung
# Erstelle Backup # Erstelle Backup
tar -czf "$BACKUP_DIR/myp_backup_$DATE.tar.gz" \ tar -czf "\$BACKUP_DIR/myp_backup_\$DATE.tar.gz" \\
-C "$APP_DIR" \ -C "\$APP_DIR" \\
--exclude='node_modules' \ --exclude='node_modules' \\
--exclude='__pycache__' \ --exclude='__pycache__' \\
--exclude='venv' \ --exclude='venv' \\
database.db \ database.db \\
.env \ .env \\
uploads/ \ uploads/ \\
logs/ \ logs/ \\
config/ \ config/ \\
2>/dev/null || true 2>/dev/null || true
# Starte Anwendung # Starte Anwendung
systemctl start myp-druckerverwaltung systemctl start myp-druckerverwaltung
echo "Backup erstellt: $BACKUP_DIR/myp_backup_$DATE.tar.gz" echo "Backup erstellt: \$BACKUP_DIR/myp_backup_\$DATE.tar.gz"
# Lösche alte Backups (älter als 30 Tage) # Lösche alte Backups (älter als 30 Tage)
find "$BACKUP_DIR" -name "myp_backup_*.tar.gz" -mtime +30 -delete find "\$BACKUP_DIR" -name "myp_backup_*.tar.gz" -mtime +30 -delete
EOF EOF
chmod +x /usr/local/bin/myp-backup chmod +x $LOCAL_BIN/myp-backup
# Erstelle Cron-Job für automatische Backups # Erstelle Cron-Job für automatische Backups
echo "0 2 * * * root /usr/local/bin/myp-backup" > /etc/cron.d/myp-backup echo "0 2 * * * root $LOCAL_BIN/myp-backup" > $CRON_DIR/myp-backup
# Aktiviere und starte Services # Aktiviere und starte Services
log "Aktiviere und starte Services..." log "Aktiviere und starte Services..."
@@ -583,9 +583,9 @@ info " • Update: myp-maintenance update"
info " • Backup erstellen: myp-backup" info " • Backup erstellen: myp-backup"
echo echo
info "🔍 Zusätzliche Konfiguration:" info "🔍 Zusätzliche Konfiguration:"
info " • Kiosk-Skript: /home/$KIOSK_USER/kiosk.sh" info " • Kiosk-Skript: $KIOSK_HOME/kiosk.sh"
info " • LightDM-Konfiguration: /etc/lightdm/lightdm.conf" info " • LightDM-Konfiguration: $LIGHTDM_CONF"
info " • Openbox-Autostart: /home/$KIOSK_USER/.config/openbox/autostart" info " • Openbox-Autostart: $KIOSK_HOME/.config/openbox/autostart"
info " • Anwendungslogs: journalctl -u myp-druckerverwaltung -f" info " • Anwendungslogs: journalctl -u myp-druckerverwaltung -f"
info " • Kiosk-Logs: journalctl -u myp-kiosk -f" info " • Kiosk-Logs: journalctl -u myp-kiosk -f"
echo echo

View File

@@ -14,6 +14,15 @@ YELLOW='\033[1;33m'
BLUE='\033[0;34m' BLUE='\033[0;34m'
NC='\033[0m' NC='\033[0m'
# Pfad-Variablen
KIOSK_HOME="/home/kiosk"
PI_HOME="/home/pi"
LOCAL_BIN="/usr/local/bin"
APP_DIR="/opt/myp-druckerverwaltung"
BACKUP_DIR="/opt/myp-backups"
BACKUP_ORIGINAL="/opt/myp-backup-original"
LIGHTDM_CONF="/etc/lightdm/lightdm.conf"
# Logging-Funktionen # Logging-Funktionen
log() { echo -e "${GREEN}[SCHNELLSTART] $1${NC}"; } log() { echo -e "${GREEN}[SCHNELLSTART] $1${NC}"; }
error() { echo -e "${RED}[FEHLER] $1${NC}"; exit 1; } error() { echo -e "${RED}[FEHLER] $1${NC}"; exit 1; }
@@ -119,18 +128,18 @@ log "=== SCHRITT 3/3: FINALISIERUNG ==="
# Kiosk-URL anpassen falls gewünscht # Kiosk-URL anpassen falls gewünscht
if [ "$kiosk_url" != "http://localhost" ]; then if [ "$kiosk_url" != "http://localhost" ]; then
log "Konfiguriere Kiosk-URL: $kiosk_url" log "Konfiguriere Kiosk-URL: $kiosk_url"
sed -i "s|http://localhost|$kiosk_url|g" /home/kiosk/kiosk.sh sed -i "s|http://localhost|$kiosk_url|g" $KIOSK_HOME/kiosk.sh
fi fi
# Erstelle Schnellzugriff-Desktop-Icons # Erstelle Schnellzugriff-Desktop-Icons
log "Erstelle Desktop-Verknüpfungen..." log "Erstelle Desktop-Verknüpfungen..."
# Für den normalen Benutzer (falls vorhanden) # Für den normalen Benutzer (falls vorhanden)
if [ -d "/home/pi" ]; then if [ -d "$PI_HOME" ]; then
mkdir -p /home/pi/Desktop mkdir -p $PI_HOME/Desktop
# Wartungs-Icon # Wartungs-Icon
cat > "/home/pi/Desktop/MYP-Wartung.desktop" << EOF cat > "$PI_HOME/Desktop/MYP-Wartung.desktop" << EOF
[Desktop Entry] [Desktop Entry]
Version=1.0 Version=1.0
Type=Application Type=Application
@@ -143,7 +152,7 @@ Categories=System;
EOF EOF
# Browser-Icon für normale Ansicht # Browser-Icon für normale Ansicht
cat > "/home/pi/Desktop/MYP-Browser.desktop" << EOF cat > "$PI_HOME/Desktop/MYP-Browser.desktop" << EOF
[Desktop Entry] [Desktop Entry]
Version=1.0 Version=1.0
Type=Application Type=Application
@@ -155,30 +164,30 @@ Terminal=false
Categories=Network; Categories=Network;
EOF EOF
chown pi:pi /home/pi/Desktop/*.desktop chown pi:pi $PI_HOME/Desktop/*.desktop
chmod +x /home/pi/Desktop/*.desktop chmod +x $PI_HOME/Desktop/*.desktop
fi fi
# Erstelle Backup der ursprünglichen Konfiguration # Erstelle Backup der ursprünglichen Konfiguration
log "Erstelle Konfigurations-Backup..." log "Erstelle Konfigurations-Backup..."
mkdir -p /opt/myp-backup-original mkdir -p $BACKUP_ORIGINAL
cp /etc/lightdm/lightdm.conf /opt/myp-backup-original/ 2>/dev/null || true cp $LIGHTDM_CONF $BACKUP_ORIGINAL/ 2>/dev/null || true
cp /home/kiosk/.config/openbox/autostart /opt/myp-backup-original/ 2>/dev/null || true cp $KIOSK_HOME/.config/openbox/autostart $BACKUP_ORIGINAL/ 2>/dev/null || true
# Erstelle Notfall-Wiederherstellungsskript # Erstelle Notfall-Wiederherstellungsskript
cat > "/usr/local/bin/myp-notfall-reset" << 'EOF' cat > "$LOCAL_BIN/myp-notfall-reset" << EOF
#!/bin/bash #!/bin/bash
echo "🚨 MYP Notfall-Reset" echo "🚨 MYP Notfall-Reset"
echo "Stoppt alle MYP-Services und stellt Original-Konfiguration wieder her" echo "Stoppt alle MYP-Services und stellt Original-Konfiguration wieder her"
echo echo
read -p "Wirklich fortfahren? (j/N): " confirm read -p "Wirklich fortfahren? (j/N): " confirm
if [[ "$confirm" =~ ^[jJ]$ ]]; then if [[ "\$confirm" =~ ^[jJ]$ ]]; then
systemctl stop myp-kiosk myp-druckerverwaltung nginx systemctl stop myp-kiosk myp-druckerverwaltung nginx
systemctl disable myp-kiosk systemctl disable myp-kiosk
# Original LightDM wiederherstellen (falls vorhanden) # Original LightDM wiederherstellen (falls vorhanden)
if [ -f "/opt/myp-backup-original/lightdm.conf" ]; then if [ -f "$BACKUP_ORIGINAL/lightdm.conf" ]; then
cp /opt/myp-backup-original/lightdm.conf /etc/lightdm/ cp $BACKUP_ORIGINAL/lightdm.conf $LIGHTDM_CONF
fi fi
echo "✅ Reset abgeschlossen. System neustarten für normale Desktop-Nutzung:" echo "✅ Reset abgeschlossen. System neustarten für normale Desktop-Nutzung:"
@@ -186,7 +195,7 @@ if [[ "$confirm" =~ ^[jJ]$ ]]; then
fi fi
EOF EOF
chmod +x /usr/local/bin/myp-notfall-reset chmod +x $LOCAL_BIN/myp-notfall-reset
# Zusammenfassung der Installation # Zusammenfassung der Installation
echo echo
@@ -207,10 +216,10 @@ info " • Backup erstellen: myp-backup"
info " • Notfall-Reset: myp-notfall-reset" info " • Notfall-Reset: myp-notfall-reset"
echo echo
info "📁 WICHTIGE PFADE:" info "📁 WICHTIGE PFADE:"
info " • Anwendung: /opt/myp-druckerverwaltung/" info " • Anwendung: $APP_DIR/"
info " • Kiosk-Skript: /home/kiosk/kiosk.sh" info " • Kiosk-Skript: $KIOSK_HOME/kiosk.sh"
info " • Logs: journalctl -u myp-kiosk -f" info " • Logs: journalctl -u myp-kiosk -f"
info " • Backups: /opt/myp-backups/" info " • Backups: $BACKUP_DIR/"
echo echo
info "🔒 SICHERHEIT:" info "🔒 SICHERHEIT:"
info " • Firewall aktiv (Ports 80, 22)" info " • Firewall aktiv (Ports 80, 22)"

File diff suppressed because one or more lines are too long

View File

@@ -203,14 +203,7 @@
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
</svg> </svg>
<span>Alle Anträge ansehen</span> <span>Anträge Übersicht</span>
</a>
<a href="{{ url_for('guest.guest_status') }}"
class="btn-secondary flex items-center gap-2">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m3-6l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2M7 20l4-16m2 16l4-16"/>
</svg>
<span>Status mit Code prüfen</span>
</a> </a>
</div> </div>
</div> </div>

View File

@@ -9,92 +9,60 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="bg-professional"> <div class="space-y-8">
<!-- Dark Mode Override --> <!-- Page Header -->
<style> <div class="dashboard-card p-6">
.dark .bg-professional { <div class="flex flex-col md:flex-row md:items-center md:justify-between gap-6">
background: #000000 !important; <div class="flex items-center gap-4">
} <div class="w-12 h-12 flex-shrink-0">
.dark .professional-hero { <svg class="w-full h-full text-slate-900 dark:text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
background: linear-gradient(135deg, #000000 0%, #1a1a1a 100%) !important; <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
border-color: #333333 !important;
}
.dark .professional-container {
background: #111111 !important;
border-color: #333333 !important;
}
.dark .mb-glass {
background: rgba(17, 17, 17, 0.95) !important;
border-color: rgba(255, 255, 255, 0.1) !important;
}
</style>
<!-- Professional Hero Header -->
<div class="professional-hero hero-pattern animate-fade-in" style="margin: 2rem; margin-bottom: 3rem;">
<div class="absolute inset-0 bg-gradient-to-r from-black/10 to-black/20 dark:from-black/40 dark:to-black/60"></div>
<!-- Status Indicator -->
<div class="absolute top-6 right-6 flex items-center space-x-4 z-10">
<div class="mb-glass rounded-full px-6 py-3 animate-scale-in">
<div class="flex items-center space-x-3">
<div class="status-dot status-online"></div>
<span class="text-sm font-semibold text-professional-primary">Live Status</span>
</div>
</div>
<div class="mb-glass rounded-full px-6 py-3 animate-scale-in">
<span id="live-time" class="text-sm font-semibold text-professional-primary"></span>
</div>
</div>
<div class="relative max-w-6xl mx-auto px-6 lg:px-8 py-20 z-10">
<div class="text-center animate-slide-up">
<!-- Mercedes-Benz Logo -->
<div class="inline-flex items-center justify-center w-28 h-28 mb-glass rounded-full mb-10 professional-shadow">
<svg class="w-14 h-14 text-professional-primary" viewBox="0 0 80 80" fill="currentColor">
<path d="M58.6,4.5C53,1.6,46.7,0,40,0c-6.7,0-13,1.6-18.6,4.5v0C8.7,11.2,0,24.6,0,40c0,15.4,8.7,28.8,21.5,35.5
C27,78.3,33.3,80,40,80c6.7,0,12.9-1.7,18.5-4.6C71.3,68.8,80,55.4,80,40C80,24.6,71.3,11.2,58.6,4.5z M4,40
c0-13.1,7-24.5,17.5-30.9v0C26.6,6,32.5,4.2,39,4l-4.5,32.7L21.5,46.8v0L8.3,57.1C5.6,52,4,46.2,4,40z M58.6,70.8
C53.1,74.1,46.8,76,40,76c-6.8,0-13.2-1.9-18.6-5.2c-4.9-2.9-8.9-6.9-11.9-11.7l11.9-4.9v0L40,46.6l18.6,7.5v0l12,4.9
C67.6,63.9,63.4,67.9,58.6,70.8z M58.6,46.8L58.6,46.8l-12.9-10L41.1,4c6.3,0.2,12.3,2,17.4,5.1v0C69,15.4,76,26.9,76,40
c0,6.2-1.5,12-4.3,17.1L58.6,46.8z"/>
</svg> </svg>
</div> </div>
<div>
<h1 class="title-professional text-6xl md:text-7xl font-bold mb-8 tracking-tight"> <h1 class="text-3xl font-bold text-slate-900 dark:text-white tracking-tight">Anfrage-Status</h1>
Anfrage-Status <p class="text-slate-500 dark:text-slate-400 mt-1">Verfolgen Sie den Status Ihrer Gastanfrage für 3D-Druck</p>
</h1> </div>
<p class="subtitle-professional text-2xl md:text-3xl max-w-5xl mx-auto leading-relaxed mb-12"> </div>
Verfolgen Sie den Status Ihrer Gastanfrage für 3D-Druck in Echtzeit <div class="flex flex-wrap gap-3">
</p> <button onclick="location.reload()"
class="btn-secondary flex items-center gap-2">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
</svg>
<span>Aktualisieren</span>
</button>
<a href="{{ url_for('guest.guest_request_form') }}"
class="btn-primary flex items-center gap-2">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"/>
</svg>
<span>Neue Anfrage</span>
</a>
</div> </div>
</div> </div>
</div> </div>
<div class="max-w-4xl mx-auto px-6 lg:px-8 -mt-12 relative z-10" style="margin-bottom: 4rem;">
<!-- Status Card -->
<div class="professional-container animate-slide-up" style="padding: 3rem; border-radius: 2rem; margin-bottom: 2rem;">
<!-- Status Badge --> <!-- Status Badge -->
<div class="flex justify-center mb-8"> <div class="dashboard-card p-6 text-center">
{% if request.status == 'pending' %} {% if request.status == 'pending' %}
<div class="inline-flex items-center px-8 py-4 rounded-3xl bg-yellow-100 dark:bg-yellow-900/30 text-yellow-800 dark:text-yellow-200 text-lg font-bold"> <div class="inline-flex items-center px-6 py-3 rounded-full bg-yellow-100 dark:bg-yellow-900/30 text-yellow-800 dark:text-yellow-200 text-lg font-semibold">
<svg class="w-6 h-6 mr-3 animate-spin" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-6 h-6 mr-3 animate-spin" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
</svg> </svg>
Wird geprüft Wird geprüft
</div> </div>
{% elif request.status == 'approved' %} {% elif request.status == 'approved' %}
<div class="inline-flex items-center px-8 py-4 rounded-3xl bg-green-100 dark:bg-green-900/30 text-green-800 dark:text-green-200 text-lg font-bold"> <div class="inline-flex items-center px-6 py-3 rounded-full bg-green-100 dark:bg-green-900/30 text-green-800 dark:text-green-200 text-lg font-semibold">
<svg class="w-6 h-6 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-6 h-6 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
</svg> </svg>
Genehmigt Genehmigt
</div> </div>
{% elif request.status == 'denied' %} {% elif request.status == 'denied' %}
<div class="inline-flex items-center px-8 py-4 rounded-3xl bg-red-100 dark:bg-red-900/30 text-red-800 dark:text-red-200 text-lg font-bold"> <div class="inline-flex items-center px-6 py-3 rounded-full bg-red-100 dark:bg-red-900/30 text-red-800 dark:text-red-200 text-lg font-semibold">
<svg class="w-6 h-6 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-6 h-6 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
</svg> </svg>
Abgelehnt Abgelehnt
</div> </div>
@@ -102,104 +70,104 @@
</div> </div>
<!-- Anfrage-Details --> <!-- Anfrage-Details -->
<div class="space-y-8 mb-10"> <div class="dashboard-card p-6">
<div class="text-center mb-12"> <div class="text-center mb-8">
<h2 class="title-professional text-3xl font-bold mb-4"> <h2 class="text-2xl font-bold text-slate-900 dark:text-white mb-2">
Anfrage Details Anfrage Details
</h2> </h2>
<p class="subtitle-professional text-lg"> <p class="text-slate-500 dark:text-slate-400">
Übersicht Ihrer eingereichten Gastanfrage Übersicht Ihrer eingereichten Gastanfrage
</p> </p>
</div> </div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-8"> <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="mb-glass p-6 rounded-2xl"> <div class="bg-gray-50 dark:bg-slate-700/30 p-4 rounded-lg">
<h3 class="text-base font-bold text-professional-primary mb-3">Anfrage-ID</h3> <h3 class="text-sm font-medium text-slate-500 dark:text-slate-400 mb-2">Anfrage-ID</h3>
<p class="text-2xl font-bold text-professional-accent">#{{ request.id }}</p> <p class="text-xl font-bold text-slate-900 dark:text-white">#{{ request.id }}</p>
</div> </div>
<div class="mb-glass p-6 rounded-2xl"> <div class="bg-gray-50 dark:bg-slate-700/30 p-4 rounded-lg">
<h3 class="text-base font-bold text-professional-primary mb-3">Erstellt am</h3> <h3 class="text-sm font-medium text-slate-500 dark:text-slate-400 mb-2">Erstellt am</h3>
<p class="text-2xl font-bold text-professional-primary">{{ request.created_at|format_datetime }}</p> <p class="text-xl font-bold text-slate-900 dark:text-white">{{ request.created_at|format_datetime }}</p>
</div> </div>
<div class="mb-glass p-6 rounded-2xl"> <div class="bg-gray-50 dark:bg-slate-700/30 p-4 rounded-lg">
<h3 class="text-base font-bold text-professional-primary mb-3">Name</h3> <h3 class="text-sm font-medium text-slate-500 dark:text-slate-400 mb-2">Name</h3>
<p class="text-2xl font-bold text-professional-primary">{{ request.name }}</p> <p class="text-xl font-bold text-slate-900 dark:text-white">{{ request.name }}</p>
</div> </div>
<div class="mb-glass p-6 rounded-2xl"> <div class="bg-gray-50 dark:bg-slate-700/30 p-4 rounded-lg">
<h3 class="text-base font-bold text-professional-primary mb-3">Gewünschte Dauer</h3> <h3 class="text-sm font-medium text-slate-500 dark:text-slate-400 mb-2">Gewünschte Dauer</h3>
<p class="text-2xl font-bold text-professional-accent">{{ request.duration_min }} Minuten</p> <p class="text-xl font-bold text-slate-900 dark:text-white">{{ request.duration_min }} Minuten</p>
</div> </div>
</div> </div>
{% if request.reason %} {% if request.reason %}
<div class="mb-glass p-6 rounded-2xl"> <div class="mt-6 bg-gray-50 dark:bg-slate-700/30 p-4 rounded-lg">
<h3 class="text-base font-bold text-professional-primary mb-4">Begründung</h3> <h3 class="text-sm font-medium text-slate-500 dark:text-slate-400 mb-2">Begründung</h3>
<p class="text-professional-secondary text-lg leading-relaxed">{{ request.reason }}</p> <p class="text-slate-700 dark:text-slate-300">{{ request.reason }}</p>
</div> </div>
{% endif %} {% endif %}
{% if request.printer %} {% if request.printer %}
<div class="mb-glass p-6 rounded-2xl"> <div class="mt-6 bg-gray-50 dark:bg-slate-700/30 p-4 rounded-lg">
<h3 class="text-base font-bold text-professional-primary mb-4">Drucker</h3> <h3 class="text-sm font-medium text-slate-500 dark:text-slate-400 mb-2">Drucker</h3>
<p class="text-professional-secondary text-lg">{{ request.printer.name }} {% if request.printer.location %}({{ request.printer.location }}){% endif %}</p> <p class="text-slate-700 dark:text-slate-300">{{ request.printer.name }} {% if request.printer.location %}({{ request.printer.location }}){% endif %}</p>
</div> </div>
{% endif %} {% endif %}
</div> </div>
<!-- Status-spezifische Inhalte --> <!-- Status-spezifische Inhalte -->
{% if request.status == 'pending' %} {% if request.status == 'pending' %}
<div class="alert-professional alert-warning" style="border-radius: 2rem; padding: 2.5rem;"> <div class="dashboard-card p-6 border-l-4 border-yellow-400">
<div class="flex-shrink-0"> <div class="flex items-start gap-4">
<div class="w-16 h-16 bg-gradient-to-br from-yellow-500 to-orange-600 rounded-3xl flex items-center justify-center"> <div class="w-12 h-12 bg-yellow-100 dark:bg-yellow-900/30 rounded-xl flex items-center justify-center flex-shrink-0">
<svg class="h-8 w-8 text-white" fill="currentColor" viewBox="0 0 20 20"> <svg class="w-6 h-6 text-yellow-600 dark:text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path> <path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd"/>
</svg> </svg>
</div> </div>
</div> <div class="flex-1">
<div class="flex-1 ml-8"> <h3 class="text-lg font-semibold text-slate-900 dark:text-white mb-2">Ihre Anfrage wird geprüft</h3>
<h3 class="text-2xl font-bold text-professional-primary mb-4">Ihre Anfrage wird geprüft</h3> <p class="text-slate-600 dark:text-slate-400">
<p class="text-lg text-professional-secondary leading-relaxed">
Unser Team prüft Ihre Anfrage mit höchster Priorität. Sie erhalten eine sofortige Benachrichtigung, sobald eine Entscheidung getroffen wurde. Unser Team prüft Ihre Anfrage mit höchster Priorität. Sie erhalten eine sofortige Benachrichtigung, sobald eine Entscheidung getroffen wurde.
Diese Seite aktualisiert sich automatisch alle 30 Sekunden. Diese Seite aktualisiert sich automatisch alle 30 Sekunden.
</p> </p>
</div> </div>
</div> </div>
</div>
{% elif request.status == 'approved' %} {% elif request.status == 'approved' %}
<div class="alert-professional alert-success" style="border-radius: 2rem; padding: 2.5rem; margin-bottom: 2rem;"> <div class="dashboard-card p-6 border-l-4 border-green-400">
<div class="flex-shrink-0"> <div class="flex items-start gap-4">
<div class="w-16 h-16 bg-gradient-to-br from-green-500 to-emerald-600 rounded-3xl flex items-center justify-center"> <div class="w-12 h-12 bg-green-100 dark:bg-green-900/30 rounded-xl flex items-center justify-center flex-shrink-0">
<svg class="h-8 w-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-6 h-6 text-green-600 dark:text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
</svg> </svg>
</div> </div>
<div class="flex-1">
<h3 class="text-lg font-semibold text-slate-900 dark:text-white mb-2">Anfrage genehmigt!</h3>
<p class="text-slate-600 dark:text-slate-400">Ihr Druckauftrag wurde genehmigt und ist bereit zum Start.</p>
</div> </div>
<div class="flex-1 ml-8">
<h3 class="text-2xl font-bold text-professional-primary mb-4">Anfrage genehmigt!</h3>
<p class="text-lg text-professional-secondary leading-relaxed">Ihr Druckauftrag wurde genehmigt und ist bereit zum Start.</p>
</div> </div>
</div> </div>
{% if otp_code %} {% if otp_code %}
<!-- Code-Anzeige --> <!-- Code-Anzeige -->
<div class="professional-container" style="padding: 2.5rem; border-radius: 2rem; margin-bottom: 2rem;"> <div class="dashboard-card p-6">
<h4 class="text-2xl font-bold text-professional-primary mb-8 text-center">Ihr Zugangscode</h4> <h4 class="text-xl font-bold text-slate-900 dark:text-white mb-6 text-center">Ihr Zugangscode</h4>
<!-- 6-stelliger Code in schönen Boxen --> <!-- 6-stelliger Code in schönen Boxen -->
<div class="flex justify-center space-x-4 mb-8"> <div class="flex justify-center gap-3 mb-6">
{% for char in otp_code %} {% for char in otp_code %}
<div class="w-20 h-20 bg-gradient-to-br from-blue-500 to-indigo-600 text-white rounded-2xl flex items-center justify-center text-3xl font-bold shadow-lg transform hover:scale-105 transition-transform duration-300"> <div class="w-16 h-16 bg-blue-100 dark:bg-blue-900/30 text-blue-900 dark:text-blue-100 rounded-lg flex items-center justify-center text-2xl font-bold">
{{ char }} {{ char }}
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
<!-- Code zum Kopieren --> <!-- Code zum Kopieren -->
<div class="text-center mb-8"> <div class="text-center mb-6">
<div class="inline-flex items-center mb-glass rounded-2xl px-6 py-4"> <div class="inline-flex items-center bg-gray-50 dark:bg-slate-700/30 rounded-lg px-4 py-3">
<span class="text-2xl font-mono font-bold text-professional-primary mr-4" id="otpCode">{{ otp_code }}</span> <span class="text-xl font-mono font-bold text-slate-900 dark:text-white mr-3" id="otpCode">{{ otp_code }}</span>
<button onclick="copyCode()" class="text-professional-accent hover:text-professional-primary transition-colors duration-200" title="Code kopieren"> <button onclick="copyCode()" class="text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 transition-colors" title="Code kopieren">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/>
</svg> </svg>
</button> </button>
@@ -207,29 +175,29 @@
</div> </div>
<!-- Wichtige Hinweise --> <!-- Wichtige Hinweise -->
<div class="alert-professional alert-warning" style="border-radius: 1.5rem; padding: 2rem; margin-bottom: 2rem;"> <div class="bg-orange-50 dark:bg-orange-900/30 border border-orange-200 dark:border-orange-800 rounded-lg p-4 mb-6">
<div class="flex-shrink-0"> <div class="flex items-start gap-3">
<div class="w-12 h-12 bg-gradient-to-br from-amber-500 to-orange-600 rounded-2xl flex items-center justify-center"> <div class="w-8 h-8 bg-orange-100 dark:bg-orange-900/50 rounded-lg flex items-center justify-center flex-shrink-0">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-5 h-5 text-orange-600 dark:text-orange-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.732-.833-2.5 0L3.734 16.5c-.77.833.192 2.5 1.732 2.5z"/> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.732-.833-2.5 0L3.734 16.5c-.77.833.192 2.5 1.732 2.5z"/>
</svg> </svg>
</div> </div>
</div> <div class="flex-1">
<div class="flex-1 ml-6"> <h5 class="text-sm font-semibold text-orange-800 dark:text-orange-300 mb-2">Wichtige Hinweise:</h5>
<h5 class="text-xl font-bold text-professional-primary mb-4">Wichtige Hinweise:</h5> <ul class="text-sm text-orange-700 dark:text-orange-400 space-y-1">
<ul class="text-base text-professional-secondary space-y-2">
<li>• Dieser Code ist nur <strong>einmalig verwendbar</strong></li> <li>• Dieser Code ist nur <strong>einmalig verwendbar</strong></li>
<li>• Notieren Sie sich den Code oder speichern Sie diese Seite</li> <li>• Notieren Sie sich den Code oder speichern Sie diese Seite</li>
<li>• Bei Verlust des Codes kontaktieren Sie den Administrator</li> <li>• Bei Verlust des Codes kontaktieren Sie den Administrator</li>
</ul> </ul>
</div> </div>
</div> </div>
</div>
<!-- Start-Button --> <!-- Start-Button -->
<div class="text-center"> <div class="text-center">
<a href="{{ url_for('guest.guest_start_job_form') }}" <a href="{{ url_for('guest.guest_start_job_form') }}"
class="btn-success-professional group px-10 py-5 text-lg"> class="btn-primary flex items-center gap-2 mx-auto">
<svg class="w-6 h-6 mr-4 group-hover:scale-110 transition-transform duration-300" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.828 14.828a4 4 0 01-5.656 0M9 10h1m4 0h1m-6 4h.01M12 5v.01M12 19v.01M12 12h.01M12 9a3 3 0 100-6 3 3 0 000 6zm0 0a3 3 0 100 6 3 3 0 000-6z"/> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.828 14.828a4 4 0 01-5.656 0M9 10h1m4 0h1m-6 4h.01M12 5v.01M12 19v.01M12 12h.01M12 9a3 3 0 100-6 3 3 0 000 6zm0 0a3 3 0 100 6 3 3 0 000-6z"/>
</svg> </svg>
Job jetzt starten Job jetzt starten
@@ -238,75 +206,45 @@
</div> </div>
{% elif show_start_link %} {% elif show_start_link %}
<!-- Code bereits vorhanden, aber noch nicht verwendet --> <!-- Code bereits vorhanden, aber noch nicht verwendet -->
<div class="professional-container" style="padding: 2.5rem; border-radius: 2rem;"> <div class="dashboard-card p-6 text-center">
<div class="text-center"> <div class="w-16 h-16 bg-blue-100 dark:bg-blue-900/30 rounded-xl flex items-center justify-center mx-auto mb-4">
<div class="w-20 h-20 bg-gradient-to-r from-blue-500 to-indigo-500 rounded-full flex items-center justify-center mx-auto mb-6"> <svg class="w-8 h-8 text-blue-600 dark:text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<svg class="w-10 h-10 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-3a1 1 0 011-1h2.586l6.243-6.243A6 6 0 0121 9z"/> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-3a1 1 0 011-1h2.586l6.243-6.243A6 6 0 0121 9z"/>
</svg> </svg>
</div> </div>
<h4 class="text-2xl font-bold text-professional-primary mb-4">Zugangscode bereits generiert</h4> <h4 class="text-lg font-semibold text-slate-900 dark:text-white mb-2">Zugangscode bereits generiert</h4>
<p class="text-lg text-professional-secondary mb-8">Ihr persönlicher Code wurde bereits erstellt und ist bereit zur Verwendung.</p> <p class="text-slate-500 dark:text-slate-400 mb-6">Ihr persönlicher Code wurde bereits erstellt und ist bereit zur Verwendung.</p>
<a href="{{ url_for('guest.guest_start_job_form') }}" <a href="{{ url_for('guest.guest_start_job_form') }}"
class="btn-professional group px-10 py-5 text-lg"> class="btn-primary flex items-center gap-2 mx-auto">
<svg class="w-6 h-6 mr-4 group-hover:scale-110 transition-transform duration-300" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-3a1 1 0 011-1h2.586l6.243-6.243A6 6 0 0121 9z"/> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-3a1 1 0 011-1h2.586l6.243-6.243A6 6 0 0121 9z"/>
</svg> </svg>
Code eingeben und starten Code eingeben und starten
</a> </a>
</div> </div>
</div>
{% endif %} {% endif %}
{% elif request.status == 'denied' %} {% elif request.status == 'denied' %}
<div class="alert-professional alert-danger" style="border-radius: 2rem; padding: 2.5rem;"> <div class="dashboard-card p-6 border-l-4 border-red-400">
<div class="flex-shrink-0"> <div class="flex items-start gap-4">
<div class="w-16 h-16 bg-gradient-to-br from-red-500 to-red-600 rounded-3xl flex items-center justify-center"> <div class="w-12 h-12 bg-red-100 dark:bg-red-900/30 rounded-xl flex items-center justify-center flex-shrink-0">
<svg class="h-8 w-8 text-white" fill="currentColor" viewBox="0 0 20 20"> <svg class="w-6 h-6 text-red-600 dark:text-red-400" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"></path> <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/>
</svg> </svg>
</div> </div>
</div> <div class="flex-1">
<div class="flex-1 ml-8"> <h3 class="text-lg font-semibold text-slate-900 dark:text-white mb-2">Anfrage abgelehnt</h3>
<h3 class="text-2xl font-bold text-professional-primary mb-4">Anfrage abgelehnt</h3> <p class="text-slate-600 dark:text-slate-400">
<p class="text-lg text-professional-secondary leading-relaxed">
Ihre Anfrage wurde leider abgelehnt. Bei Fragen wenden Sie sich bitte an unser Team. Ihre Anfrage wurde leider abgelehnt. Bei Fragen wenden Sie sich bitte an unser Team.
</p> </p>
</div> </div>
</div> </div>
</div>
{% endif %} {% endif %}
</div>
<!-- Aktionen -->
<div class="flex items-center justify-center space-x-6">
<a href="{{ url_for('guest.guest_request_form') }}"
class="btn-professional group px-8 py-4">
<svg class="w-6 h-6 mr-3 group-hover:scale-110 transition-transform duration-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"/>
</svg>
Neue Anfrage stellen
</a>
<button onclick="location.reload()"
class="btn-professional group px-8 py-4">
<svg class="w-6 h-6 mr-3 group-hover:rotate-180 transition-transform duration-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
</svg>
Aktualisieren
</button>
</div>
</div>
</div> </div>
<script> <script>
// Live Time Update
function updateLiveTime() {
const now = new Date();
document.getElementById('live-time').textContent = now.toLocaleTimeString('de-DE');
}
updateLiveTime();
setInterval(updateLiveTime, 1000);
// Code-Kopier-Funktion // Code-Kopier-Funktion
function copyCode() { function copyCode() {
const codeElement = document.getElementById('otpCode'); const codeElement = document.getElementById('otpCode');
@@ -355,7 +293,7 @@ function showCopySuccess() {
const originalHTML = button.innerHTML; const originalHTML = button.innerHTML;
button.innerHTML = ` button.innerHTML = `
<svg class="w-6 h-6 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-5 h-5 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
</svg> </svg>
`; `;