feat: add service and FAQ API methods

Add createServiceApi (getServices, getServiceBySlug, getServiceCategories)
and createFaqApi (getFaqs, getFaqsByCategory) modules following existing
factory pattern. Wire into createPayloadClient as client.services and
client.faqs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Martin Porwoll 2026-02-21 00:01:11 +00:00
parent d8e16db535
commit 12f91b8b81
3 changed files with 95 additions and 0 deletions

33
src/api-client/faqs.ts Normal file
View file

@ -0,0 +1,33 @@
/**
* FAQ API functions
*/
import type { Faq } from '../types/collections'
import type { PaginatedResponse, CollectionQueryParams } from '../types/api'
import type { PayloadClient } from './client'
export function createFaqApi(client: PayloadClient) {
return {
/**
* Get all FAQs for the current tenant
*/
async getFaqs(options?: CollectionQueryParams): Promise<PaginatedResponse<Faq>> {
return client.getCollection<Faq>('faqs', {
...options,
limit: options?.limit ?? 100,
sort: options?.sort ?? 'order',
})
},
/**
* Get FAQs filtered by category string (e.g. "allgemein", "kardiologie")
*/
async getFaqsByCategory(category: string, options?: Pick<CollectionQueryParams, 'locale' | 'depth'>): Promise<PaginatedResponse<Faq>> {
return client.getCollection<Faq>('faqs', {
...options,
where: { 'category][equals': category },
limit: 100,
sort: 'order',
})
},
}
}

View file

@ -18,6 +18,8 @@ import { createPageApi } from './pages'
import { createPostApi } from './posts' import { createPostApi } from './posts'
import { createNavigationApi } from './navigation' import { createNavigationApi } from './navigation'
import { createSettingsApi } from './settings' import { createSettingsApi } from './settings'
import { createServiceApi } from './services'
import { createFaqApi } from './faqs'
export type { PayloadClientConfig } from './client' export type { PayloadClientConfig } from './client'
export { PayloadClient, PayloadAPIError } from './client' export { PayloadClient, PayloadAPIError } from './client'
@ -41,6 +43,12 @@ export function createPayloadClient(config: PayloadClientConfig) {
/** Site settings, SEO, cookie config */ /** Site settings, SEO, cookie config */
settings: createSettingsApi(client), settings: createSettingsApi(client),
/** Service & service category queries */
services: createServiceApi(client),
/** FAQ queries */
faqs: createFaqApi(client),
/** /**
* Generic collection query use for collections not covered above * Generic collection query use for collections not covered above
* *

View file

@ -0,0 +1,54 @@
/**
* Service & Service Category API functions
*/
import type { Service, ServiceCategory } from '../types/collections'
import type { PaginatedResponse, CollectionQueryParams } from '../types/api'
import type { PayloadClient } from './client'
export interface ServiceQueryOptions extends CollectionQueryParams {
category?: number | string
isFeatured?: boolean
}
export function createServiceApi(client: PayloadClient) {
return {
/**
* Get all active services, optionally filtered by category
*/
async getServices(options?: ServiceQueryOptions): Promise<PaginatedResponse<Service>> {
const where: Record<string, unknown> = {}
if (options?.category) where['category][equals'] = options.category
if (options?.isFeatured) where['isFeatured][equals'] = true
return client.getCollection<Service>('services', {
...options,
sort: options?.sort ?? 'order',
where: { ...where, ...options?.where },
})
},
/**
* Get a single service by slug
*/
async getServiceBySlug(slug: string, options?: Pick<CollectionQueryParams, 'locale' | 'depth'>): Promise<Service | null> {
const result = await client.getCollection<Service>('services', {
...options,
depth: options?.depth ?? 3,
where: { 'slug][equals': slug },
limit: 1,
})
return result.docs[0] ?? null
},
/**
* Get all service categories
*/
async getServiceCategories(options?: Pick<CollectionQueryParams, 'locale' | 'depth'>): Promise<PaginatedResponse<ServiceCategory>> {
return client.getCollection<ServiceCategory>('service-categories', {
...options,
limit: 100,
sort: 'order',
})
},
}
}