diff --git a/Web/app.py b/Web/app.py
index 3558f9f..9bbbd25 100755
--- a/Web/app.py
+++ b/Web/app.py
@@ -5918,6 +5918,11 @@ def get_bookings():
result = []
for booking in bookings:
+ raw_booking_user = booking.get('User') or ''
+ try:
+ booking_user = decrypt_text(raw_booking_user) if raw_booking_user else ''
+ except Exception:
+ booking_user = str(raw_booking_user)
start_dt = booking.get('Start')
if not start_dt:
continue
@@ -5960,10 +5965,10 @@ def get_bookings():
'end': end_dt.isoformat() if isinstance(end_dt, datetime.datetime) else str(end_dt),
'status': status,
'itemId': item_id,
- 'userName': str(booking.get('User') or ''),
+ 'userName': str(booking_user),
'notes': str(booking.get('Notes') or ''),
'period': period,
- 'isCurrentUser': str(booking.get('User') or '') == username,
+ 'isCurrentUser': str(booking_user) == username,
'itemBorrower': item_borrower,
})
@@ -7911,9 +7916,14 @@ def get_planned_bookings(item_id):
cursor = ausleihungen.find({'Item': item_id, 'Status': 'planned'}).sort('Start', 1)
bookings = []
for r in cursor:
+ raw_user = r.get('User') or ''
+ try:
+ booking_user = decrypt_text(raw_user) if raw_user else ''
+ except Exception:
+ booking_user = str(raw_user)
bookings.append({
'id': str(r.get('_id')),
- 'user': r.get('User', ''),
+ 'user': booking_user,
'period': r.get('Period'),
'start': r.get('Start').isoformat() if r.get('Start') else None,
'end': r.get('End').isoformat() if r.get('End') else None,
@@ -7940,7 +7950,13 @@ def get_planned_bookings_public(item_id):
cursor = ausleihungen.find({'Item': item_id, 'Status': 'planned'}).sort('Start', 1)
bookings = []
for r in cursor:
+ raw_user = r.get('User') or ''
+ try:
+ booking_user = decrypt_text(raw_user) if raw_user else ''
+ except Exception:
+ booking_user = str(raw_user)
bookings.append({
+ 'user': booking_user,
'period': r.get('Period'),
'start': r.get('Start').isoformat() if r.get('Start') else None,
'end': r.get('End').isoformat() if r.get('End') else None
@@ -12311,7 +12327,11 @@ def cancel_ausleihung_route(id):
# Log ausleihung details for debugging
ausleihung_status = ausleihung.get('Status', 'unknown')
- ausleihung_user = ausleihung.get('User', 'unknown')
+ raw_ausleihung_user = ausleihung.get('User', '')
+ try:
+ ausleihung_user = decrypt_text(raw_ausleihung_user) if raw_ausleihung_user else ''
+ except Exception:
+ ausleihung_user = str(raw_ausleihung_user or '')
print(f"Found ausleihung: ID={id}, Status={ausleihung_status}")
current_permissions = us.get_effective_permissions(session['username'])
diff --git a/Web/templates/main_admin.html b/Web/templates/main_admin.html
index 3df2731..ff3bf0d 100755
--- a/Web/templates/main_admin.html
+++ b/Web/templates/main_admin.html
@@ -4063,21 +4063,29 @@ document.addEventListener('DOMContentLoaded', ()=>{
const badgeText = entry.type === 'repair' ? 'Repariert' : 'Schaden';
const metaLine = entry.meta ? `
${escapeHtml(entry.meta)}
` : '';
return `
-
-
-
${badgeText}
-
${entry.dateLabel}
+
+
+ ${badgeText}
+
-
Von: ${entry.actor}
-
${entry.description}
- ${metaLine}
+
Von${entry.actor}
+
${entry.description}
+ ${entry.meta ? `
${escapeHtml(entry.meta)}
` : ''}
`;
}).join('')
: '
Keine Beschädigungs-Historie vorhanden.
';
modalContent.innerHTML = `
-
${escapeHtml(item.Name || '')}
+
+
+ Objektdetails
+
${escapeHtml(item.Name || '')}
+
+
+ ${isBorrowed ? 'Ausgeliehen' : 'Verfügbar'}
+
+
${borrowerInfoHtml}
${appointmentInfoHtml}
@@ -4090,7 +4098,7 @@ document.addEventListener('DOMContentLoaded', ()=>{
` : ''}
-
+
Ort:
${escapeHtml(item.Ort || '-')}
@@ -4145,22 +4153,22 @@ document.addEventListener('DOMContentLoaded', ()=>{
{% if current_permissions.actions.get('can_view_logs', False) %}
-
+
Beschädigungs-Historie
-
{% endif %}
-
Verfügbarkeit prüfen:
+
Verfügbarkeit prüfen
-
+
Geplante Ausleihen:
-
+
📅
Kalender anzeigen
@@ -5381,5 +5389,308 @@ document.addEventListener('DOMContentLoaded', ()=>{
border-radius: 10px !important;
}
}
+
+/* Detailed item modal: compact hierarchy and calm information density. */
+#item-modal .modal-content {
+ width: min(94vw, 880px);
+ max-width: 880px;
+ margin: 4vh auto;
+ padding: 0;
+ overflow: hidden;
+ border: 1px solid #d8e1eb;
+ border-radius: 16px;
+ background: var(--ui-surface);
+ box-shadow: 0 24px 70px rgba(15, 23, 42, 0.22);
+}
+
+#item-modal .modal-content > *:not(.item-modal-heading):not(.modal-image-container):not(.modal-details):not(.modal-actions) {
+ margin-left: 28px;
+ margin-right: 28px;
+}
+
+#item-modal .item-modal-heading {
+ display: flex;
+ align-items: flex-start;
+ justify-content: space-between;
+ gap: 18px;
+ padding: 26px 30px 22px;
+ border-bottom: 1px solid #e6edf4;
+ background: linear-gradient(180deg, #f8fbfe 0%, var(--ui-surface) 100%);
+}
+
+#item-modal .item-modal-eyebrow {
+ display: block;
+ margin-bottom: 5px;
+ color: #708197;
+ font-size: 0.72rem;
+ font-weight: 800;
+ letter-spacing: 0.12em;
+ text-transform: uppercase;
+}
+
+#item-modal .item-modal-heading h2 {
+ margin: 0;
+ color: #172536;
+ font-size: clamp(1.25rem, 2.5vw, 1.7rem);
+ line-height: 1.2;
+ text-align: left;
+ overflow-wrap: anywhere;
+}
+
+#item-modal .item-modal-status {
+ display: inline-flex;
+ align-items: center;
+ gap: 7px;
+ flex: 0 0 auto;
+ margin-top: 5px;
+ padding: 6px 10px;
+ border: 1px solid;
+ border-radius: 999px;
+ font-size: 0.78rem;
+ font-weight: 800;
+ white-space: nowrap;
+}
+
+#item-modal .item-modal-status.is-available {
+ color: #17633b;
+ border-color: #b9e2ca;
+ background: #effaf3;
+}
+
+#item-modal .item-modal-status.is-borrowed {
+ color: #9b3d32;
+ border-color: #f2c5bf;
+ background: #fff4f2;
+}
+
+#item-modal .item-modal-status-dot {
+ width: 7px;
+ height: 7px;
+ border-radius: 50%;
+ background: currentColor;
+}
+
+#item-modal .modal-image-container {
+ min-height: 180px;
+ margin: 0;
+ padding: 22px 28px;
+ border-radius: 0;
+ background: #f4f7fa;
+}
+
+#item-modal .modal-image {
+ max-height: 320px;
+ border-radius: 10px;
+ box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);
+}
+
+#item-modal .item-modal-details {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 0 22px;
+ margin: 0;
+ padding: 24px 28px 4px;
+}
+
+#item-modal .item-modal-details .detail-group {
+ display: block;
+ min-width: 0;
+ margin: 0;
+ padding: 12px 0;
+ border-bottom: 1px solid #edf1f5;
+}
+
+#item-modal .item-modal-details .detail-label {
+ min-width: 0;
+ margin: 0 0 4px;
+ color: #718096;
+ font-size: 0.72rem;
+ font-weight: 800;
+ letter-spacing: 0.06em;
+ text-transform: uppercase;
+}
+
+#item-modal .item-modal-details .detail-value {
+ min-width: 0;
+ color: #243447;
+ font-size: 0.95rem;
+ line-height: 1.45;
+ overflow-wrap: anywhere;
+}
+
+#item-modal .item-modal-details .detail-group.full-width,
+#item-modal .item-modal-details .item-modal-history,
+#item-modal .item-modal-details .item-modal-bookings {
+ grid-column: 1 / -1;
+}
+
+#item-modal .item-modal-details .detail-group.full-width .detail-value {
+ padding: 12px 14px;
+ border: 1px solid #e1e8ef;
+ border-radius: 9px;
+ background: #f8fafc;
+}
+
+#item-modal .item-modal-details .item-modal-history,
+#item-modal .item-modal-details .item-modal-bookings {
+ margin-top: 12px !important;
+ padding: 16px;
+ border: 1px solid #dfe7ef;
+ border-radius: 12px;
+ background: #fbfcfd;
+}
+
+#item-modal .modal-section-toggle {
+ min-height: 38px;
+ margin: 0 0 12px !important;
+ padding: 8px 12px;
+ border: 1px solid #cdd8e3;
+ border-radius: 8px;
+ background: var(--ui-surface);
+ color: #36516c;
+ font-size: 0.86rem;
+ font-weight: 750;
+ box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
+}
+
+#item-modal .modal-section-toggle:hover {
+ border-color: #9db6cc;
+ background: #f1f6fa;
+}
+
+#item-modal .modal-history-panel {
+ margin-top: 4px;
+ padding: 12px;
+ border: 1px solid #e2e9f0;
+ border-radius: 10px;
+ background: #f5f8fb;
+}
+
+#item-modal .damage-history-list {
+ display: grid;
+ gap: 9px;
+}
+
+#item-modal .damage-history-entry {
+ position: relative;
+ display: grid;
+ gap: 7px;
+ padding: 12px 14px 12px 17px;
+ border: 1px solid #dce5ed;
+ border-radius: 9px;
+ background: var(--ui-surface);
+}
+
+#item-modal .damage-history-entry::before {
+ position: absolute;
+ inset: 0 auto 0 0;
+ width: 3px;
+ content: '';
+ border-radius: 9px 0 0 9px;
+ background: #e35d54;
+}
+
+#item-modal .damage-history-entry.is-repair::before {
+ background: #3aa76d;
+}
+
+#item-modal .damage-history-entry-head {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 10px;
+}
+
+#item-modal .damage-history-badge {
+ padding: 3px 8px;
+ border-radius: 999px;
+ font-size: 0.72rem;
+ font-weight: 800;
+}
+
+#item-modal .damage-history-entry time,
+#item-modal .damage-history-meta {
+ color: #738196;
+ font-size: 0.78rem;
+}
+
+#item-modal .damage-history-actor {
+ display: flex;
+ gap: 5px;
+ color: #425466;
+ font-size: 0.84rem;
+}
+
+#item-modal .damage-history-actor strong {
+ color: #718096;
+ font-weight: 700;
+}
+
+#item-modal .damage-history-description {
+ color: #243447;
+ font-size: 0.91rem;
+ line-height: 1.4;
+}
+
+#item-modal .modal-actions {
+ justify-content: flex-end;
+ gap: 9px;
+ margin: 0;
+ padding: 18px 28px 24px;
+ border-top: 1px solid #e6edf4;
+ background: #fbfcfd;
+}
+
+@media (max-width: 640px) {
+ #item-modal .modal-content {
+ width: calc(100vw - 18px);
+ margin: 9px auto;
+ border-radius: 13px;
+ }
+
+ #item-modal .item-modal-heading {
+ align-items: flex-start;
+ flex-direction: column;
+ gap: 10px;
+ padding: 21px 20px 17px;
+ }
+
+ #item-modal .item-modal-status {
+ margin-top: 0;
+ }
+
+ #item-modal .modal-image-container {
+ padding: 16px 18px;
+ }
+
+ #item-modal .item-modal-details {
+ grid-template-columns: 1fr;
+ gap: 0;
+ padding: 16px 18px 0;
+ }
+
+ #item-modal .item-modal-details .detail-group.full-width,
+ #item-modal .item-modal-details .item-modal-history,
+ #item-modal .item-modal-details .item-modal-bookings {
+ grid-column: auto;
+ }
+
+ #item-modal .item-modal-details .item-modal-history,
+ #item-modal .item-modal-details .item-modal-bookings {
+ padding: 13px;
+ }
+
+ #item-modal .modal-actions {
+ justify-content: stretch;
+ padding: 15px 18px 19px;
+ }
+
+ #item-modal .modal-actions > *,
+ #item-modal .modal-actions form,
+ #item-modal .modal-actions button {
+ flex: 1 1 100%;
+ width: 100%;
+ }
+}
{% endblock %}