596 lines
29 KiB
HTML
596 lines
29 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="de" class="h-full">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
|
<meta name="description" content="MYP Platform - Mercedes-Benz 3D Druck Management System">
|
|
<meta name="robots" content="noindex, nofollow">
|
|
<meta name="theme-color" content="#000000" id="theme-color">
|
|
<meta name="csrf-token" content="{{ csrf_token() }}">
|
|
|
|
<title>{% block title %}MYP Platform - Mercedes-Benz{% endblock %}</title>
|
|
|
|
<!-- PWA Manifest -->
|
|
<link rel="manifest" href="{{ url_for('static', filename='manifest.json') }}">
|
|
|
|
<!-- Favicon -->
|
|
<link rel="icon" type="image/svg+xml" href="{{ url_for('static', filename='favicon.svg') }}">
|
|
|
|
<!-- CSS Bundle -->
|
|
<link href="{{ url_for('static', filename='css/tailwind.min.css') }}" rel="stylesheet">
|
|
<link href="{{ url_for('static', filename='fontawesome/css/all.min.css') }}" rel="stylesheet">
|
|
|
|
<!-- Modern Styles with Glassmorphism -->
|
|
<style>
|
|
/* Root Variables */
|
|
:root {
|
|
--glass-bg: rgba(255, 255, 255, 0.7);
|
|
--glass-border: rgba(255, 255, 255, 0.2);
|
|
--shadow-color: rgba(0, 0, 0, 0.1);
|
|
--text-primary: #1e293b;
|
|
--text-secondary: #64748b;
|
|
}
|
|
|
|
.dark {
|
|
--glass-bg: rgba(30, 41, 59, 0.7);
|
|
--glass-border: rgba(255, 255, 255, 0.1);
|
|
--shadow-color: rgba(0, 0, 0, 0.3);
|
|
--text-primary: #f1f5f9;
|
|
--text-secondary: #94a3b8;
|
|
}
|
|
|
|
/* Glassmorphism Base */
|
|
.glass {
|
|
background: var(--glass-bg);
|
|
backdrop-filter: blur(12px);
|
|
-webkit-backdrop-filter: blur(12px);
|
|
border: 1px solid var(--glass-border);
|
|
box-shadow: 0 8px 32px var(--shadow-color);
|
|
}
|
|
|
|
/* Optimized for Raspberry Pi */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.glass {
|
|
backdrop-filter: blur(8px);
|
|
-webkit-backdrop-filter: blur(8px);
|
|
}
|
|
}
|
|
|
|
/* Sticky Navigation */
|
|
.navbar-sticky {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
z-index: 50;
|
|
}
|
|
|
|
/* Main content offset for sticky navbar */
|
|
.main-offset {
|
|
padding-top: 4rem;
|
|
}
|
|
|
|
/* Smooth transitions */
|
|
* {
|
|
transition-property: background-color, border-color, color, fill, stroke;
|
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
transition-duration: 150ms;
|
|
}
|
|
|
|
/* Custom scrollbar */
|
|
::-webkit-scrollbar {
|
|
width: 8px;
|
|
height: 8px;
|
|
}
|
|
|
|
::-webkit-scrollbar-track {
|
|
background: transparent;
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb {
|
|
background: rgba(0, 0, 0, 0.2);
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.dark ::-webkit-scrollbar-thumb {
|
|
background: rgba(255, 255, 255, 0.2);
|
|
}
|
|
|
|
/* Mobile menu animations */
|
|
.mobile-menu {
|
|
transform: translateX(-100%);
|
|
transition: transform 0.3s ease-in-out;
|
|
}
|
|
|
|
.mobile-menu.active {
|
|
transform: translateX(0);
|
|
}
|
|
|
|
/* Active nav item */
|
|
.nav-active {
|
|
background: rgba(59, 130, 246, 0.1);
|
|
border-left: 3px solid #3b82f6;
|
|
}
|
|
|
|
.dark .nav-active {
|
|
background: rgba(59, 130, 246, 0.2);
|
|
}
|
|
|
|
/* Hover effects */
|
|
.hover-lift {
|
|
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
|
}
|
|
|
|
.hover-lift:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 12px 40px var(--shadow-color);
|
|
}
|
|
|
|
/* Loading animation */
|
|
@keyframes pulse {
|
|
0%, 100% { opacity: 1; }
|
|
50% { opacity: 0.5; }
|
|
}
|
|
|
|
.animate-pulse {
|
|
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
|
}
|
|
</style>
|
|
|
|
<!-- Dark Mode Script (Instant) -->
|
|
<script>
|
|
(function(){
|
|
const savedMode = localStorage.getItem('myp-dark-mode');
|
|
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
const isDark = savedMode === 'true' || (savedMode === null && prefersDark);
|
|
|
|
if (isDark) {
|
|
document.documentElement.classList.add('dark');
|
|
document.getElementById('theme-color')?.setAttribute('content', '#1e293b');
|
|
} else {
|
|
document.documentElement.classList.remove('dark');
|
|
document.getElementById('theme-color')?.setAttribute('content', '#ffffff');
|
|
}
|
|
})();
|
|
</script>
|
|
|
|
{% block head %}{% endblock %}
|
|
</head>
|
|
|
|
<body class="h-full bg-gradient-to-br from-slate-50 to-slate-100 dark:from-slate-900 dark:to-slate-800 text-slate-900 dark:text-slate-100">
|
|
<!-- Fixed Navbar with Glassmorphism -->
|
|
<nav class="navbar-sticky glass">
|
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
<div class="flex items-center justify-between h-16">
|
|
<!-- Logo & Brand -->
|
|
<div class="flex items-center">
|
|
<!-- Mobile Menu Button -->
|
|
<button id="mobile-menu-btn" class="lg:hidden p-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10">
|
|
<i class="fas fa-bars text-lg"></i>
|
|
</button>
|
|
|
|
<!-- Logo -->
|
|
<a href="{{ url_for('dashboard') if current_user.is_authenticated else url_for('index') }}"
|
|
class="flex items-center space-x-3 ml-2 lg:ml-0 hover-lift">
|
|
<div class="w-10 h-10 bg-white dark:bg-slate-800 rounded-xl shadow-lg p-2">
|
|
<svg class="w-full h-full text-slate-900 dark:text-white" fill="currentColor" viewBox="0 0 80 80">
|
|
<path d="M58.6,4.5C53,1.6,46.7,0,40,0c-6.7,0-13,1.6-18.6,4.5v0C8.7,11.2,0,24.6,0,40c0,15.4,8.7,28.8,21.5,35.5C27,78.3,33.3,80,40,80c6.7,0,12.9-1.7,18.5-4.6C71.3,68.8,80,55.4,80,40C80,24.6,71.3,11.2,58.6,4.5z M4,40c0-13.1,7-24.5,17.5-30.9v0C26.6,6,32.5,4.2,39,4l-4.5,32.7L21.5,46.8v0L8.3,57.1C5.6,52,4,46.2,4,40z M58.6,70.8C53.1,74.1,46.8,76,40,76c-6.8,0-13.2-1.9-18.6-5.2c-4.9-2.9-8.9-6.9-11.9-11.7l11.9-4.9v0L40,46.6l18.6,7.5v0l12,4.9C67.6,63.9,63.4,67.9,58.6,70.8z M58.6,46.8L58.6,46.8l-12.9-10L41.1,4c6.3,0.2,12.3,2,17.4,5.1v0C69,15.4,76,26.9,76,40c0,6.2-1.5,12-4.3,17.1L58.6,46.8z"/>
|
|
</svg>
|
|
</div>
|
|
<div class="hidden sm:block">
|
|
<div class="text-lg font-bold">MYP Platform</div>
|
|
<div class="text-xs text-slate-600 dark:text-slate-400">Mercedes-Benz</div>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
|
|
<!-- Desktop Navigation -->
|
|
{% if current_user.is_authenticated %}
|
|
<div class="hidden lg:flex items-center space-x-1 flex-1 justify-center mx-8">
|
|
{% set current_route = request.endpoint or '' %}
|
|
|
|
<a href="{{ url_for('dashboard') }}"
|
|
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'dashboard' else '' }}">
|
|
<i class="fas fa-tachometer-alt mr-2"></i>
|
|
<span>Dashboard</span>
|
|
</a>
|
|
|
|
<a href="{{ url_for('printers_page') }}"
|
|
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'printers_page' else '' }}">
|
|
<i class="fas fa-print mr-2"></i>
|
|
<span>Drucker</span>
|
|
</a>
|
|
|
|
<a href="{{ url_for('jobs_page') }}"
|
|
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'jobs_page' else '' }}">
|
|
<i class="fas fa-tasks mr-2"></i>
|
|
<span>Aufträge</span>
|
|
</a>
|
|
|
|
<a href="{{ url_for('calendar.calendar_view') }}"
|
|
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'calendar.calendar_view' else '' }}">
|
|
<i class="fas fa-calendar mr-2"></i>
|
|
<span>Kalender</span>
|
|
</a>
|
|
|
|
<a href="{{ url_for('energy.energy_dashboard') }}"
|
|
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'energy.energy_dashboard' else '' }}">
|
|
<i class="fas fa-bolt mr-2"></i>
|
|
<span>Energie</span>
|
|
</a>
|
|
|
|
<a href="{{ url_for('stats_page') }}"
|
|
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'stats_page' else '' }}">
|
|
<i class="fas fa-chart-bar mr-2"></i>
|
|
<span>Statistiken</span>
|
|
</a>
|
|
|
|
<a href="{{ url_for('tapo.tapo_dashboard') }}"
|
|
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route and 'tapo' in current_route else '' }}">
|
|
<i class="fas fa-plug mr-2"></i>
|
|
<span>Smart Plugs</span>
|
|
</a>
|
|
|
|
<a href="{{ url_for('guest.guest_request_form') }}"
|
|
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route and 'guest' in current_route else '' }}">
|
|
<i class="fas fa-user-plus mr-2"></i>
|
|
<span>Gast</span>
|
|
</a>
|
|
|
|
{% if current_user.is_admin %}
|
|
<a href="{{ url_for('admin.admin_dashboard') }}"
|
|
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route and 'admin' in current_route else '' }}">
|
|
<i class="fas fa-cog mr-2"></i>
|
|
<span>Admin</span>
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Right side actions -->
|
|
<div class="flex items-center space-x-2">
|
|
{% if current_user.is_authenticated %}
|
|
<!-- Notifications -->
|
|
<button class="p-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10 relative">
|
|
<i class="fas fa-bell"></i>
|
|
<span class="absolute top-1 right-1 w-2 h-2 bg-red-500 rounded-full hidden"></span>
|
|
</button>
|
|
{% endif %}
|
|
|
|
<!-- Dark Mode Toggle -->
|
|
<button id="darkModeToggle"
|
|
class="p-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10">
|
|
<i class="fas fa-sun sun-icon"></i>
|
|
<i class="fas fa-moon moon-icon hidden"></i>
|
|
</button>
|
|
|
|
<!-- User Menu -->
|
|
{% if current_user.is_authenticated %}
|
|
<div class="relative">
|
|
<button id="user-menu-btn"
|
|
class="flex items-center space-x-2 p-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10">
|
|
<div class="w-8 h-8 bg-gradient-to-br from-blue-500 to-purple-600 rounded-full flex items-center justify-center text-white text-sm font-bold">
|
|
{{ current_user.email[0].upper() if current_user.email else 'U' }}
|
|
</div>
|
|
<i class="fas fa-chevron-down text-xs"></i>
|
|
</button>
|
|
|
|
<!-- Dropdown -->
|
|
<div id="user-dropdown"
|
|
class="hidden absolute right-0 mt-2 w-64 glass rounded-xl overflow-hidden">
|
|
<div class="p-4 border-b border-white/10">
|
|
<p class="font-semibold">{{ current_user.email }}</p>
|
|
<p class="text-sm text-slate-600 dark:text-slate-400">{{ 'Administrator' if current_user.is_admin else 'Benutzer' }}</p>
|
|
</div>
|
|
<div class="p-2">
|
|
<a href="{{ url_for('users.user_profile') }}"
|
|
class="flex items-center px-3 py-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10">
|
|
<i class="fas fa-user w-4 mr-3"></i>
|
|
Mein Profil
|
|
</a>
|
|
<a href="{{ url_for('users.user_settings') }}"
|
|
class="flex items-center px-3 py-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10">
|
|
<i class="fas fa-cog w-4 mr-3"></i>
|
|
Einstellungen
|
|
</a>
|
|
<a href="{{ url_for('guest.guest_requests_overview') }}"
|
|
class="flex items-center px-3 py-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10">
|
|
<i class="fas fa-clipboard-list w-4 mr-3"></i>
|
|
Meine Anfragen
|
|
</a>
|
|
<div class="border-t border-white/10 my-2"></div>
|
|
<a href="{{ url_for('legal.system_info') }}"
|
|
class="flex items-center px-3 py-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10">
|
|
<i class="fas fa-info-circle w-4 mr-3"></i>
|
|
System-Info
|
|
</a>
|
|
<div class="border-t border-white/10 my-2"></div>
|
|
<button onclick="handleLogout()"
|
|
class="w-full flex items-center px-3 py-2 rounded-lg hover:bg-red-500/20 text-red-600 dark:text-red-400">
|
|
<i class="fas fa-sign-out-alt w-4 mr-3"></i>
|
|
Abmelden
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<a href="{{ url_for('auth.login') }}"
|
|
class="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg font-medium">
|
|
Anmelden
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<!-- Mobile Menu Overlay -->
|
|
<div id="mobile-menu-overlay" class="lg:hidden fixed inset-0 bg-black/50 z-40 hidden"></div>
|
|
|
|
<!-- Mobile Menu -->
|
|
<nav id="mobile-menu" class="lg:hidden fixed top-0 left-0 bottom-0 w-72 glass z-50 mobile-menu">
|
|
<div class="p-4">
|
|
<div class="flex items-center justify-between mb-6">
|
|
<h2 class="text-lg font-bold">Navigation</h2>
|
|
<button id="mobile-menu-close" class="p-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10">
|
|
<i class="fas fa-times"></i>
|
|
</button>
|
|
</div>
|
|
|
|
{% if current_user.is_authenticated %}
|
|
<div class="space-y-1">
|
|
{% set current_route = request.endpoint or '' %}
|
|
|
|
<a href="{{ url_for('dashboard') }}"
|
|
class="flex items-center px-3 py-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'dashboard' else '' }}">
|
|
<i class="fas fa-tachometer-alt w-5 mr-3"></i>
|
|
Dashboard
|
|
</a>
|
|
|
|
<a href="{{ url_for('printers_page') }}"
|
|
class="flex items-center px-3 py-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'printers_page' else '' }}">
|
|
<i class="fas fa-print w-5 mr-3"></i>
|
|
Drucker
|
|
</a>
|
|
|
|
<a href="{{ url_for('jobs_page') }}"
|
|
class="flex items-center px-3 py-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'jobs_page' else '' }}">
|
|
<i class="fas fa-tasks w-5 mr-3"></i>
|
|
Aufträge
|
|
</a>
|
|
|
|
<a href="{{ url_for('calendar.calendar_view') }}"
|
|
class="flex items-center px-3 py-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'calendar.calendar_view' else '' }}">
|
|
<i class="fas fa-calendar w-5 mr-3"></i>
|
|
Kalender
|
|
</a>
|
|
|
|
<a href="{{ url_for('energy.energy_dashboard') }}"
|
|
class="flex items-center px-3 py-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'energy.energy_dashboard' else '' }}">
|
|
<i class="fas fa-bolt w-5 mr-3"></i>
|
|
Energie
|
|
</a>
|
|
|
|
<a href="{{ url_for('stats_page') }}"
|
|
class="flex items-center px-3 py-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'stats_page' else '' }}">
|
|
<i class="fas fa-chart-bar w-5 mr-3"></i>
|
|
Statistiken
|
|
</a>
|
|
|
|
<a href="{{ url_for('tapo.tapo_dashboard') }}"
|
|
class="flex items-center px-3 py-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route and 'tapo' in current_route else '' }}">
|
|
<i class="fas fa-plug w-5 mr-3"></i>
|
|
Smart Plugs
|
|
</a>
|
|
|
|
<a href="{{ url_for('guest.guest_request_form') }}"
|
|
class="flex items-center px-3 py-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route and 'guest' in current_route else '' }}">
|
|
<i class="fas fa-user-plus w-5 mr-3"></i>
|
|
Gast-Anfrage
|
|
</a>
|
|
|
|
{% if current_user.is_admin %}
|
|
<a href="{{ url_for('admin.admin_dashboard') }}"
|
|
class="flex items-center px-3 py-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route and 'admin' in current_route else '' }}">
|
|
<i class="fas fa-cog w-5 mr-3"></i>
|
|
Admin
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</nav>
|
|
|
|
<!-- Flash Messages -->
|
|
{% with messages = get_flashed_messages(with_categories=true) %}
|
|
{% if messages %}
|
|
<div class="fixed top-20 right-4 z-50 space-y-2">
|
|
{% for category, message in messages %}
|
|
<div class="glass rounded-lg p-4 max-w-sm animate-pulse" id="flash-{{ loop.index }}">
|
|
<div class="flex items-start">
|
|
<i class="fas {{ 'fa-check-circle text-green-500' if category == 'success' else 'fa-exclamation-circle text-red-500' if category == 'error' else 'fa-info-circle text-blue-500' }} mt-0.5 mr-3"></i>
|
|
<div class="flex-1">
|
|
<p class="text-sm font-medium">{{ message }}</p>
|
|
</div>
|
|
<button onclick="this.parentElement.parentElement.remove()" class="ml-3 hover:opacity-70">
|
|
<i class="fas fa-times text-sm"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
setTimeout(() => {
|
|
document.getElementById('flash-{{ loop.index }}')?.remove();
|
|
}, 5000);
|
|
</script>
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
{% endwith %}
|
|
|
|
<!-- Main Content -->
|
|
<main class="main-offset min-h-screen">
|
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
{% block content %}{% endblock %}
|
|
</div>
|
|
</main>
|
|
|
|
<!-- Footer -->
|
|
<footer class="glass border-t border-white/10">
|
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-8">
|
|
<!-- Brand -->
|
|
<div>
|
|
<div class="flex items-center space-x-3 mb-4">
|
|
<div class="w-8 h-8">
|
|
<svg class="w-full h-full text-slate-900 dark:text-white" fill="currentColor" viewBox="0 0 80 80">
|
|
<path d="M58.6,4.5C53,1.6,46.7,0,40,0c-6.7,0-13,1.6-18.6,4.5v0C8.7,11.2,0,24.6,0,40c0,15.4,8.7,28.8,21.5,35.5C27,78.3,33.3,80,40,80c6.7,0,12.9-1.7,18.5-4.6C71.3,68.8,80,55.4,80,40C80,24.6,71.3,11.2,58.6,4.5z M4,40c0-13.1,7-24.5,17.5-30.9v0C26.6,6,32.5,4.2,39,4l-4.5,32.7L21.5,46.8v0L8.3,57.1C5.6,52,4,46.2,4,40z M58.6,70.8C53.1,74.1,46.8,76,40,76c-6.8,0-13.2-1.9-18.6-5.2c-4.9-2.9-8.9-6.9-11.9-11.7l11.9-4.9v0L40,46.6l18.6,7.5v0l12,4.9C67.6,63.9,63.4,67.9,58.6,70.8z M58.6,46.8L58.6,46.8l-12.9-10L41.1,4c6.3,0.2,12.3,2,17.4,5.1v0C69,15.4,76,26.9,76,40c0,6.2-1.5,12-4.3,17.1L58.6,46.8z"/>
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<h3 class="font-bold">MYP Platform</h3>
|
|
<p class="text-xs text-slate-600 dark:text-slate-400">Mercedes-Benz</p>
|
|
</div>
|
|
</div>
|
|
<p class="text-sm text-slate-600 dark:text-slate-400">
|
|
Professionelles 3D-Druck Management
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Quick Links -->
|
|
<div>
|
|
<h4 class="font-semibold mb-4">Quick Links</h4>
|
|
<ul class="space-y-2 text-sm">
|
|
<li><a href="{{ url_for('dashboard') }}" class="hover:text-blue-500">Dashboard</a></li>
|
|
<li><a href="{{ url_for('printers_page') }}" class="hover:text-blue-500">Drucker</a></li>
|
|
<li><a href="{{ url_for('jobs_page') }}" class="hover:text-blue-500">Aufträge</a></li>
|
|
<li><a href="{{ url_for('calendar.calendar_view') }}" class="hover:text-blue-500">Kalender</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<!-- System -->
|
|
<div>
|
|
<h4 class="font-semibold mb-4">System</h4>
|
|
<ul class="space-y-2 text-sm">
|
|
<li class="flex items-center">
|
|
<span class="w-2 h-2 bg-green-500 rounded-full mr-2"></span>
|
|
<span>Online</span>
|
|
</li>
|
|
<li>Version 3.0.0</li>
|
|
<li><a href="{{ url_for('legal.system_info') }}" class="hover:text-blue-500">System-Info</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<!-- Legal -->
|
|
<div>
|
|
<h4 class="font-semibold mb-4">Rechtliches</h4>
|
|
<ul class="space-y-2 text-sm">
|
|
<li><a href="{{ url_for('legal.imprint') }}" class="hover:text-blue-500">Impressum</a></li>
|
|
<li><a href="{{ url_for('legal.privacy') }}" class="hover:text-blue-500">Datenschutz</a></li>
|
|
<li><a href="{{ url_for('legal.terms') }}" class="hover:text-blue-500">Nutzungsbedingungen</a></li>
|
|
</ul>
|
|
<p class="text-xs text-slate-600 dark:text-slate-400 mt-4">
|
|
© 2024 Mercedes-Benz Group AG
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
|
|
<!-- JavaScript -->
|
|
<script>
|
|
// Dark Mode Toggle
|
|
const darkModeToggle = document.getElementById('darkModeToggle');
|
|
const sunIcon = document.querySelector('.sun-icon');
|
|
const moonIcon = document.querySelector('.moon-icon');
|
|
|
|
function updateDarkMode() {
|
|
const isDark = document.documentElement.classList.contains('dark');
|
|
sunIcon.classList.toggle('hidden', isDark);
|
|
moonIcon.classList.toggle('hidden', !isDark);
|
|
document.getElementById('theme-color').setAttribute('content', isDark ? '#1e293b' : '#ffffff');
|
|
}
|
|
|
|
darkModeToggle?.addEventListener('click', () => {
|
|
document.documentElement.classList.toggle('dark');
|
|
const isDark = document.documentElement.classList.contains('dark');
|
|
localStorage.setItem('myp-dark-mode', isDark);
|
|
updateDarkMode();
|
|
});
|
|
|
|
updateDarkMode();
|
|
|
|
// Mobile Menu
|
|
const mobileMenuBtn = document.getElementById('mobile-menu-btn');
|
|
const mobileMenuClose = document.getElementById('mobile-menu-close');
|
|
const mobileMenu = document.getElementById('mobile-menu');
|
|
const mobileMenuOverlay = document.getElementById('mobile-menu-overlay');
|
|
|
|
function openMobileMenu() {
|
|
mobileMenu.classList.add('active');
|
|
mobileMenuOverlay.classList.remove('hidden');
|
|
document.body.style.overflow = 'hidden';
|
|
}
|
|
|
|
function closeMobileMenu() {
|
|
mobileMenu.classList.remove('active');
|
|
mobileMenuOverlay.classList.add('hidden');
|
|
document.body.style.overflow = '';
|
|
}
|
|
|
|
mobileMenuBtn?.addEventListener('click', openMobileMenu);
|
|
mobileMenuClose?.addEventListener('click', closeMobileMenu);
|
|
mobileMenuOverlay?.addEventListener('click', closeMobileMenu);
|
|
|
|
// User Dropdown
|
|
const userMenuBtn = document.getElementById('user-menu-btn');
|
|
const userDropdown = document.getElementById('user-dropdown');
|
|
|
|
userMenuBtn?.addEventListener('click', (e) => {
|
|
e.stopPropagation();
|
|
userDropdown.classList.toggle('hidden');
|
|
});
|
|
|
|
document.addEventListener('click', () => {
|
|
userDropdown?.classList.add('hidden');
|
|
});
|
|
|
|
userDropdown?.addEventListener('click', (e) => {
|
|
e.stopPropagation();
|
|
});
|
|
|
|
// Logout Handler
|
|
function handleLogout() {
|
|
if (confirm('Möchten Sie sich wirklich abmelden?')) {
|
|
const form = document.createElement('form');
|
|
form.method = 'POST';
|
|
form.action = '{{ url_for("auth.logout") }}';
|
|
|
|
const csrfToken = document.querySelector('meta[name="csrf-token"]');
|
|
if (csrfToken) {
|
|
const input = document.createElement('input');
|
|
input.type = 'hidden';
|
|
input.name = 'csrf_token';
|
|
input.value = csrfToken.getAttribute('content');
|
|
form.appendChild(input);
|
|
}
|
|
|
|
document.body.appendChild(form);
|
|
form.submit();
|
|
}
|
|
}
|
|
|
|
// Smooth scroll for anchor links
|
|
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
|
anchor.addEventListener('click', function (e) {
|
|
e.preventDefault();
|
|
const target = document.querySelector(this.getAttribute('href'));
|
|
if (target) {
|
|
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
|
|
{% block scripts %}{% endblock %}
|
|
</body>
|
|
</html> |