Quelltext des aktuellen Standes
<?php
$this->layout('layouts/main', [
'page_title' => $page_title,
'current_route' => $current_route,
'full_width' => true,
]);
$monthNames = ['','Januar','Februar','März','April','Mai','Juni',
'Juli','August','September','Oktober','November','Dezember'];
$dayNames = ['Mo','Di','Mi','Do','Fr','Sa','So'];
$today = date('Y-m-d');
$todayDay = (int)date('j');
$todayMon = (int)date('n');
$todayYear = (int)date('Y');
?>
<style>
a { text-decoration: none; }
a:hover { text-decoration: none; }
/* ld- = loan devices module */
.ld-wrap { padding: 0; }
/* Calendar nav */
.ld-cal-nav {
background: var(--gray-50);
border: 1px solid var(--gray-200);
border-bottom: none;
border-radius: 0.25rem 0.25rem 0 0;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.75rem 1.25rem;
}
.ld-cal-nav-arrow {
display: inline-flex; align-items: center; gap: 0.3rem;
background: var(--color-bg); color: var(--gray-700);
border: 1px solid var(--gray-200); border-radius: 0.4rem; padding: 0.4rem 0.85rem;
font-size: 0.82rem; font-weight: 600; cursor: pointer; text-decoration: none;
transition: background 0.15s;
}
.ld-cal-nav-arrow:hover { background: var(--gray-100); }
.ld-cal-month-title { font-size: 1.1rem; font-weight: 700; color: var(--gray-900); }
/* Body */
/* Calendar grid */
.ld-calendar {
border: 1px solid var(--gray-200);
border-radius: 0.25rem;
overflow: hidden;
}
.ld-cal-header {
display: grid; grid-template-columns: repeat(7, 1fr);
background: var(--gray-50); border-bottom: 1px solid var(--gray-200);
}
.ld-cal-header-cell {
text-align: center; padding: 0.5rem;
font-size: 0.75rem; font-weight: 700; color: var(--gray-500);
border-right: 1px solid var(--gray-200);
}
.ld-cal-header-cell:last-child { border-right: none; }
/* Week row */
.ld-week { border-bottom: 1px solid var(--gray-200); }
.ld-week:last-child { border-bottom: none; }
.ld-week-days {
display: grid; grid-template-columns: repeat(7, 1fr);
}
.ld-cal-cell {
min-height: 36px; padding: 0.3rem 0.4rem 0;
border-right: 1px solid var(--gray-200);
}
.ld-cal-cell:last-child { border-right: none; }
.ld-cal-cell.empty { background: var(--gray-50); }
.ld-cal-cell.today { background: var(--amber-50); }
.ld-cal-day-num {
font-size: 0.78rem; font-weight: 700; color: var(--gray-700);
display: inline-flex; width: 1.5rem; height: 1.5rem;
align-items: center; justify-content: center; border-radius: 50%;
}
.ld-cal-cell.today .ld-cal-day-num { background: var(--amber-600); color: var(--color-on-accent); }
/* Bar lanes */
.ld-week-bars {
display: grid; grid-template-columns: repeat(7, 1fr);
padding: 2px 0 4px; gap: 2px 0;
min-height: 4px;
}
.ld-bar {
height: 20px; overflow: hidden;
display: flex; align-items: center;
}
.ld-bar a {
display: block; width: 100%; height: 100%;
font-size: 0.67rem; font-weight: 600; color: var(--color-on-accent);
padding: 0 0.4rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
border-radius: 3px; line-height: 20px;
}
.ld-bar a:hover { opacity: 0.85; }
/* Bar shape based on position */
.ld-bar.bar-start a { border-radius: 3px 0 0 3px; padding-right: 0; }
.ld-bar.bar-mid a { border-radius: 0; padding: 0; font-size:0; }
.ld-bar.bar-end a { border-radius: 0 3px 3px 0; padding-left: 0; font-size:0; }
.ld-bar.bar-single a { border-radius: 3px; }
/* Continues from previous week – no left rounding */
.ld-bar.bar-cont-l a { border-radius: 0 3px 3px 0; }
.ld-bar.bar-cont-l.bar-end a { border-radius: 0 3px 3px 0; }
/* Reserved bars */
.ld-bar.bar-reserved a { opacity: 0.75; background: repeating-linear-gradient(90deg, transparent, transparent 3px, rgba(255,255,255,0.3) 3px, rgba(255,255,255,0.3) 4px); }
/* Offene Anfragen (pending) – gestrichelt, transparent, noch nicht bestätigt */
.ld-bar.bar-pending a { opacity: 0.55; background: repeating-linear-gradient(45deg, transparent, transparent 4px, rgba(255,255,255,0.45) 4px, rgba(255,255,255,0.45) 6px); }
.ld-bar.bar-pending { outline: 1px dashed rgba(255,255,255,0.85); outline-offset: -2px; border-radius: 3px; }
/* Überfällige Ausleihen */
.ld-bar.bar-overdue a { background: var(--red-600) !important; animation: overdue-pulse 2s ease-in-out infinite; }
@keyframes overdue-pulse { 0%,100% { opacity:1; } 50% { opacity:0.7; } }
@media (prefers-reduced-motion: reduce) { .ld-bar.bar-overdue a, [class*="overdue-pulse"] { animation: none !important; } }
/* Legend */
.ld-legend {
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
margin-top: 1.25rem;
padding: 1rem 1.25rem;
background: var(--gray-50);
border-radius: 0.25rem;
border: 1px solid var(--gray-200);
}
.ld-legend-item {
display: flex;
align-items: center;
gap: 0.4rem;
font-size: 0.78rem;
color: var(--gray-700);
text-decoration: none;
}
.ld-legend-dot {
width: 10px; height: 10px;
border-radius: 50%;
flex-shrink: 0;
}
.ld-legend-device { font-weight: 600; }
.ld-legend-sep { color: var(--gray-300); }
/* Tab bar */
.ld-tabs {
display: flex;
gap: 0.25rem;
border-bottom: 2px solid var(--gray-200);
margin-bottom: 1.75rem;
}
.ld-tab {
padding: 0.6rem 1.1rem;
font-size: 0.85rem;
font-weight: 600;
color: var(--gray-500);
text-decoration: none;
border-bottom: 2px solid transparent;
margin-bottom: -2px;
transition: color 0.15s, border-color 0.15s;
}
.ld-tab:hover { color: var(--amber-600); }
.ld-tab.active { color: var(--amber-600); border-bottom-color: var(--amber-600); }
@media (max-width: 768px) {
/* Kalender auf Mobile: horizontales Scrollen statt Quetschen */
.ld-calendar-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.ld-calendar { min-width: 320px; }
.ld-cal-cell { min-height: 48px; }
.ld-bar a { font-size: 0.58rem; }
.ld-today-grid { grid-template-columns: 1fr !important; }
.ld-tabs { overflow-x: auto; white-space: nowrap; padding-bottom: 2px; }
}
@media (max-width: 480px) {
.ld-cal-nav-arrow { padding: 0.35rem 0.6rem; font-size: 0.78rem; }
.ld-month-title { font-size: 0.95rem; }
.ld-legend { flex-direction: column; gap: 0.5rem; }
}
</style>
<div class="ld-wrap">
<!-- Content Header -->
<div class="content-header">
<div>
<h1><?= $this->te('Leihgeräte') ?></h1>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/"><?= $this->te('Home') ?></a></li>
<li class="breadcrumb-item active"><?= $this->te('Leihgeräte') ?></li>
</ol>
</div>
<div class="content-header-actions">
<a href="/loans/lendings" class="btn btn-default"><?= $this->te('Ausleihen') ?></a>
<a href="/loans/devices" class="btn btn-default"><?= $this->te('Geräte') ?></a>
<a href="/loans/statistics" class="btn btn-default"><?= $this->te('Auswertung') ?></a>
<?php if ($can_issue): ?>
<a href="/loans/issue" class="btn btn-warning"><?= $this->te('Ausgeben') ?></a>
<?php endif; ?>
</div>
</div>
<!-- KPI Small Boxes -->
<div class="page-body">
<div class="kpi-row">
<div class="kpi-col">
<div class="small-box bg-info">
<div class="inner"><h3><?= (int)$summary['total'] ?></h3><p><?= $this->te('Gesamt') ?></p></div>
<div class="icon"><i class="fas fa-laptop"></i></div>
</div>
</div>
<div class="kpi-col">
<div class="small-box bg-success">
<div class="inner"><h3><?= (int)$summary['available'] ?></h3><p><?= $this->te('Verfügbar') ?></p></div>
<div class="icon"><i class="fas fa-check"></i></div>
</div>
</div>
<div class="kpi-col">
<div class="small-box <?= (int)$summary['lent'] > 0 ? 'bg-warning' : 'bg-secondary' ?>">
<div class="inner"><h3><?= (int)$summary['lent'] ?></h3><p><?= $this->te('Ausgeliehen') ?></p></div>
<div class="icon"><i class="fas fa-share-square"></i></div>
</div>
</div>
<div class="kpi-col">
<div class="small-box bg-secondary">
<div class="inner"><h3><?= (int)$summary['reserved'] ?></h3><p><?= $this->te('Reserviert') ?></p></div>
<div class="icon"><i class="fas fa-clock"></i></div>
</div>
</div>
<?php if ((int)($summary['unclaimed'] ?? 0) > 0): ?>
<div class="kpi-col">
<a href="/loans/lendings?unclaimed=1">
<div class="small-box bg-warning">
<div class="inner"><h3><?= (int)$summary['unclaimed'] ?></h3><p><?= $this->te('Nicht abgeholt') ?></p></div>
<div class="icon"><i class="fas fa-hourglass-half"></i></div>
</div>
</a>
</div>
<?php endif; ?>
</div>
<?php if (!empty($pending_requests)): ?>
<!-- Offene Self-Service-Anfragen -->
<div style="margin:0 0 1.25rem;border:1px solid var(--blue-200);background:var(--blue-50);border-radius:0.25rem;overflow:hidden;">
<div style="display:flex;align-items:center;gap:0.5rem;padding:0.6rem 1rem;background:var(--blue-100);border-bottom:1px solid var(--blue-200);">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#2563eb" stroke-width="2.5"><path d="M22 11.08V12a10 10 0 11-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>
<span style="font-weight:700;color:var(--blue-800);font-size:0.88rem;"><?= count($pending_requests) ?> offene Anfrage<?= count($pending_requests) !== 1 ? 'n' : '' ?> – warten auf Bestätigung</span>
</div>
<?php foreach ($pending_requests as $i => $pr): ?>
<a href="/loans/lendings/<?= (int)$pr['id'] ?>"
style="display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:0.55rem 1rem;color:var(--gray-700);<?= $i < count($pending_requests) - 1 ? 'border-bottom:1px solid var(--blue-100);' : '' ?>">
<span style="min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">
<strong style="color:var(--gray-900);"><?= $this->e($pr['device_title']) ?></strong>
<span style="color:var(--gray-500);"> · <?= $this->e($pr['borrower_name']) ?></span>
</span>
<span style="flex-shrink:0;font-size:0.8rem;color:var(--gray-500);">
<?= date('d.m.Y', strtotime($pr['planned_start'])) ?> – <?= date('d.m.Y', strtotime($pr['planned_end'])) ?>
</span>
</a>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php if (!empty($overdue_lendings)): ?>
<!-- Überfällige Ausleihen (monatsunabhängig) -->
<div style="margin:0 0 1.25rem;border:1px solid var(--red-200);background:var(--red-50);border-radius:0.25rem;overflow:hidden;">
<div style="display:flex;align-items:center;gap:0.5rem;padding:0.6rem 1rem;background:var(--red-100);border-bottom:1px solid var(--red-200);">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#dc2626" stroke-width="2.5"><path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
<span style="font-weight:700;color:var(--red-800);font-size:0.88rem;"><?= count($overdue_lendings) ?> überfällige Ausleihe<?= count($overdue_lendings) !== 1 ? 'n' : '' ?></span>
</div>
<?php foreach ($overdue_lendings as $i => $ol): ?>
<a href="/loans/lendings/<?= (int)$ol['id'] ?>"
style="display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:0.55rem 1rem;color:var(--gray-700);<?= $i < count($overdue_lendings) - 1 ? 'border-bottom:1px solid var(--red-100);' : '' ?>">
<span style="min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">
<strong style="color:var(--gray-900);"><?= $this->e($ol['device_title']) ?></strong>
<span style="color:var(--gray-500);"> · <?= $this->e($ol['borrower_name']) ?></span>
</span>
<span style="flex-shrink:0;font-size:0.8rem;font-weight:700;color:var(--red-600);">
<?= (int)$ol['days_overdue'] ?> Tag<?= (int)$ol['days_overdue'] !== 1 ? 'e' : '' ?> überfällig
<span style="color:var(--gray-400);font-weight:400;">(fällig <?= date('d.m.Y', strtotime($ol['planned_end'])) ?>)</span>
</span>
</a>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php if (!empty($today_activity['pickups']) || !empty($today_activity['returns'])): ?>
<!-- Heute-Aktivität -->
<div class="ld-today-grid" style="display:grid;grid-template-columns:1fr 1fr;gap:1rem;margin:0 0 1.25rem;">
<div style="border:1px solid var(--amber-200);background:var(--amber-50);border-radius:0.25rem;overflow:hidden;">
<div style="padding:0.55rem 1rem;font-weight:700;color:var(--amber-800);font-size:0.83rem;border-bottom:1px solid var(--amber-200);background:var(--amber-100);">
<?= $this->t('Heute abzuholen') ?> (<?= count($today_activity['pickups']) ?>)
</div>
<?php if (empty($today_activity['pickups'])): ?>
<div style="padding:0.75rem 1rem;color:var(--gray-400);font-size:0.82rem;"><?= $this->te('Keine offenen Abholungen.') ?></div>
<?php else: foreach ($today_activity['pickups'] as $p): ?>
<a href="/loans/lendings/<?= (int)$p['id'] ?>" style="display:flex;justify-content:space-between;gap:0.75rem;padding:0.5rem 1rem;color:var(--gray-700);border-bottom:1px solid var(--amber-100);">
<span style="min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;"><strong style="color:var(--gray-900);"><?= $this->e($p['device_title']) ?></strong> · <?= $this->e($p['borrower_name']) ?></span>
<span style="flex-shrink:0;color:var(--gray-400);font-size:0.8rem;">ab <?= date('d.m.', strtotime($p['planned_start'])) ?></span>
</a>
<?php endforeach; endif; ?>
</div>
<div style="border:1px solid var(--green-200);background:var(--green-50);border-radius:0.25rem;overflow:hidden;">
<div style="padding:0.55rem 1rem;font-weight:700;color:var(--green-700);font-size:0.83rem;border-bottom:1px solid var(--green-200);background:var(--green-100);">
<?= $this->t('Heute zurück') ?> (<?= count($today_activity['returns']) ?>)
</div>
<?php if (empty($today_activity['returns'])): ?>
<div style="padding:0.75rem 1rem;color:var(--gray-400);font-size:0.82rem;"><?= $this->te('Keine Rückgaben heute.') ?></div>
<?php else: foreach ($today_activity['returns'] as $r): ?>
<a href="/loans/lendings/<?= (int)$r['id'] ?>" style="display:flex;justify-content:space-between;gap:0.75rem;padding:0.5rem 1rem;color:var(--gray-700);border-bottom:1px solid var(--green-100);">
<span style="min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;"><strong style="color:var(--gray-900);"><?= $this->e($r['device_title']) ?></strong> · <?= $this->e($r['borrower_name']) ?></span>
<span style="flex-shrink:0;color:var(--green-600);font-size:0.8rem;font-weight:600;"><?= $this->te('fällig heute') ?></span>
</a>
<?php endforeach; endif; ?>
</div>
</div>
<?php endif; ?>
<!-- Month nav -->
<div class="ld-cal-nav">
<a href="/loans?year=<?= $prevYear ?>&month=<?= $prevMonth ?>" class="ld-cal-nav-arrow">
← <?= $monthNames[$prevMonth] ?>
</a>
<div style="display:flex;align-items:center;gap:0.75rem;">
<span class="ld-cal-month-title"><?= $monthNames[$month] ?> <?= $year ?></span>
<?php if (!($month === $todayMon && $year === $todayYear)): ?>
<a href="/loans" class="ld-cal-nav-arrow" style="padding:0.3rem 0.7rem;"><?= $this->te('Heute') ?></a>
<?php endif; ?>
</div>
<a href="/loans?year=<?= $nextYear ?>&month=<?= $nextMonth ?>" class="ld-cal-nav-arrow">
<?= $monthNames[$nextMonth] ?> →
</a>
</div>
<!-- Calendar -->
<?php
// Build weeks: array of 7-element arrays (null = empty, int = day number)
$calCells = array_fill(0, $startDow - 1, null);
for ($d = 1; $d <= $daysInMonth; $d++) $calCells[] = $d;
while (count($calCells) % 7 !== 0) $calCells[] = null;
$calWeeks = array_chunk($calCells, 7);
// Precompute clamped day range per lending
foreach ($lendings as &$l) {
$ls = date('Y-m', strtotime($l['planned_start']));
$le = date('Y-m', strtotime($l['planned_end']));
$curMon = sprintf('%04d-%02d', $year, $month);
$l['_ds'] = ($ls < $curMon) ? 1 : (int)date('j', strtotime($l['planned_start']));
$l['_de'] = ($le > $curMon) ? $daysInMonth : (int)date('j', strtotime($l['planned_end']));
// actual start/end in month?
$l['_actual_start'] = ($ls === $curMon);
$l['_actual_end'] = ($le === $curMon);
}
unset($l);
// Assign bars to lanes per week (greedy lane packing)
$weekBars = [];
foreach ($calWeeks as $wi => $weekDays) {
$wDays = array_filter($weekDays, fn($d) => $d !== null);
if (empty($wDays)) { $weekBars[$wi] = []; continue; }
$wFirst = min($wDays); $wLast = max($wDays);
$bars = [];
foreach ($lendings as $l) {
if ($l['_de'] < $wFirst || $l['_ds'] > $wLast) continue;
$barDay1 = max($l['_ds'], $wFirst);
$barDay2 = min($l['_de'], $wLast);
// find column (1-7) of barDay1 / barDay2 in this week
$col1 = $col2 = null;
foreach ($weekDays as $ci => $d) {
if ($d === $barDay1) $col1 = $ci + 1;
if ($d === $barDay2) $col2 = $ci + 1;
}
if ($col1 === null || $col2 === null) continue;
$roundLeft = $l['_actual_start'] && ($barDay1 === $l['_ds']);
$roundRight = $l['_actual_end'] && ($barDay2 === $l['_de']);
$bars[] = ['l'=>$l,'col1'=>$col1,'col2'=>$col2,'rl'=>$roundLeft,'rr'=>$roundRight];
}
// Lane assignment
$laneRanges = [];
foreach ($bars as &$bar) {
$lane = 0;
while (true) {
if (!isset($laneRanges[$lane])) break;
$ok = true;
foreach ($laneRanges[$lane] as $r) {
if ($bar['col1'] <= $r[1] && $bar['col2'] >= $r[0]) { $ok = false; break; }
}
if ($ok) break;
$lane++;
}
$laneRanges[$lane][] = [$bar['col1'], $bar['col2']];
$bar['lane'] = $lane + 1; // grid-row is 1-based
}
unset($bar);
$weekBars[$wi] = $bars;
}
?>
<div class="ld-calendar-wrap"><div class="ld-calendar">
<!-- Header -->
<div class="ld-cal-header">
<?php foreach ($dayNames as $dn): ?>
<div class="ld-cal-header-cell"><?= $dn ?></div>
<?php endforeach; ?>
</div>
<!-- Weeks -->
<?php foreach ($calWeeks as $wi => $weekDays): ?>
<div class="ld-week">
<!-- Day number cells -->
<div class="ld-week-days">
<?php foreach ($weekDays as $d):
$isToday = ($d === $todayDay && $month === $todayMon && $year === $todayYear);
?>
<div class="ld-cal-cell <?= $d === null ? 'empty' : ($isToday ? 'today' : '') ?>">
<?php if ($d !== null): ?>
<span class="ld-cal-day-num"><?= $d ?></span>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>
<!-- Bar lanes -->
<?php if (!empty($weekBars[$wi])): ?>
<div class="ld-week-bars" style="grid-template-rows: repeat(<?= max(array_column($weekBars[$wi], 'lane')) ?>, 22px);">
<?php foreach ($weekBars[$wi] as $bar):
$l = $bar['l'];
$color = $deviceColors[$l['device_id']] ?? 'var(--gray-500)';
$isRes = $l['status'] === 'reserved';
$isPending = $l['status'] === 'pending';
$isOverdue = ($l['status'] === 'active' && $l['planned_end'] < $today);
$span = $bar['col2'] - $bar['col1'] + 1;
// Shape class
if ($span === 1) {
$shape = $bar['rl'] && $bar['rr'] ? 'bar-single' : ($bar['rl'] ? 'bar-start' : ($bar['rr'] ? 'bar-end' : 'bar-mid'));
} else {
$shape = ($bar['rl'] ? 'bar-start' : 'bar-cont-l');
if (!$bar['rr']) $shape .= ' bar-cont-r';
}
$barClasses = $shape;
if ($isRes) $barClasses .= ' bar-reserved';
if ($isPending) $barClasses .= ' bar-pending';
if ($isOverdue) $barClasses .= ' bar-overdue';
$titlePrefix = $isPending ? 'Anfrage (Freigabe offen): ' : '';
$labelPrefix = $isPending ? '? ' : '';
?>
<div class="ld-bar <?= $barClasses ?>"
style="grid-column:<?= $bar['col1'] ?>/<?= $bar['col2']+1 ?>; grid-row:<?= $bar['lane'] ?>; background:<?= $color ?>;">
<a href="/loans/lendings/<?= $l['id'] ?>"
style="background:<?= $color ?>;"
title="<?= $this->e($titlePrefix . $l['device_title']) ?> — <?= $this->e($l['borrower_name']) ?>">
<?= $this->e($labelPrefix . $l['device_title']) ?> · <?= $this->e($l['borrower_name']) ?>
</a>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div></div><!-- /ld-calendar-wrap -->
<!-- Legend – immer anzeigen -->
<div class="ld-legend">
<span style="font-size:0.75rem;font-weight:700;color:var(--gray-500);text-transform:uppercase;letter-spacing:0.05em;align-self:center;"><?= $this->te('Legende:') ?></span>
<?php
$seenDevices = [];
foreach ($lendings as $l) {
if (isset($seenDevices[$l['device_id']])) continue;
$seenDevices[$l['device_id']] = $l;
}
foreach ($seenDevices as $devId => $l):
$col = $deviceColors[$devId] ?? 'var(--gray-500)';
?>
<a href="/loans/devices/<?= $devId ?>" class="ld-legend-item">
<span class="ld-legend-dot" style="background:<?= $col ?>"></span>
<span class="ld-legend-device"><?= $this->e($l['device_title']) ?></span>
<span class="ld-legend-sep">·</span>
<span style="color:var(--gray-500)"><?= $this->e($l['device_type']) ?></span>
</a>
<?php endforeach; ?>
<div style="margin-left:auto;display:flex;gap:0.75rem;align-items:center;">
<span style="font-size:0.72rem;color:var(--gray-500);display:flex;align-items:center;gap:0.3rem;">
<span style="width:16px;height:10px;border-radius:2px;background:var(--gray-500);opacity:0.8;display:inline-block;"></span>
<?= $this->te('Aktiv') ?>
</span>
<span style="font-size:0.72rem;color:var(--gray-500);display:flex;align-items:center;gap:0.3rem;">
<span style="width:16px;height:10px;border-radius:2px;border:1.5px dashed var(--gray-500);display:inline-block;"></span>
<?= $this->te('Reserviert') ?>
</span>
<span style="font-size:0.72rem;color:var(--red-600);display:flex;align-items:center;gap:0.3rem;font-weight:600;">
<span style="width:16px;height:10px;border-radius:2px;background:var(--red-600);display:inline-block;"></span>
<?= $this->te('Überfällig') ?>
</span>
</div>
</div>
<?php if (empty($lendings)): ?>
<div style="text-align:center;padding:3rem 1rem;color:var(--gray-400);">
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" style="margin:0 auto 1rem;display:block;opacity:0.4"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>
<p style="font-size:0.95rem;font-weight:600;"><?= $this->te('Keine Ausleihen in diesem Monat') ?></p>
<?php if ($can_issue): ?>
<a href="/loans/issue" style="display:inline-block;margin-top:0.75rem;color:var(--amber-600);font-weight:600;font-size:0.85rem;"><?= $this->te('Gerät ausgeben →') ?></a>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
</div>