"Refactor database files, update CSS, improve templates"
This commit is contained in:
parent
1d4acb4840
commit
f3cce9c400
Binary file not shown.
Binary file not shown.
@ -281,6 +281,14 @@ class User(UserMixin, Base):
|
||||
active = Column(Boolean, default=True) # Für Flask-Login is_active
|
||||
created_at = Column(DateTime, default=datetime.now)
|
||||
last_login = Column(DateTime, nullable=True) # Letzter Login-Zeitstempel
|
||||
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now) # Automatische Aktualisierung
|
||||
settings = Column(Text, nullable=True) # JSON-String für Benutzereinstellungen
|
||||
|
||||
# Zusätzliche Profil-Felder für bessere Benutzerverwaltung
|
||||
department = Column(String(100), nullable=True) # Abteilung
|
||||
position = Column(String(100), nullable=True) # Position/Rolle im Unternehmen
|
||||
phone = Column(String(50), nullable=True) # Telefonnummer
|
||||
bio = Column(Text, nullable=True) # Kurze Beschreibung/Bio
|
||||
|
||||
jobs = relationship("Job", back_populates="user", foreign_keys="Job.user_id", cascade="all, delete-orphan")
|
||||
owned_jobs = relationship("Job", foreign_keys="Job.owner_id", overlaps="owner")
|
||||
@ -328,6 +336,12 @@ class User(UserMixin, Base):
|
||||
"role": self.role,
|
||||
"active": self.active,
|
||||
"created_at": self.created_at.isoformat() if self.created_at else None,
|
||||
"last_login": self.last_login.isoformat() if self.last_login else None,
|
||||
"updated_at": self.updated_at.isoformat() if self.updated_at else None,
|
||||
"settings": self.settings,
|
||||
"department": self.department,
|
||||
"position": self.position,
|
||||
"phone": self.phone,
|
||||
"last_login": self.last_login.isoformat() if self.last_login else None
|
||||
}
|
||||
|
||||
|
@ -1,465 +0,0 @@
|
||||
/* Mercedes-Benz Design System */
|
||||
/* Einheitliches Design für alle Seiten mit Glassmorphism und Mercedes-Farben */
|
||||
|
||||
:root {
|
||||
/* Mercedes Primärfarben */
|
||||
--mb-black: #000000;
|
||||
--mb-silver: #C0C0C0;
|
||||
--mb-platinum: #E5E4E2;
|
||||
--mb-charcoal: #36454F;
|
||||
--mb-steel: #71797E;
|
||||
|
||||
/* Light Mode Farben */
|
||||
--bg-primary-light: #ffffff;
|
||||
--bg-secondary-light: #f8fafc;
|
||||
--bg-tertiary-light: #f1f5f9;
|
||||
--text-primary-light: #0f172a;
|
||||
--text-secondary-light: #334155;
|
||||
--text-muted-light: #64748b;
|
||||
--border-light: #e2e8f0;
|
||||
|
||||
/* Dark Mode Farben - Mercedes Tiefschwarz */
|
||||
--bg-primary-dark: #000000;
|
||||
--bg-secondary-dark: #0a0a0a;
|
||||
--bg-tertiary-dark: #141414;
|
||||
--text-primary-dark: #ffffff;
|
||||
--text-secondary-dark: #e2e8f0;
|
||||
--text-muted-dark: #94a3b8;
|
||||
--border-dark: #1e1e1e;
|
||||
|
||||
/* Glassmorphism */
|
||||
--glass-bg-light: rgba(255, 255, 255, 0.8);
|
||||
--glass-bg-dark: rgba(0, 0, 0, 0.8);
|
||||
--glass-border-light: rgba(255, 255, 255, 0.2);
|
||||
--glass-border-dark: rgba(255, 255, 255, 0.1);
|
||||
|
||||
/* Spacing System */
|
||||
--space-xs: 0.5rem;
|
||||
--space-sm: 1rem;
|
||||
--space-md: 1.5rem;
|
||||
--space-lg: 2rem;
|
||||
--space-xl: 3rem;
|
||||
--space-2xl: 4rem;
|
||||
--space-3xl: 6rem;
|
||||
|
||||
/* Radius System */
|
||||
--radius-sm: 0.5rem;
|
||||
--radius-md: 1rem;
|
||||
--radius-lg: 1.5rem;
|
||||
--radius-xl: 2rem;
|
||||
|
||||
/* Shadow System */
|
||||
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
||||
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
||||
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
||||
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
|
||||
--shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / 0.25);
|
||||
--shadow-glass: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
|
||||
}
|
||||
|
||||
/* Base Styles */
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
transition: background-color 0.3s ease, color 0.3s ease;
|
||||
}
|
||||
|
||||
/* Light Mode */
|
||||
:root:not(.dark) {
|
||||
color-scheme: light;
|
||||
}
|
||||
|
||||
body:not(.dark) {
|
||||
background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
|
||||
color: var(--text-primary-light);
|
||||
}
|
||||
|
||||
/* Dark Mode - Mercedes Tiefschwarz */
|
||||
.dark {
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
.dark body {
|
||||
background: linear-gradient(135deg, var(--bg-primary-dark) 0%, var(--bg-secondary-dark) 100%);
|
||||
color: var(--text-primary-dark);
|
||||
}
|
||||
|
||||
/* Container System */
|
||||
.mercedes-container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 var(--space-md);
|
||||
}
|
||||
|
||||
.mercedes-container-wide {
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
padding: 0 var(--space-md);
|
||||
}
|
||||
|
||||
.mercedes-container-narrow {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 0 var(--space-md);
|
||||
}
|
||||
|
||||
/* Glassmorphism Cards */
|
||||
.glass-card {
|
||||
background: var(--glass-bg-light);
|
||||
border: 1px solid var(--glass-border-light);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
border-radius: var(--radius-lg);
|
||||
box-shadow: var(--shadow-glass);
|
||||
padding: var(--space-lg);
|
||||
margin: var(--space-md) 0;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.dark .glass-card {
|
||||
background: var(--glass-bg-dark);
|
||||
border: 1px solid var(--glass-border-dark);
|
||||
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
|
||||
.glass-card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: var(--shadow-2xl);
|
||||
}
|
||||
|
||||
.dark .glass-card:hover {
|
||||
box-shadow: 0 32px 64px 0 rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
/* Premium Card Variants */
|
||||
.glass-card-hero {
|
||||
background: var(--glass-bg-light);
|
||||
border: 1px solid var(--glass-border-light);
|
||||
backdrop-filter: blur(24px);
|
||||
-webkit-backdrop-filter: blur(24px);
|
||||
border-radius: var(--radius-xl);
|
||||
padding: var(--space-3xl);
|
||||
margin: var(--space-xl) 0;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.dark .glass-card-hero {
|
||||
background: rgba(0, 0, 0, 0.9);
|
||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.glass-card-hero::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);
|
||||
}
|
||||
|
||||
.dark .glass-card-hero::before {
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);
|
||||
}
|
||||
|
||||
/* Text Styles */
|
||||
.mercedes-title {
|
||||
font-size: 3rem;
|
||||
font-weight: 700;
|
||||
line-height: 1.1;
|
||||
margin-bottom: var(--space-md);
|
||||
background: linear-gradient(135deg, var(--text-primary-light) 0%, var(--text-secondary-light) 100%);
|
||||
background-clip: text;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.dark .mercedes-title {
|
||||
background: linear-gradient(135deg, var(--text-primary-dark) 0%, var(--text-secondary-dark) 100%);
|
||||
background-clip: text;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.mercedes-subtitle {
|
||||
font-size: 1.25rem;
|
||||
color: var(--text-secondary-light);
|
||||
margin-bottom: var(--space-lg);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.dark .mercedes-subtitle {
|
||||
color: var(--text-secondary-dark);
|
||||
}
|
||||
|
||||
.mercedes-text {
|
||||
color: var(--text-primary-light);
|
||||
line-height: 1.6;
|
||||
margin-bottom: var(--space-md);
|
||||
}
|
||||
|
||||
.dark .mercedes-text {
|
||||
color: var(--text-primary-dark);
|
||||
}
|
||||
|
||||
.mercedes-text-muted {
|
||||
color: var(--text-muted-light);
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.dark .mercedes-text-muted {
|
||||
color: var(--text-muted-dark);
|
||||
}
|
||||
|
||||
/* Button System */
|
||||
.mercedes-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: var(--space-sm) var(--space-lg);
|
||||
font-weight: 600;
|
||||
border-radius: var(--radius-md);
|
||||
transition: all 0.3s ease;
|
||||
text-decoration: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mercedes-btn-primary {
|
||||
background: linear-gradient(135deg, var(--mb-black) 0%, var(--mb-charcoal) 100%);
|
||||
color: white;
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
|
||||
.mercedes-btn-primary:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: var(--shadow-xl);
|
||||
}
|
||||
|
||||
.dark .mercedes-btn-primary {
|
||||
background: linear-gradient(135deg, #ffffff 0%, var(--mb-silver) 100%);
|
||||
color: var(--mb-black);
|
||||
}
|
||||
|
||||
.mercedes-btn-secondary {
|
||||
background: var(--glass-bg-light);
|
||||
border: 1px solid var(--glass-border-light);
|
||||
backdrop-filter: blur(10px);
|
||||
color: var(--text-primary-light);
|
||||
}
|
||||
|
||||
.dark .mercedes-btn-secondary {
|
||||
background: var(--glass-bg-dark);
|
||||
border: 1px solid var(--glass-border-dark);
|
||||
color: var(--text-primary-dark);
|
||||
}
|
||||
|
||||
.mercedes-btn-secondary:hover {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.dark .mercedes-btn-secondary:hover {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
/* Form Elements */
|
||||
.mercedes-input {
|
||||
width: 100%;
|
||||
padding: var(--space-sm) var(--space-md);
|
||||
border: 1px solid var(--border-light);
|
||||
border-radius: var(--radius-md);
|
||||
background: var(--glass-bg-light);
|
||||
backdrop-filter: blur(10px);
|
||||
color: var(--text-primary-light);
|
||||
transition: all 0.3s ease;
|
||||
margin-bottom: var(--space-sm);
|
||||
}
|
||||
|
||||
.dark .mercedes-input {
|
||||
border: 1px solid var(--border-dark);
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
color: var(--text-primary-dark);
|
||||
}
|
||||
|
||||
.mercedes-input:focus {
|
||||
outline: none;
|
||||
border-color: var(--mb-charcoal);
|
||||
box-shadow: 0 0 0 3px rgba(54, 69, 79, 0.1);
|
||||
}
|
||||
|
||||
.dark .mercedes-input:focus {
|
||||
border-color: var(--mb-silver);
|
||||
box-shadow: 0 0 0 3px rgba(192, 192, 192, 0.1);
|
||||
}
|
||||
|
||||
/* Status Indicators */
|
||||
.mercedes-status {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: var(--space-xs) var(--space-sm);
|
||||
border-radius: var(--radius-sm);
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.mercedes-status-online {
|
||||
background: rgba(16, 185, 129, 0.1);
|
||||
color: #059669;
|
||||
border: 1px solid rgba(16, 185, 129, 0.2);
|
||||
}
|
||||
|
||||
.mercedes-status-offline {
|
||||
background: rgba(239, 68, 68, 0.1);
|
||||
color: #dc2626;
|
||||
border: 1px solid rgba(239, 68, 68, 0.2);
|
||||
}
|
||||
|
||||
.mercedes-status-warning {
|
||||
background: rgba(245, 158, 11, 0.1);
|
||||
color: #d97706;
|
||||
border: 1px solid rgba(245, 158, 11, 0.2);
|
||||
}
|
||||
|
||||
/* Grid System */
|
||||
.mercedes-grid {
|
||||
display: grid;
|
||||
gap: var(--space-lg);
|
||||
margin: var(--space-lg) 0;
|
||||
}
|
||||
|
||||
.mercedes-grid-1 { grid-template-columns: 1fr; }
|
||||
.mercedes-grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
|
||||
.mercedes-grid-3 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
|
||||
.mercedes-grid-4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
|
||||
|
||||
/* Responsive Breakpoints */
|
||||
@media (max-width: 768px) {
|
||||
.mercedes-container,
|
||||
.mercedes-container-wide,
|
||||
.mercedes-container-narrow {
|
||||
padding: 0 var(--space-sm);
|
||||
}
|
||||
|
||||
.glass-card {
|
||||
padding: var(--space-md);
|
||||
}
|
||||
|
||||
.glass-card-hero {
|
||||
padding: var(--space-xl);
|
||||
}
|
||||
|
||||
.mercedes-title {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.mercedes-grid-2,
|
||||
.mercedes-grid-3,
|
||||
.mercedes-grid-4 {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
/* Page Sections */
|
||||
.mercedes-header {
|
||||
padding: var(--space-2xl) 0;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mercedes-section {
|
||||
padding: var(--space-xl) 0;
|
||||
}
|
||||
|
||||
.mercedes-footer {
|
||||
padding: var(--space-xl) 0 var(--space-lg) 0;
|
||||
border-top: 1px solid var(--border-light);
|
||||
margin-top: var(--space-3xl);
|
||||
}
|
||||
|
||||
.dark .mercedes-footer {
|
||||
border-top: 1px solid var(--border-dark);
|
||||
}
|
||||
|
||||
/* Loading States */
|
||||
.mercedes-loading {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: var(--space-md);
|
||||
}
|
||||
|
||||
.mercedes-spinner {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
border: 2px solid transparent;
|
||||
border-top: 2px solid var(--mb-charcoal);
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
.dark .mercedes-spinner {
|
||||
border-top-color: var(--mb-silver);
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
/* Animations */
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(20px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
@keyframes slideIn {
|
||||
from { opacity: 0; transform: translateX(-20px); }
|
||||
to { opacity: 1; transform: translateX(0); }
|
||||
}
|
||||
|
||||
.mercedes-fade-in {
|
||||
animation: fadeIn 0.6s ease-out;
|
||||
}
|
||||
|
||||
.mercedes-slide-in {
|
||||
animation: slideIn 0.6s ease-out;
|
||||
}
|
||||
|
||||
/* Utility Classes */
|
||||
.mercedes-text-center { text-align: center; }
|
||||
.mercedes-text-left { text-align: left; }
|
||||
.mercedes-text-right { text-align: right; }
|
||||
|
||||
.mercedes-mb-sm { margin-bottom: var(--space-sm); }
|
||||
.mercedes-mb-md { margin-bottom: var(--space-md); }
|
||||
.mercedes-mb-lg { margin-bottom: var(--space-lg); }
|
||||
.mercedes-mb-xl { margin-bottom: var(--space-xl); }
|
||||
|
||||
.mercedes-mt-sm { margin-top: var(--space-sm); }
|
||||
.mercedes-mt-md { margin-top: var(--space-md); }
|
||||
.mercedes-mt-lg { margin-top: var(--space-lg); }
|
||||
.mercedes-mt-xl { margin-top: var(--space-xl); }
|
||||
|
||||
.mercedes-p-sm { padding: var(--space-sm); }
|
||||
.mercedes-p-md { padding: var(--space-md); }
|
||||
.mercedes-p-lg { padding: var(--space-lg); }
|
||||
.mercedes-p-xl { padding: var(--space-xl); }
|
||||
|
||||
/* Hide scrollbar but allow scrolling */
|
||||
.mercedes-scrollbar-hidden::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mercedes-scrollbar-hidden {
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
}
|
2
backend/app/static/css/tailwind.min.css
vendored
2
backend/app/static/css/tailwind.min.css
vendored
File diff suppressed because one or more lines are too long
@ -24,11 +24,12 @@
|
||||
|
||||
<!-- CSS -->
|
||||
<link href="{{ url_for('static', filename='css/tailwind.min.css') }}" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='css/mercedes-design-system.css') }}" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='css/components.css') }}" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='css/professional-theme.css') }}" rel="stylesheet">
|
||||
|
||||
<!-- Preload critical resources -->
|
||||
<link rel="preload" href="{{ url_for('static', filename='js/ui-components.js') }}" as="script">
|
||||
<link rel="preload" href="{{ url_for('static', filename='js/offline-app.js') }}" as="script">
|
||||
|
||||
<!-- Additional CSS -->
|
||||
{% block extra_css %}{% endblock %}
|
||||
@ -99,17 +100,17 @@
|
||||
{% block head %}{% endblock %}
|
||||
</head>
|
||||
|
||||
<body class="min-h-screen flex flex-col transition-colors duration-300">
|
||||
<body class="min-h-screen flex flex-col bg-white text-slate-900 dark:bg-black dark:text-white transition-colors duration-300 text-base mercedes-background">
|
||||
|
||||
<!-- Navigation -->
|
||||
<nav class="glass-card !rounded-none !margin-0 sticky top-0 z-50">
|
||||
<div class="mercedes-container">
|
||||
<nav class="navbar">
|
||||
<div class="max-w-7xl mx-auto px-3 sm:px-4 lg:px-6">
|
||||
<div class="flex items-center justify-between h-16 sm:h-18 lg:h-20">
|
||||
<!-- Brand Section -->
|
||||
<div class="flex-shrink-0">
|
||||
<a href="{{ url_for('dashboard') }}" class="flex items-center space-x-3 group" aria-label="Zur Startseite">
|
||||
<a href="{{ url_for('dashboard') }}" class="navbar-brand" aria-label="Zur Startseite">
|
||||
<!-- Mercedes-Benz Logo -->
|
||||
<div class="w-10 h-10 transition-all duration-300 group-hover:rotate-12">
|
||||
<div class="w-5 h-5 sm:w-6 sm:h-6 lg:w-7 lg:h-7 transition-all duration-300 group-hover:rotate-12">
|
||||
<svg class="w-full h-full text-slate-900 dark:text-white transition-colors duration-300" fill="currentColor" viewBox="0 0 80 80" aria-hidden="true">
|
||||
<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
|
||||
@ -120,67 +121,67 @@
|
||||
</svg>
|
||||
</div>
|
||||
<!-- Brand Text -->
|
||||
<div class="flex flex-col">
|
||||
<span class="text-lg font-bold text-slate-900 dark:text-white transition-colors duration-300 tracking-tight">Mercedes-Benz</span>
|
||||
<div class="flex flex-col ml-2">
|
||||
<span class="text-base lg:text-lg font-bold text-slate-900 dark:text-white transition-colors duration-300 tracking-tight">Mercedes-Benz</span>
|
||||
<span class="text-xs font-medium text-slate-600 dark:text-slate-400 transition-colors duration-300">MYP 3D-Druck Platform</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Desktop Navigation Menu -->
|
||||
<!-- Desktop Navigation Menu - überarbeitetes Design -->
|
||||
<div class="hidden lg:flex flex-1 justify-center">
|
||||
<nav class="flex items-center space-x-2" role="navigation" aria-label="Hauptnavigation">
|
||||
<nav class="navbar-menu-new" role="navigation" aria-label="Hauptnavigation">
|
||||
<a href="{{ url_for('dashboard') }}"
|
||||
class="mercedes-btn mercedes-btn-secondary {{ 'mercedes-btn-primary' if request.endpoint == 'dashboard' else '' }}">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
class="nav-item {{ 'active' if request.endpoint == 'dashboard' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2H5a2 2 0 00-2-2z"/>
|
||||
</svg>
|
||||
<span>Dashboard</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('printers_page') }}"
|
||||
class="mercedes-btn mercedes-btn-secondary {{ 'mercedes-btn-primary' if request.endpoint == 'printers_page' else '' }}">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
class="nav-item {{ 'active' if request.endpoint == 'printers_page' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z"/>
|
||||
</svg>
|
||||
<span>3D-Drucker</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('jobs_page') }}"
|
||||
class="mercedes-btn mercedes-btn-secondary {{ 'mercedes-btn-primary' if request.endpoint == 'jobs_page' else '' }}">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
class="nav-item {{ 'active' if request.endpoint == 'jobs_page' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/>
|
||||
</svg>
|
||||
<span>Druckaufträge</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('stats_page') }}"
|
||||
class="mercedes-btn mercedes-btn-secondary {{ 'mercedes-btn-primary' if request.endpoint == 'stats_page' else '' }}">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
class="nav-item {{ 'active' if request.endpoint == 'stats_page' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
|
||||
</svg>
|
||||
<span>Statistiken</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('calendar.calendar_view') }}"
|
||||
class="mercedes-btn mercedes-btn-secondary {{ 'mercedes-btn-primary' if request.endpoint == 'calendar.calendar_view' else '' }}">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
class="nav-item {{ 'active' if request.endpoint == 'calendar.calendar_view' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
|
||||
</svg>
|
||||
<span>Schichtplan</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('guest.guest_request_form') }}"
|
||||
class="mercedes-btn mercedes-btn-secondary {{ 'mercedes-btn-primary' if request.endpoint == 'guest.guest_request_form' else '' }}">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
class="nav-item {{ 'active' if request.endpoint == 'guest.guest_request_form' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
|
||||
</svg>
|
||||
<span>Gastanfrage</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('guest.guest_requests_overview') }}"
|
||||
class="mercedes-btn mercedes-btn-secondary {{ 'mercedes-btn-primary' if request.endpoint == 'guest.guest_requests_overview' else '' }}">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
class="nav-item {{ 'active' if request.endpoint == 'guest.guest_requests_overview' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<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>
|
||||
<span>Anträge Übersicht</span>
|
||||
@ -188,8 +189,8 @@
|
||||
|
||||
{% if current_user.is_authenticated and current_user.is_admin %}
|
||||
<a href="{{ url_for('admin_page') }}"
|
||||
class="mercedes-btn mercedes-btn-secondary {{ 'mercedes-btn-primary' if request.endpoint == 'admin_page' else '' }}">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
class="nav-item {{ 'active' if request.endpoint == 'admin_page' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
|
||||
</svg>
|
||||
@ -200,11 +201,11 @@
|
||||
</div>
|
||||
|
||||
<!-- Rechte Seite der Navbar -->
|
||||
<div class="flex items-center space-x-3">
|
||||
<!-- Mobile Menu Toggle -->
|
||||
<div class="flex items-center space-x-2 sm:space-x-3">
|
||||
<!-- Mobile Menu Toggle (neu) -->
|
||||
<button
|
||||
id="mobileMenuToggle"
|
||||
class="lg:hidden mercedes-btn mercedes-btn-secondary !p-2"
|
||||
class="lg:hidden p-2 rounded-full text-slate-700 dark:text-slate-300 hover:bg-slate-100/80 dark:hover:bg-slate-800/50"
|
||||
aria-label="Menü öffnen"
|
||||
aria-expanded="false"
|
||||
>
|
||||
@ -213,35 +214,63 @@
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<!-- Dark Mode Toggle - Premium Design -->
|
||||
<button
|
||||
id="darkModeToggle"
|
||||
class="mercedes-btn mercedes-btn-secondary !p-3 group relative overflow-hidden"
|
||||
aria-label="Dark Mode umschalten"
|
||||
data-action="toggle-dark-mode"
|
||||
title="Design wechseln"
|
||||
>
|
||||
<!-- Sonnen-Icon (Light Mode) -->
|
||||
<svg class="sun-icon w-5 h-5 text-amber-500 transition-all duration-500" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M12 2.25a.75.75 0 01.75.75v2.25a.75.75 0 01-1.5 0V3a.75.75 0 01.75-.75zM7.5 12a4.5 4.5 0 119 0 4.5 4.5 0 01-9 0zM18.894 6.166a.75.75 0 00-1.06-1.06l-1.591 1.59a.75.75 0 101.06 1.061l1.591-1.59zM21.75 12a.75.75 0 01-.75.75h-2.25a.75.75 0 010-1.5H21a.75.75 0 01.75.75zM17.834 18.894a.75.75 0 001.06-1.06l-1.59-1.591a.75.75 0 10-1.061 1.06l1.59 1.591zM12 18a.75.75 0 01.75.75V21a.75.75 0 01-1.5 0v-2.25A.75.75 0 0112 18zM7.758 17.303a.75.75 0 00-1.061-1.06l-1.591 1.59a.75.75 0 001.06 1.061l1.591-1.59zM6 12a.75.75 0 01-.75.75H3a.75.75 0 010-1.5h2.25A.75.75 0 016 12zM6.697 7.757a.75.75 0 001.06-1.06l-1.59-1.591a.75.75 0 00-1.061 1.06l1.59 1.591z"/>
|
||||
</svg>
|
||||
<!-- Dark Mode Toggle - Moderner, schöner Design -->
|
||||
<div class="relative">
|
||||
<button
|
||||
id="darkModeToggle"
|
||||
class="dark-mode-toggle-premium group"
|
||||
aria-label="Dark Mode umschalten"
|
||||
data-action="toggle-dark-mode"
|
||||
title="Design wechseln"
|
||||
>
|
||||
<!-- Hintergrund-Ring für besseren visuellen Effekt -->
|
||||
<div class="absolute inset-0 rounded-full bg-gradient-to-r from-amber-300 to-orange-400 dark:from-blue-400 dark:to-purple-500 opacity-0 group-hover:opacity-100 blur-sm transition-all duration-500"></div>
|
||||
|
||||
<!-- Mond-Icon (Dark Mode) -->
|
||||
<svg class="moon-icon hidden w-5 h-5 text-blue-400 transition-all duration-500" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path fill-rule="evenodd" d="M9.528 1.718a.75.75 0 01.162.819A8.97 8.97 0 009 6a9 9 0 009 9 8.97 8.97 0 003.463-.69.75.75 0 01.981.98 10.503 10.503 0 01-9.694 6.46c-5.799 0-10.5-4.701-10.5-10.5 0-4.368 2.667-8.112 6.46-9.694a.75.75 0 01.818.162z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
</button>
|
||||
<!-- Haupt-Container -->
|
||||
<div class="relative flex items-center justify-center w-11 h-11 rounded-full bg-white/80 dark:bg-slate-800/80 backdrop-blur-md border border-slate-200/50 dark:border-slate-600/50 shadow-lg dark:shadow-slate-900/20 transition-all duration-300 group-hover:scale-105 group-active:scale-95">
|
||||
|
||||
<!-- Sonnen-Icon (Light Mode) -->
|
||||
<div class="sun-icon absolute inset-0 flex items-center justify-center transition-all duration-500 ease-in-out opacity-100 dark:opacity-0 scale-100 dark:scale-75 rotate-0 dark:rotate-90">
|
||||
<svg class="w-5 h-5 text-amber-500 drop-shadow-sm" fill="currentColor" viewBox="0 0 24 24" style="margin: auto;">
|
||||
<path d="M12 2.25a.75.75 0 01.75.75v2.25a.75.75 0 01-1.5 0V3a.75.75 0 01.75-.75zM7.5 12a4.5 4.5 0 119 0 4.5 4.5 0 01-9 0zM18.894 6.166a.75.75 0 00-1.06-1.06l-1.591 1.59a.75.75 0 101.06 1.061l1.591-1.59zM21.75 12a.75.75 0 01-.75.75h-2.25a.75.75 0 010-1.5H21a.75.75 0 01.75.75zM17.834 18.894a.75.75 0 001.06-1.06l-1.59-1.591a.75.75 0 10-1.061 1.06l1.59 1.591zM12 18a.75.75 0 01.75.75V21a.75.75 0 01-1.5 0v-2.25A.75.75 0 0112 18zM7.758 17.303a.75.75 0 00-1.061-1.06l-1.591 1.59a.75.75 0 001.06 1.061l1.591-1.59zM6 12a.75.75 0 01-.75.75H3a.75.75 0 010-1.5h2.25A.75.75 0 016 12zM6.697 7.757a.75.75 0 001.06-1.06l-1.59-1.591a.75.75 0 00-1.061 1.06l1.59 1.591z"/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<!-- Mond-Icon (Dark Mode) -->
|
||||
<div class="moon-icon absolute inset-0 flex items-center justify-center transition-all duration-500 ease-in-out opacity-0 dark:opacity-100 scale-75 dark:scale-100 rotate-90 dark:rotate-0">
|
||||
<svg class="w-5 h-5 text-blue-400 drop-shadow-sm" fill="currentColor" viewBox="0 0 24 24" style="margin: auto;">
|
||||
<path fill-rule="evenodd" d="M9.528 1.718a.75.75 0 01.162.819A8.97 8.97 0 009 6a9 9 0 009 9 8.97 8.97 0 003.463-.69.75.75 0 01.981.98 10.503 10.503 0 01-9.694 6.46c-5.799 0-10.5-4.701-10.5-10.5 0-4.368 2.667-8.112 6.46-9.694a.75.75 0 01.818.162z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<!-- Animierte Punkte für zusätzlichen visuellen Effekt -->
|
||||
<div class="absolute -inset-1 rounded-full opacity-0 group-hover:opacity-100 transition-opacity duration-300">
|
||||
<div class="animate-pulse absolute top-0 left-1/2 w-1 h-1 bg-amber-400 dark:bg-blue-400 rounded-full transform -translate-x-1/2 -translate-y-1"></div>
|
||||
<div class="animate-pulse absolute bottom-0 left-1/2 w-1 h-1 bg-amber-400 dark:bg-blue-400 rounded-full transform -translate-x-1/2 translate-y-1 animation-delay-500"></div>
|
||||
<div class="animate-pulse absolute top-1/2 left-0 w-1 h-1 bg-amber-400 dark:bg-blue-400 rounded-full transform -translate-y-1/2 -translate-x-1 animation-delay-1000"></div>
|
||||
<div class="animate-pulse absolute top-1/2 right-0 w-1 h-1 bg-amber-400 dark:bg-blue-400 rounded-full transform -translate-y-1/2 translate-x-1 animation-delay-1500"></div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<!-- Tooltip -->
|
||||
<div class="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 px-2 py-1 bg-slate-900 dark:bg-slate-700 text-white text-xs rounded whitespace-nowrap opacity-0 group-hover:opacity-100 transition-opacity duration-200 pointer-events-none z-50">
|
||||
<span class="dark:hidden">Dark Mode aktivieren</span>
|
||||
<span class="hidden dark:inline">Light Mode aktivieren</span>
|
||||
<div class="absolute top-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-l-4 border-r-4 border-t-4 border-transparent border-t-slate-900 dark:border-t-slate-700"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if current_user.is_authenticated %}
|
||||
<!-- Benachrichtigungen -->
|
||||
<div class="relative">
|
||||
<button
|
||||
id="notificationToggle"
|
||||
class="mercedes-btn mercedes-btn-secondary !p-3 relative"
|
||||
class="relative p-2 rounded-full text-slate-700 dark:text-slate-300 hover:bg-slate-100/80 dark:hover:bg-slate-800/50 transition-all duration-200"
|
||||
aria-label="Benachrichtigungen anzeigen"
|
||||
title="Benachrichtigungen"
|
||||
>
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"/>
|
||||
</svg>
|
||||
<!-- Badge für ungelesene Benachrichtigungen -->
|
||||
@ -251,12 +280,12 @@
|
||||
</button>
|
||||
|
||||
<!-- Benachrichtigungs-Dropdown -->
|
||||
<div id="notificationDropdown" class="absolute right-0 mt-2 w-80 glass-card z-50 hidden">
|
||||
<div id="notificationDropdown" class="absolute right-0 mt-2 w-80 bg-white dark:bg-slate-800 rounded-lg shadow-lg border border-slate-200 dark:border-slate-600 z-50 hidden">
|
||||
<div class="p-4 border-b border-slate-200 dark:border-slate-600">
|
||||
<h3 class="text-lg font-semibold">Benachrichtigungen</h3>
|
||||
<h3 class="text-lg font-semibold text-slate-900 dark:text-white">Benachrichtigungen</h3>
|
||||
</div>
|
||||
<div id="notificationList" class="max-h-96 overflow-y-auto">
|
||||
<div class="p-4 text-center mercedes-text-muted">
|
||||
<div class="p-4 text-center text-slate-500 dark:text-slate-400">
|
||||
Keine neuen Benachrichtigungen
|
||||
</div>
|
||||
</div>
|
||||
@ -268,30 +297,30 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- User Profile Dropdown -->
|
||||
<!-- User Profile Dropdown - neues Design -->
|
||||
<div class="relative" id="user-menu-container">
|
||||
<button
|
||||
id="user-menu-button"
|
||||
class="mercedes-btn mercedes-btn-secondary flex items-center space-x-2"
|
||||
class="user-menu-button-new"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-label="Benutzermenu öffnen"
|
||||
>
|
||||
<!-- Profile Avatar -->
|
||||
<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 font-semibold">
|
||||
<div class="user-avatar-new">
|
||||
{{ current_user.email[0].upper() if current_user.email else 'U' }}
|
||||
</div>
|
||||
<!-- User Info (hidden on mobile) -->
|
||||
<div class="hidden md:block text-left">
|
||||
<div class="text-sm font-semibold">{{ current_user.email.split('@')[0] if current_user.email else 'Benutzer' }}</div>
|
||||
<div class="text-xs mercedes-text-muted">Mercedes-Benz Mitarbeiter</div>
|
||||
<div class="hidden md:block text-left ml-2">
|
||||
<div class="text-sm font-semibold text-slate-900 dark:text-white transition-colors duration-300">{{ current_user.email.split('@')[0] if current_user.email else 'Benutzer' }}</div>
|
||||
<div class="text-xs text-slate-600 dark:text-slate-400 transition-colors duration-300">Mercedes-Benz Mitarbeiter</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
{% else %}
|
||||
<!-- Login Button -->
|
||||
<!-- Login Button - neues Design -->
|
||||
<a href="{{ url_for('login') }}"
|
||||
class="mercedes-btn mercedes-btn-primary">
|
||||
class="login-button-new">
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 16l-4-4m0 0l4-4m-4 4h14m-5 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"/>
|
||||
</svg>
|
||||
@ -303,152 +332,154 @@
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Mobile Menu -->
|
||||
<div id="mobileMenu" class="glass-card !rounded-none hidden lg:hidden">
|
||||
<nav class="mercedes-container" role="navigation" aria-label="Mobile Navigation">
|
||||
<div class="mercedes-grid mercedes-grid-1 !gap-2 !my-4">
|
||||
<a href="{{ url_for('dashboard') }}"
|
||||
class="mercedes-btn mercedes-btn-secondary justify-start {{ 'mercedes-btn-primary' if request.endpoint == 'dashboard' else '' }}">
|
||||
<svg class="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2H5a2 2 0 00-2-2z"/>
|
||||
</svg>
|
||||
<span>Dashboard</span>
|
||||
</a>
|
||||
<!-- Mobile Menu (neu) -->
|
||||
<div id="mobileMenu" class="mobile-menu-new hidden lg:hidden">
|
||||
<nav class="flex flex-col space-y-1 px-3 py-4" role="navigation" aria-label="Mobile Navigation">
|
||||
<a href="{{ url_for('dashboard') }}"
|
||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'dashboard' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2H5a2 2 0 00-2-2z"/>
|
||||
</svg>
|
||||
<span>Dashboard</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('printers_page') }}"
|
||||
class="mercedes-btn mercedes-btn-secondary justify-start {{ 'mercedes-btn-primary' if request.endpoint == 'printers_page' else '' }}">
|
||||
<svg class="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z"/>
|
||||
</svg>
|
||||
<span>3D-Drucker</span>
|
||||
</a>
|
||||
<a href="{{ url_for('printers_page') }}"
|
||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'printers_page' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z"/>
|
||||
</svg>
|
||||
<span>3D-Drucker</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('jobs_page') }}"
|
||||
class="mercedes-btn mercedes-btn-secondary justify-start {{ 'mercedes-btn-primary' if request.endpoint == 'jobs_page' else '' }}">
|
||||
<svg class="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/>
|
||||
</svg>
|
||||
<span>Druckaufträge</span>
|
||||
</a>
|
||||
<a href="{{ url_for('jobs_page') }}"
|
||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'jobs_page' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/>
|
||||
</svg>
|
||||
<span>Druckaufträge</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('stats_page') }}"
|
||||
class="mercedes-btn mercedes-btn-secondary justify-start {{ 'mercedes-btn-primary' if request.endpoint == 'stats_page' else '' }}">
|
||||
<svg class="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
|
||||
</svg>
|
||||
<span>Statistiken</span>
|
||||
</a>
|
||||
<a href="{{ url_for('stats_page') }}"
|
||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'stats_page' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
|
||||
</svg>
|
||||
<span>Statistiken</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('calendar.calendar_view') }}"
|
||||
class="mercedes-btn mercedes-btn-secondary justify-start {{ 'mercedes-btn-primary' if request.endpoint == 'calendar.calendar_view' else '' }}">
|
||||
<svg class="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
|
||||
</svg>
|
||||
<span>Schichtplan</span>
|
||||
</a>
|
||||
<a href="{{ url_for('calendar.calendar_view') }}"
|
||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'calendar.calendar_view' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
|
||||
</svg>
|
||||
<span>Schichtplan</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('guest.guest_request_form') }}"
|
||||
class="mercedes-btn mercedes-btn-secondary justify-start {{ 'mercedes-btn-primary' if request.endpoint == 'guest.guest_request_form' else '' }}">
|
||||
<svg class="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
|
||||
</svg>
|
||||
<span>Gastanfrage</span>
|
||||
</a>
|
||||
<a href="{{ url_for('guest.guest_request_form') }}"
|
||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'guest.guest_request_form' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
|
||||
</svg>
|
||||
<span>Gastanfrage</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('guest.guest_requests_overview') }}"
|
||||
class="mercedes-btn mercedes-btn-secondary justify-start {{ 'mercedes-btn-primary' if request.endpoint == 'guest.guest_requests_overview' else '' }}">
|
||||
<svg class="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<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>
|
||||
<span>Anträge Übersicht</span>
|
||||
</a>
|
||||
<a href="{{ url_for('guest.guest_requests_overview') }}"
|
||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'guest.guest_requests_overview' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<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>
|
||||
<span>Anträge Übersicht</span>
|
||||
</a>
|
||||
|
||||
{% if current_user.is_authenticated and current_user.is_admin %}
|
||||
<a href="{{ url_for('admin_page') }}"
|
||||
class="mercedes-btn mercedes-btn-secondary justify-start {{ 'mercedes-btn-primary' if request.endpoint == 'admin_page' else '' }}">
|
||||
<svg class="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
|
||||
</svg>
|
||||
<span>Administration</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if current_user.is_authenticated and current_user.is_admin %}
|
||||
<a href="{{ url_for('admin_page') }}"
|
||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'admin_page' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
|
||||
</svg>
|
||||
<span>Administration</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main id="main-content" class="flex-grow mercedes-container mercedes-section">
|
||||
<!-- Flash Messages -->
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
<div class="mercedes-mb-lg">
|
||||
{% for category, message in messages %}
|
||||
<div class="glass-card mercedes-status mercedes-status-{{ 'online' if category == 'success' else 'warning' if category == 'warning' else 'offline' }}">
|
||||
{{ message }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
<main id="main-content" class="flex-grow max-w-7xl w-full mx-auto px-3 sm:px-6 lg:px-8 py-4 sm:py-8">
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<!-- Flash Messages -->
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
<div class="flash-messages mb-4">
|
||||
{% for category, message in messages %}
|
||||
<div class="alert alert-{{ category }} mb-2">
|
||||
{{ message }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
{% block content %}{% endblock %}
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Mercedes-Benz Footer -->
|
||||
<footer class="mercedes-footer">
|
||||
<div class="mercedes-container">
|
||||
<div class="mercedes-grid mercedes-grid-3">
|
||||
<!-- Brand Section -->
|
||||
<div class="mercedes-fade-in">
|
||||
<div class="flex items-center gap-3 mercedes-mb-md">
|
||||
<div class="w-8 h-8">
|
||||
<svg class="w-full h-full text-slate-900 dark:text-white transition-colors duration-300" 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.5
|
||||
C27,78.3,33.3,80,40,80c6.7,0,12.9-1.7,18.5-4.6C71.3,68.8,80,55.4,80,40C80,24.6,71.3,11.2,58.6,4.5z M4,40
|
||||
c0-13.1,7-24.5,17.5-30.9v0C26.6,6,32.5,4.2,39,4l-4.5,32.7L21.5,46.8v0L8.3,57.1C5.6,52,4,46.2,4,40z M58.6,70.8
|
||||
C53.1,74.1,46.8,76,40,76c-6.8,0-13.2-1.9-18.6-5.2c-4.9-2.9-8.9-6.9-11.9-11.7l11.9-4.9v0L40,46.6l18.6,7.5v0l12,4.9
|
||||
C67.6,63.9,63.4,67.9,58.6,70.8z M58.6,46.8L58.6,46.8l-12.9-10L41.1,4c6.3,0.2,12.3,2,17.4,5.1v0C69,15.4,76,26.9,76,40
|
||||
c0,6.2-1.5,12-4.3,17.1L58.6,46.8z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-lg font-bold">Mercedes-Benz</div>
|
||||
<div class="text-sm mercedes-text-muted">MYP Platform</div>
|
||||
<footer class="bg-white dark:bg-black border-t border-gray-200 dark:border-slate-700 mt-auto transition-colors duration-300">
|
||||
<div class="max-w-screen-xl w-full mx-auto px-3 sm:px-6 lg:px-8">
|
||||
<div class="py-4 sm:py-8 border-t border-gray-200 dark:border-slate-700 mt-8 sm:mt-12 pt-4 sm:pt-8">
|
||||
<div class="grid grid-cols-1 sm:grid-cols-3 gap-6 sm:gap-8">
|
||||
<!-- Brand Section - Stack on mobile -->
|
||||
<div class="flex flex-col space-y-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-6 h-6">
|
||||
<svg class="w-full h-full text-slate-900 dark:text-white transition-colors duration-300" 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.5
|
||||
C27,78.3,33.3,80,40,80c6.7,0,12.9-1.7,18.5-4.6C71.3,68.8,80,55.4,80,40C80,24.6,71.3,11.2,58.6,4.5z M4,40
|
||||
c0-13.1,7-24.5,17.5-30.9v0C26.6,6,32.5,4.2,39,4l-4.5,32.7L21.5,46.8v0L8.3,57.1C5.6,52,4,46.2,4,40z M58.6,70.8
|
||||
C53.1,74.1,46.8,76,40,76c-6.8,0-13.2-1.9-18.6-5.2c-4.9-2.9-8.9-6.9-11.9-11.7l11.9-4.9v0L40,46.6l18.6,7.5v0l12,4.9
|
||||
C67.6,63.9,63.4,67.9,58.6,70.8z M58.6,46.8L58.6,46.8l-12.9-10L41.1,4c6.3,0.2,12.3,2,17.4,5.1v0C69,15.4,76,26.9,76,40
|
||||
c0,6.2-1.5,12-4.3,17.1L58.6,46.8z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-base font-bold text-slate-900 dark:text-white transition-colors duration-300">Mercedes-Benz</div>
|
||||
<div class="text-xs text-slate-600 dark:text-slate-400 transition-colors duration-300">MYP Platform</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-xs text-slate-600 dark:text-slate-400 leading-relaxed transition-colors duration-300">
|
||||
Das Beste oder nichts - Professionelles 3D-Druck Management für Mercedes-Benz.
|
||||
</p>
|
||||
</div>
|
||||
<p class="mercedes-text-muted leading-relaxed">
|
||||
Das Beste oder nichts - Professionelles 3D-Druck Management für Mercedes-Benz.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- System Info -->
|
||||
<div class="mercedes-fade-in">
|
||||
<h3 class="text-lg font-semibold mercedes-mb-md">System</h3>
|
||||
<div class="space-y-2 mercedes-text-muted">
|
||||
<div class="flex justify-between">
|
||||
<span>Version:</span>
|
||||
<span class="font-medium">3.0.0</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span>Status:</span>
|
||||
<div id="connection-status" class="flex items-center space-x-1">
|
||||
<div class="w-2 h-2 bg-green-400 rounded-full animate-pulse"></div>
|
||||
<span class="text-green-500 dark:text-green-400 font-medium">Online</span>
|
||||
<!-- System Info -->
|
||||
<div class="flex flex-col space-y-4">
|
||||
<h3 class="text-lg font-semibold text-slate-900 dark:text-white transition-colors duration-300">System</h3>
|
||||
<div class="space-y-2 text-xs text-slate-600 dark:text-slate-400 leading-relaxed transition-colors duration-300">
|
||||
<div class="flex justify-between">
|
||||
<span>Version:</span>
|
||||
<span class="text-slate-900 dark:text-white font-medium transition-colors duration-300">3.0.0</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span>Status:</span>
|
||||
<div id="connection-status" class="flex items-center space-x-1">
|
||||
<div class="w-2 h-2 bg-green-400 rounded-full animate-pulse"></div>
|
||||
<span class="text-green-500 dark:text-green-400 font-medium transition-colors duration-300">Online</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Copyright -->
|
||||
<div class="mercedes-fade-in">
|
||||
<h3 class="text-lg font-semibold mercedes-mb-md">Rechtliches</h3>
|
||||
<div class="space-y-2 mercedes-text-muted">
|
||||
<p>© 2024 Mercedes-Benz Group AG</p>
|
||||
<p>Alle Rechte vorbehalten.</p>
|
||||
<p class="text-xs">
|
||||
Entwickelt für interne Mercedes-Benz Anwendungen
|
||||
</p>
|
||||
<!-- Copyright -->
|
||||
<div class="flex flex-col space-y-4">
|
||||
<h3 class="text-lg font-semibold text-slate-900 dark:text-white transition-colors duration-300">Rechtliches</h3>
|
||||
<div class="space-y-2 text-xs text-slate-600 dark:text-slate-400 leading-relaxed transition-colors duration-300">
|
||||
<p>© 2024 Mercedes-Benz Group AG</p>
|
||||
<p>Alle Rechte vorbehalten.</p>
|
||||
<p class="text-xs text-slate-500 dark:text-slate-500 transition-colors duration-300">
|
||||
Entwickelt für interne Mercedes-Benz Anwendungen
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,12 +2,234 @@
|
||||
|
||||
{% block title %}Dashboard - Mercedes-Benz MYP Platform{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<style>
|
||||
/* Professional Mercedes-Benz Dashboard Styles */
|
||||
.mb-dashboard-card {
|
||||
background: white;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.dark .mb-dashboard-card {
|
||||
background: var(--mb-black, #000000); /* Schwarzer Hintergrund im Dark Mode */
|
||||
border-color: var(--border-primary, #334155);
|
||||
}
|
||||
|
||||
.mb-dashboard-card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
.dark .mb-dashboard-card:hover {
|
||||
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.3), 0 10px 10px -5px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.mb-stat-card {
|
||||
background: linear-gradient(135deg, #f0f9ff 0%, #e6f2ff 100%);
|
||||
color: #0f172a;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.dark .mb-stat-card {
|
||||
background: linear-gradient(135deg, #000000 0%, #111827 100%); /* Mercedes Schwarz */
|
||||
color: var(--text-primary, #f8fafc);
|
||||
}
|
||||
|
||||
.mb-stat-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -50%;
|
||||
right: -50%;
|
||||
width: 200%;
|
||||
height: 200%;
|
||||
background: radial-gradient(circle, rgba(0, 114, 206, 0.1) 0%, transparent 70%);
|
||||
animation: pulse-glow 4s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.dark .mb-stat-card::before {
|
||||
background: radial-gradient(circle, rgba(255, 255, 255, 0.05) 0%, transparent 70%); /* Subtle glow for dark */
|
||||
}
|
||||
|
||||
@keyframes pulse-glow {
|
||||
0%, 100% { opacity: 0.5; transform: scale(1); }
|
||||
50% { opacity: 0.8; transform: scale(1.05); }
|
||||
}
|
||||
|
||||
.mb-stat-icon {
|
||||
background: rgba(0, 0, 0, 0.1); /* Schwarz statt Blau */
|
||||
backdrop-filter: blur(10px);
|
||||
border-radius: 16px;
|
||||
padding: 16px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.dark .mb-stat-icon {
|
||||
background: rgba(255, 255, 255, 0.1); /* Lighter icon background for contrast */
|
||||
}
|
||||
|
||||
.mb-stat-card:hover .mb-stat-icon {
|
||||
transform: scale(1.1);
|
||||
background: rgba(0, 0, 0, 0.2); /* Schwarz statt Blau */
|
||||
}
|
||||
|
||||
.dark .mb-stat-card:hover .mb-stat-icon {
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
.mb-status-indicator {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.mb-status-indicator::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
animation: status-pulse 2s infinite;
|
||||
}
|
||||
|
||||
.mb-status-online {
|
||||
background: #10b981;
|
||||
}
|
||||
|
||||
.mb-status-online::after {
|
||||
background: #10b981;
|
||||
}
|
||||
|
||||
.mb-status-busy {
|
||||
background: #f59e0b;
|
||||
}
|
||||
|
||||
.mb-status-busy::after {
|
||||
background: #f59e0b;
|
||||
}
|
||||
|
||||
.mb-status-offline {
|
||||
background: #ef4444;
|
||||
}
|
||||
|
||||
.mb-status-offline::after {
|
||||
background: #ef4444;
|
||||
}
|
||||
|
||||
.mb-status-idle {
|
||||
background: #6b7280;
|
||||
}
|
||||
|
||||
.mb-status-idle::after {
|
||||
background: #6b7280;
|
||||
}
|
||||
|
||||
@keyframes status-pulse {
|
||||
0% { transform: scale(1); opacity: 1; }
|
||||
50% { transform: scale(1.5); opacity: 0.5; }
|
||||
100% { transform: scale(2); opacity: 0; }
|
||||
}
|
||||
|
||||
.mb-progress-container {
|
||||
background: #f3f4f6;
|
||||
height: 8px;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.dark .mb-progress-container {
|
||||
background: #374151;
|
||||
}
|
||||
|
||||
.mb-progress-bar {
|
||||
background: linear-gradient(90deg, #000000 0%, #333333 100%); /* Schwarz statt Blau */
|
||||
height: 100%;
|
||||
border-radius: 4px;
|
||||
transition: width 0.8s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.dark .mb-progress-bar {
|
||||
background: linear-gradient(90deg, #f3f4f6 0%, #e5e7eb 100%);
|
||||
}
|
||||
|
||||
.mb-progress-bar::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
|
||||
animation: progress-shine 2s infinite;
|
||||
}
|
||||
|
||||
@keyframes progress-shine {
|
||||
0% { transform: translateX(-100%); }
|
||||
100% { transform: translateX(100%); }
|
||||
}
|
||||
|
||||
.mb-activity-item {
|
||||
border-left: 4px solid #000000; /* Schwarz statt Blau */
|
||||
background: linear-gradient(90deg, rgba(0, 0, 0, 0.05) 0%, transparent 100%); /* Schwarz statt Blau */
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
border-radius: 0 8px 8px 0;
|
||||
}
|
||||
|
||||
.dark .mb-activity-item {
|
||||
border-left-color: #f3f4f6;
|
||||
background: linear-gradient(90deg, rgba(255, 255, 255, 0.02) 0%, transparent 100%);
|
||||
}
|
||||
|
||||
/* Light/Dark Mode compatible cards */
|
||||
.glass-card-light {
|
||||
@apply bg-white/70 dark:bg-black/80 backdrop-blur-lg border border-gray-200/80 dark:border-slate-700/30 rounded-xl shadow-xl transition-all duration-300;
|
||||
backdrop-filter: blur(12px);
|
||||
-webkit-backdrop-filter: blur(12px);
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.dark .glass-card-light {
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
.section-title {
|
||||
@apply text-slate-800 dark:text-white text-xl font-semibold mb-4;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
@apply text-slate-900 dark:text-white font-bold text-2xl;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
@apply text-slate-500 dark:text-slate-400 text-sm;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="mercedes-section">
|
||||
<!-- Dashboard Header -->
|
||||
<div class="glass-card-hero mercedes-text-center">
|
||||
<div class="space-y-8">
|
||||
<!-- Dashboard Header Card -->
|
||||
<div class="dashboard-card p-6">
|
||||
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-6">
|
||||
<div class="flex items-center gap-6 md:justify-start justify-center">
|
||||
<div class="flex items-center gap-6">
|
||||
<div class="w-16 h-16 flex-shrink-0">
|
||||
<svg class="w-full h-full text-slate-900 dark:text-white" fill="currentColor" viewBox="0 0 80 80" aria-hidden="true">
|
||||
<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
|
||||
@ -18,29 +240,29 @@
|
||||
c0,6.2-1.5,12-4.3,17.1L58.6,46.8z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="mercedes-text-left">
|
||||
<h1 class="mercedes-title">Dashboard</h1>
|
||||
<p class="mercedes-subtitle">Übersicht über Ihre 3D-Druck Aktivitäten</p>
|
||||
<div>
|
||||
<h1 class="text-3xl font-bold text-slate-900 dark:text-white tracking-tight">Dashboard</h1>
|
||||
<p class="text-slate-500 dark:text-slate-400 mt-1">Übersicht über Ihre 3D-Druck Aktivitäten</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-3 justify-center md:justify-end">
|
||||
<div class="flex flex-wrap gap-3">
|
||||
<button id="refreshDashboard"
|
||||
class="mercedes-btn mercedes-btn-secondary">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
class="btn-secondary flex items-center gap-2">
|
||||
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<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('jobs_page') }}"
|
||||
class="mercedes-btn mercedes-btn-primary">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
class="btn-primary flex items-center gap-2">
|
||||
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
|
||||
</svg>
|
||||
<span>Neuer Auftrag</span>
|
||||
</a>
|
||||
<a href="{{ url_for('guest.guest_requests_overview') }}"
|
||||
class="mercedes-btn mercedes-btn-secondary">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
class="btn-secondary flex items-center gap-2">
|
||||
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<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>
|
||||
<span>Anträge Übersicht</span>
|
||||
@ -50,15 +272,15 @@
|
||||
</div>
|
||||
|
||||
<!-- Stats Overview Cards -->
|
||||
<div class="mercedes-grid mercedes-grid-4 mercedes-fade-in">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||
<!-- Active Jobs Card -->
|
||||
<div class="glass-card mercedes-text-center">
|
||||
<div class="flex justify-between items-start mercedes-mb-md">
|
||||
<div class="mercedes-text-left">
|
||||
<h3 class="mercedes-text-muted">Aktive Aufträge</h3>
|
||||
<div class="text-3xl font-bold mercedes-text mercedes-mt-sm">{{ active_jobs_count }}</div>
|
||||
<div class="dashboard-card p-6">
|
||||
<div class="flex justify-between">
|
||||
<div>
|
||||
<h3 class="stat-label">Aktive Aufträge</h3>
|
||||
<div class="stat-value">{{ active_jobs_count }}</div>
|
||||
</div>
|
||||
<div class="w-12 h-12 bg-gradient-to-br from-blue-500 to-blue-600 rounded-full flex items-center justify-center text-white">
|
||||
<div class="mb-stat-icon text-slate-900 dark:text-white">
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01" />
|
||||
</svg>
|
||||
@ -67,13 +289,13 @@
|
||||
</div>
|
||||
|
||||
<!-- Available Printers Card -->
|
||||
<div class="glass-card mercedes-text-center">
|
||||
<div class="flex justify-between items-start mercedes-mb-md">
|
||||
<div class="mercedes-text-left">
|
||||
<h3 class="mercedes-text-muted">Verfügbare Drucker</h3>
|
||||
<div class="text-3xl font-bold mercedes-text mercedes-mt-sm">{{ available_printers_count }}</div>
|
||||
<div class="dashboard-card p-6">
|
||||
<div class="flex justify-between">
|
||||
<div>
|
||||
<h3 class="stat-label">Verfügbare Drucker</h3>
|
||||
<div class="stat-value">{{ available_printers_count }}</div>
|
||||
</div>
|
||||
<div class="w-12 h-12 bg-gradient-to-br from-green-500 to-green-600 rounded-full flex items-center justify-center text-white">
|
||||
<div class="mb-stat-icon text-green-600 dark:text-green-400">
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2m-2-4h.01M17 16h.01" />
|
||||
</svg>
|
||||
@ -82,13 +304,13 @@
|
||||
</div>
|
||||
|
||||
<!-- Total Jobs Card -->
|
||||
<div class="glass-card mercedes-text-center">
|
||||
<div class="flex justify-between items-start mercedes-mb-md">
|
||||
<div class="mercedes-text-left">
|
||||
<h3 class="mercedes-text-muted">Aufträge (gesamt)</h3>
|
||||
<div class="text-3xl font-bold mercedes-text mercedes-mt-sm">{{ total_jobs_count }}</div>
|
||||
<div class="dashboard-card p-6">
|
||||
<div class="flex justify-between">
|
||||
<div>
|
||||
<h3 class="stat-label">Aufträge (gesamt)</h3>
|
||||
<div class="stat-value">{{ total_jobs_count }}</div>
|
||||
</div>
|
||||
<div class="w-12 h-12 bg-gradient-to-br from-purple-500 to-purple-600 rounded-full flex items-center justify-center text-white">
|
||||
<div class="mb-stat-icon text-purple-600 dark:text-purple-400">
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 17v-2m3 2v-4m3 4v-6m2 10H7a2 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>
|
||||
@ -97,13 +319,13 @@
|
||||
</div>
|
||||
|
||||
<!-- Success Rate Card -->
|
||||
<div class="glass-card mercedes-text-center">
|
||||
<div class="flex justify-between items-start mercedes-mb-md">
|
||||
<div class="mercedes-text-left">
|
||||
<h3 class="mercedes-text-muted">Erfolgsrate</h3>
|
||||
<div class="text-3xl font-bold mercedes-text mercedes-mt-sm">{{ success_rate }}%</div>
|
||||
<div class="dashboard-card p-6">
|
||||
<div class="flex justify-between">
|
||||
<div>
|
||||
<h3 class="stat-label">Erfolgsrate</h3>
|
||||
<div class="stat-value">{{ success_rate }}%</div>
|
||||
</div>
|
||||
<div class="w-12 h-12 bg-gradient-to-br from-amber-500 to-amber-600 rounded-full flex items-center justify-center text-white">
|
||||
<div class="mb-stat-icon text-amber-600 dark:text-amber-400">
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z" />
|
||||
</svg>
|
||||
@ -113,12 +335,12 @@
|
||||
</div>
|
||||
|
||||
<!-- Active Jobs Section -->
|
||||
<div class="glass-card mercedes-slide-in">
|
||||
<h2 class="text-2xl font-bold mercedes-text mercedes-mb-lg">Aktuelle Druckaufträge</h2>
|
||||
<div class="dashboard-card p-6">
|
||||
<h2 class="section-title">Aktuelle Druckaufträge</h2>
|
||||
<div class="overflow-hidden">
|
||||
<table class="min-w-full divide-y divide-gray-200 dark:divide-slate-700">
|
||||
<thead>
|
||||
<tr class="text-left text-xs font-medium mercedes-text-muted uppercase tracking-wider">
|
||||
<tr class="text-left text-xs font-medium text-slate-500 dark:text-slate-400 uppercase tracking-wider">
|
||||
<th class="px-6 py-3">Status</th>
|
||||
<th class="px-6 py-3">Auftrag</th>
|
||||
<th class="px-6 py-3">Drucker</th>
|
||||
@ -133,41 +355,42 @@
|
||||
<tr class="hover:bg-gray-50 dark:hover:bg-slate-700/50">
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="flex items-center">
|
||||
<div class="mercedes-status {{ 'mercedes-status-online' if job.status_class == 'mb-status-online' else 'mercedes-status-warning' if job.status_class == 'mb-status-busy' else 'mercedes-status-offline' }}">
|
||||
<div class="mb-status-indicator {{ job.status_class }}"></div>
|
||||
<span class="ml-2 text-sm font-medium text-slate-700 dark:text-slate-300">
|
||||
{{ job.status_text }}
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="text-sm font-medium mercedes-text">{{ job.name }}</div>
|
||||
<div class="text-xs mercedes-text-muted">{{ job.file_name }}</div>
|
||||
<div class="text-sm font-medium text-slate-900 dark:text-white">{{ job.name }}</div>
|
||||
<div class="text-xs text-slate-500 dark:text-slate-400">{{ job.file_name }}</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="text-sm mercedes-text">{{ job.printer }}</div>
|
||||
<div class="text-sm text-slate-700 dark:text-slate-300">{{ job.printer }}</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="text-sm mercedes-text">{{ job.start_time }}</div>
|
||||
<div class="text-sm text-slate-700 dark:text-slate-300">{{ job.start_time }}</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2 mb-1">
|
||||
<div class="bg-gradient-to-r from-black to-gray-700 dark:from-white dark:to-gray-300 h-2 rounded-full transition-all duration-500" style="width: {{ job.progress }}%"></div>
|
||||
<div class="mb-progress-container">
|
||||
<div class="mb-progress-bar" style="width: {{ job.progress }}%"></div>
|
||||
</div>
|
||||
<div class="text-xs text-right mercedes-text-muted">{{ job.progress }}%</div>
|
||||
<div class="text-xs text-right mt-1 text-slate-500 dark:text-slate-400">{{ job.progress }}%</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-right">
|
||||
<a href="{{ url_for('job_detail', job_id=job.id) }}" class="mercedes-btn mercedes-btn-secondary text-sm">Details</a>
|
||||
<a href="{{ url_for('job_detail', job_id=job.id) }}" class="text-slate-900 dark:text-white hover:text-slate-700 dark:hover:text-slate-300 font-medium">Details</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="6" class="px-6 py-8 text-center">
|
||||
<div class="mercedes-text-muted">
|
||||
<div class="text-slate-500 dark:text-slate-400">
|
||||
<svg class="w-12 h-12 mx-auto mb-3 text-slate-400 dark:text-slate-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01" />
|
||||
</svg>
|
||||
<p class="mercedes-text font-medium mb-1">Keine aktiven Druckaufträge</p>
|
||||
<p class="mercedes-text-muted">Starten Sie einen neuen Druckauftrag, um ihn hier zu sehen.</p>
|
||||
<p class="text-slate-700 dark:text-slate-300 font-medium mb-1">Keine aktiven Druckaufträge</p>
|
||||
<p class="text-slate-500 dark:text-slate-400 text-sm">Starten Sie einen neuen Druckauftrag, um ihn hier zu sehen.</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@ -175,75 +398,74 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="mercedes-mt-lg mercedes-text-right">
|
||||
<a href="{{ url_for('jobs_page') }}" class="mercedes-btn mercedes-btn-secondary">
|
||||
<div class="mt-4 text-right">
|
||||
<a href="{{ url_for('jobs_page') }}" class="text-slate-900 dark:text-white hover:text-slate-700 dark:hover:text-slate-300 text-sm font-medium">
|
||||
Alle Druckaufträge anzeigen →
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Printer Status and Recent Activity -->
|
||||
<div class="mercedes-grid mercedes-grid-2 mercedes-fade-in">
|
||||
<!-- Last Row: Printer Status and Recent Activity -->
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
||||
<!-- Available Printers -->
|
||||
<div class="glass-card">
|
||||
<h2 class="text-2xl font-bold mercedes-text mercedes-mb-lg">Druckerstatus</h2>
|
||||
<div class="dashboard-card p-6">
|
||||
<h2 class="section-title">Druckerstatus</h2>
|
||||
<div class="space-y-4">
|
||||
{% if printers and printers|length > 0 %}
|
||||
{% for printer in printers %}
|
||||
<div class="glass-card !margin-0 flex items-center justify-between">
|
||||
<div class="flex items-center justify-between p-4 rounded-xl bg-gray-50 dark:bg-slate-700/30">
|
||||
<div class="flex items-center">
|
||||
<div class="mercedes-status {{ 'mercedes-status-online' if printer.status_class == 'mb-status-online' else 'mercedes-status-warning' if printer.status_class == 'mb-status-busy' else 'mercedes-status-offline' }} mr-3">
|
||||
{{ printer.status_text }}
|
||||
</div>
|
||||
<div class="mb-status-indicator {{ printer.status_class }} mr-3"></div>
|
||||
<div>
|
||||
<div class="text-sm font-medium mercedes-text">{{ printer.name }}</div>
|
||||
<div class="text-xs mercedes-text-muted">{{ printer.model }}</div>
|
||||
<div class="text-sm font-medium text-slate-900 dark:text-white">{{ printer.name }}</div>
|
||||
<div class="text-xs text-slate-500 dark:text-slate-400">{{ printer.model }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mercedes-text-right">
|
||||
<div class="text-xs mercedes-text-muted">{{ printer.location }}</div>
|
||||
<div class="text-right">
|
||||
<div class="text-sm font-medium text-slate-700 dark:text-slate-300">{{ printer.status_text }}</div>
|
||||
<div class="text-xs text-slate-500 dark:text-slate-400">{{ printer.location }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="mercedes-text-center mercedes-p-xl">
|
||||
<div class="text-center py-8">
|
||||
<svg class="w-12 h-12 mx-auto mb-3 text-slate-400 dark:text-slate-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2m-2-4h.01M17 16h.01" />
|
||||
</svg>
|
||||
<p class="mercedes-text font-medium mb-1">Keine Drucker gefunden</p>
|
||||
<p class="mercedes-text-muted">Prüfen Sie die Verbindung oder fügen Sie Drucker hinzu.</p>
|
||||
<p class="text-slate-700 dark:text-slate-300 font-medium mb-1">Keine Drucker gefunden</p>
|
||||
<p class="text-slate-500 dark:text-slate-400 text-sm">Prüfen Sie die Verbindung oder fügen Sie Drucker hinzu.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="mercedes-mt-lg mercedes-text-right">
|
||||
<a href="{{ url_for('printers_page') }}" class="mercedes-btn mercedes-btn-secondary">
|
||||
<div class="mt-4 text-right">
|
||||
<a href="{{ url_for('printers_page') }}" class="text-slate-900 dark:text-white hover:text-slate-700 dark:hover:text-slate-300 text-sm font-medium">
|
||||
Alle Drucker anzeigen →
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Recent Activity -->
|
||||
<div class="glass-card">
|
||||
<h2 class="text-2xl font-bold mercedes-text mercedes-mb-lg">Letzte Aktivitäten</h2>
|
||||
<div class="dashboard-card p-6">
|
||||
<h2 class="section-title">Letzte Aktivitäten</h2>
|
||||
<div class="space-y-3">
|
||||
{% if activities and activities|length > 0 %}
|
||||
{% for activity in activities %}
|
||||
<div class="border-l-4 border-black dark:border-white pl-4 py-3 bg-black/5 dark:bg-white/5 rounded-r-lg">
|
||||
<div class="mb-activity-item pl-4 py-3">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex-1">
|
||||
<p class="text-sm mercedes-text">{{ activity.description }}</p>
|
||||
<p class="text-xs mercedes-text-muted">{{ activity.time }}</p>
|
||||
<p class="text-sm text-slate-700 dark:text-slate-300">{{ activity.description }}</p>
|
||||
<p class="text-xs text-slate-500 dark:text-slate-400">{{ activity.time }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="mercedes-text-center mercedes-p-xl">
|
||||
<div class="text-center py-8">
|
||||
<svg class="w-12 h-12 mx-auto mb-3 text-slate-400 dark:text-slate-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
<p class="mercedes-text font-medium mb-1">Keine Aktivitäten</p>
|
||||
<p class="mercedes-text-muted">Ihre Aktivitäten werden hier angezeigt.</p>
|
||||
<p class="text-slate-700 dark:text-slate-300 font-medium mb-1">Keine Aktivitäten</p>
|
||||
<p class="text-slate-500 dark:text-slate-400 text-sm">Ihre Aktivitäten werden hier angezeigt.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
@ -252,7 +474,7 @@
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
{% block extra_js %}
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Refresh Button
|
||||
@ -265,6 +487,7 @@
|
||||
|
||||
// Dashboard Theme Switch Updates
|
||||
window.addEventListener('darkModeChanged', function(e) {
|
||||
// Update any theme-specific elements if needed
|
||||
console.log('Theme changed to:', e.detail.isDark ? 'dark' : 'light');
|
||||
});
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user