Styling
This commit is contained in:
@@ -24,10 +24,10 @@ body {
|
|||||||
|
|
||||||
/* Navbar */
|
/* Navbar */
|
||||||
.navbar {
|
.navbar {
|
||||||
background-color: #2c3e50;
|
background-color: #0066FF;
|
||||||
color: white;
|
color: white;
|
||||||
padding: 15px 0;
|
padding: 15px 0;
|
||||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar .container {
|
.navbar .container {
|
||||||
@@ -104,6 +104,15 @@ body {
|
|||||||
background-color: #7f8c8d;
|
background-color: #7f8c8d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn-logout {
|
||||||
|
background-color: #e74c3c;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-logout:hover {
|
||||||
|
background-color: #c0392b;
|
||||||
|
}
|
||||||
|
|
||||||
.btn-success {
|
.btn-success {
|
||||||
background-color: #27ae60;
|
background-color: #27ae60;
|
||||||
color: white;
|
color: white;
|
||||||
@@ -146,14 +155,14 @@ body {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
background: #0066FF;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-box {
|
.login-box {
|
||||||
background: white;
|
background: white;
|
||||||
padding: 40px;
|
padding: 40px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
box-shadow: 0 10px 25px rgba(0,0,0,0.2);
|
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
}
|
}
|
||||||
@@ -242,7 +251,7 @@ body {
|
|||||||
border-color: #3498db;
|
border-color: #3498db;
|
||||||
background-color: #f0f8ff;
|
background-color: #f0f8ff;
|
||||||
transform: translateY(-1px);
|
transform: translateY(-1px);
|
||||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.role-checkbox-label-small {
|
.role-checkbox-label-small {
|
||||||
@@ -259,7 +268,7 @@ body {
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.role-checkbox-input:checked + .role-checkbox-text {
|
.role-checkbox-input:checked+.role-checkbox-text {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #2c3e50;
|
color: #2c3e50;
|
||||||
}
|
}
|
||||||
@@ -308,9 +317,10 @@ body {
|
|||||||
background: white;
|
background: white;
|
||||||
padding: 30px;
|
padding: 30px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0; /* Ermöglicht Flexbox-Shrinking */
|
min-width: 0;
|
||||||
|
/* Ermöglicht Flexbox-Shrinking */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* User Stats Panel */
|
/* User Stats Panel */
|
||||||
@@ -318,7 +328,7 @@ body {
|
|||||||
background: white;
|
background: white;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
width: 280px;
|
width: 280px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@@ -454,7 +464,7 @@ table input[type="text"] {
|
|||||||
background: white;
|
background: white;
|
||||||
padding: 30px;
|
padding: 30px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -577,7 +587,7 @@ table input[type="text"] {
|
|||||||
background: white;
|
background: white;
|
||||||
padding: 30px 40px;
|
padding: 30px 40px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -768,7 +778,7 @@ table input[type="text"] {
|
|||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pdf-iframe:not([src=""]) ~ .pdf-fallback {
|
.pdf-iframe:not([src=""])~.pdf-fallback {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -917,7 +927,7 @@ table input[type="text"] {
|
|||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 25px 30px;
|
padding: 25px 30px;
|
||||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -997,14 +1007,14 @@ table input[type="text"] {
|
|||||||
.dashboard-layout {
|
.dashboard-layout {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-stats-panel {
|
.user-stats-panel {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 15px;
|
gap: 15px;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-card {
|
.stat-card {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
@@ -1016,39 +1026,39 @@ table input[type="text"] {
|
|||||||
.dashboard-container {
|
.dashboard-container {
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-row {
|
.form-row {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
.week-selector {
|
.week-selector {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 15px;
|
gap: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
table {
|
table {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
table th,
|
table th,
|
||||||
table td {
|
table td {
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-stats-panel {
|
.user-stats-panel {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-card {
|
.stat-card {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.activity-row {
|
.activity-row {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
.overtime-vacation-controls {
|
.overtime-vacation-controls {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -210,25 +210,15 @@ function registerVerwaltungRoutes(app) {
|
|||||||
vacationDays += 0.5;
|
vacationDays += 0.5;
|
||||||
vacationHours += 4; // Halber Tag = 4 Stunden
|
vacationHours += 4; // Halber Tag = 4 Stunden
|
||||||
// Bei halbem Tag Urlaub können noch Arbeitsstunden vorhanden sein
|
// Bei halbem Tag Urlaub können noch Arbeitsstunden vorhanden sein
|
||||||
|
// WICHTIG: total_hours enthält bereits Wochenend-Prozentsätze (aus timesheet.js)
|
||||||
if (entry.total_hours) {
|
if (entry.total_hours) {
|
||||||
let hours = entry.total_hours;
|
totalHours += parseFloat(entry.total_hours) || 0;
|
||||||
// Wochenend-Prozentsatz anwenden (nur auf tatsächlich gearbeitete Stunden)
|
|
||||||
const weekendPercentage = getWeekendPercentage(entry.date);
|
|
||||||
if (weekendPercentage >= 100 && hours > 0 && !entry.sick_status) {
|
|
||||||
hours = hours * (weekendPercentage / 100);
|
|
||||||
}
|
|
||||||
totalHours += hours;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Kein Urlaub - zähle nur Arbeitsstunden
|
// Kein Urlaub - zähle nur Arbeitsstunden
|
||||||
|
// WICHTIG: total_hours enthält bereits Wochenend-Prozentsätze (aus timesheet.js)
|
||||||
if (entry.total_hours) {
|
if (entry.total_hours) {
|
||||||
let hours = entry.total_hours;
|
totalHours += parseFloat(entry.total_hours) || 0;
|
||||||
// Wochenend-Prozentsatz anwenden (nur auf tatsächlich gearbeitete Stunden, nicht auf Krankheit)
|
|
||||||
const weekendPercentage = getWeekendPercentage(entry.date);
|
|
||||||
if (weekendPercentage > 0 && hours > 0 && !entry.sick_status) {
|
|
||||||
hours = hours * (1 + weekendPercentage / 100);
|
|
||||||
}
|
|
||||||
totalHours += hours;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
<% }); %>
|
<% }); %>
|
||||||
</select>
|
</select>
|
||||||
<% } %>
|
<% } %>
|
||||||
<a href="/logout" class="btn btn-secondary">Abmelden</a>
|
<a href="/logout" class="btn btn-logout">Abmelden</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
<% }); %>
|
<% }); %>
|
||||||
</select>
|
</select>
|
||||||
<% } %>
|
<% } %>
|
||||||
<a href="/logout" class="btn btn-secondary">Abmelden</a>
|
<a href="/logout" class="btn btn-logout">Abmelden</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -98,6 +98,12 @@
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #2c3e50;
|
color: #2c3e50;
|
||||||
}
|
}
|
||||||
|
.summary-value.overtime-positive {
|
||||||
|
color: #27ae60 !important;
|
||||||
|
}
|
||||||
|
.summary-value.overtime-negative {
|
||||||
|
color: #e74c3c !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -117,7 +123,7 @@
|
|||||||
<% }); %>
|
<% }); %>
|
||||||
</select>
|
</select>
|
||||||
<% } %>
|
<% } %>
|
||||||
<a href="/logout" class="btn btn-secondary">Abmelden</a>
|
<a href="/logout" class="btn btn-logout">Abmelden</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -142,6 +148,10 @@
|
|||||||
<span class="summary-label">Verbleibend:</span>
|
<span class="summary-label">Verbleibend:</span>
|
||||||
<span class="summary-value" id="remainingOvertime">-</span>
|
<span class="summary-value" id="remainingOvertime">-</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="summary-item" id="offsetItem" style="display: none;">
|
||||||
|
<span class="summary-label">Manuelle Korrektur (Verwaltung):</span>
|
||||||
|
<span class="summary-value" id="overtimeOffset">-</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="loading" class="loading">Lade Daten...</div>
|
<div id="loading" class="loading">Lade Daten...</div>
|
||||||
@@ -231,17 +241,38 @@
|
|||||||
totalOvertime += week.overtime_hours;
|
totalOvertime += week.overtime_hours;
|
||||||
totalOvertimeTaken += week.overtime_taken;
|
totalOvertimeTaken += week.overtime_taken;
|
||||||
});
|
});
|
||||||
const remainingOvertime = totalOvertime - totalOvertimeTaken + (data.overtime_offset_hours || 0);
|
const overtimeOffset = data.overtime_offset_hours || 0;
|
||||||
|
const remainingOvertime = totalOvertime - totalOvertimeTaken + overtimeOffset;
|
||||||
|
|
||||||
// Zusammenfassung anzeigen
|
// Zusammenfassung anzeigen
|
||||||
document.getElementById('totalOvertime').textContent =
|
const totalOvertimeEl = document.getElementById('totalOvertime');
|
||||||
|
totalOvertimeEl.textContent =
|
||||||
(totalOvertime >= 0 ? '+' : '') + totalOvertime.toFixed(2) + ' h';
|
(totalOvertime >= 0 ? '+' : '') + totalOvertime.toFixed(2) + ' h';
|
||||||
document.getElementById('totalOvertimeTaken').textContent =
|
totalOvertimeEl.className =
|
||||||
|
'summary-value ' + (totalOvertime >= 0 ? 'overtime-positive' : 'overtime-negative');
|
||||||
|
|
||||||
|
const totalOvertimeTakenEl = document.getElementById('totalOvertimeTaken');
|
||||||
|
totalOvertimeTakenEl.textContent =
|
||||||
totalOvertimeTaken.toFixed(2) + ' h';
|
totalOvertimeTaken.toFixed(2) + ' h';
|
||||||
document.getElementById('remainingOvertime').textContent =
|
totalOvertimeTakenEl.className = 'summary-value overtime-positive';
|
||||||
|
|
||||||
|
const remainingOvertimeEl = document.getElementById('remainingOvertime');
|
||||||
|
remainingOvertimeEl.textContent =
|
||||||
(remainingOvertime >= 0 ? '+' : '') + remainingOvertime.toFixed(2) + ' h';
|
(remainingOvertime >= 0 ? '+' : '') + remainingOvertime.toFixed(2) + ' h';
|
||||||
document.getElementById('remainingOvertime').className =
|
remainingOvertimeEl.className =
|
||||||
'summary-value ' + (remainingOvertime >= 0 ? 'overtime-positive' : 'overtime-negative');
|
'summary-value ' + (remainingOvertime >= 0 ? 'overtime-positive' : 'overtime-negative');
|
||||||
|
|
||||||
|
// Manuelle Korrektur anzeigen (nur wenn vorhanden)
|
||||||
|
const offsetItem = document.getElementById('offsetItem');
|
||||||
|
const offsetValue = document.getElementById('overtimeOffset');
|
||||||
|
if (overtimeOffset !== 0) {
|
||||||
|
offsetValue.textContent = (overtimeOffset >= 0 ? '+' : '') + overtimeOffset.toFixed(2) + ' h';
|
||||||
|
offsetValue.className = 'summary-value ' + (overtimeOffset >= 0 ? 'overtime-positive' : 'overtime-negative');
|
||||||
|
offsetItem.style.display = 'flex';
|
||||||
|
} else {
|
||||||
|
offsetItem.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
summaryBoxEl.style.display = 'block';
|
summaryBoxEl.style.display = 'block';
|
||||||
|
|
||||||
// Tabelle füllen
|
// Tabelle füllen
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
<% }); %>
|
<% }); %>
|
||||||
</select>
|
</select>
|
||||||
<% } %>
|
<% } %>
|
||||||
<a href="/logout" class="btn btn-secondary">Abmelden</a>
|
<a href="/logout" class="btn btn-logout">Abmelden</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user