Projektauswertung hinzugefügt
This commit is contained in:
@@ -80,12 +80,15 @@
|
||||
<!-- Rechte Seitenleiste mit Statistiken und Erfassungs-URLs -->
|
||||
<div class="user-stats-panel">
|
||||
<!-- Statistik-Karten -->
|
||||
<div class="stat-card">
|
||||
<div class="stat-card stat-card-overtime">
|
||||
<div class="stat-label" style="display: flex; align-items: center; gap: 5px;">
|
||||
Aktuelle Überstunden
|
||||
<span class="help-icon" onclick="showHelpModal('overtime-help')" style="cursor: pointer; color: #3498db; font-size: 14px; font-weight: bold; width: 18px; height: 18px; border-radius: 50%; background: #e8f4f8; display: inline-flex; align-items: center; justify-content: center; line-height: 1;">?</span>
|
||||
</div>
|
||||
<div class="stat-value" id="currentOvertime">-</div>
|
||||
<div class="stat-value-wrapper">
|
||||
<div class="stat-value stat-value-blurred" id="currentOvertime">-</div>
|
||||
<div class="stat-blur-hint">Zum Anzeigen Maus drüberziehen</div>
|
||||
</div>
|
||||
<div class="stat-unit">Stunden</div>
|
||||
<div style="margin-top: 10px;">
|
||||
<a href="/overtime-breakdown" class="btn btn-primary" style="width: 100%; font-size: 13px; padding: 8px 12px;">Details anzeigen</a>
|
||||
|
||||
185
views/projekt-auswertung.ejs
Normal file
185
views/projekt-auswertung.ejs
Normal file
@@ -0,0 +1,185 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Projektauswertung - Verwaltung</title>
|
||||
<link rel="icon" type="image/png" href="/images/favicon.png">
|
||||
<link rel="stylesheet" href="/css/style.css">
|
||||
<%- include('header') %>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar">
|
||||
<div class="container">
|
||||
<div class="navbar-brand">
|
||||
<img src="/images/header.png" alt="Logo" class="navbar-logo">
|
||||
<h1>Projektauswertung - Verwaltung</h1>
|
||||
</div>
|
||||
<div class="nav-right">
|
||||
<span>Verwaltung: <%= user.firstname %> <%= user.lastname %></span>
|
||||
<% if (user.roles && user.roles.length > 1) { %>
|
||||
<select id="roleSwitcher" class="role-switcher" style="margin-right: 10px; padding: 5px 10px; border-radius: 4px; border: 1px solid #ddd;">
|
||||
<% const roleLabels = { 'mitarbeiter': 'Mitarbeiter', 'verwaltung': 'Verwaltung', 'admin': 'Administrator' }; %>
|
||||
<% user.roles.forEach(function(role) { %>
|
||||
<option value="<%= role %>" <%= user.currentRole === role ? 'selected' : '' %>><%= roleLabels[role] || role %></option>
|
||||
<% }); %>
|
||||
</select>
|
||||
<% } %>
|
||||
<a href="/logout" class="btn btn-logout">Abmelden</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container verwaltung-container">
|
||||
<div class="verwaltung-panel">
|
||||
<h2>Projektauswertung nach Mitarbeitern</h2>
|
||||
<p>Geben Sie eine Projektnummer ein, um alle erfassten Stunden pro Mitarbeiter für dieses Projekt auszuwerten.</p>
|
||||
|
||||
<div style="margin-bottom: 15px;">
|
||||
<a href="/verwaltung" class="btn btn-secondary">« Zurück zur Verwaltung</a>
|
||||
</div>
|
||||
|
||||
<form method="GET" action="/verwaltung/projektauswertung" class="projekt-filter-form" style="margin-bottom: 20px;">
|
||||
<div class="form-group">
|
||||
<label for="projectNumber"><strong>Projektnummer</strong></label>
|
||||
<input
|
||||
type="text"
|
||||
id="projectNumber"
|
||||
name="project"
|
||||
value="<%= projectNumber || '' %>"
|
||||
class="form-control"
|
||||
placeholder="z. B. 12345"
|
||||
required
|
||||
style="max-width: 240px;">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Auswerten</button>
|
||||
</form>
|
||||
|
||||
<% if (projectNumber && !hasResults) { %>
|
||||
<div class="empty-state">
|
||||
<p>Für das Projekt <strong><%= projectNumber %></strong> wurden keine Stunden gefunden.</p>
|
||||
</div>
|
||||
<% } %>
|
||||
|
||||
<% if (hasResults) { %>
|
||||
<h3>Ergebnis für Projekt <span style="white-space: nowrap;"><%= projectNumber %></span></h3>
|
||||
<table class="timesheet-table" style="margin-top: 15px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Mitarbeiter</th>
|
||||
<th style="text-align: right;">Gesamtzeit (h:mm)</th>
|
||||
<th style="width: 1%; white-space: nowrap;"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% results.forEach(function(row) {
|
||||
const activities = (breakdownByUser && breakdownByUser[row.userId]) || [];
|
||||
%>
|
||||
<tr class="employee-summary-row" data-user-id="<%= row.userId %>">
|
||||
<td><strong><%= row.firstname %> <%= row.lastname %></strong></td>
|
||||
<td style="text-align: right;"><%= row.totalHoursFormatted %> h</td>
|
||||
<td style="text-align: right;">
|
||||
<% if (activities.length > 0) { %>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-secondary btn-sm toggle-details-btn"
|
||||
data-user-id="<%= row.userId %>">
|
||||
Details
|
||||
</button>
|
||||
<% } %>
|
||||
</td>
|
||||
</tr>
|
||||
<% if (activities.length > 0) { %>
|
||||
<tr class="employee-details-row" data-user-id="<%= row.userId %>" style="display: none; background-color: #fafafa;">
|
||||
<td colspan="3">
|
||||
<div style="padding: 10px 5px 5px 5px;">
|
||||
<strong>Aufschlüsselung für <%= row.firstname %> <%= row.lastname %>:</strong>
|
||||
<table class="timesheet-table" style="margin-top: 8px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Datum</th>
|
||||
<th>Tätigkeit</th>
|
||||
<th style="text-align: right;">Stunden (h:mm)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% activities.forEach(function(a) { %>
|
||||
<tr>
|
||||
<td><%= a.date %></td>
|
||||
<td><%= a.description && a.description.trim() !== '' ? a.description : '-' %></td>
|
||||
<td style="text-align: right;"><%= a.formatted %> h</td>
|
||||
</tr>
|
||||
<% }); %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<% } %>
|
||||
<% }); %>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th>Gesamt Projektstunden</th>
|
||||
<th style="text-align: right;"><%= totalProjectHoursFormatted %> h</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Rollenwechsel-Handler (analog zu Verwaltung-Ansicht) und Details-Collapsibles
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const roleSwitcher = document.getElementById('roleSwitcher');
|
||||
if (roleSwitcher) {
|
||||
roleSwitcher.addEventListener('change', async function() {
|
||||
const newRole = this.value;
|
||||
try {
|
||||
const response = await fetch('/api/user/switch-role', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ role: newRole })
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
if (newRole === 'admin') {
|
||||
window.location.href = '/admin';
|
||||
} else if (newRole === 'verwaltung') {
|
||||
window.location.href = '/verwaltung';
|
||||
} else {
|
||||
window.location.href = '/dashboard';
|
||||
}
|
||||
} else {
|
||||
alert('Fehler beim Wechseln der Rolle: ' + (result.error || 'Unbekannter Fehler'));
|
||||
this.value = '<%= user.currentRole || "verwaltung" %>';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Rollenwechsel:', error);
|
||||
alert('Fehler beim Wechseln der Rolle');
|
||||
this.value = '<%= user.currentRole || "verwaltung" %>';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Mitarbeiter-Details (Aktivitäten) ein-/ausklappen
|
||||
document.querySelectorAll('.toggle-details-btn').forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
const userId = this.dataset.userId;
|
||||
const row = document.querySelector('.employee-details-row[data-user-id="' + userId + '"]');
|
||||
if (!row) return;
|
||||
const isHidden = row.style.display === 'none' || row.style.display === '';
|
||||
row.style.display = isHidden ? 'table-row' : 'none';
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<%- include('footer') %>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
</div>
|
||||
<div class="nav-right">
|
||||
<span>Verwaltung: <%= user.firstname %> <%= user.lastname %></span>
|
||||
<a href="/verwaltung/projektauswertung" class="btn btn-secondary" style="margin-right: 10px;">Projektauswertung</a>
|
||||
<% if (user.roles && user.roles.length > 1) { %>
|
||||
<select id="roleSwitcher" class="role-switcher" style="margin-right: 10px; padding: 5px 10px; border-radius: 4px; border: 1px solid #ddd;">
|
||||
<% const roleLabels = { 'mitarbeiter': 'Mitarbeiter', 'verwaltung': 'Verwaltung', 'admin': 'Administrator' }; %>
|
||||
|
||||
Reference in New Issue
Block a user