import { t, i18n } from '../../i18n.js' import { directus } from '../../services/directus.js' import { auth } from '../../services/auth.js' import { favoritesService } from '../../services/favorites.js' import { escapeHTML } from '../../utils/helpers.js' import '../listing-card.js' import '../skeleton-card.js' class PageFavorites extends HTMLElement { constructor() { super() this.listings = [] this.loading = true this.error = null } connectedCallback() { this._unsubs = [] this.render() this.loadFavorites() this._unsubs.push(i18n.subscribe(() => this.render())) this._unsubs.push(favoritesService.subscribe(() => this.loadFavorites())) } disconnectedCallback() { this._unsubs.forEach(fn => fn()) this._unsubs = [] } async loadFavorites() { const ids = favoritesService.getAll() if (ids.length === 0) { this.loading = false this.listings = [] this.updateContent() return } try { const response = await directus.getListings({ filter: { id: { _in: ids }, status: { _eq: 'published' } }, limit: 50 }) this.listings = response.items || [] this.loading = false this.updateContent() } catch (err) { console.error('Failed to load favorites:', err) this.error = err.message this.loading = false this.updateContent() } } render() { this.innerHTML = /* html */`
${this.renderContent()}
` } updateContent() { const container = this.querySelector('#favorites-content') if (container) { container.innerHTML = this.renderContent() } } renderContent() { if (this.loading) { return Array(4).fill(0).map(() => '').join('') } if (this.error) { return /* html */`
⚠️

${t('common.error')}

` } if (this.listings.length === 0) { return /* html */`
❤️

${t('favorites.empty')}

${t('favorites.emptyHint')}

${t('favorites.browse')}
` } 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, 180) : '' const locationName = listing.location?.name || '' return /* html */` ` }).join('') } } customElements.define('page-favorites', PageFavorites) const style = document.createElement('style') style.textContent = /* css */` page-favorites .favorites-page { padding: var(--space-lg) 0; } page-favorites .page-header { margin-bottom: var(--space-xl); } page-favorites .page-header h1 { margin: 0 0 var(--space-xs); } page-favorites .page-subtitle { color: var(--color-text-muted); margin: 0; } page-favorites .empty-state { grid-column: 1 / -1; text-align: center; padding: var(--space-3xl); } page-favorites .empty-icon { font-size: 4rem; margin-bottom: var(--space-md); filter: grayscale(1); } page-favorites .empty-state h3 { margin: 0 0 var(--space-sm); } page-favorites .empty-state p { color: var(--color-text-muted); margin: 0 0 var(--space-lg); } ` document.head.appendChild(style)