new listing layout
This commit is contained in:
@@ -158,7 +158,7 @@
|
||||
/* Listings Grid - responsive columns */
|
||||
.listings-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
gap: var(--space-md);
|
||||
}
|
||||
|
||||
|
||||
@@ -129,28 +129,29 @@ class PageListing extends HTMLElement {
|
||||
|
||||
this.innerHTML = /* html */`
|
||||
<article class="listing-detail">
|
||||
<!-- Gallery - Full Width -->
|
||||
<div class="listing-gallery">
|
||||
<div class="listing-image-main" id="main-image">
|
||||
${firstImage
|
||||
? `<img src="${firstImage}" alt="${this.escapeHtml(this.listing.title)}" id="main-img">`
|
||||
: this.getPlaceholderSvg()}
|
||||
</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, 150)}" alt="">
|
||||
</button>
|
||||
`).join('')}
|
||||
<!-- Two Column Layout -->
|
||||
<div class="listing-layout">
|
||||
<!-- Left Column: Gallery, Header, Description, More Listings -->
|
||||
<div class="listing-main">
|
||||
<!-- Gallery -->
|
||||
<div class="listing-gallery">
|
||||
<div class="listing-image-main" id="main-image">
|
||||
${firstImage
|
||||
? `<img src="${firstImage}" alt="${this.escapeHtml(this.listing.title)}" id="main-img">`
|
||||
: this.getPlaceholderSvg()}
|
||||
</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, 150)}" alt="">
|
||||
</button>
|
||||
`).join('')}
|
||||
</div>
|
||||
` : ''}
|
||||
</div>
|
||||
` : ''}
|
||||
</div>
|
||||
|
||||
<!-- Content Row: Info + Actions Sidebar -->
|
||||
<div class="listing-content">
|
||||
<!-- Main Info -->
|
||||
<div class="listing-info">
|
||||
<!-- Header -->
|
||||
<header class="listing-header">
|
||||
${categoryName ? `<a href="#/search?category=${this.listing.category?.slug}" class="badge badge-primary">${this.escapeHtml(categoryName)}</a>` : ''}
|
||||
<h1>${this.escapeHtml(this.listing.title)}</h1>
|
||||
@@ -161,12 +162,46 @@ class PageListing extends HTMLElement {
|
||||
<span class="meta-item meta-date">${t('listing.postedOn')} ${createdDate}</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
<!-- Sidebar Mobile (shown only on mobile, between header and description) -->
|
||||
<div class="sidebar-mobile">
|
||||
${this.renderSidebar()}
|
||||
</div>
|
||||
|
||||
<!-- Description -->
|
||||
<section class="listing-description">
|
||||
<h2>${t('listing.description')}</h2>
|
||||
<div class="description-text">${this.formatDescription(this.listing.description)}</div>
|
||||
</section>
|
||||
|
||||
|
||||
<!-- Location Mobile (shown only on mobile) -->
|
||||
${this.listing.location ? `
|
||||
<section class="listing-location-section location-mobile">
|
||||
<h2>${t('listing.location')}</h2>
|
||||
<location-map
|
||||
name="${this.escapeHtml(this.listing.location.name || '')}"
|
||||
postal-code="${this.escapeHtml(this.listing.location.postal_code || '')}"
|
||||
country="${this.escapeHtml(this.listing.location.country || '')}"
|
||||
></location-map>
|
||||
</section>
|
||||
` : ''}
|
||||
|
||||
<!-- Seller's Other Listings -->
|
||||
${this.sellerListings.length > 0 ? `
|
||||
<section class="seller-listings">
|
||||
<h2>${t('listing.moreFromSeller')}</h2>
|
||||
<div class="listings-grid">
|
||||
${this.sellerListings.map(listing => this.renderListingCard(listing)).join('')}
|
||||
</div>
|
||||
</section>
|
||||
` : ''}
|
||||
</div>
|
||||
|
||||
<!-- Right Column: Sidebar, Location (Desktop only) -->
|
||||
<aside class="listing-sidebar sidebar-desktop">
|
||||
${this.renderSidebar()}
|
||||
|
||||
<!-- Location Desktop -->
|
||||
${this.listing.location ? `
|
||||
<section class="listing-location-section">
|
||||
<h2>${t('listing.location')}</h2>
|
||||
@@ -177,73 +212,64 @@ class PageListing extends HTMLElement {
|
||||
></location-map>
|
||||
</section>
|
||||
` : ''}
|
||||
</div>
|
||||
|
||||
<!-- Actions Sidebar -->
|
||||
<aside class="listing-sidebar">
|
||||
<div class="sidebar-card">
|
||||
<button class="btn btn-primary btn-lg sidebar-btn" id="contact-btn">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
|
||||
</svg>
|
||||
${t('listing.contactSeller')}
|
||||
</button>
|
||||
|
||||
<div class="sidebar-actions">
|
||||
<button class="action-btn ${this.isFavorite ? 'active' : ''}" id="favorite-btn" title="${t('home.addFavorite')}">
|
||||
${this.getFavoriteIcon()}
|
||||
<span>${this.isFavorite ? t('home.removeFavorite') : t('home.addFavorite')}</span>
|
||||
</button>
|
||||
|
||||
<button class="action-btn" id="share-btn" title="${t('listing.share') || 'Teilen'}">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<circle cx="18" cy="5" r="3"></circle>
|
||||
<circle cx="6" cy="12" r="3"></circle>
|
||||
<circle cx="18" cy="19" r="3"></circle>
|
||||
<line x1="8.59" y1="13.51" x2="15.42" y2="17.49"></line>
|
||||
<line x1="15.41" y1="6.51" x2="8.59" y2="10.49"></line>
|
||||
</svg>
|
||||
<span>${t('listing.share') || 'Teilen'}</span>
|
||||
</button>
|
||||
|
||||
<button class="action-btn" id="report-btn" title="${t('listing.report') || 'Melden'}">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"></path>
|
||||
<line x1="4" y1="22" x2="4" y2="15"></line>
|
||||
</svg>
|
||||
<span>${t('listing.report') || 'Melden'}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Seller Card -->
|
||||
<div class="sidebar-card seller-card">
|
||||
<div class="seller-header">
|
||||
<div class="seller-avatar">?</div>
|
||||
<div class="seller-info">
|
||||
<strong>${t('listing.anonymousSeller')}</strong>
|
||||
<span>${t('listing.memberSince')} 2024</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
<!-- Seller's Other Listings -->
|
||||
${this.sellerListings.length > 0 ? `
|
||||
<section class="seller-listings">
|
||||
<h2>${t('listing.moreFromSeller') || 'Weitere Anzeigen des Anbieters'}</h2>
|
||||
<div class="listings-grid">
|
||||
${this.sellerListings.map(listing => this.renderListingCard(listing)).join('')}
|
||||
</div>
|
||||
</section>
|
||||
` : ''}
|
||||
</article>
|
||||
|
||||
${this.renderContactDialog()}
|
||||
`
|
||||
}
|
||||
|
||||
renderSidebar() {
|
||||
return /* html */`
|
||||
<div class="sidebar-card">
|
||||
<button class="btn btn-primary btn-lg sidebar-btn" id="contact-btn">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
|
||||
</svg>
|
||||
${t('listing.contactSeller')}
|
||||
</button>
|
||||
|
||||
<div class="sidebar-actions">
|
||||
<button class="action-btn ${this.isFavorite ? 'active' : ''}" id="favorite-btn" title="${t('home.addFavorite')}">
|
||||
${this.getFavoriteIcon()}
|
||||
<span>${this.isFavorite ? t('home.removeFavorite') : t('home.addFavorite')}</span>
|
||||
</button>
|
||||
|
||||
<button class="action-btn" id="share-btn" title="${t('listing.share')}">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<circle cx="18" cy="5" r="3"></circle>
|
||||
<circle cx="6" cy="12" r="3"></circle>
|
||||
<circle cx="18" cy="19" r="3"></circle>
|
||||
<line x1="8.59" y1="13.51" x2="15.42" y2="17.49"></line>
|
||||
<line x1="15.41" y1="6.51" x2="8.59" y2="10.49"></line>
|
||||
</svg>
|
||||
<span>${t('listing.share')}</span>
|
||||
</button>
|
||||
|
||||
<button class="action-btn" id="report-btn" title="${t('listing.report')}">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"></path>
|
||||
<line x1="4" y1="22" x2="4" y2="15"></line>
|
||||
</svg>
|
||||
<span>${t('listing.report')}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Seller Card -->
|
||||
<div class="sidebar-card seller-card">
|
||||
<div class="seller-header">
|
||||
<div class="seller-avatar">?</div>
|
||||
<div class="seller-info">
|
||||
<strong>${t('listing.anonymousSeller')}</strong>
|
||||
<span>${t('listing.memberSince')} 2024</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
renderListingCard(listing) {
|
||||
const imageId = listing.images?.[0]?.directus_files_id?.id || listing.images?.[0]?.directus_files_id
|
||||
const imageUrl = imageId ? directus.getThumbnailUrl(imageId, 300) : ''
|
||||
@@ -500,22 +526,43 @@ style.textContent = /* css */`
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
/* Content Row */
|
||||
page-listing .listing-content {
|
||||
/* Two Column Layout */
|
||||
page-listing .listing-layout {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 320px;
|
||||
gap: var(--space-xl);
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
page-listing .listing-main {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* Mobile: Hide desktop sidebar, show mobile elements */
|
||||
page-listing .sidebar-mobile {
|
||||
display: none;
|
||||
}
|
||||
|
||||
page-listing .location-mobile {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
page-listing .listing-content {
|
||||
page-listing .listing-layout {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
page-listing .listing-sidebar {
|
||||
position: static;
|
||||
order: -1;
|
||||
|
||||
page-listing .listing-sidebar.sidebar-desktop {
|
||||
display: none;
|
||||
}
|
||||
|
||||
page-listing .sidebar-mobile {
|
||||
display: flex;
|
||||
margin-bottom: var(--space-xl);
|
||||
}
|
||||
|
||||
page-listing .location-mobile {
|
||||
display: block;
|
||||
}
|
||||
|
||||
page-listing .sidebar-card {
|
||||
@@ -523,11 +570,6 @@ style.textContent = /* css */`
|
||||
}
|
||||
}
|
||||
|
||||
/* Main Info */
|
||||
page-listing .listing-info {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
page-listing .listing-header {
|
||||
margin-bottom: var(--space-xl);
|
||||
}
|
||||
@@ -581,17 +623,16 @@ style.textContent = /* css */`
|
||||
|
||||
/* Sidebar */
|
||||
page-listing .listing-sidebar {
|
||||
position: sticky;
|
||||
top: var(--space-lg);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-md);
|
||||
position: sticky;
|
||||
top: var(--space-lg);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
page-listing .listing-sidebar {
|
||||
position: static;
|
||||
}
|
||||
page-listing .sidebar-mobile {
|
||||
flex-direction: column;
|
||||
gap: var(--space-md);
|
||||
}
|
||||
|
||||
page-listing .sidebar-card {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "dgray.io - Marktplatz",
|
||||
"name": "dgray.io - marketplace",
|
||||
"short_name": "dgray.io",
|
||||
"description": "Anonymer Marktplatz mit Monero-Bezahlung",
|
||||
"description": "Anonymous marketplace with Monero payment",
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"background_color": "#FAFAFA",
|
||||
@@ -56,14 +56,14 @@
|
||||
"categories": ["shopping", "lifestyle"],
|
||||
"shortcuts": [
|
||||
{
|
||||
"name": "Anzeige erstellen",
|
||||
"short_name": "Erstellen",
|
||||
"name": "create ad",
|
||||
"short_name": "create",
|
||||
"url": "/#/create",
|
||||
"icons": [{ "src": "assets/icons/icon-96.png", "sizes": "96x96" }]
|
||||
},
|
||||
{
|
||||
"name": "Suchen",
|
||||
"short_name": "Suche",
|
||||
"name": "search",
|
||||
"short_name": "search",
|
||||
"url": "/#/search",
|
||||
"icons": [{ "src": "assets/icons/icon-96.png", "sizes": "96x96" }]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user