refactor: replace hardcoded categories with Directus-powered category tree and translations

This commit is contained in:
2026-02-07 11:23:39 +01:00
parent 4f00b303e8
commit bb50615e0a
12 changed files with 391 additions and 196 deletions

View File

@@ -21,7 +21,7 @@ class PageCreate extends HTMLElement {
this.formData = this.loadDraft() || this.getEmptyFormData()
this.imageFiles = []
this.imagePreviews = []
this.categories = []
this.categoryTree = []
this.submitting = false
this.isNewAccount = true
}
@@ -183,10 +183,10 @@ class PageCreate extends HTMLElement {
async loadCategories() {
try {
this.categories = await categoriesService.getAll()
this.categoryTree = await categoriesService.getTree()
} catch (e) {
console.error('Failed to load categories:', e)
this.categories = []
this.categoryTree = []
}
}
@@ -238,10 +238,14 @@ class PageCreate extends HTMLElement {
<label class="label" for="category">${t('create.category')}</label>
<select class="input" id="category" name="category" required>
<option value="">${t('create.selectCategory')}</option>
${this.categories.map(cat => `
<option value="${cat.id}" ${this.formData.category === cat.id ? 'selected' : ''}>
${t(`categories.${cat.slug}`) || cat.name}
</option>
${(this.categoryTree || []).map(cat => `
<optgroup label="${categoriesService.getTranslatedName(cat)}">
${(cat.children || []).map(sub => `
<option value="${sub.id}" ${this.formData.category === sub.id ? 'selected' : ''}>
${categoriesService.getTranslatedName(sub)}
</option>
`).join('')}
</optgroup>
`).join('')}
</select>
</div>

View File

@@ -21,6 +21,7 @@ class PageHome extends HTMLElement {
// Filter state
this.query = ''
this.category = ''
this.subcategory = ''
this.sort = 'newest'
this.minPrice = null
this.maxPrice = null
@@ -39,8 +40,7 @@ class PageHome extends HTMLElement {
this.setupPullToRefresh()
this.loadListings()
this.unsubscribe = i18n.subscribe(() => {
this.render()
this.setupEventListeners()
this.updateTextContent()
})
// Re-render listings on auth change to show owner badges
@@ -129,6 +129,7 @@ class PageHome extends HTMLElement {
searchBox?.addEventListener('filter-change', (e) => {
const hadLocation = this.hasUserLocation()
this.category = e.detail.category || ''
this.subcategory = e.detail.subcategory || ''
this.query = e.detail.query || ''
this.updateUserLocation(e.detail)
this.updateUrl()
@@ -147,6 +148,7 @@ class PageHome extends HTMLElement {
e.stopPropagation()
this.query = e.detail.query || ''
this.category = e.detail.category || ''
this.subcategory = e.detail.subcategory || ''
this.updateUserLocation(e.detail)
this.updateUrl()
this.resetAndSearch()
@@ -184,6 +186,7 @@ class PageHome extends HTMLElement {
this.querySelector('#clear-filters')?.addEventListener('click', () => {
this.query = ''
this.category = ''
this.subcategory = ''
this.sort = 'newest'
this.minPrice = null
this.maxPrice = null
@@ -210,6 +213,7 @@ class PageHome extends HTMLElement {
const filters = {
search: this.query || undefined,
category: this.category || undefined,
subcategory: this.subcategory || undefined,
sort: isDistanceSort ? 'newest' : this.sort, // Backend can't sort by distance
minPrice: this.minPrice,
maxPrice: this.maxPrice,
@@ -348,6 +352,28 @@ class PageHome extends HTMLElement {
}
}
updateTextContent() {
const titleEl = this.querySelector('.listings-title')
if (titleEl) titleEl.textContent = this.getListingsTitle()
const sortSelect = this.querySelector('#sort-select')
if (sortSelect) {
sortSelect.querySelectorAll('option').forEach(opt => {
const key = {
distance: 'search.sortDistance',
newest: 'search.sortNewest',
oldest: 'search.sortOldest',
price_asc: 'search.sortPriceAsc',
price_desc: 'search.sortPriceDesc'
}[opt.value]
if (key) opt.textContent = t(key)
})
}
const searchBox = this.querySelector('search-box')
if (searchBox) searchBox.loadAndRender()
}
getListingsTitle() {
if (this.hasActiveFilters()) {
const count = this.listings.length

View File

@@ -7,6 +7,7 @@ import { escapeHTML } from '../../utils/helpers.js'
import '../chat-widget.js'
import '../location-map.js'
import '../listing-card.js'
import { categoriesService } from '../../services/categories.js'
class PageListing extends HTMLElement {
constructor() {
@@ -150,7 +151,9 @@ class PageListing extends HTMLElement {
const firstImage = hasImages ? this.getImageUrl(images[0]) : null
this.allImages = images
const categoryName = this.listing.category?.name || ''
const categoryName = this.listing.category
? categoriesService.getTranslatedName(this.listing.category)
: ''
const priceInfo = this.getFormattedPrice()
const createdDate = this.listing.date_created
? new Date(this.listing.date_created).toLocaleDateString()