Quelltext des aktuellen Standes
<?php
$this->layout('layouts/main', [
'page_title' => $page_title,
'current_route' => $current_route,
'full_width' => true,
]);
$statusConfig = [
'pending' => ['Anfrage offen', 'status-pill--info', 'status-dot--warning', 'Diese Self-Service-Anfrage wartet auf Bestätigung durch das IT-Team.'],
'reserved' => ['Reserviert', 'status-pill--warning', 'status-dot--warning', 'Dieses Gerät ist für den angegebenen Zeitraum reserviert.'],
'active' => ['Aktiv – Ausgeliehen', 'status-pill--success', 'status-dot--success', 'Das Gerät ist derzeit ausgeliehen.'],
'returned' => ['Zurückgegeben', 'status-pill--neutral', '', 'Das Gerät wurde zurückgegeben.'],
'cancelled'=> ['Storniert', 'status-pill--danger', 'status-dot--danger', 'Dieser Vorgang wurde storniert.'],
];
[$slabel, $spill, $sdot, $sdesc] = $statusConfig[$lending['status']] ?? ['Unbekannt','status-pill--neutral','',''];
// Unterschriften-Anforderung ist nur 30 Minuten gültig (wie auf dem Signatur-Tablet).
// Abgelaufene Token gelten nicht mehr als "ausstehend".
$sigPending = !empty($lending['signature_token'])
&& empty($lending['signature_data'])
&& !empty($lending['signature_requested_at'])
&& strtotime((string)$lending['signature_requested_at']) > (time() - 1800);
?>
<style>
a { text-decoration: none; }
a:hover { text-decoration: none; }
.lls-wrap { padding:0; }
.lls-layout { display:grid; grid-template-columns:1fr 300px; gap:1.75rem; align-items:start; }
.lls-info-list { display:flex; flex-direction:column; gap:0.75rem; }
.lls-info-row { display:flex; flex-direction:column; gap:0.15rem; }
.lls-info-label { font-size:0.72rem; font-weight:700; text-transform:uppercase; letter-spacing:0.05em; color:var(--gray-400); }
.lls-info-value { font-size:0.88rem; color:var(--gray-700); }
.lls-info-grid { display:grid; grid-template-columns:1fr 1fr; gap:1rem; }
/* Accessory checklist */
.lls-acc-item { display:flex; align-items:center; gap:0.75rem; padding:0.6rem 0.75rem; border-radius:0.25rem; margin-bottom:0.4rem; }
.lls-acc-out { background:var(--amber-100); }
.lls-acc-in { background:var(--green-100); }
.lls-acc-missing { background:var(--red-100); }
.lls-acc-icon { flex-shrink:0; }
.lls-acc-name { font-size:0.88rem; font-weight:600; color:var(--gray-700); flex:1; }
/* Device preview */
.lls-device-preview { display:flex; gap:1rem; align-items:center; text-decoration:none; color:inherit; padding:0.75rem; background:var(--gray-50); border-radius:0.25rem; border:1px solid var(--gray-200); transition:background 0.15s; }
.lls-device-preview:hover { background:var(--gray-100); }
.lls-device-img { width:56px; height:56px; border-radius:0.375rem; object-fit:cover; background:var(--gray-200); flex-shrink:0; display:flex; align-items:center; justify-content:center; overflow:hidden; }
.lls-device-img img { width:100%; height:100%; object-fit:cover; }
.lls-device-info-name { font-size:0.9rem; font-weight:700; color:var(--gray-900); }
.lls-device-info-meta { font-size:0.78rem; color:var(--gray-500); }
@media(max-width:960px) {
.lls-layout { grid-template-columns:1fr; }
.lls-info-grid { grid-template-columns:1fr; }
}
</style>
<div class="lls-wrap">
<!-- Content Header -->
<div class="content-header">
<div>
<h1><?= $this->t('Ausleihvorgang #') ?><?= $lending['id'] ?></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">#<?= $lending['id'] ?></li>
</ol>
</div>
<div class="content-header-actions">
<span class="status-pill <?= $spill ?>">
<span class="status-dot <?= $sdot ?>"></span>
<?= $slabel ?>
</span>
<a href="/loans/devices/<?= $lending['device_id'] ?>" class="btn btn-default btn-sm"><?= $this->te('Zum Gerät') ?></a>
<a href="/loans/lendings/<?= $lending['id'] ?>/pdf" target="_blank" rel="noopener" class="btn btn-default btn-sm">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>
<?= $this->te('Leihschein') ?>
</a>
<?php if ($lending['status'] === 'returned'): ?>
<a href="/loans/lendings/<?= $lending['id'] ?>/return-pdf" target="_blank" rel="noopener" class="btn btn-default btn-sm">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 14l-4-4 4-4"/><path d="M5 10h11a4 4 0 010 8h-1"/></svg>
<?= $this->te('Rückgabeschein') ?>
</a>
<?php endif; ?>
<?php if ($can_issue && $lending['status'] === 'pending'): ?>
<form method="POST" action="/loans/lendings/<?= $lending['id'] ?>/approve" style="display:inline;">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<button type="submit" class="btn btn-success btn-sm">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M20 6L9 17l-5-5"/></svg>
<?= $this->te('Anfrage bestätigen') ?>
</button>
</form>
<button type="button" class="btn btn-danger btn-sm" onclick="openRejectModal()">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M18 6L6 18M6 6l12 12"/></svg>
<?= $this->te('Ablehnen') ?>
</button>
<?php endif; ?>
<?php if ($can_issue && $lending['status'] === 'reserved'): ?>
<button type="button" class="btn btn-success btn-sm" onclick="openIssueModal()">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
<?= $this->te('Herausgeben') ?>
</button>
<button class="btn btn-default btn-sm" onclick="openExtendModal()"><?= $this->te('🕑 Verlängern') ?></button>
<button class="btn btn-danger btn-sm" onclick="cancelLending()"><?= $this->te('Stornieren') ?></button>
<?php endif; ?>
<?php if ($can_issue && $lending['status'] === 'active'): ?>
<a href="/loans/lendings/<?= $lending['id'] ?>/return" class="btn btn-success btn-sm">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M19 12H5M12 5l-7 7 7 7"/></svg>
<?= $this->te('Rücknehmen') ?>
</a>
<button class="btn btn-default btn-sm" onclick="openExtendModal()"><?= $this->te('🕑 Verlängern') ?></button>
<?php if (!empty($lending['signature_data'])): ?>
<span class="btn btn-default btn-sm" style="cursor:default;opacity:0.8;">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M20 6L9 17l-5-5"/></svg>
<?= $this->te('Unterschrift vorhanden') ?>
</span>
<?php elseif ($sigPending): ?>
<form method="POST" action="/loans/lendings/<?= $lending['id'] ?>/cancel-signature" style="display:inline;">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<button type="submit" class="btn btn-danger btn-sm"><?= $this->te('✕ Anforderung abbrechen') ?></button>
</form>
<?php else: ?>
<form method="POST" action="/loans/lendings/<?= $lending['id'] ?>/request-signature" style="display:inline;">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<button type="submit" class="btn btn-default btn-sm">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 013 3L7 19l-4 1 1-4L16.5 3.5z"/></svg>
<?= $this->te('Unterschrift einholen') ?>
</button>
</form>
<?php endif; ?>
<button class="btn btn-danger btn-sm" onclick="cancelLending()"><?= $this->te('Stornieren') ?></button>
<?php endif; ?>
</div>
</div>
<div class="page-body lls-layout">
<!-- Main -->
<div class="lls-main">
<!-- Dates & Borrower -->
<div class="detail-card">
<div class="detail-card-header"><span class="detail-card-title"><?= $this->te('Ausleihdetails') ?></span></div>
<div class="detail-card-body">
<div class="lls-info-grid" style="margin-bottom:1rem;">
<div class="lls-info-row">
<span class="lls-info-label"><?= $this->te('Ausleiher') ?></span>
<span class="lls-info-value" style="font-weight:600;font-size:0.95rem;display:inline-flex;align-items:center;gap:0.45rem;">
<?php if (!empty($lending['borrower_person_image'])): ?>
<img src="<?= $this->e($lending['borrower_person_image']) ?>"
alt="<?= $this->e($lending['borrower_name']) ?>"
style="width:1.75rem;height:1.75rem;border-radius:50%;object-fit:cover;flex-shrink:0;">
<?php elseif (!empty($lending['borrower_name'])): ?>
<?php
$lColors = ['var(--blue-600)','var(--violet-600)','var(--red-600)','var(--emerald-600)','var(--amber-600)','var(--color-primary)'];
$lci = abs(crc32($lending['borrower_name']) % count($lColors));
?>
<span style="width:1.75rem;height:1.75rem;border-radius:50%;background:<?= $lColors[$lci] ?>;color:var(--color-on-accent);display:inline-flex;align-items:center;justify-content:center;font-size:0.72rem;font-weight:700;flex-shrink:0;"><?= mb_strtoupper(mb_substr($lending['borrower_name'], 0, 1)) ?></span>
<?php endif; ?>
<?= $this->e($lending['borrower_name']) ?>
</span>
</div>
<div class="lls-info-row">
<span class="lls-info-label"><?= $this->te('Zweck') ?></span>
<span class="lls-info-value"><?= $this->e($lending['purpose'] ?? '–') ?></span>
</div>
<?php if ($lending['borrower_email']): ?>
<div class="lls-info-row">
<span class="lls-info-label"><?= $this->te('E-Mail') ?></span>
<span class="lls-info-value"><a href="mailto:<?= $this->e($lending['borrower_email']) ?>" style="color:var(--amber-600);"><?= $this->e($lending['borrower_email']) ?></a></span>
</div>
<?php endif; ?>
<?php if ($lending['borrower_phone']): ?>
<div class="lls-info-row">
<span class="lls-info-label"><?= $this->te('Telefon') ?></span>
<span class="lls-info-value"><?= $this->e($lending['borrower_phone']) ?></span>
</div>
<?php endif; ?>
</div>
<div class="lls-info-grid">
<div class="lls-info-row">
<span class="lls-info-label"><?= $this->te('Geplant von') ?></span>
<span class="lls-info-value" style="font-weight:600;"><?= date('d.m.Y', strtotime($lending['planned_start'])) ?></span>
</div>
<div class="lls-info-row">
<span class="lls-info-label"><?= $this->te('Geplant bis') ?></span>
<span class="lls-info-value" style="font-weight:600;">
<?= date('d.m.Y', strtotime($lending['planned_end'])) ?>
<?php if (!empty($lending['extension_old_end'])): ?>
<span style="font-size:0.75rem;font-weight:400;color:var(--amber-600);margin-left:0.4rem;">(verlängert von <?= date('d.m.Y', strtotime($lending['extension_old_end'])) ?>)</span>
<?php endif; ?>
</span>
</div>
<?php if ($lending['actual_start']): ?>
<div class="lls-info-row">
<span class="lls-info-label"><?= $this->te('Tatsächlich ausgegeben') ?></span>
<span class="lls-info-value"><?= $this->te('{zeitpunkt} Uhr', ['zeitpunkt' => date('d.m.Y H:i', strtotime($lending['actual_start']))]) ?></span>
</div>
<?php endif; ?>
<?php if ($lending['actual_end']): ?>
<div class="lls-info-row">
<span class="lls-info-label"><?= $this->te('Tatsächlich zurück') ?></span>
<span class="lls-info-value"><?= $this->te('{zeitpunkt} Uhr', ['zeitpunkt' => date('d.m.Y H:i', strtotime($lending['actual_end']))]) ?></span>
</div>
<?php endif; ?>
</div>
</div>
</div>
<!-- Accessories -->
<?php if (!empty($accessories)): ?>
<div class="detail-card">
<div class="detail-card-header"><span class="detail-card-title"><?= $this->te('Mitgegebenes Zubehör') ?></span></div>
<div class="detail-card-body">
<?php foreach ($accessories as $acc):
$checkedOut = (bool)$acc['checked_out'];
$checkedIn = $acc['checked_in'] !== null ? (bool)$acc['checked_in'] : null;
if (!$checkedOut) continue;
?>
<div class="lls-acc-item <?= $checkedIn === true ? 'lls-acc-in' : ($checkedIn === false ? 'lls-acc-missing' : 'lls-acc-out') ?>">
<span class="lls-acc-icon">
<?php if ($checkedIn === true): ?>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#16a34a" stroke-width="2.5"><path d="M20 6L9 17l-5-5"/></svg>
<?php elseif ($checkedIn === false): ?>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#dc2626" stroke-width="2.5"><path d="M18 6L6 18M6 6l12 12"/></svg>
<?php else: ?>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#d97706" stroke-width="2.5"><path d="M20.24 12.24a6 6 0 00-8.49-8.49L5 10.5V19h8.5z"/></svg>
<?php endif; ?>
</span>
<span class="lls-acc-name"><?= $this->e($acc['name']) ?></span>
<?php if ($checkedIn === true): ?>
<span class="status-pill status-pill--success"><?= $this->te('Zurück') ?></span>
<?php elseif ($checkedIn === false): ?>
<span class="status-pill status-pill--danger"><?= $this->te('Nicht zurück') ?></span>
<?php else: ?>
<span class="status-pill status-pill--warning"><?= $this->te('Ausgeliehen') ?></span>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
<!-- Ablehnungsgrund (abgelehnte Self-Service-Anfrage) -->
<?php if (!empty($lending['rejection_reason'])): ?>
<div class="detail-card">
<div class="detail-card-header"><span class="detail-card-title"><?= $this->te('Ablehnungsgrund') ?></span></div>
<div class="detail-card-body">
<p style="font-size:0.88rem;color:var(--red-700);white-space:pre-line;"><?= $this->e($lending['rejection_reason']) ?></p>
</div>
</div>
<?php endif; ?>
<!-- Notes / Return notes -->
<?php if (!empty($lending['notes']) || !empty($lending['return_notes'])): ?>
<div class="detail-card">
<div class="detail-card-header"><span class="detail-card-title"><?= $this->te('Notizen') ?></span></div>
<div class="detail-card-body" style="display:flex;flex-direction:column;gap:0.75rem;">
<?php if (!empty($lending['notes'])): ?>
<div>
<div style="font-size:0.72rem;font-weight:700;text-transform:uppercase;letter-spacing:0.05em;color:var(--gray-400);margin-bottom:0.35rem;"><?= $this->te('Ausgabe-Notiz') ?></div>
<p style="font-size:0.88rem;color:var(--gray-600);white-space:pre-line;"><?= $this->e($lending['notes']) ?></p>
</div>
<?php endif; ?>
<?php if (!empty($lending['return_notes'])): ?>
<div>
<div style="font-size:0.72rem;font-weight:700;text-transform:uppercase;letter-spacing:0.05em;color:var(--gray-400);margin-bottom:0.35rem;"><?= $this->te('Rücknahme-Notiz') ?></div>
<p style="font-size:0.88rem;color:var(--gray-600);white-space:pre-line;"><?= $this->e($lending['return_notes']) ?></p>
</div>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
</div>
<!-- Sidebar -->
<div class="lls-aside">
<!-- Device -->
<div class="detail-card">
<div class="detail-card-header"><span class="detail-card-title"><?= $this->te('Gerät') ?></span></div>
<div class="detail-card-body">
<a href="/loans/devices/<?= $lending['device_id'] ?>" class="lls-device-preview">
<div class="lls-device-img">
<?php if (!empty($lending['device_image'])): ?>
<img src="<?= $this->e($lending['device_image']) ?>" alt="">
<?php else: ?>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#9ca3af" stroke-width="1.5"><rect x="2" y="3" width="20" height="14" rx="2"/><path d="M8 21h8M12 17v4"/></svg>
<?php endif; ?>
</div>
<div>
<div class="lls-device-info-name"><?= $this->e($lending['device_title']) ?></div>
<div class="lls-device-info-meta">
<?= $this->e($lending['device_type']) ?>
<?php if (!empty($lending['serial_number'])): ?> · S/N <?= $this->e($lending['serial_number']) ?><?php endif; ?>
</div>
</div>
</a>
</div>
</div>
<?php if (!empty($group_lendings)): ?>
<!-- Group: other devices in same lending -->
<div class="detail-card">
<div class="detail-card-header"><span class="detail-card-title"><?= $this->te('Kombinierter Verleih') ?></span></div>
<div class="detail-card-body" style="display:flex;flex-direction:column;gap:0.6rem;">
<p style="font-size:0.78rem;color:var(--gray-500);margin-bottom:0.25rem;"><?= count($group_lendings) === 1
? $this->te('Dieses Gerät wurde gemeinsam mit einem weiteren Gerät ausgegeben:')
: $this->t('Dieses Gerät wurde gemeinsam mit {anzahl} weiteren Geräten ausgegeben:', ['anzahl' => count($group_lendings)]) ?></p>
<?php foreach ($group_lendings as $gl):
$glStatusCfg = ['reserved'=>['status-pill--warning','Reserviert'],'active'=>['status-pill--success','Aktiv'],'returned'=>['status-pill--neutral','Zurück'],'cancelled'=>['status-pill--danger','Storniert']];
[$glCol, $glLbl] = $glStatusCfg[$gl['status']] ?? ['status-pill--neutral','?'];
?>
<a href="/loans/lendings/<?= $gl['id'] ?>" class="lls-device-preview">
<div class="lls-device-img">
<?php if (!empty($gl['device_image'])): ?>
<img src="<?= $this->e($gl['device_image']) ?>" alt="">
<?php else: ?>
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#9ca3af" stroke-width="1.5"><rect x="2" y="3" width="20" height="14" rx="2"/><path d="M8 21h8M12 17v4"/></svg>
<?php endif; ?>
</div>
<div style="flex:1;min-width:0;">
<div class="lls-device-info-name"><?= $this->e($gl['device_title']) ?></div>
<div class="lls-device-info-meta"><?= $this->e($gl['device_type'] ?? '') ?></div>
</div>
<span class="status-pill <?= $glCol ?>" style="flex-shrink:0;"><?= $glLbl ?></span>
</a>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
<!-- Staff -->
<div class="detail-card">
<div class="detail-card-header"><span class="detail-card-title"><?= $this->te('Mitarbeitende') ?></span></div>
<div class="detail-card-body">
<div class="lls-info-list">
<div class="lls-info-row">
<span class="lls-info-label"><?= $this->te('Reserviert von') ?></span>
<span class="lls-info-value"><?= $this->e($lending['created_by_name'] ?? '–') ?></span>
</div>
<div class="lls-info-row">
<span class="lls-info-label"><?= $this->te('Herausgegeben von') ?></span>
<span class="lls-info-value"><?= $this->e($lending['issued_by_name'] ?? '–') ?></span>
</div>
<div class="lls-info-row">
<span class="lls-info-label"><?= $this->te('Zurückgenommen von') ?></span>
<span class="lls-info-value"><?= $this->e($lending['returned_by_name'] ?? '–') ?></span>
</div>
<?php if (!empty($lending['extended_by_name'])): ?>
<div class="lls-info-row" style="border-top:1px solid var(--gray-100);padding-top:0.75rem;margin-top:0.25rem;">
<span class="lls-info-label" style="color:var(--amber-600);"><?= $this->te('Verlängert von') ?></span>
<span class="lls-info-value" style="font-weight:600;"><?= $this->e($lending['extended_by_name']) ?></span>
<?php if (!empty($lending['extension_at'])): ?>
<span class="lls-info-value" style="font-size:0.78rem;color:var(--gray-500);"><?= $this->te('{zeitpunkt} Uhr', ['zeitpunkt' => date('d.m.Y H:i', strtotime($lending['extension_at']))]) ?></span>
<?php endif; ?>
<?php if (!empty($lending['extension_reason'])): ?>
<span class="lls-info-label" style="margin-top:0.35rem;"><?= $this->te('Begründung') ?></span>
<span class="lls-info-value" style="font-size:0.85rem;color:var(--gray-700);"><?= $this->e($lending['extension_reason']) ?></span>
<?php endif; ?>
</div>
<?php endif; ?>
<div class="lls-info-row">
<span class="lls-info-label"><?= $this->te('Erstellt am') ?></span>
<span class="lls-info-value"><?= $this->te('{zeitpunkt} Uhr', ['zeitpunkt' => date('d.m.Y H:i', strtotime($lending['created_at']))]) ?></span>
</div>
</div>
</div>
</div>
<!-- Unterschrift -->
<?php if (!empty($lending['signature_data'])): ?>
<div class="detail-card">
<div class="detail-card-header"><span class="detail-card-title"><?= $this->te('Unterschrift') ?></span></div>
<div class="detail-card-body">
<img src="<?= $this->e($lending['signature_data']) ?>" alt="<?= $this->te('Unterschrift') ?>"
id="sigThumb"
title="<?= $this->te('Klicken zum Vergrößern') ?>"
style="max-width:100%;border:1px solid var(--gray-200);border-radius:0.25rem;background:var(--color-bg);cursor:zoom-in;">
<div style="margin-top:0.6rem;font-size:0.78rem;color:var(--gray-500);">
<?= $this->t('Erhalten am') ?> <?= $this->te('{zeitpunkt} Uhr', ['zeitpunkt' => date('d.m.Y H:i', strtotime($lending['signature_obtained_at']))]) ?>
</div>
</div>
</div>
<!-- Lightbox -->
<div id="sigLightbox" style="display:none;position:fixed;inset:0;z-index:9999;background:rgba(0,0,0,0.75);align-items:center;justify-content:center;cursor:zoom-out;"
onclick="document.getElementById('sigLightbox').style.display='none';">
<img src="<?= $this->e($lending['signature_data']) ?>" alt="<?= $this->te('Unterschrift') ?>"
style="max-width:90vw;max-height:90vh;border-radius:0.25rem;background:var(--color-bg);box-shadow:0 25px 50px rgba(0,0,0,0.4);padding:1rem;">
</div>
<script>
document.getElementById('sigThumb').addEventListener('click', function() {
document.getElementById('sigLightbox').style.display = 'flex';
});
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape') document.getElementById('sigLightbox').style.display = 'none';
});
</script>
<?php elseif ($sigPending): ?>
<div class="detail-card">
<div class="detail-card-header"><span class="detail-card-title"><?= $this->te('Unterschrift') ?></span></div>
<div class="detail-card-body" style="display:flex;align-items:center;gap:0.6rem;">
<span style="display:inline-flex;width:8px;height:8px;border-radius:50%;background:var(--amber-600);flex-shrink:0;animation:sig-pulse 1.5s infinite;"></span>
<span style="font-size:0.85rem;color:var(--amber-800);font-weight:600;"><?= $this->te('Warte auf Unterschrift…') ?></span>
</div>
<style>
@keyframes sig-pulse{0%,100%{opacity:1;}50%{opacity:0.3;}}
@media (prefers-reduced-motion: reduce) { [style*="sig-pulse"] { animation: none !important; } }
</style>
</div>
<script>
(function() {
var timer = setInterval(function() {
fetch('/api/loans/lendings/<?= (int)$lending['id'] ?>/signature-status', { cache: 'no-store' })
.then(function(r) { return r.json(); })
.then(function(data) {
// pending = weiter warten; alles andere (obtained/expired/none)
// → neu laden, damit die UI den aktuellen Stand zeigt.
if (data.status !== 'pending') {
clearInterval(timer);
location.reload();
}
})
.catch(function() { /* ignore network hiccups */ });
}, 3000);
}());
</script>
<?php endif; ?>
</div>
</div>
</div>
<?php if ($can_issue && $lending['status'] === 'pending'): ?>
<!-- Ablehnungs-Modal -->
<div id="rejectModal" class="modal-overlay" style="display:none;">
<div class="modal-card" style="max-width:440px;">
<div class="modal-header">
<h2><?= $this->te('Anfrage ablehnen') ?></h2>
<button type="button" class="modal-close" onclick="closeRejectModal()" aria-label="<?= $this->te('Schließen') ?>">×</button>
</div>
<form method="POST" action="/loans/lendings/<?= $lending['id'] ?>/reject">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<div class="modal-body">
<div class="form-group">
<label for="rejReason"><?= $this->te('Begründung (wird dem Anfragenden mitgeteilt)') ?></label>
<textarea id="rejReason" name="rejection_reason" rows="3" class="form-control"
placeholder="<?= $this->te('z.B. Gerät ist im gewünschten Zeitraum bereits verplant...') ?>"></textarea>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" onclick="closeRejectModal()"><?= $this->te('Abbrechen') ?></button>
<button type="submit" class="btn btn-danger"><?= $this->te('Anfrage ablehnen') ?></button>
</div>
</form>
</div>
</div>
<script>
function openRejectModal() { var m = document.getElementById('rejectModal'); m.style.display = 'flex'; var f = document.getElementById('rejReason'); if (f) setTimeout(function(){ f.focus(); }, 30); }
function closeRejectModal() { document.getElementById('rejectModal').style.display = 'none'; }
document.getElementById('rejectModal').addEventListener('click', function(e) { if (e.target === this) closeRejectModal(); });
document.addEventListener('keydown', function(e) { if (e.key === 'Escape') { var m = document.getElementById('rejectModal'); if (m && m.style.display === 'flex') closeRejectModal(); } });
</script>
<?php endif; ?>
<?php if ($can_issue && in_array($lending['status'], ['active','reserved'])): ?>
<form id="cancelForm" method="POST" action="/loans/lendings/<?= $lending['id'] ?>/cancel" style="display:none;">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
</form>
<!-- Herausgeben-Modal -->
<?php if ($lending['status'] === 'reserved'): ?>
<div id="issueModal" class="modal-overlay" style="display:none;">
<div class="modal-card" style="max-width:480px;">
<div class="modal-header">
<div>
<h2><?= $this->te('Gerät herausgeben') ?></h2>
<p style="margin:0.15rem 0 0;font-size:0.82rem;color:var(--gray-500);"><?= $this->te('Bitte bestätigen Sie, welches Zubehör mitgegeben wird.') ?></p>
</div>
<button type="button" class="modal-close" onclick="closeIssueModal()" aria-label="<?= $this->te('Schließen') ?>">×</button>
</div>
<form method="POST" action="/loans/lendings/<?= $lending['id'] ?>/issue">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<div class="modal-body">
<?php
$issueAccessories = array_filter($accessories ?? [], fn($a) => (bool)$a['checked_out'] || $a['checked_out'] === null);
// Show all device accessories (from device), not just pre-selected ones
$allDeviceAccs = $accessories ?? [];
?>
<?php if (!empty($allDeviceAccs)): ?>
<p style="font-size:0.78rem;font-weight:700;text-transform:uppercase;letter-spacing:0.05em;color:var(--gray-500);margin:0 0 0.75rem;"><?= $this->te('Zubehör') ?></p>
<div style="display:flex;flex-direction:column;gap:0.4rem;">
<?php foreach ($allDeviceAccs as $acc): ?>
<label style="display:flex;align-items:center;gap:0.75rem;padding:0.6rem 0.75rem;border-radius:0.25rem;border:1px solid var(--gray-200);cursor:pointer;transition:background 0.1s;"
onmouseover="this.style.background='var(--gray-50)'" onmouseout="this.style.background=''">
<input type="checkbox" name="accessories[<?= (int)$acc['accessory_id'] ?>]" value="1"
<?= $acc['checked_out'] ? 'checked' : '' ?>
style="width:16px;height:16px;cursor:pointer;accent-color:var(--amber-600);">
<span style="font-size:0.88rem;font-weight:600;color:var(--gray-700);flex:1;"><?= $this->e($acc['name']) ?></span>
<?php if (!empty($acc['description'])): ?>
<span style="font-size:0.75rem;color:var(--gray-400);"><?= $this->e($acc['description']) ?></span>
<?php endif; ?>
</label>
<?php endforeach; ?>
</div>
<?php else: ?>
<p style="font-size:0.88rem;color:var(--gray-500);text-align:center;padding:0.75rem 0;"><?= $this->te('Kein Zubehör erfasst.') ?></p>
<?php endif; ?>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" onclick="closeIssueModal()"><?= $this->te('Abbrechen') ?></button>
<button type="submit" class="btn btn-primary">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
<?= $this->te('Herausgeben') ?>
</button>
</div>
</form>
</div>
</div>
<?php endif; ?>
<!-- Verlängerungs-Modal -->
<div id="extendModal" class="modal-overlay" style="display:none;">
<div class="modal-card" style="max-width:440px;">
<div class="modal-header">
<h2><?= $this->te('Ausleihe verlängern') ?></h2>
<button type="button" class="modal-close" onclick="closeExtendModal()" aria-label="<?= $this->te('Schließen') ?>">×</button>
</div>
<form method="POST" action="/loans/lendings/<?= $lending['id'] ?>/extend">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<div class="modal-body" style="display:flex;flex-direction:column;gap:1rem;">
<div>
<label style="display:block;font-size:0.78rem;font-weight:700;text-transform:uppercase;letter-spacing:0.05em;color:var(--gray-500);margin-bottom:0.4rem;"><?= $this->te('Bisheriges Datum') ?></label>
<div style="font-size:0.9rem;font-weight:600;color:var(--gray-700);"><?= date('d.m.Y', strtotime($lending['planned_end'])) ?></div>
</div>
<div class="form-group">
<label for="extNewEnd"><?= $this->te('Neues Rückgabedatum') ?> <span class="text-danger">*</span></label>
<input type="date" id="extNewEnd" name="new_end_date" required class="form-control"
min="<?= date('Y-m-d', strtotime($lending['planned_end'] . ' +1 day')) ?>">
</div>
<div class="form-group">
<label for="extReason"><?= $this->te('Begründung') ?></label>
<textarea id="extReason" name="extension_reason" rows="3" class="form-control"
placeholder="<?= $this->te('z.B. Projekt dauert länger als geplant...') ?>"></textarea>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" onclick="closeExtendModal()"><?= $this->te('Abbrechen') ?></button>
<button type="submit" class="btn btn-primary"><?= $this->te('Verlängern') ?></button>
</div>
</form>
</div>
</div>
<script>
function cancelLending() {
if (confirm('Ausleihvorgang wirklich stornieren?')) {
document.getElementById('cancelForm').submit();
}
}
function openIssueModal() {
var m = document.getElementById('issueModal');
if (m) {
m.style.display = 'flex';
var f = m.querySelector('input, button[type=submit]');
if (f) setTimeout(function() { f.focus(); }, 30);
}
}
function closeIssueModal() {
var m = document.getElementById('issueModal');
if (m) { m.style.display = 'none'; }
}
document.addEventListener('DOMContentLoaded', function() {
var im = document.getElementById('issueModal');
if (im) im.addEventListener('click', function(e) { if (e.target === this) closeIssueModal(); });
});
function openExtendModal() {
var m = document.getElementById('extendModal');
m.style.display = 'flex';
var f = document.getElementById('extNewEnd');
if (f) setTimeout(function() { f.focus(); }, 30);
}
function closeExtendModal() {
document.getElementById('extendModal').style.display = 'none';
}
document.getElementById('extendModal').addEventListener('click', function(e) {
if (e.target === this) closeExtendModal();
});
// Escape schließt offene Modals
document.addEventListener('keydown', function(e) {
if (e.key !== 'Escape') return;
var im = document.getElementById('issueModal');
var em = document.getElementById('extendModal');
if (im && im.style.display === 'flex') closeIssueModal();
if (em && em.style.display === 'flex') closeExtendModal();
});
</script>
<?php endif; ?>