Verwaltung: Backend auf Lazyloading der Kalenderwochen umgestellt

This commit is contained in:
2026-03-12 18:24:37 +01:00
parent 8595b099db
commit 91603f1617
3 changed files with 544 additions and 380 deletions

View File

@@ -0,0 +1,146 @@
<% employee.weeks.forEach(function(week, weekIndex) { %>
<div class="week-group" data-week-index="<%= weekIndex %>">
<div class="week-header">
<div class="week-info">
<div class="week-dates">
<%
function getCalendarWeek(dateStr) {
const date = new Date(dateStr);
const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
const dayNum = d.getUTCDay() || 7;
d.setUTCDate(d.getUTCDate() + 4 - dayNum);
const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
const weekNo = Math.ceil((((d - yearStart) / 86400000) + 1) / 7);
return weekNo;
}
const calendarWeek = getCalendarWeek(week.week_start);
%>
<strong>Kalenderwoche <%= String(calendarWeek).padStart(2, '0') %>:</strong> <%= new Date(week.week_start).toLocaleDateString('de-DE') %> -
<%= new Date(week.week_end).toLocaleDateString('de-DE') %>
</div>
<div class="group-stats" data-user-id="<%= employee.user.id %>" data-week-start="<%= week.week_start %>" data-week-end="<%= week.week_end %>" style="margin-top: 10px;">
<div class="stats-loading" style="display: inline-block; color: #666;">Lade Statistiken...</div>
</div>
<div class="week-versions-info" style="margin-top: 5px;">
<span class="version-count"><%= week.total_versions %> Version<%= week.total_versions !== 1 ? 'en' : '' %></span>
</div>
<% if (week.has_new_version_after_download) { %>
<div class="new-version-warning" style="margin-top: 10px;">
<strong>ACHTUNG: Neue version eingereicht</strong>
</div>
<% } %>
</div>
<button class="btn btn-secondary btn-sm toggle-versions-btn">
<span class="toggle-icon">▼</span> Versionen
</button>
</div>
<div class="versions-container" style="display: none;">
<table class="timesheet-table versions-table">
<thead>
<tr>
<th>Version</th>
<th>Eingereicht am</th>
<th>Grund</th>
<th>Kommentar</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
<% week.versions.forEach(function(ts) { %>
<tr class="timesheet-row" data-timesheet-id="<%= ts.id %>">
<td>
<span class="version-badge">
Version <%= ts.version || 1 %>
</span>
<% if (ts.pdf_downloaded_at) { %>
<%
let downloadedByName = 'Unbekannt';
if (ts.downloaded_by_firstname && ts.downloaded_by_lastname) {
downloadedByName = `${ts.downloaded_by_firstname} ${ts.downloaded_by_lastname}`;
} else if (ts.downloaded_by_firstname) {
downloadedByName = ts.downloaded_by_firstname;
} else if (ts.downloaded_by_lastname) {
downloadedByName = ts.downloaded_by_lastname;
}
%>
<span class="pdf-downloaded-marker" title="PDF wurde am <%= new Date(ts.pdf_downloaded_at).toLocaleString('de-DE') %> von <%= downloadedByName %> heruntergeladen">
✓ Heruntergeladen von <%= downloadedByName %>
</span>
<% } else { %>
<span class="pdf-not-downloaded-marker">⭕ Nicht heruntergeladen</span>
<% } %>
</td>
<td><%= new Date(ts.submitted_at).toLocaleString('de-DE') %></td>
<td>
<% if (ts.version_reason && ts.version_reason.trim() !== '') { %>
<span style="color: #666; font-size: 13px;" title="<%= ts.version_reason %>">
<%= ts.version_reason.length > 50 ? ts.version_reason.substring(0, 50) + '...' : ts.version_reason %>
</span>
<% } else { %>
<span style="color: #999; font-style: italic;">-</span>
<% } %>
</td>
<td>
<div class="admin-comment-cell" style="display: flex; gap: 8px; align-items: flex-start; min-width: 300px;">
<textarea
class="admin-comment-input"
data-timesheet-id="<%= ts.id %>"
rows="2"
style="flex: 1; min-width: 250px; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-size: 13px; resize: vertical;"
placeholder="Kommentar..."><%= ts.admin_comment || '' %></textarea>
<button
class="btn btn-success btn-sm save-comment-btn"
data-timesheet-id="<%= ts.id %>"
style="white-space: nowrap; padding: 8px 12px;"
title="Kommentar speichern">
💾
</button>
</div>
</td>
<td>
<button class="btn btn-info btn-sm toggle-pdf-btn" data-timesheet-id="<%= ts.id %>">
<span class="arrow-icon">▶</span> PDF anzeigen
</button>
<a href="/api/timesheet/pdf/<%= ts.id %>" class="btn btn-primary btn-sm pdf-download-link" data-timesheet-id="<%= ts.id %>" target="_blank" download>
📥 PDF herunterladen
</a>
</td>
</tr>
<tr class="pdf-preview-row" data-timesheet-id="<%= ts.id %>" style="display: none;">
<td colspan="5">
<div class="pdf-preview-container">
<div class="pdf-preview-header">
<h3>PDF-Vorschau: <%= employee.user.firstname %> <%= employee.user.lastname %> - Version <%= ts.version || 1 %> - <%= new Date(ts.week_start).toLocaleDateString('de-DE') %> bis <%= new Date(ts.week_end).toLocaleDateString('de-DE') %></h3>
<button class="btn btn-secondary btn-sm close-pdf-btn" data-timesheet-id="<%= ts.id %>">
✕ Schließen
</button>
</div>
<div class="pdf-viewer-wrapper">
<iframe
data-src="/api/timesheet/pdf/<%= ts.id %>?inline=true"
class="pdf-iframe"
frameborder="0"
type="application/pdf"
allow="fullscreen">
<p>Ihr Browser unterstützt keine PDF-Vorschau.
<a href="/api/timesheet/pdf/<%= ts.id %>?inline=true" target="_blank">PDF in neuem Tab öffnen</a>
</p>
</iframe>
<div class="pdf-fallback">
<p>PDF wird geladen...</p>
<a href="/api/timesheet/pdf/<%= ts.id %>?inline=true" target="_blank" class="btn btn-primary">
PDF in neuem Tab öffnen
</a>
</div>
</div>
</div>
</td>
</tr>
<% }); %>
</tbody>
</table>
</div>
</div>
<% }); %>