Produktfotos: Von VanVan im Adminbereich hochgeladene Bilder werden jetzt auf Produktkarten und der Produktdetailseite angezeigt (Hauptbild + klickbare Miniaturbilder), statt immer nur den Platzhalter zu zeigen

This commit is contained in:
qcigano
2026-08-02 16:08:25 +02:00
parent 63dd57d529
commit 345dd736ba
6 changed files with 117 additions and 35 deletions
+4
View File
@@ -20,9 +20,13 @@ const desc = product.beschreibung[lang];
---
<a href={`${localePrefix(lang)}/produkt/${product.slug}/`} class="card product-card">
<div class="product-media">
{product.bilder && product.bilder.length > 0 ? (
<img class="product-photo" src={product.bilder[0]} alt={name} loading="lazy" />
) : (
<div class="img-placeholder" role="img" aria-label={`${t.common.photoSoon}: ${name}`}>
{t.common.photoSoon}<br /><span class="small">{name}</span>
</div>
)}
<div class="product-badges">
{product.badges.map((b) => (
<span class={`badge ${b === "sale" ? "badge-sale" : ""}`}>{badgeLabel[b]}</span>
+21 -5
View File
@@ -42,14 +42,22 @@ const felder: [string, string | undefined][] = [
<div class="grid grid-2 product-detail">
<div>
{product.bilder && product.bilder.length > 0 ? (
<>
<img id="product-hero-img" class="product-photo product-hero" src={product.bilder[0]} alt={name} />
{product.bilder.length > 1 && (
<div class="thumb-row">
{product.bilder.map((bild) => (
<img class="product-photo thumb" src={bild} alt={name} data-full={bild} />
))}
</div>
)}
</>
) : (
<div class="img-placeholder product-hero" role="img" aria-label={`${t.common.photoSoon}: ${name}`}>
{t.common.photoSoon}<br /><span class="small">{t.product.photoNote}</span>
</div>
<div class="thumb-row">
<div class="img-placeholder thumb"></div>
<div class="img-placeholder thumb"></div>
<div class="img-placeholder thumb"></div>
</div>
)}
</div>
<div>
@@ -118,4 +126,12 @@ const felder: [string, string | undefined][] = [
confirm.style.display = "block";
setTimeout(() => (confirm.style.display = "none"), 2500);
});
// Klick auf ein Miniaturbild zeigt es groß im Hauptbild an (mehrere Produktfotos).
const heroImg = document.getElementById("product-hero-img") as HTMLImageElement | null;
document.querySelectorAll<HTMLImageElement>(".thumb.product-photo").forEach((thumb) => {
thumb.addEventListener("click", () => {
if (heroImg && thumb.dataset.full) heroImg.src = thumb.dataset.full;
});
});
</script>
+21 -5
View File
@@ -42,14 +42,22 @@ const felder: [string, string | undefined][] = [
<div class="grid grid-2 product-detail">
<div>
{product.bilder && product.bilder.length > 0 ? (
<>
<img id="product-hero-img" class="product-photo product-hero" src={product.bilder[0]} alt={name} />
{product.bilder.length > 1 && (
<div class="thumb-row">
{product.bilder.map((bild) => (
<img class="product-photo thumb" src={bild} alt={name} data-full={bild} />
))}
</div>
)}
</>
) : (
<div class="img-placeholder product-hero" role="img" aria-label={`${t.common.photoSoon}: ${name}`}>
{t.common.photoSoon}<br /><span class="small">{t.product.photoNote}</span>
</div>
<div class="thumb-row">
<div class="img-placeholder thumb"></div>
<div class="img-placeholder thumb"></div>
<div class="img-placeholder thumb"></div>
</div>
)}
</div>
<div>
@@ -118,4 +126,12 @@ const felder: [string, string | undefined][] = [
confirm.style.display = "block";
setTimeout(() => (confirm.style.display = "none"), 2500);
});
// Klick auf ein Miniaturbild zeigt es groß im Hauptbild an (mehrere Produktfotos).
const heroImg = document.getElementById("product-hero-img") as HTMLImageElement | null;
document.querySelectorAll<HTMLImageElement>(".thumb.product-photo").forEach((thumb) => {
thumb.addEventListener("click", () => {
if (heroImg && thumb.dataset.full) heroImg.src = thumb.dataset.full;
});
});
</script>
+21 -5
View File
@@ -42,14 +42,22 @@ const felder: [string, string | undefined][] = [
<div class="grid grid-2 product-detail">
<div>
{product.bilder && product.bilder.length > 0 ? (
<>
<img id="product-hero-img" class="product-photo product-hero" src={product.bilder[0]} alt={name} />
{product.bilder.length > 1 && (
<div class="thumb-row">
{product.bilder.map((bild) => (
<img class="product-photo thumb" src={bild} alt={name} data-full={bild} />
))}
</div>
)}
</>
) : (
<div class="img-placeholder product-hero" role="img" aria-label={`${t.common.photoSoon}: ${name}`}>
{t.common.photoSoon}<br /><span class="small">{t.product.photoNote}</span>
</div>
<div class="thumb-row">
<div class="img-placeholder thumb"></div>
<div class="img-placeholder thumb"></div>
<div class="img-placeholder thumb"></div>
</div>
)}
</div>
<div>
@@ -118,4 +126,12 @@ const felder: [string, string | undefined][] = [
confirm.style.display = "block";
setTimeout(() => (confirm.style.display = "none"), 2500);
});
// Klick auf ein Miniaturbild zeigt es groß im Hauptbild an (mehrere Produktfotos).
const heroImg = document.getElementById("product-hero-img") as HTMLImageElement | null;
document.querySelectorAll<HTMLImageElement>(".thumb.product-photo").forEach((thumb) => {
thumb.addEventListener("click", () => {
if (heroImg && thumb.dataset.full) heroImg.src = thumb.dataset.full;
});
});
</script>
+21 -5
View File
@@ -42,14 +42,22 @@ const felder: [string, string | undefined][] = [
<div class="grid grid-2 product-detail">
<div>
{product.bilder && product.bilder.length > 0 ? (
<>
<img id="product-hero-img" class="product-photo product-hero" src={product.bilder[0]} alt={name} />
{product.bilder.length > 1 && (
<div class="thumb-row">
{product.bilder.map((bild) => (
<img class="product-photo thumb" src={bild} alt={name} data-full={bild} />
))}
</div>
)}
</>
) : (
<div class="img-placeholder product-hero" role="img" aria-label={`${t.common.photoSoon}: ${name}`}>
{t.common.photoSoon}<br /><span class="small">{t.product.photoNote}</span>
</div>
<div class="thumb-row">
<div class="img-placeholder thumb"></div>
<div class="img-placeholder thumb"></div>
<div class="img-placeholder thumb"></div>
</div>
)}
</div>
<div>
@@ -118,4 +126,12 @@ const felder: [string, string | undefined][] = [
confirm.style.display = "block";
setTimeout(() => (confirm.style.display = "none"), 2500);
});
// Klick auf ein Miniaturbild zeigt es groß im Hauptbild an (mehrere Produktfotos).
const heroImg = document.getElementById("product-hero-img") as HTMLImageElement | null;
document.querySelectorAll<HTMLImageElement>(".thumb.product-photo").forEach((thumb) => {
thumb.addEventListener("click", () => {
if (heroImg && thumb.dataset.full) heroImg.src = thumb.dataset.full;
});
});
</script>
+14
View File
@@ -220,6 +220,20 @@ a.card:hover {
background-image: repeating-linear-gradient(135deg, rgba(244,241,247,0.03) 0 2px, transparent 2px 14px);
}
/* Echtes Produktfoto (von VanVan im Adminbereich hochgeladen) — ersetzt den Platzhalter, sobald
`bilder` am Produkt gesetzt ist. Gleiche Maße/Ecken wie der Platzhalter, damit beim Hochladen
des ersten Fotos nichts im Layout springt. */
.product-photo {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
border-radius: var(--radius-m);
}
.product-media .product-photo { aspect-ratio: 1 / 1; }
.thumb.product-photo { cursor: pointer; transition: outline-color 0.2s var(--ease); outline: 2px solid transparent; outline-offset: 2px; }
.thumb.product-photo:hover { outline-color: var(--c-accent); }
/* Portrait-Frame — edler Bilderrahmen für Porträtfotos (Startseite, Über die Kreative, ...) */
.portrait-frame {
position: relative;