Fix: Bilderdarstellung in Artikel-Kachelansicht
All checks were successful
Docker Build & Push / build-and-push (push) Successful in 37s

This commit is contained in:
Gemini
2026-05-14 18:16:23 +00:00
parent 1847528363
commit 7ff740b7ff

View File

@@ -177,7 +177,7 @@ $conn->close();
</div>
<div id="view-container-grid" class="p-3" style="max-height: 75vh; overflow-y: auto; display: none;">
<div class="row g-3" id="articlesGridBody"></div>
<div class="lager-grid" id="articlesGridBody"></div>
</div>
</div>
</div>
@@ -218,6 +218,45 @@ $conn->close();
</div>
<div id="image-preview-tooltip" class="image-preview-tooltip"></div>
<style>
.lager-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(145px, 1fr));
gap: 12px; padding: 5px;
align-items: start;
}
.lager-card {
border: 1px solid #eee; border-radius: 8px; padding: 6px;
text-align: center; background: #fff; display: flex; flex-direction: column;
transition: transform 0.1s, box-shadow 0.1s;
height: 200px;
position: relative;
}
.lager-card:hover { transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0,0,0,0.05); }
.lager-img-wrapper {
width: 100%; height: 90px; margin-bottom: 6px; display: flex;
align-items: center; justify-content: center; overflow: hidden;
flex-shrink: 0;
}
.lager-img-wrapper img.lager-card-img {
width: 100% !important; height: 100% !important;
max-width: 100% !important; max-height: 90px !important;
object-fit: contain !important; border-radius: 4px;
}
.lager-title {
font-size: 0.85em; font-weight: 600; margin-bottom: 2px;
line-height: 1.1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
flex-shrink: 0;
}
.lager-meta {
font-size: 0.7em; color: #6c757d; margin-bottom: 2px;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
line-height: 1.1; flex-shrink: 0;
}
.lager-controls {
margin-top: auto;
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function () {
const articlesData = <?php echo json_encode($articles); ?>;
@@ -358,47 +397,38 @@ document.addEventListener('DOMContentLoaded', function () {
function generateCardHTML(article) {
const imagePath = article.image_url ? article.image_url : 'assets/images/keinbild.png';
const productLink = article.product_url ? `<a href="${article.product_url}" target="_blank" class="btn btn-sm btn-outline-secondary" data-bs-toggle="tooltip" title="Produktseite öffnen"><i class="fas fa-external-link-alt"></i></a>` : '';
const householdBadge = article.household_id ? `<span class="badge bg-success" data-bs-toggle="tooltip" title="Für den Haushalt freigegeben"><i class="fas fa-users"></i></span>` : `<span class="badge bg-secondary" data-bs-toggle="tooltip" title="Privater Artikel"><i class="fas fa-user"></i></span>`;
const consumableIcon = article.consumable == 1 ? ` <i class="fas fa-cookie-bite text-warning" data-bs-toggle="tooltip" title="Verbrauchsartikel"></i>` : '';
const quantityBadge = article.consumable == 1 ? `<span class="badge bg-secondary rounded-pill" data-bs-toggle="tooltip" title="Verbrauchsartikel">&infin;</span>` : `<span class="badge bg-secondary rounded-pill">${article.quantity_owned} x</span>`;
const productLink = article.product_url ? `<a href="${article.product_url}" target="_blank" class="btn btn-sm btn-outline-secondary px-1 py-0" title="Produktseite öffnen"><i class="fas fa-external-link-alt"></i></a>` : '';
const householdBadge = article.household_id ? `<span class="badge bg-success" title="Für den Haushalt freigegeben"><i class="fas fa-users"></i></span>` : `<span class="badge bg-secondary" title="Privater Artikel"><i class="fas fa-user"></i></span>`;
const consumableIcon = article.consumable == 1 ? ` <i class="fas fa-cookie-bite text-warning" title="Verbrauchsartikel"></i>` : '';
const quantityBadge = article.consumable == 1 ? `<span class="badge bg-secondary rounded-pill" title="Verbrauchsartikel">&infin;</span>` : `<span class="badge bg-secondary rounded-pill">${article.quantity_owned}x</span>`;
let actionButtons = '';
const isOwner = (article.user_id == currentUserId);
const isHouseholdArticle = (article.household_id && article.household_id == currentUserHouseholdId);
if (isOwner || isHouseholdArticle) {
actionButtons = `<div class="btn-group">
<a href="edit_article.php?id=${article.id}" class="btn btn-sm btn-outline-primary" data-bs-toggle="tooltip" title="Bearbeiten"><i class="fas fa-edit"></i></a>`;
actionButtons += `<form action="articles.php" method="post" class="d-inline" onsubmit="return confirm('Sind Sie sicher?');"><input type="hidden" name="delete_article_id" value="${article.id}"><button type="submit" class="btn btn-sm btn-outline-danger" data-bs-toggle="tooltip" title="Löschen"><i class="fas fa-trash"></i></button></form>`;
actionButtons += `</div>`;
actionButtons = `
<a href="edit_article.php?id=${article.id}" class="btn btn-sm btn-outline-primary px-1 py-0" title="Bearbeiten"><i class="fas fa-edit"></i></a>
<form action="articles.php" method="post" class="d-inline" onsubmit="return confirm('Sind Sie sicher?');"><input type="hidden" name="delete_article_id" value="${article.id}"><button type="submit" class="btn btn-sm btn-outline-danger px-1 py-0" title="Löschen"><i class="fas fa-trash"></i></button></form>`;
}
const metaText = [article.manufacturer_name, article.product_designation].filter(Boolean).join(' - ');
return `
<div class="col-12 col-sm-6 col-md-4 col-lg-3">
<div class="card h-100 shadow-sm position-relative border-0 article-card">
<img src="${imagePath}" class="card-img-top article-image-trigger" data-preview-url="${imagePath}" alt="${article.name}" style="height: 180px; object-fit: cover; cursor: pointer; border-radius: calc(.25rem - 1px) calc(.25rem - 1px) 0 0;">
<div class="position-absolute top-0 end-0 p-2">
${householdBadge} ${consumableIcon}
</div>
<div class="card-body d-flex flex-column p-3">
<h5 class="card-title text-truncate mb-2" title="${article.name}">${article.name}</h5>
<div class="mb-2">
<span class="badge bg-light text-dark border"><i class="fas fa-weight-hanging me-1"></i> ${new Intl.NumberFormat('de-DE').format(article.weight_grams)} g</span>
${quantityBadge}
</div>
<div class="mb-3">
<span class="badge bg-info text-dark border">${article.category_name || 'Ohne Kat.'}</span>
</div>
<p class="card-text small text-muted mb-1 mt-auto" style="line-height: 1.2;">
${article.manufacturer_name ? `<strong>Hersteller:</strong> ${article.manufacturer_name}<br>` : ''}
${article.product_designation ? `<strong>Modell:</strong> ${article.product_designation}` : ''}
</p>
</div>
<div class="card-footer bg-light border-top d-flex justify-content-between align-items-center p-2">
${productLink}
${actionButtons}
</div>
<div class="lager-card article-card" title="${article.name}${metaText ? ' (' + metaText + ')' : ''}">
<div class="position-absolute top-0 end-0 p-1" style="z-index: 10;">
${householdBadge} ${consumableIcon}
</div>
<div class="lager-img-wrapper">
<img src="${imagePath}" class="lager-card-img article-image-trigger" data-preview-url="${imagePath}" alt="${article.name}" style="cursor: pointer;">
</div>
<div class="lager-title">${article.name}</div>
<div class="lager-meta">${metaText}</div>
<div class="text-muted d-block mb-1" style="font-size:0.75em;">${new Intl.NumberFormat('de-DE').format(article.weight_grams)} g | ${quantityBadge}</div>
<div class="lager-meta"><span class="badge bg-info text-dark border w-100 text-truncate p-1">${article.category_name || 'Ohne Kat.'}</span></div>
<div class="lager-controls d-flex justify-content-center gap-1 mt-auto">
${productLink}
${actionButtons}
</div>
</div>
`;