improve listing
This commit is contained in:
@@ -53,9 +53,12 @@ class PageListing extends HTMLElement {
|
||||
return
|
||||
}
|
||||
|
||||
const images = this.listing.images || []
|
||||
const images = (this.listing.images || []).slice(0, 5)
|
||||
const hasImages = images.length > 0
|
||||
const firstImage = hasImages ? this.getImageUrl(images[0]) : null
|
||||
const firstImage = hasImages ? this.getImageUrl(images[0], 800) : null
|
||||
this.currentImageIndex = 0
|
||||
this.allImages = images
|
||||
|
||||
const placeholderSvg = /* html */`
|
||||
<svg class="placeholder-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
|
||||
@@ -65,7 +68,6 @@ class PageListing extends HTMLElement {
|
||||
`
|
||||
|
||||
const categoryName = this.listing.category?.name || this.listing.category?.slug || ''
|
||||
const locationName = this.listing.location?.name || ''
|
||||
const price = this.formatPrice(this.listing.price, this.listing.currency)
|
||||
const createdDate = this.listing.date_created
|
||||
? new Date(this.listing.date_created).toLocaleDateString()
|
||||
@@ -74,16 +76,16 @@ class PageListing extends HTMLElement {
|
||||
this.innerHTML = /* html */`
|
||||
<article class="listing-detail">
|
||||
<div class="listing-gallery">
|
||||
<div class="listing-image-main">
|
||||
<div class="listing-image-main" id="main-image">
|
||||
${firstImage
|
||||
? `<img src="${firstImage}" alt="${this.escapeHtml(this.listing.title)}">`
|
||||
? `<img src="${firstImage}" alt="${this.escapeHtml(this.listing.title)}" id="main-img">`
|
||||
: placeholderSvg}
|
||||
</div>
|
||||
${images.length > 1 ? `
|
||||
<div class="listing-thumbnails">
|
||||
${images.map((img, i) => `
|
||||
<button class="thumbnail ${i === 0 ? 'active' : ''}" data-index="${i}">
|
||||
<img src="${this.getImageUrl(img, 100)}" alt="">
|
||||
<img src="${this.getImageUrl(img, 150)}" alt="">
|
||||
</button>
|
||||
`).join('')}
|
||||
</div>
|
||||
@@ -95,7 +97,6 @@ class PageListing extends HTMLElement {
|
||||
${categoryName ? `<span class="badge badge-primary">${this.escapeHtml(categoryName)}</span>` : ''}
|
||||
<h1>${this.escapeHtml(this.listing.title)}</h1>
|
||||
<p class="listing-price">${price}</p>
|
||||
${locationName ? `<p class="listing-location">📍 ${this.escapeHtml(locationName)}</p>` : ''}
|
||||
${this.listing.condition ? `<p class="listing-condition">${this.getConditionLabel(this.listing.condition)}</p>` : ''}
|
||||
</header>
|
||||
|
||||
@@ -220,6 +221,22 @@ class PageListing extends HTMLElement {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
// Thumbnail gallery
|
||||
const thumbnails = this.querySelectorAll('.thumbnail')
|
||||
const mainImg = this.querySelector('#main-img')
|
||||
|
||||
thumbnails.forEach(thumb => {
|
||||
thumb.addEventListener('click', () => {
|
||||
const index = parseInt(thumb.dataset.index)
|
||||
if (mainImg && this.allImages[index]) {
|
||||
mainImg.src = this.getImageUrl(this.allImages[index], 800)
|
||||
thumbnails.forEach(t => t.classList.remove('active'))
|
||||
thumb.classList.add('active')
|
||||
this.currentImageIndex = index
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
getImageUrl(image, size = null) {
|
||||
@@ -297,6 +314,14 @@ style.textContent = /* css */`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
page-listing .listing-image-main img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
background: var(--color-bg-tertiary);
|
||||
}
|
||||
|
||||
page-listing .listing-image-main .placeholder-icon {
|
||||
@@ -305,6 +330,47 @@ style.textContent = /* css */`
|
||||
color: var(--color-border);
|
||||
}
|
||||
|
||||
page-listing .listing-thumbnails {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
gap: var(--space-xs);
|
||||
padding: var(--space-xs);
|
||||
background: var(--color-bg-secondary);
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
page-listing .listing-thumbnails {
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
gap: 4px;
|
||||
padding: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
page-listing .thumbnail {
|
||||
aspect-ratio: 1;
|
||||
border: 2px solid transparent;
|
||||
border-radius: var(--radius-md);
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
transition: border-color var(--transition-fast), opacity var(--transition-fast);
|
||||
padding: 0;
|
||||
background: var(--color-bg-tertiary);
|
||||
}
|
||||
|
||||
page-listing .thumbnail:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
page-listing .thumbnail.active {
|
||||
border-color: var(--color-primary);
|
||||
}
|
||||
|
||||
page-listing .thumbnail img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
page-listing .listing-info header {
|
||||
margin-bottom: var(--space-xl);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user