Files
kashilo/js/services/listings.js

93 lines
2.9 KiB
JavaScript

/**
* Listings Service - Higher-level API for listing operations
* Wraps directus.js with business logic and convenience methods
*/
import { directus } from './directus.js'
import { categoriesService } from './categories.js'
class ListingsService {
async getListingsWithFilters(filters = {}) {
const directusFilter = { status: { _eq: 'published' } }
if (filters.category) {
if (filters.subcategory) {
directusFilter.category = { slug: { _eq: filters.subcategory } }
} else {
const all = await categoriesService.getAll()
const parent = all.find(c => c.slug === filters.category && !c.parent)
if (parent) {
const childSlugs = all
.filter(c => (c.parent?.id || c.parent) === parent.id)
.map(c => c.slug)
directusFilter.category = { slug: { _in: [filters.category, ...childSlugs] } }
} else {
directusFilter.category = { slug: { _eq: filters.category } }
}
}
}
if (filters.location) {
directusFilter.location = { _eq: filters.location }
}
if (filters.minPrice != null) {
directusFilter.price = directusFilter.price || {}
directusFilter.price._gte = filters.minPrice
}
if (filters.maxPrice != null) {
directusFilter.price = directusFilter.price || {}
directusFilter.price._lte = filters.maxPrice
}
if (filters.condition) {
directusFilter.condition = { _eq: filters.condition }
}
if (filters.shipping === true) {
directusFilter.shipping = { _eq: true }
}
if (filters.priceType) {
directusFilter.price_type = { _eq: filters.priceType }
}
const sortMap = {
'newest': ['-date_created'],
'oldest': ['date_created'],
'price_asc': ['price'],
'price_desc': ['-price'],
'views': ['-views']
}
return directus.getListings({
filter: directusFilter,
sort: sortMap[filters.sort] || ['-date_created'],
limit: filters.limit || 20,
page: filters.page || 1,
search: filters.search
})
}
isPaidAndActive(listing) {
return listing.paid_at
&& listing.expires_at
&& new Date(listing.expires_at) > new Date()
}
canTogglePublish(listing) {
return listing.status === 'published' || (listing.status === 'draft' && this.isPaidAndActive(listing))
}
isSoftDeleted(listing) {
return listing.status === 'deleted'
}
canPublicView(listing) {
return listing.status === 'published'
}
}
export const listingsService = new ListingsService()