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:
@@ -20,9 +20,13 @@ const desc = product.beschreibung[lang];
|
||||
---
|
||||
<a href={`${localePrefix(lang)}/produkt/${product.slug}/`} class="card product-card">
|
||||
<div class="product-media">
|
||||
<div class="img-placeholder" role="img" aria-label={`${t.common.photoSoon}: ${name}`}>
|
||||
{t.common.photoSoon}<br /><span class="small">{name}</span>
|
||||
</div>
|
||||
{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>
|
||||
|
||||
@@ -42,14 +42,22 @@ const felder: [string, string | undefined][] = [
|
||||
|
||||
<div class="grid grid-2 product-detail">
|
||||
<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>
|
||||
{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>
|
||||
|
||||
<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>
|
||||
|
||||
@@ -42,14 +42,22 @@ const felder: [string, string | undefined][] = [
|
||||
|
||||
<div class="grid grid-2 product-detail">
|
||||
<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>
|
||||
{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>
|
||||
|
||||
<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>
|
||||
|
||||
@@ -42,14 +42,22 @@ const felder: [string, string | undefined][] = [
|
||||
|
||||
<div class="grid grid-2 product-detail">
|
||||
<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>
|
||||
{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>
|
||||
|
||||
<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>
|
||||
|
||||
@@ -42,14 +42,22 @@ const felder: [string, string | undefined][] = [
|
||||
|
||||
<div class="grid grid-2 product-detail">
|
||||
<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>
|
||||
{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>
|
||||
|
||||
<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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user