205 lines
7.6 KiB
Plaintext
205 lines
7.6 KiB
Plaintext
<!DOCTYPE html>
|
||
<html lang="de">
|
||
<head>
|
||
<%- include('partials/head') %>
|
||
</head>
|
||
<body>
|
||
<%- include('partials/header') %>
|
||
|
||
<main class="container">
|
||
<section class="balance-card <%= totalBalanceMinutes < 0 ? 'is-negative' : 'is-positive' %>">
|
||
<span class="balance-card__label">Aktueller Saldo</span>
|
||
<div class="balance-card__rule" aria-hidden="true"></div>
|
||
<span class="balance-card__figure"><%= formatBalance(totalBalanceMinutes) %></span>
|
||
<span class="balance-card__hint">Stunden, inkl. Startguthaben aus den Einstellungen</span>
|
||
</section>
|
||
|
||
<% if (error) { %>
|
||
<p class="notice notice--error"><%= error %></p>
|
||
<% } %>
|
||
|
||
<div class="layout">
|
||
<section class="card entry-card">
|
||
<h2 class="card__title"><%= editEntry ? 'Buchung bearbeiten' : 'Buchung erfassen' %></h2>
|
||
<form action="/entries" method="POST" class="form" id="entry-form">
|
||
<label class="field">
|
||
<span class="field__label">Datum</span>
|
||
<input
|
||
type="date"
|
||
name="date"
|
||
value="<%= editEntry ? editEntry.date : '' %>"
|
||
required
|
||
/>
|
||
</label>
|
||
|
||
<div class="field-row">
|
||
<label class="field">
|
||
<span class="field__label">Arbeitsbeginn</span>
|
||
<input
|
||
type="time"
|
||
name="startTime"
|
||
value="<%= editEntry ? editEntry.startTime : '' %>"
|
||
required
|
||
/>
|
||
</label>
|
||
<label class="field">
|
||
<span class="field__label">Arbeitsende</span>
|
||
<input
|
||
type="time"
|
||
name="endTime"
|
||
value="<%= editEntry ? editEntry.endTime : '' %>"
|
||
required
|
||
/>
|
||
</label>
|
||
</div>
|
||
|
||
<div class="field">
|
||
<span class="field__label">
|
||
Pausen
|
||
<span class="field__label-hint">(jeweils Start – Ende)</span>
|
||
</span>
|
||
<div id="breaks-container">
|
||
<% if (editEntry && editEntry.breaks && editEntry.breaks.length > 0) { %>
|
||
<% editEntry.breaks.forEach((b) => { %>
|
||
<div class="break-row">
|
||
<input type="time" name="breakStart" value="<%= b.start %>" />
|
||
<span class="break-dash" aria-hidden="true">–</span>
|
||
<input type="time" name="breakEnd" value="<%= b.end %>" />
|
||
<button
|
||
type="button"
|
||
class="break-remove"
|
||
aria-label="Pause entfernen"
|
||
title="Pause entfernen"
|
||
>×</button>
|
||
</div>
|
||
<% }) %>
|
||
<% } %>
|
||
</div>
|
||
<button type="button" id="add-break" class="button button--ghost break-add-btn">
|
||
+ Pause hinzufügen
|
||
</button>
|
||
</div>
|
||
|
||
<label class="field">
|
||
<span class="field__label">Notiz (optional)</span>
|
||
<input
|
||
type="text"
|
||
name="note"
|
||
maxlength="200"
|
||
value="<%= editEntry ? editEntry.note : '' %>"
|
||
placeholder="z. B. Außendienst, Homeoffice …"
|
||
/>
|
||
</label>
|
||
|
||
<button type="submit" class="button button--primary button--block">
|
||
<%= editEntry ? 'Änderung speichern' : 'Buchung speichern' %>
|
||
</button>
|
||
<% if (editEntry) { %>
|
||
<a href="/" class="button button--ghost button--block">Abbrechen</a>
|
||
<% } %>
|
||
</form>
|
||
<p class="card__footnote">
|
||
Ein Tag = ein Eintrag. Pausen mit End- vor Startzeit werden ignoriert.
|
||
Bereits bestehende Buchungen für ein Datum werden beim erneuten Speichern aktualisiert.
|
||
</p>
|
||
</section>
|
||
|
||
<section class="card ledger-card">
|
||
<h2 class="card__title">Letzte Buchungen</h2>
|
||
<% if (entries.length === 0) { %>
|
||
<p class="empty-state">Noch keine Buchungen erfasst. Trag deinen ersten Arbeitstag links ein.</p>
|
||
<% } else { %>
|
||
<div class="table-scroll">
|
||
<table class="ledger-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Datum</th>
|
||
<th>Start</th>
|
||
<th>Ende</th>
|
||
<th>Pausen</th>
|
||
<th>Pause (ges.)</th>
|
||
<th>Gearbeitet</th>
|
||
<th>Saldo</th>
|
||
<th>Notiz</th>
|
||
<th class="ledger-table__actions-col"></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<% entries.forEach((entry) => { %>
|
||
<tr>
|
||
<td><%= formatDateDisplay(entry.date) %></td>
|
||
<td class="num"><%= entry.startTime %></td>
|
||
<td class="num"><%= entry.endTime %></td>
|
||
<td class="num">
|
||
<% if (entry.breaks && entry.breaks.length > 0) { %>
|
||
<span class="break-pills">
|
||
<% entry.breaks.forEach((b) => { %>
|
||
<span class="break-pill"><%= b.start %>–<%= b.end %></span>
|
||
<% }) %>
|
||
</span>
|
||
<% } else { %>
|
||
<span class="muted">–</span>
|
||
<% } %>
|
||
</td>
|
||
<td class="num">
|
||
<% if (entry.breakMinutes > 0) { %>
|
||
<%= minutesToHM(entry.breakMinutes) %>
|
||
<% } else { %>
|
||
<span class="muted">–</span>
|
||
<% } %>
|
||
</td>
|
||
<td class="num"><%= minutesToHM(entry.workedMinutes) %></td>
|
||
<td class="num <%= entry.balanceMinutes < 0 ? 'is-negative' : 'is-positive' %>">
|
||
<%= formatBalance(entry.balanceMinutes) %>
|
||
</td>
|
||
<td class="ledger-table__note"><%= entry.note %></td>
|
||
<td class="ledger-table__actions">
|
||
<a href="/?edit=<%= entry.date %>" class="link-button">Bearbeiten</a>
|
||
<form action="/entries/<%= entry._id %>/delete" method="POST">
|
||
<button type="submit" class="link-button link-button--danger">Löschen</button>
|
||
</form>
|
||
</td>
|
||
</tr>
|
||
<% }) %>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<% } %>
|
||
</section>
|
||
</div>
|
||
|
||
<% if (monthlyAgg.length > 0) { %>
|
||
<section class="card">
|
||
<h2 class="card__title">Monatsabschluss</h2>
|
||
<div class="table-scroll">
|
||
<table class="ledger-table ledger-table--compact">
|
||
<thead>
|
||
<tr>
|
||
<th>Monat</th>
|
||
<th>Buchungstage</th>
|
||
<th>Gearbeitet</th>
|
||
<th>Saldo</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<% monthlyAgg.forEach((month) => { %>
|
||
<tr>
|
||
<td><%= formatMonthDisplay(month._id) %></td>
|
||
<td class="num"><%= month.days %></td>
|
||
<td class="num"><%= minutesToHM(month.worked) %> h</td>
|
||
<td class="num <%= month.balance < 0 ? 'is-negative' : 'is-positive' %>">
|
||
<%= formatBalance(month.balance) %>
|
||
</td>
|
||
</tr>
|
||
<% }) %>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</section>
|
||
<% } %>
|
||
</main>
|
||
|
||
<script src="/js/app.js"></script>
|
||
</body>
|
||
</html>
|