|
|
|
@ -42,7 +42,7 @@ |
|
|
|
<% if remaining.present? || soll.present? || weekly.present? %> |
|
|
|
<tr> |
|
|
|
<td><%= typ.capitalize %></td> |
|
|
|
<td><%= art %></td> |
|
|
|
<td><%= art.capitalize %></td> |
|
|
|
<td><%= remaining ? "#{remaining / 60} h #{remaining % 60} min" : "—" %></td> |
|
|
|
<td><%= soll || "—" %> h</td> |
|
|
|
<td><%= weekly || "—" %> h/Woche</td> |
|
|
|
@ -59,19 +59,23 @@ |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="mb-3"> |
|
|
|
<input type="text" id="entryFilter" class="form-control" placeholder="🔍 Filter nach Datum, Typ, Art …"> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 📋 Tabelle aller Einträge --> |
|
|
|
<div class="mb-5"> |
|
|
|
<h4 class="mb-3">📋 Einträge</h4> |
|
|
|
<div class="table-responsive"> |
|
|
|
<table class="table table-striped table-hover"> |
|
|
|
<table class="table table-striped table-hover" id="entriesTable"> |
|
|
|
<thead> |
|
|
|
<tr> |
|
|
|
<th>Datum</th> |
|
|
|
<th>Zeit</th> |
|
|
|
<th>Typ</th> |
|
|
|
<th>Art</th> |
|
|
|
<th>Kilometer</th> |
|
|
|
<th>Pauschale</th> |
|
|
|
<th data-sort-index="0" class="sortable">Datum</th> |
|
|
|
<th data-sort-index="1" class="sortable">Zeit</th> |
|
|
|
<th data-sort-index="2" class="sortable">Typ</th> |
|
|
|
<th data-sort-index="3" class="sortable">Art</th> |
|
|
|
<th data-sort-index="4" class="sortable">Kilometer</th> |
|
|
|
<th data-sort-index="5" class="sortable">Pauschale</th> |
|
|
|
<th>Aktionen</th> |
|
|
|
</tr> |
|
|
|
</thead> |
|
|
|
@ -80,8 +84,8 @@ |
|
|
|
<tr> |
|
|
|
<td><%= entry.date.strftime('%d.%m.%Y') %></td> |
|
|
|
<td><%= entry.hours.to_i %>h <%= entry.minutes.to_i %>min</td> |
|
|
|
<td><%= entry.praktikums_typ %></td> |
|
|
|
<td><%= entry.entry_art %></td> |
|
|
|
<td><%= entry.praktikums_typ.capitalize %></td> |
|
|
|
<td><%= entry.entry_art.capitalize %></td> |
|
|
|
<td><%= entry.distance_km.to_f %> km</td> |
|
|
|
<td><%= number_to_currency(entry.kilometer_pauschale, unit: "€", separator: ",", delimiter: ".") %></td> |
|
|
|
<td class="text-end"> |
|
|
|
@ -134,3 +138,60 @@ |
|
|
|
}); |
|
|
|
}); |
|
|
|
</script> |
|
|
|
|
|
|
|
<script> |
|
|
|
document.addEventListener("DOMContentLoaded", function () { |
|
|
|
const filterInput = document.getElementById("entryFilter"); |
|
|
|
const table = document.getElementById("entriesTable"); |
|
|
|
const tableRows = table?.querySelectorAll("tbody tr"); |
|
|
|
|
|
|
|
if (filterInput && table && tableRows) { |
|
|
|
filterInput.addEventListener("keyup", function () { |
|
|
|
const query = this.value.toLowerCase(); |
|
|
|
|
|
|
|
tableRows.forEach(row => { |
|
|
|
const text = row.textContent.toLowerCase(); |
|
|
|
row.style.display = text.includes(query) ? "" : "none"; |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
}); |
|
|
|
</script> |
|
|
|
<script> |
|
|
|
document.addEventListener("DOMContentLoaded", () => { |
|
|
|
const table = document.getElementById("entriesTable"); |
|
|
|
const headers = table.querySelectorAll("th.sortable"); |
|
|
|
let sortDirection = 1; |
|
|
|
|
|
|
|
headers.forEach((header, index) => { |
|
|
|
header.style.cursor = 'pointer'; |
|
|
|
header.addEventListener("click", () => { |
|
|
|
const tbody = table.querySelector("tbody"); |
|
|
|
const rows = Array.from(tbody.querySelectorAll("tr")); |
|
|
|
|
|
|
|
const isNumeric = header.dataset.sort === 'km' || header.dataset.sort === 'pauschale'; |
|
|
|
const isDate = header.dataset.sort === 'date'; |
|
|
|
|
|
|
|
rows.sort((a, b) => { |
|
|
|
const cellA = a.children[index].textContent.trim(); |
|
|
|
const cellB = b.children[index].textContent.trim(); |
|
|
|
|
|
|
|
if (isDate) { |
|
|
|
return sortDirection * (new Date(cellA.split('.').reverse().join('-')) - new Date(cellB.split('.').reverse().join('-'))); |
|
|
|
} |
|
|
|
|
|
|
|
if (isNumeric) { |
|
|
|
const numA = parseFloat(cellA.replace(/[^\d,.-]/g, "").replace(",", ".")); |
|
|
|
const numB = parseFloat(cellB.replace(/[^\d,.-]/g, "").replace(",", ".")); |
|
|
|
return sortDirection * (numA - numB); |
|
|
|
} |
|
|
|
|
|
|
|
return sortDirection * cellA.localeCompare(cellB); |
|
|
|
}); |
|
|
|
|
|
|
|
rows.forEach(row => tbody.appendChild(row)); |
|
|
|
sortDirection *= -1; // Toggle asc/desc |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|
</script> |