Quelltext des aktuellen Standes
<?php
$this->layout('layouts/main', [
'page_title' => $page_title,
'current_route' => $current_route,
'full_width' => true,
]);
$statusCfg = [
'pending' => ['Anfrage offen', 'status-pill--info'],
'reserved' => ['Reserviert', 'status-pill--warning'],
'active' => ['Ausgeliehen', 'status-pill--success'],
'returned' => ['Zurückgegeben', 'status-pill--neutral'],
'cancelled' => ['Storniert', 'status-pill--danger'],
];
$curSort = $sort ?? '';
$curDir = $dir ?? 'asc';
// Sortierbarer Spaltenkopf: Link, der die Richtung toggelt und Filter erhält.
$sortTh = function (string $key, string $label) use ($curSort, $curDir, $search, $status_filter, $overdue_only, $unclaimed_only) {
$nextDir = ($curSort === $key && $curDir === 'asc') ? 'desc' : 'asc';
$arrow = $curSort === $key ? ($curDir === 'asc' ? ' ↑' : ' ↓') : '';
$params = ['sort' => $key, 'dir' => $nextDir];
if ($search !== '') { $params['q'] = $search; }
if ($status_filter !== '') { $params['status'] = $status_filter; }
if ($overdue_only) { $params['overdue'] = '1'; }
if ($unclaimed_only) { $params['unclaimed'] = '1'; }
$href = '/loans/lendings?' . http_build_query($params);
return '<th><a href="' . $this->e($href) . '" style="color:inherit;white-space:nowrap;">' . $this->e($label) . $arrow . '</a></th>';
};
?>
<style>
a { text-decoration: none; }
.lli-wrap { padding: 0; }
.lli-overdue { color:var(--red-600); font-weight:700; font-size:0.74rem; }
.lli-unclaimed { color:var(--amber-700); font-weight:700; font-size:0.74rem; }
.lli-chk { display:inline-flex; align-items:center; gap:0.35rem; font-size:0.85rem; color:var(--gray-700); }
</style>
<div class="lli-wrap">
<div class="content-header">
<div>
<h1><?= $this->te('Ausleihen') ?></h1>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/"><?= $this->te('Home') ?></a></li>
<li class="breadcrumb-item"><a href="/loans"><?= $this->te('Leihgeräte') ?></a></li>
<li class="breadcrumb-item active"><?= $this->te('Ausleihen') ?></li>
</ol>
</div>
<div class="content-header-actions">
<a href="/loans" class="btn btn-default"><?= $this->te('Kalender') ?></a>
<a href="/loans/devices" class="btn btn-default"><?= $this->te('Geräte') ?></a>
<?php if ($can_issue): ?>
<a href="/loans/issue" class="btn btn-warning"><?= $this->te('Ausgeben') ?></a>
<?php endif; ?>
</div>
</div>
<div class="page-body">
<!-- Filter -->
<div class="card card-outline card-primary" style="margin-bottom:1.25rem;">
<div class="filter-card-body">
<form method="GET" action="/loans/lendings" style="display:flex;gap:0.75rem;flex-wrap:wrap;align-items:center;width:100%;">
<input type="search" name="q" value="<?= $this->e($search) ?>" placeholder="<?= $this->te('Ausleiher, Gerät, Seriennummer…') ?>" class="form-control form-control-sm" style="min-width:220px;width:auto;" autocomplete="off">
<select name="status" class="form-control form-control-sm" style="width:auto;" onchange="this.form.submit()">
<option value=""><?= $this->te('Alle Status') ?></option>
<?php foreach ($statusCfg as $val => [$label, $col]): ?>
<option value="<?= $val ?>" <?= $status_filter === $val ? 'selected' : '' ?>><?= $label ?></option>
<?php endforeach; ?>
</select>
<label class="lli-chk">
<input type="checkbox" name="overdue" value="1" <?= $overdue_only ? 'checked' : '' ?> onchange="this.form.submit()">
<?= $this->te('Nur überfällige') ?>
</label>
<label class="lli-chk">
<input type="checkbox" name="unclaimed" value="1" <?= $unclaimed_only ? 'checked' : '' ?> onchange="this.form.submit()">
<?= $this->te('Nur nicht abgeholte') ?>
</label>
<button type="submit" class="btn btn-primary btn-sm"><?= $this->te('Suchen') ?></button>
<?php if ($search || $status_filter || $overdue_only || $unclaimed_only): ?>
<a href="/loans/lendings" style="font-size:0.82rem;color:var(--gray-500);"><?= $this->te('Zurücksetzen') ?></a>
<?php endif; ?>
<span style="margin-left:auto;font-size:0.82rem;color:var(--gray-500);"><?= (int)($total ?? count($lendings)) ?> <?= (int)($total ?? count($lendings)) === 1 ? 'Vorgang' : 'Vorgänge' ?></span>
</form>
</div>
</div>
<?php if (empty($lendings)): ?>
<div class="empty-state">
<p style="font-weight:600;"><?= $this->te('Keine Ausleihvorgänge gefunden.') ?></p>
</div>
<?php else: ?>
<div class="table-wrapper">
<table class="data-table">
<thead>
<tr>
<?= $sortTh('status', 'Status') ?>
<?= $sortTh('device', 'Gerät') ?>
<?= $sortTh('borrower', 'Ausleiher') ?>
<?= $sortTh('period', 'Zeitraum') ?>
<?= $sortTh('issuer', 'Ausgegeben von') ?>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<?php foreach ($lendings as $l):
[$slabel, $scol] = $statusCfg[$l['status']] ?? ['?', 'status-pill--neutral'];
$isOverdue = !empty($l['is_overdue']);
$isUnclaimed = !empty($l['is_unclaimed']);
?>
<tr>
<td>
<span class="status-pill <?= $scol ?>"><?= $slabel ?></span>
<?php if ($isOverdue): ?><div class="lli-overdue"><?= $this->te('überfällig') ?></div><?php endif; ?>
<?php if ($isUnclaimed): ?><div class="lli-unclaimed"><?= $this->te('nicht abgeholt') ?></div><?php endif; ?>
</td>
<td>
<a href="/loans/devices/<?= (int)$l['device_id'] ?>" style="font-weight:600;color:var(--gray-900);"><?= $this->e($l['device_title']) ?></a>
<?php if (!empty($l['device_type'])): ?><div style="color:var(--gray-400);font-size:0.78rem;"><?= $this->e($l['device_type']) ?></div><?php endif; ?>
</td>
<td style="font-weight:600;"><?= $this->e($l['borrower_name']) ?></td>
<td style="white-space:nowrap;color:var(--gray-700);">
<?= date('d.m.Y', strtotime($l['planned_start'])) ?>
<span style="color:var(--gray-400);">–</span>
<?= date('d.m.Y', strtotime($l['planned_end'])) ?>
</td>
<td style="color:var(--gray-500);"><?= $this->e($l['issued_by_name'] ?? '–') ?></td>
<td><a href="/loans/lendings/<?= (int)$l['id'] ?>" style="color:var(--amber-600);font-weight:600;"><?= $this->te('Details') ?></a></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php if (($pages ?? 1) > 1): ?>
<div class="ld-pagination" style="display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-top:1rem;flex-wrap:wrap;">
<span style="font-size:0.82rem;color:var(--gray-500);">Seite <?= (int)$page ?> von <?= (int)$pages ?> · <?= (int)$total ?> Einträge</span>
<div style="display:flex;align-items:center;gap:0.5rem;">
<?php
$pageBase = '/loans/lendings?status=' . urlencode($status_filter)
. '&q=' . urlencode($search)
. '&overdue=' . ($overdue_only ? '1' : '')
. '&unclaimed=' . ($unclaimed_only ? '1' : '')
. '&sort=' . urlencode($curSort)
. '&dir=' . urlencode($curDir);
?>
<?php if ((int)$page > 1): ?>
<a class="btn btn-sm btn-default" href="<?= $pageBase ?>&page=<?= (int)$page - 1 ?>"><?= $this->te('Zurück') ?></a>
<?php else: ?>
<span class="btn btn-sm btn-default" style="opacity:0.5;pointer-events:none;"><?= $this->te('Zurück') ?></span>
<?php endif; ?>
<span style="font-size:0.82rem;color:var(--gray-500);"><?= (int)$page ?> / <?= (int)$pages ?></span>
<?php if ((int)$page < (int)$pages): ?>
<a class="btn btn-sm btn-default" href="<?= $pageBase ?>&page=<?= (int)$page + 1 ?>"><?= $this->te('Weiter') ?></a>
<?php else: ?>
<span class="btn btn-sm btn-default" style="opacity:0.5;pointer-events:none;"><?= $this->te('Weiter') ?></span>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
<?php endif; ?>
</div>
</div>