feat: refactor CSV filter & export section and enhance row styling in monthly view
All checks were successful
Build and Push Docker Image / build (push) Successful in 38s
All checks were successful
Build and Push Docker Image / build (push) Successful in 38s
This commit is contained in:
@@ -418,128 +418,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CSV Filter & Export Section (Collapsible) -->
|
||||
<details class="mt-4 pt-4 border-t border-gray-700">
|
||||
<summary class="cursor-pointer text-gray-300 hover:text-gray-100 font-medium flex items-center gap-2 select-none">
|
||||
<i data-lucide="chevron-down" class="w-5 h-5 transition-transform details-chevron"></i>
|
||||
<i data-lucide="filter" class="w-5 h-5 text-blue-400"></i>
|
||||
<span>CSV Filter & Export</span>
|
||||
</summary>
|
||||
<div class="mt-4 flex flex-wrap gap-4 items-end">
|
||||
<div class="flex-1 min-w-[200px]">
|
||||
<label for="filterFrom" class="block text-sm font-medium text-gray-300 mb-1">Von</label>
|
||||
<input type="text" id="filterFrom"
|
||||
class="w-full px-4 py-2 border border-gray-600 bg-gray-700 text-gray-100 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||
placeholder="DD.MM.YYYY">
|
||||
</div>
|
||||
|
||||
<div class="flex-1 min-w-[200px]">
|
||||
<label for="filterTo" class="block text-sm font-medium text-gray-300 mb-1">Bis</label>
|
||||
<input type="text" id="filterTo"
|
||||
class="w-full px-4 py-2 border border-gray-600 bg-gray-700 text-gray-100 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||
placeholder="DD.MM.YYYY">
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2">
|
||||
<button id="btnFilter"
|
||||
class="inline-flex items-center justify-center w-10 h-10 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-all duration-200 shadow-sm" title="Filtern">
|
||||
<i data-lucide="search" class="w-5 h-5"></i>
|
||||
</button>
|
||||
|
||||
<button id="btnClearFilter"
|
||||
class="inline-flex items-center justify-center w-10 h-10 bg-gray-700 text-gray-100 rounded-lg hover:bg-gray-600 transition-all duration-200 shadow-sm" title="Filter zurücksetzen">
|
||||
<i data-lucide="x-circle" class="w-5 h-5"></i>
|
||||
</button>
|
||||
|
||||
<button id="btnExport"
|
||||
class="inline-flex items-center justify-center w-10 h-10 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-all duration-200 shadow-sm" title="Export (alle)">
|
||||
<i data-lucide="download" class="w-5 h-5"></i>
|
||||
</button>
|
||||
|
||||
<button id="btnExportDeviations"
|
||||
class="inline-flex items-center justify-center w-10 h-10 bg-amber-600 text-white rounded-lg hover:bg-amber-700 transition-all duration-200 shadow-sm" title="Export (nur Abweichungen)">
|
||||
<i data-lucide="alert-circle" class="w-5 h-5"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<!-- Settings Section (Collapsible) -->
|
||||
<details class="mt-4 pt-4 border-t border-gray-700">
|
||||
<summary class="cursor-pointer text-gray-300 hover:text-gray-100 font-medium flex items-center gap-2 select-none">
|
||||
<i data-lucide="chevron-down" class="w-5 h-5 transition-transform details-chevron"></i>
|
||||
<i data-lucide="settings" class="w-5 h-5 text-purple-400"></i>
|
||||
<span>Einstellungen</span>
|
||||
</summary>
|
||||
<div class="mt-4 mb-2 text-right">
|
||||
<span id="versionInfo" class="text-xs text-gray-500 font-mono"></span>
|
||||
</div>
|
||||
<div class="mt-4 flex flex-wrap gap-4 items-center">
|
||||
<div class="flex-1 min-w-[200px]">
|
||||
<label for="employeeName" class="block text-sm font-medium text-gray-300 mb-1">Mitarbeitername</label>
|
||||
<input type="text" id="employeeName" placeholder="Max Mustermann"
|
||||
class="w-full px-4 py-2 border border-gray-600 bg-gray-700 text-gray-100 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent">
|
||||
</div>
|
||||
<div class="flex-1 min-w-[200px]">
|
||||
<label for="employeeId" class="block text-sm font-medium text-gray-300 mb-1">Personalnummer</label>
|
||||
<input type="text" id="employeeId" placeholder="12345"
|
||||
class="w-full px-4 py-2 border border-gray-600 bg-gray-700 text-gray-100 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 flex flex-wrap gap-4 items-center">
|
||||
<div class="flex-1 min-w-[200px]">
|
||||
<label for="bundeslandSelect" class="block text-sm font-medium text-gray-300 mb-1">Bundesland (Feiertage)</label>
|
||||
<select id="bundeslandSelect"
|
||||
class="w-full px-4 py-2 border border-gray-600 bg-gray-700 text-gray-100 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent">
|
||||
<option value="BW">Baden-Württemberg</option>
|
||||
<option value="BY">Bayern</option>
|
||||
<option value="BE">Berlin</option>
|
||||
<option value="BB">Brandenburg</option>
|
||||
<option value="HB">Bremen</option>
|
||||
<option value="HH">Hamburg</option>
|
||||
<option value="HE">Hessen</option>
|
||||
<option value="MV">Mecklenburg-Vorpommern</option>
|
||||
<option value="NI">Niedersachsen</option>
|
||||
<option value="NW">Nordrhein-Westfalen</option>
|
||||
<option value="RP">Rheinland-Pfalz</option>
|
||||
<option value="SL">Saarland</option>
|
||||
<option value="SN">Sachsen</option>
|
||||
<option value="ST">Sachsen-Anhalt</option>
|
||||
<option value="SH">Schleswig-Holstein</option>
|
||||
<option value="TH">Thüringen</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="flex-1 min-w-[200px]">
|
||||
<label for="vacationDaysInput" class="block text-sm font-medium text-gray-300 mb-1">Urlaubstage pro Jahr</label>
|
||||
<input type="number" id="vacationDaysInput" min="0" max="50" value="30"
|
||||
class="w-full px-4 py-2 border border-gray-600 bg-gray-700 text-gray-100 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Database Export/Import -->
|
||||
<div class="mt-6 pt-4 border-t border-gray-600">
|
||||
<h3 class="text-sm font-semibold text-gray-300 mb-3 flex items-center gap-2">
|
||||
<i data-lucide="database" class="w-4 h-4 text-purple-400"></i>
|
||||
Datenbank Verwaltung
|
||||
</h3>
|
||||
<div class="flex flex-wrap gap-3">
|
||||
<button id="btnExportDB" class="flex items-center gap-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition-colors">
|
||||
<i data-lucide="download" class="w-4 h-4"></i>
|
||||
Datenbank exportieren
|
||||
</button>
|
||||
<button id="btnImportDB" class="flex items-center gap-2 px-4 py-2 bg-green-600 hover:bg-green-700 text-white rounded-lg transition-colors">
|
||||
<i data-lucide="upload" class="w-4 h-4"></i>
|
||||
Datenbank importieren
|
||||
</button>
|
||||
<input type="file" id="importDBFile" accept=".json" class="hidden">
|
||||
</div>
|
||||
<p class="text-xs text-gray-500 mt-2">
|
||||
<i data-lucide="info" class="w-3 h-3 inline"></i>
|
||||
Export erstellt eine JSON-Datei mit allen Einträgen und Einstellungen. Import überschreibt alle vorhandenen Daten.
|
||||
</p>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
|
||||
<!-- Statistics -->
|
||||
@@ -600,7 +478,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Total Balance -->
|
||||
<div class="glass-card rounded-xl p-6 border-2 border-purple-500/30 shadow-lg shadow-purple-500/20">
|
||||
<div class="glass-card rounded-xl p-6">
|
||||
<div class="flex justify-between items-center">
|
||||
<div>
|
||||
<div class="text-sm text-gray-300 mb-2 uppercase tracking-wide font-semibold flex items-center gap-1">
|
||||
@@ -625,14 +503,12 @@
|
||||
<!-- Left: Action Buttons (hidden on mobile, shown on desktop at start) -->
|
||||
<div class="hidden lg:flex gap-3 flex-wrap justify-start order-2 lg:order-1">
|
||||
<button id="btnToggleBulkEdit"
|
||||
class="btn-elevated inline-flex items-center gap-2 px-5 py-3 bg-gradient-to-r from-gray-700 to-gray-600 text-gray-100 rounded-xl font-semibold" title="Mehrfachauswahl aktivieren">
|
||||
class="btn-elevated inline-flex items-center justify-center w-12 h-12 bg-gradient-to-r from-gray-700 to-gray-600 text-gray-100 rounded-xl font-semibold" title="Mehrfachauswahl aktivieren">
|
||||
<i data-lucide="check-square" class="w-5 h-5"></i>
|
||||
<span>Auswahl</span>
|
||||
</button>
|
||||
<button id="btnAutoFill"
|
||||
class="btn-elevated inline-flex items-center gap-2 px-5 py-3 bg-gradient-to-r from-indigo-600 to-indigo-500 text-white rounded-xl font-semibold" title="Monat ausfüllen (8h)">
|
||||
class="btn-elevated inline-flex items-center justify-center w-12 h-12 bg-gradient-to-r from-indigo-600 to-indigo-500 text-white rounded-xl font-semibold" title="Monat ausfüllen (8h)">
|
||||
<i data-lucide="calendar-check" class="w-5 h-5"></i>
|
||||
<span>Ausfüllen</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -663,16 +539,14 @@
|
||||
<!-- Mobile Action Buttons (shown only on mobile, below navigation) -->
|
||||
<div class="flex lg:hidden gap-3 flex-wrap justify-center order-3">
|
||||
<button onclick="document.getElementById('btnToggleBulkEdit').click()"
|
||||
class="btn-elevated inline-flex items-center gap-2 px-5 py-3 bg-gradient-to-r from-gray-700 to-gray-600 text-gray-100 rounded-xl font-semibold" title="Mehrfachauswahl aktivieren">
|
||||
class="btn-elevated inline-flex items-center justify-center w-12 h-12 bg-gradient-to-r from-gray-700 to-gray-600 text-gray-100 rounded-xl font-semibold" title="Mehrfachauswahl aktivieren">
|
||||
<i data-lucide="check-square" class="w-5 h-5"></i>
|
||||
<span>Auswahl</span>
|
||||
</button>
|
||||
<button onclick="document.getElementById('btnAutoFill').click()"
|
||||
class="btn-elevated inline-flex items-center gap-2 px-5 py-3 bg-gradient-to-r from-indigo-600 to-indigo-500 text-white rounded-xl font-semibold" title="Monat ausfüllen (8h)">
|
||||
class="btn-elevated inline-flex items-center justify-center w-12 h-12 bg-gradient-to-r from-indigo-600 to-indigo-500 text-white rounded-xl font-semibold" title="Monat ausfüllen (8h)">
|
||||
<i data-lucide="calendar-check" class="w-5 h-5"></i>
|
||||
<span>Ausfüllen</span>
|
||||
</button>
|
||||
<button onclick="document.getElementById('btnExportPDF').click()"
|
||||
<button id="btnExportPDFMobile" onclick="document.getElementById('btnExportPDF').click()"
|
||||
class="btn-elevated inline-flex items-center gap-2 px-5 py-3 bg-gradient-to-r from-red-600 to-red-500 text-white rounded-xl font-semibold" title="Monat als PDF exportieren">
|
||||
<i data-lucide="file-text" class="w-5 h-5"></i>
|
||||
<span>PDF Export</span>
|
||||
@@ -753,22 +627,22 @@
|
||||
<div class="premium-table rounded-xl overflow-hidden border border-gray-700/50 shadow-2xl">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full">
|
||||
<thead class="bg-gradient-to-r from-gray-800 to-gray-700 border-b-2 border-blue-500/30">
|
||||
<thead class="bg-gradient-to-r from-slate-800/80 to-slate-700/80 backdrop-blur-sm border-b border-blue-500/20">
|
||||
<tr>
|
||||
<th id="checkboxHeader" class="hidden px-2 py-4 text-center text-xs font-bold text-gray-300 uppercase tracking-wider">
|
||||
<input type="checkbox" id="masterCheckbox" class="w-5 h-5 text-blue-600 bg-gray-700 border-gray-600 rounded focus:ring-blue-500" title="Alle auswählen/abwählen">
|
||||
<th id="checkboxHeader" class="hidden px-3 py-4 text-center text-xs font-semibold text-gray-300 uppercase tracking-wider">
|
||||
<input type="checkbox" id="masterCheckbox" class="w-4 h-4 text-blue-500 bg-gray-700/50 border-gray-600 rounded focus:ring-2 focus:ring-blue-500/50" title="Alle auswählen/abwählen">
|
||||
</th>
|
||||
<th class="px-2 py-4 text-left text-xs font-bold text-gray-300 uppercase tracking-wider">Tag</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-bold text-gray-300 uppercase tracking-wider">Datum</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-bold text-gray-300 uppercase tracking-wider">Start</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-bold text-gray-300 uppercase tracking-wider">Ende</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-bold text-gray-300 uppercase tracking-wider">Pause (Min)</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-bold text-gray-300 uppercase tracking-wider">Netto (Std)</th>
|
||||
<th class="px-6 py-4 text-center text-xs font-bold text-gray-300 uppercase tracking-wider">Ort</th>
|
||||
<th class="px-6 py-4 text-center text-xs font-bold text-gray-300 uppercase tracking-wider">Action</th>
|
||||
<th class="px-3 py-4 text-left text-xs font-semibold text-gray-300 uppercase tracking-wider">Tag</th>
|
||||
<th class="px-4 py-4 text-left text-xs font-semibold text-gray-300 uppercase tracking-wider">Datum</th>
|
||||
<th class="px-4 py-4 text-left text-xs font-semibold text-gray-300 uppercase tracking-wider">Start</th>
|
||||
<th class="px-4 py-4 text-left text-xs font-semibold text-gray-300 uppercase tracking-wider">Ende</th>
|
||||
<th class="px-4 py-4 text-left text-xs font-semibold text-gray-300 uppercase tracking-wider">Pause</th>
|
||||
<th class="px-4 py-4 text-left text-xs font-semibold text-gray-300 uppercase tracking-wider">Netto</th>
|
||||
<th class="px-4 py-4 text-center text-xs font-semibold text-gray-300 uppercase tracking-wider">Ort</th>
|
||||
<th class="px-4 py-4 text-center text-xs font-semibold text-gray-300 uppercase tracking-wider">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="entriesTableBody" class="divide-y divide-gray-700/50">
|
||||
<tbody id="entriesTableBody" class="divide-y divide-gray-600/50">
|
||||
<!-- Entries will be inserted here dynamically -->
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -881,6 +755,132 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CSV Filter & Export Section (Collapsible) -->
|
||||
<div class="container mx-auto px-4 py-8 max-w-7xl">
|
||||
<details class="premium-card rounded-xl p-6">
|
||||
<summary class="cursor-pointer text-gray-300 hover:text-gray-100 font-medium flex items-center gap-2 select-none">
|
||||
<i data-lucide="chevron-down" class="w-5 h-5 transition-transform details-chevron"></i>
|
||||
<i data-lucide="filter" class="w-5 h-5 text-blue-400"></i>
|
||||
<span>CSV Filter & Export</span>
|
||||
</summary>
|
||||
<div class="mt-4 flex flex-wrap gap-4 items-end">
|
||||
<div class="flex-1 min-w-[200px]">
|
||||
<label for="filterFrom" class="block text-sm font-medium text-gray-300 mb-1">Von</label>
|
||||
<input type="text" id="filterFrom"
|
||||
class="w-full px-4 py-2 border border-gray-600 bg-gray-700 text-gray-100 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||
placeholder="DD.MM.YYYY">
|
||||
</div>
|
||||
|
||||
<div class="flex-1 min-w-[200px]">
|
||||
<label for="filterTo" class="block text-sm font-medium text-gray-300 mb-1">Bis</label>
|
||||
<input type="text" id="filterTo"
|
||||
class="w-full px-4 py-2 border border-gray-600 bg-gray-700 text-gray-100 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||
placeholder="DD.MM.YYYY">
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2">
|
||||
<button id="btnFilter"
|
||||
class="inline-flex items-center justify-center w-10 h-10 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-all duration-200 shadow-sm" title="Filtern">
|
||||
<i data-lucide="search" class="w-5 h-5"></i>
|
||||
</button>
|
||||
|
||||
<button id="btnClearFilter"
|
||||
class="inline-flex items-center justify-center w-10 h-10 bg-gray-700 text-gray-100 rounded-lg hover:bg-gray-600 transition-all duration-200 shadow-sm" title="Filter zurücksetzen">
|
||||
<i data-lucide="x-circle" class="w-5 h-5"></i>
|
||||
</button>
|
||||
|
||||
<button id="btnExport"
|
||||
class="inline-flex items-center justify-center w-10 h-10 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-all duration-200 shadow-sm" title="Export (alle)">
|
||||
<i data-lucide="download" class="w-5 h-5"></i>
|
||||
</button>
|
||||
|
||||
<button id="btnExportDeviations"
|
||||
class="inline-flex items-center justify-center w-10 h-10 bg-amber-600 text-white rounded-lg hover:bg-amber-700 transition-all duration-200 shadow-sm" title="Export (nur Abweichungen)">
|
||||
<i data-lucide="alert-circle" class="w-5 h-5"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
|
||||
<!-- Settings Section (Collapsible) -->
|
||||
<div class="container mx-auto px-4 pb-8 max-w-7xl">
|
||||
<details class="premium-card rounded-xl p-6">
|
||||
<summary class="cursor-pointer text-gray-300 hover:text-gray-100 font-medium flex items-center gap-2 select-none">
|
||||
<i data-lucide="chevron-down" class="w-5 h-5 transition-transform details-chevron"></i>
|
||||
<i data-lucide="settings" class="w-5 h-5 text-purple-400"></i>
|
||||
<span>Einstellungen</span>
|
||||
</summary>
|
||||
<div class="mt-4 mb-2 text-right">
|
||||
<span id="versionInfo" class="text-xs text-gray-500 font-mono"></span>
|
||||
</div>
|
||||
<div class="mt-4 flex flex-wrap gap-4 items-center">
|
||||
<div class="flex-1 min-w-[200px]">
|
||||
<label for="employeeName" class="block text-sm font-medium text-gray-300 mb-1">Mitarbeitername</label>
|
||||
<input type="text" id="employeeName" placeholder="Max Mustermann"
|
||||
class="w-full px-4 py-2 border border-gray-600 bg-gray-700 text-gray-100 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent">
|
||||
</div>
|
||||
<div class="flex-1 min-w-[200px]">
|
||||
<label for="employeeId" class="block text-sm font-medium text-gray-300 mb-1">Personalnummer</label>
|
||||
<input type="text" id="employeeId" placeholder="12345"
|
||||
class="w-full px-4 py-2 border border-gray-600 bg-gray-700 text-gray-100 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 flex flex-wrap gap-4 items-center">
|
||||
<div class="flex-1 min-w-[200px]">
|
||||
<label for="bundeslandSelect" class="block text-sm font-medium text-gray-300 mb-1">Bundesland (Feiertage)</label>
|
||||
<select id="bundeslandSelect"
|
||||
class="w-full px-4 py-2 border border-gray-600 bg-gray-700 text-gray-100 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent">
|
||||
<option value="BW">Baden-Württemberg</option>
|
||||
<option value="BY">Bayern</option>
|
||||
<option value="BE">Berlin</option>
|
||||
<option value="BB">Brandenburg</option>
|
||||
<option value="HB">Bremen</option>
|
||||
<option value="HH">Hamburg</option>
|
||||
<option value="HE">Hessen</option>
|
||||
<option value="MV">Mecklenburg-Vorpommern</option>
|
||||
<option value="NI">Niedersachsen</option>
|
||||
<option value="NW">Nordrhein-Westfalen</option>
|
||||
<option value="RP">Rheinland-Pfalz</option>
|
||||
<option value="SL">Saarland</option>
|
||||
<option value="SN">Sachsen</option>
|
||||
<option value="ST">Sachsen-Anhalt</option>
|
||||
<option value="SH">Schleswig-Holstein</option>
|
||||
<option value="TH">Thüringen</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="flex-1 min-w-[200px]">
|
||||
<label for="vacationDaysInput" class="block text-sm font-medium text-gray-300 mb-1">Urlaubstage pro Jahr</label>
|
||||
<input type="number" id="vacationDaysInput" min="0" max="50" value="30"
|
||||
class="w-full px-4 py-2 border border-gray-600 bg-gray-700 text-gray-100 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Database Export/Import -->
|
||||
<div class="mt-6 pt-4 border-t border-gray-600">
|
||||
<h3 class="text-sm font-semibold text-gray-300 mb-3 flex items-center gap-2">
|
||||
<i data-lucide="database" class="w-4 h-4 text-purple-400"></i>
|
||||
Datenbank Verwaltung
|
||||
</h3>
|
||||
<div class="flex flex-wrap gap-3">
|
||||
<button id="btnExportDB" class="flex items-center gap-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition-colors">
|
||||
<i data-lucide="download" class="w-4 h-4"></i>
|
||||
Datenbank exportieren
|
||||
</button>
|
||||
<button id="btnImportDB" class="flex items-center gap-2 px-4 py-2 bg-green-600 hover:bg-green-700 text-white rounded-lg transition-colors">
|
||||
<i data-lucide="upload" class="w-4 h-4"></i>
|
||||
Datenbank importieren
|
||||
</button>
|
||||
<input type="file" id="importDBFile" accept=".json" class="hidden">
|
||||
</div>
|
||||
<p class="text-xs text-gray-500 mt-2">
|
||||
<i data-lucide="info" class="w-3 h-3 inline"></i>
|
||||
Export erstellt eine JSON-Datei mit allen Einträgen und Einstellungen. Import überschreibt alle vorhandenen Daten.
|
||||
</p>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
|
||||
<!-- Flatpickr JS -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/flatpickr/dist/l10n/de.js"></script>
|
||||
|
||||
@@ -1015,15 +1015,15 @@ function renderMonthlyView(entries) {
|
||||
const entryType = entry.entryType || 'work';
|
||||
|
||||
// Row color based on entry type and location
|
||||
let rowClass = 'hover:bg-gray-700';
|
||||
let rowClass = 'hover:bg-slate-600/40 transition-colors';
|
||||
if (entryType === 'vacation') {
|
||||
rowClass = 'hover:bg-yellow-900 bg-yellow-950';
|
||||
rowClass = 'hover:bg-yellow-800/50 bg-yellow-900/30 transition-colors';
|
||||
} else if (entryType === 'flextime') {
|
||||
rowClass = 'hover:bg-cyan-900 bg-cyan-950';
|
||||
rowClass = 'hover:bg-cyan-800/50 bg-cyan-900/30 transition-colors';
|
||||
} else if (location === 'home') {
|
||||
rowClass = 'hover:bg-green-900 bg-green-950';
|
||||
rowClass = 'hover:bg-green-800/50 bg-green-900/30 transition-colors';
|
||||
} else if (weekend) {
|
||||
rowClass = 'hover:bg-gray-700 bg-gray-700';
|
||||
rowClass = 'hover:bg-slate-600/50 bg-slate-700/30 transition-colors';
|
||||
}
|
||||
|
||||
|
||||
@@ -1041,13 +1041,13 @@ function renderMonthlyView(entries) {
|
||||
if (entryType === 'vacation') {
|
||||
displayIcon = '<i data-lucide="plane" class="w-4 h-4 inline"></i>';
|
||||
displayText = 'Urlaub';
|
||||
displayTimes = `<td class="px-6 py-4 whitespace-nowrap text-sm text-center text-gray-400" colspan="3">
|
||||
displayTimes = `<td class="px-4 py-3 whitespace-nowrap text-sm text-center text-gray-400" colspan="3">
|
||||
<span class="italic">Urlaub</span>
|
||||
</td>`;
|
||||
} else if (entryType === 'flextime') {
|
||||
displayIcon = '<i data-lucide="clock" class="w-4 h-4 inline"></i>';
|
||||
displayText = 'Gleitzeit';
|
||||
displayTimes = `<td class="px-6 py-4 whitespace-nowrap text-sm text-center text-gray-400" colspan="3">
|
||||
displayTimes = `<td class="px-4 py-3 whitespace-nowrap text-sm text-center text-gray-400" colspan="3">
|
||||
<span class="italic">Gleittag (8h)</span>
|
||||
</td>`;
|
||||
} else {
|
||||
@@ -1063,15 +1063,15 @@ function renderMonthlyView(entries) {
|
||||
: entry.endTime;
|
||||
|
||||
displayTimes = `
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-100 editable-cell"
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-100 editable-cell"
|
||||
data-field="startTime" data-id="${entry.id}" data-value="${entry.startTime}">
|
||||
${entry.startTime}
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-100 ${isTimerRunning ? '' : 'editable-cell'}"
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-100 ${isTimerRunning ? '' : 'editable-cell'}"
|
||||
${isTimerRunning ? '' : `data-field="endTime" data-id="${entry.id}" data-value="${entry.endTime}"`}>
|
||||
${endTimeDisplay}
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-100 ${isTimerRunning ? '' : 'editable-cell'}"
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-100 ${isTimerRunning ? '' : 'editable-cell'}"
|
||||
${isTimerRunning ? `id="current-day-pause"` : `data-field="pauseMinutes" data-id="${entry.id}" data-value="${entry.pauseMinutes}"`}>
|
||||
${entry.pauseMinutes}
|
||||
</td>`;
|
||||
@@ -1079,28 +1079,28 @@ function renderMonthlyView(entries) {
|
||||
|
||||
// Checkbox column (always present for consistent layout)
|
||||
const checkboxCell = bulkEditMode ? `
|
||||
<td class="px-2 py-4 whitespace-nowrap text-center">
|
||||
<input type="checkbox" class="entry-checkbox w-5 h-5 text-blue-600 bg-gray-700 border-gray-600 rounded focus:ring-blue-500"
|
||||
<td class="px-2 py-3 whitespace-nowrap text-center">
|
||||
<input type="checkbox" class="entry-checkbox w-4 h-4 text-blue-600 bg-gray-700 border-gray-600 rounded focus:ring-blue-500"
|
||||
data-id="${entry.id}" ${selectedEntries.has(entry.id) ? 'checked' : ''}>
|
||||
</td>
|
||||
` : '<td class="hidden"></td>';
|
||||
|
||||
row.innerHTML = checkboxCell + `
|
||||
<td class="px-2 py-4 whitespace-nowrap text-sm font-medium ${weekend ? 'text-blue-400' : 'text-gray-100'}">${dayOfWeek}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-100">${formatDateDisplay(entry.date)}</td>
|
||||
<td class="px-2 py-3 whitespace-nowrap text-sm font-medium ${weekend ? 'text-blue-400' : 'text-gray-100'}">${dayOfWeek}</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-100">${formatDateDisplay(entry.date)}</td>
|
||||
${displayTimes}
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm font-semibold text-gray-100" id="${isToday ? 'current-day-net-hours' : ''}">${entry.netHours.toFixed(2)}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-center text-gray-100">
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm font-semibold text-gray-100" id="${isToday ? 'current-day-net-hours' : ''}">${entry.netHours.toFixed(2)}</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-center text-gray-100">
|
||||
<span class="text-lg">${displayIcon}</span> ${displayText}
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-center">
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-center">
|
||||
<div class="flex gap-2 justify-center">
|
||||
${entryType === 'work' ? `
|
||||
<button class="btn-edit inline-flex items-center justify-center w-8 h-8 text-blue-500 hover:text-blue-600 hover:bg-blue-500/10 rounded transition-all" data-id="${entry.id}" title="Bearbeiten">
|
||||
<button class="btn-edit inline-flex items-center justify-center w-8 h-8 text-blue-400/80 hover:text-blue-400 hover:bg-blue-500/10 rounded transition-all" data-id="${entry.id}" title="Bearbeiten">
|
||||
<i data-lucide="pencil" class="w-4 h-4"></i>
|
||||
</button>
|
||||
` : ''}
|
||||
<button class="btn-delete inline-flex items-center justify-center w-8 h-8 text-red-500 hover:text-red-600 hover:bg-red-500/10 rounded transition-all" data-id="${entry.id}" title="Löschen">
|
||||
<button class="btn-delete inline-flex items-center justify-center w-8 h-8 text-red-400/80 hover:text-red-400 hover:bg-red-500/10 rounded transition-all" data-id="${entry.id}" title="Löschen">
|
||||
<i data-lucide="trash-2" class="w-4 h-4"></i>
|
||||
</button>
|
||||
</div>
|
||||
@@ -1113,8 +1113,8 @@ function renderMonthlyView(entries) {
|
||||
|
||||
// Don't mark future days as red, only past workdays without entries
|
||||
const isFutureDay = dateObj > today;
|
||||
let emptyRowClass = weekend ? 'hover:bg-gray-700 bg-gray-700' :
|
||||
isFutureDay ? 'hover:bg-gray-700' : 'hover:bg-gray-700 bg-red-950/40';
|
||||
let emptyRowClass = weekend ? 'hover:bg-slate-600/50 bg-slate-700/30 transition-colors' :
|
||||
isFutureDay ? 'hover:bg-slate-600/40 transition-colors' : 'hover:bg-slate-600/40 bg-red-900/30 transition-colors';
|
||||
|
||||
|
||||
row.className = emptyRowClass;
|
||||
@@ -1127,29 +1127,29 @@ function renderMonthlyView(entries) {
|
||||
|
||||
// Checkbox cell for empty days (in bulk edit mode)
|
||||
const checkboxCell = bulkEditMode ? `
|
||||
<td class="px-2 py-4 whitespace-nowrap text-center">
|
||||
<input type="checkbox" class="empty-day-checkbox w-5 h-5 text-blue-600 bg-gray-700 border-gray-600 rounded focus:ring-blue-500"
|
||||
<td class="px-2 py-3 whitespace-nowrap text-center">
|
||||
<input type="checkbox" class="empty-day-checkbox w-4 h-4 text-blue-600 bg-gray-700 border-gray-600 rounded focus:ring-blue-500"
|
||||
data-date="${dateISO}" ${selectedEntries.has(dateISO) ? 'checked' : ''}>
|
||||
</td>
|
||||
` : '<td class="hidden"></td>';
|
||||
const colspan = bulkEditMode ? '5' : '5';
|
||||
|
||||
row.innerHTML = checkboxCell + `
|
||||
<td class="px-2 py-4 whitespace-nowrap text-sm font-medium ${weekend ? 'text-blue-400' : 'text-gray-100'}">${dayOfWeek}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-100">${formatDateDisplay(dateISO)}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm ${holidayName ? 'text-blue-400 font-semibold' : 'text-gray-500'}" colspan="${colspan}">
|
||||
<td class="px-2 py-3 whitespace-nowrap text-sm font-medium ${weekend ? 'text-blue-400' : 'text-gray-100'}">${dayOfWeek}</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-100">${formatDateDisplay(dateISO)}</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm ${holidayName ? 'text-blue-400 font-semibold' : 'text-gray-500'}" colspan="${colspan}">
|
||||
<span class="italic">${displayText}</span>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-center">
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-center">
|
||||
<div class="flex gap-1 justify-center">
|
||||
<button class="btn-add-work inline-flex items-center justify-center w-7 h-7 text-indigo-500 hover:text-indigo-600 hover:bg-indigo-500/10 rounded transition-all" data-date="${dateISO}" title="Arbeit eintragen">
|
||||
<button class="btn-add-work inline-flex items-center justify-center w-7 h-7 text-indigo-400/80 hover:text-indigo-400 hover:bg-indigo-500/10 rounded transition-all" data-date="${dateISO}" title="Arbeit eintragen">
|
||||
<i data-lucide="plus" class="w-4 h-4"></i>
|
||||
</button>
|
||||
${!weekend ? `
|
||||
<button class="btn-add-vacation inline-flex items-center justify-center w-7 h-7 text-amber-500 hover:text-amber-600 hover:bg-amber-500/10 rounded transition-all" data-date="${dateISO}" title="Urlaub eintragen">
|
||||
<button class="btn-add-vacation inline-flex items-center justify-center w-7 h-7 text-amber-400/80 hover:text-amber-400 hover:bg-amber-500/10 rounded transition-all" data-date="${dateISO}" title="Urlaub eintragen">
|
||||
<i data-lucide="plane" class="w-4 h-4"></i>
|
||||
</button>
|
||||
<button class="btn-add-flextime inline-flex items-center justify-center w-7 h-7 text-cyan-500 hover:text-cyan-600 hover:bg-cyan-500/10 rounded transition-all" data-date="${dateISO}" title="Gleitzeit eintragen">
|
||||
<button class="btn-add-flextime inline-flex items-center justify-center w-7 h-7 text-cyan-400/80 hover:text-cyan-400 hover:bg-cyan-500/10 rounded transition-all" data-date="${dateISO}" title="Gleitzeit eintragen">
|
||||
<i data-lucide="clock" class="w-4 h-4"></i>
|
||||
</button>
|
||||
` : ''}
|
||||
@@ -1290,10 +1290,14 @@ async function loadMonthlyView() {
|
||||
(displayYear === today.getFullYear() && displayMonth >= today.getMonth());
|
||||
|
||||
const pdfButton = document.getElementById('btnExportPDF');
|
||||
const pdfButtonMobile = document.getElementById('btnExportPDFMobile');
|
||||
|
||||
if (isCurrentOrFutureMonth) {
|
||||
pdfButton.style.display = 'none';
|
||||
if (pdfButtonMobile) pdfButtonMobile.style.display = 'none';
|
||||
} else {
|
||||
pdfButton.style.display = '';
|
||||
if (pdfButtonMobile) pdfButtonMobile.style.display = '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user