slight changes to the dispaying of the Detailed Library Modals

This commit is contained in:
2026-07-07 22:25:55 +02:00
parent 1a99448a2e
commit d0f2afae57
+50 -24
View File
@@ -4,7 +4,7 @@
{% block content %} {% block content %}
<style> <style>
/* 1. The Dark Background Overlay */ /* The Dark Background Overlay */
.modal { .modal {
position: fixed; position: fixed;
top: 0; top: 0;
@@ -12,13 +12,13 @@
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
background-color: rgba(0, 0, 0, 0.6); background-color: rgba(0, 0, 0, 0.6);
/* Ensure display is controlled by JS, but set up for centering */ /* Display is managed by JS (none/flex) */
align-items: center; align-items: center;
justify-content: center; justify-content: center;
z-index: 1000; z-index: 1000;
} }
/* 2. The White Modal Box */ /* The White Modal Box */
.modal-content { .modal-content {
background-color: #fff; background-color: #fff;
padding: 20px; padding: 20px;
@@ -26,16 +26,16 @@
max-width: 600px; max-width: 600px;
border-radius: 8px; border-radius: 8px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
/* These three lines are the magic for a fixed header + scrolling body */ /* Flexbox allows the header to stay fixed while the body scrolls */
display: flex; display: flex;
flex-direction: column; flex-direction: column;
max-height: 85vh; /* Prevents the box from being taller than the screen */ max-height: 85vh;
} }
/* 3. The Close Button */ /* The Close Button */
.close { .close {
align-self: flex-end; /* Pushes the 'x' to the right side */ align-self: flex-end;
color: #aaa; color: #aaa;
font-size: 28px; font-size: 28px;
font-weight: bold; font-weight: bold;
@@ -43,19 +43,18 @@
line-height: 1; line-height: 1;
margin-bottom: 10px; margin-bottom: 10px;
} }
.close:hover, .close:hover,
.close:focus { .close:focus {
color: #000; color: #000;
text-decoration: none; text-decoration: none;
} }
/* 4. The Scrollable Content Area */
#detailContent {
overflow-y: auto; /* Adds the scrollbar ONLY if the text is too long */
padding-right: 10px; /* Optional: adds a little breathing room for the scrollbar */
}
/* The Scrollable Content Area */
#detailContent {
overflow-y: auto; /* Adds scrollbar only if needed */
padding-right: 10px; /* Prevents text from rubbing against the scrollbar */
}
/* Library table-only view styles */ /* Library table-only view styles */
.library-table-container { .library-table-container {
max-width: 1400px; max-width: 1400px;
@@ -592,14 +591,14 @@
</div> </div>
</div> </div>
<!-- Detail Modal --> <script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.0.6/purify.min.js"></script>
<div id="detailModal" class="modal" style="display: none;"> <div id="detailModal" class="modal" style="display: none;">
<div class="modal-content"> <div class="modal-content">
<span class="close" onclick="closeDetailModal()">&times;</span> <span class="close" onclick="closeDetailModal()">&times;</span>
<div id="detailContent"></div> <div id="detailContent"></div>
</div> </div>
</div> </div>
<script src="https://cdn.jsdelivr.net/npm/@ericblade/quagga2/dist/quagga.js"></script> <script src="https://cdn.jsdelivr.net/npm/@ericblade/quagga2/dist/quagga.js"></script>
<script> <script>
// ========================================================================= // =========================================================================
@@ -1098,20 +1097,47 @@
return div.innerHTML; return div.innerHTML;
} }
// Opens the modal and fetches the data
function showItemDetail(itemId) { function showItemDetail(itemId) {
const detailContent = document.getElementById('detailContent');
const detailModal = document.getElementById('detailModal');
// 1. Show the loading state immediately
detailContent.innerHTML = '<p>Loading details...</p>';
detailModal.style.display = 'flex';
// 2. Fetch the data
fetch(`/api/item_detail/${itemId}`) fetch(`/api/item_detail/${itemId}`)
.then(r => r.text()) .then(response => {
.then(html => { if (!response.ok) {
document.getElementById('detailContent').innerHTML = html; throw new Error(`HTTP error! status: ${response.status}`);
document.getElementById('detailModal').style.display = 'flex'; }
return response.text();
}) })
.catch(err => console.error('Error loading detail:', err)); .then(html => {
// 3. Clean the HTML and display it
detailContent.innerHTML = DOMPurify.sanitize(html);
})
.catch(err => {
console.error('Error loading detail:', err);
detailContent.innerHTML = '<p>Sorry, we could not load the item details. Please try again later.</p>';
});
} }
// Closes the modal via the 'x' button
function closeDetailModal() { function closeDetailModal() {
document.getElementById('detailModal').style.display = 'none'; document.getElementById('detailModal').style.display = 'none';
} }
// Closes the modal if the user clicks the dark background overlay
window.onclick = function(event) {
const modal = document.getElementById('detailModal');
// If the click happened directly on the dark overlay (not the white box)
if (event.target === modal) {
closeDetailModal();
}
};
// ========================================================================= // =========================================================================
// 5. EVENT LISTENERS INITIALIZATION & ON-LOAD INITIALIZER // 5. EVENT LISTENERS INITIALIZATION & ON-LOAD INITIALIZER
// ========================================================================= // =========================================================================