djmdy
This commit is contained in:
parent
b59f256e7b
commit
f6b60af78b
@ -1301,3 +1301,45 @@ body:not(.admin-body) > * {
|
||||
background: #fee2e2;
|
||||
border-color: var(--error);
|
||||
}
|
||||
|
||||
/* ---- Rechnungshistorie in Mitglied-Detail ---- */
|
||||
.karte-header-sub {
|
||||
margin-left: auto;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-muted);
|
||||
background: var(--bg);
|
||||
padding: 2px 10px;
|
||||
border-radius: 20px;
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
.invoice-history-wrap {
|
||||
max-height: 272px; /* ca. 6 Zeilen */
|
||||
overflow-y: auto;
|
||||
border-radius: 0 0 14px 14px;
|
||||
}
|
||||
.invoice-history-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 0.88rem;
|
||||
}
|
||||
.invoice-history-table thead th {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
padding: 10px 16px;
|
||||
background: var(--bg);
|
||||
font-size: 0.75rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
color: var(--text-muted);
|
||||
border-bottom: 1.5px solid var(--border);
|
||||
}
|
||||
.invoice-history-table td {
|
||||
padding: 10px 16px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
vertical-align: middle;
|
||||
}
|
||||
.invoice-history-row:last-child td { border-bottom: none; }
|
||||
.invoice-history-row:hover td { background: #f8f8ff; cursor: default; }
|
||||
|
||||
@ -175,6 +175,11 @@ router.get('/members/:id', requireAdmin, async (req, res) => {
|
||||
'SELECT * FROM membership_pauses WHERE membership_id = ? ORDER BY pause_start DESC',
|
||||
[req.params.id]
|
||||
);
|
||||
const [invoices] = await db.query(`
|
||||
SELECT * FROM invoices
|
||||
WHERE membership_id = ?
|
||||
ORDER BY period DESC, created_at DESC
|
||||
`, [req.params.id]);
|
||||
const [tariffs] = await db.query(
|
||||
'SELECT * FROM tariffs WHERE active = 1 ORDER BY name ASC'
|
||||
);
|
||||
@ -183,6 +188,7 @@ router.get('/members/:id', requireAdmin, async (req, res) => {
|
||||
member: rows[0],
|
||||
pauses,
|
||||
tariffs,
|
||||
invoices,
|
||||
admin: req.session.adminUser,
|
||||
success: req.query.success || null,
|
||||
error: req.query.error || null
|
||||
|
||||
@ -303,6 +303,68 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ===== KARTE 5: Rechnungshistorie ===== -->
|
||||
<div class="karte karte-full">
|
||||
<div class="karte-header">
|
||||
<span class="karte-icon">🧾</span>
|
||||
<h3>Rechnungshistorie</h3>
|
||||
<span class="karte-header-sub"><%= invoices.length %> Rechnung(en)</span>
|
||||
</div>
|
||||
<div class="karte-body" style="padding:0">
|
||||
<% if (invoices.length === 0) { %>
|
||||
<p class="karte-empty" style="padding:20px">Noch keine Rechnungen vorhanden.</p>
|
||||
<% } else { %>
|
||||
<div class="invoice-history-wrap">
|
||||
<table class="invoice-history-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Nr.</th>
|
||||
<th>Periode</th>
|
||||
<th>Betrag</th>
|
||||
<th>Status</th>
|
||||
<th>Datum</th>
|
||||
<th>Aktion</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% invoices.forEach(inv => { %>
|
||||
<tr class="invoice-history-row">
|
||||
<td class="invoice-nr">PF24-<%= String(inv.id).padStart(6,'0') %></td>
|
||||
<td><strong><%= inv.period %></strong></td>
|
||||
<td>
|
||||
<% if (inv.status === 'cancelled') { %>
|
||||
<span style="text-decoration:line-through;color:var(--text-muted)">
|
||||
<%= Number(inv.amount).toFixed(2).replace('.', ',') %> €
|
||||
</span>
|
||||
<% } else { %>
|
||||
<strong><%= Number(inv.amount).toFixed(2).replace('.', ',') %> €</strong>
|
||||
<% } %>
|
||||
</td>
|
||||
<td>
|
||||
<span class="invoice-status <%= inv.status === 'paid' ? 'paid' : inv.status === 'cancelled' ? 'cancelled' : 'open' %>">
|
||||
<%= inv.status === 'paid' ? '✅ Bezahlt' : inv.status === 'cancelled' ? '🚫 Storniert' : '🔴 Offen' %>
|
||||
</span>
|
||||
</td>
|
||||
<td><small class="text-muted"><%= new Date(inv.created_at).toLocaleDateString('de-DE') %></small></td>
|
||||
<td>
|
||||
<% if (inv.status === 'cancelled') { %>
|
||||
<a href="/admin/billing/export/storno-pdf/<%= inv.id %>"
|
||||
class="btn btn-sm btn-storno" target="_blank">🚫 Storno-PDF</a>
|
||||
<% } else { %>
|
||||
<a href="/admin/billing/export/pdf/<%= inv.id %>"
|
||||
class="btn btn-sm btn-outline" target="_blank">📄 Rechnung</a>
|
||||
<% } %>
|
||||
</td>
|
||||
</tr>
|
||||
<% }) %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><!-- end karteikarte-grid -->
|
||||
</form>
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user