169 lines
4.9 KiB
JavaScript
169 lines
4.9 KiB
JavaScript
import { t, i18n } from '../../i18n.js'
|
|
import { listingsService } from '../../services/listings.js'
|
|
import { directus } from '../../services/directus.js'
|
|
import '../listing-card.js'
|
|
import '../search-box.js'
|
|
|
|
class PageHome extends HTMLElement {
|
|
constructor() {
|
|
super()
|
|
this.listings = []
|
|
this.loading = true
|
|
this.error = null
|
|
this.currentFilters = {}
|
|
}
|
|
|
|
connectedCallback() {
|
|
this.render()
|
|
this.setupEventListeners()
|
|
this.loadListings()
|
|
this.unsubscribe = i18n.subscribe(() => {
|
|
this.render()
|
|
this.setupEventListeners()
|
|
})
|
|
}
|
|
|
|
disconnectedCallback() {
|
|
if (this.unsubscribe) this.unsubscribe()
|
|
}
|
|
|
|
setupEventListeners() {
|
|
const searchBox = this.querySelector('search-box')
|
|
|
|
// Listen for filter changes (live update)
|
|
searchBox?.addEventListener('filter-change', (e) => {
|
|
this.currentFilters = e.detail
|
|
this.loadListings()
|
|
})
|
|
|
|
// Listen for search submit (with query)
|
|
searchBox?.addEventListener('search', (e) => {
|
|
e.preventDefault()
|
|
e.stopPropagation()
|
|
this.currentFilters = e.detail
|
|
this.loadListings()
|
|
return false
|
|
})
|
|
}
|
|
|
|
async loadListings() {
|
|
try {
|
|
this.loading = true
|
|
this.error = null
|
|
this.updateListingsSection()
|
|
|
|
const filters = {
|
|
search: this.currentFilters.query || undefined,
|
|
category: this.currentFilters.category || undefined,
|
|
limit: 20
|
|
}
|
|
|
|
const response = await listingsService.getListingsWithFilters(filters)
|
|
this.listings = response.items || []
|
|
this.loading = false
|
|
this.updateListingsSection()
|
|
} catch (err) {
|
|
console.error('Failed to load listings:', err)
|
|
this.error = err.message
|
|
this.loading = false
|
|
this.updateListingsSection()
|
|
}
|
|
}
|
|
|
|
updateListingsSection() {
|
|
const listingsGrid = this.querySelector('.listings-grid')
|
|
const sectionTitle = this.querySelector('.listings-title')
|
|
|
|
if (listingsGrid) {
|
|
listingsGrid.innerHTML = this.renderListings()
|
|
}
|
|
|
|
if (sectionTitle) {
|
|
sectionTitle.textContent = this.getListingsTitle()
|
|
}
|
|
}
|
|
|
|
getListingsTitle() {
|
|
if (this.currentFilters.query || this.currentFilters.category) {
|
|
const count = this.listings.length
|
|
return t('search.resultsCount', { count }) || `${count} Ergebnisse`
|
|
}
|
|
return t('home.recentListings')
|
|
}
|
|
|
|
render() {
|
|
this.innerHTML = /* html */`
|
|
<section class="search-section">
|
|
<search-box no-navigate></search-box>
|
|
</section>
|
|
|
|
<section class="recent-listings">
|
|
<h2 class="listings-title">${this.getListingsTitle()}</h2>
|
|
<div class="listings-grid">
|
|
${this.renderListings()}
|
|
</div>
|
|
</section>
|
|
`
|
|
}
|
|
|
|
renderListings() {
|
|
if (this.loading) {
|
|
return /* html */`<p class="loading-text">${t('common.loading')}</p>`
|
|
}
|
|
|
|
if (this.error) {
|
|
return /* html */`<p class="error-text">${t('common.error')}</p>`
|
|
}
|
|
|
|
if (this.listings.length === 0) {
|
|
return /* html */`<p class="empty-text">${t('home.noListings')}</p>`
|
|
}
|
|
|
|
return this.listings.map(listing => {
|
|
const imageId = listing.images?.[0]?.directus_files_id?.id || listing.images?.[0]?.directus_files_id
|
|
const imageUrl = imageId ? directus.getThumbnailUrl(imageId, 300) : ''
|
|
const locationName = listing.location?.name || ''
|
|
|
|
return /* html */`
|
|
<listing-card
|
|
listing-id="${listing.id}"
|
|
title="${listing.title || ''}"
|
|
price="${listing.price || ''}"
|
|
currency="${listing.currency || 'EUR'}"
|
|
location="${locationName}"
|
|
image="${imageUrl}"
|
|
></listing-card>
|
|
`
|
|
}).join('')
|
|
}
|
|
}
|
|
|
|
customElements.define('page-home', PageHome)
|
|
|
|
const style = document.createElement('style')
|
|
style.textContent = /* css */`
|
|
/* Search Section */
|
|
page-home .search-section {
|
|
padding: var(--space-xl) 0;
|
|
}
|
|
|
|
/* Listings */
|
|
page-home .recent-listings {
|
|
margin-bottom: var(--space-xl);
|
|
}
|
|
|
|
page-home .listings-title {
|
|
margin-bottom: var(--space-lg);
|
|
}
|
|
|
|
page-home .loading-text,
|
|
page-home .error-text,
|
|
page-home .empty-text {
|
|
text-align: center;
|
|
padding: var(--space-xl);
|
|
color: var(--color-text-muted);
|
|
grid-column: 1 / -1;
|
|
}
|
|
`
|
|
document.head.appendChild(style)
|