/** * Payload CMS API functions — powered by @c2s/payload-contracts * * Uses the shared API client for transport (tenant isolation, fetch caching). * Returns data typed with local interfaces for component compatibility. * * Navigation uses contracts types directly (schema matches). * Other types use 'as unknown as' bridge since local types differ * from CMS types (meta vs seo, id string vs number, etc.). */ import { cms } from "./cms" import type { Navigation } from "@c2s/payload-contracts/types" import type { Page, Post, Favorite, Series, Testimonial, FAQ, SeoSettings, PaginatedResponse, SiteSettings, } from "./types" export type { Navigation } const TENANT_ID = process.env.NEXT_PUBLIC_TENANT_ID || "9" // Pages export async function getPage(slug: string, locale = "de"): Promise { const result = await cms.pages.getPage(slug, { locale: locale as "de" | "en", depth: 2, }) return result as unknown as Page | null } export async function getPages(options: { limit?: number page?: number locale?: string } = {}): Promise> { const result = await cms.pages.getPages({ limit: options.limit || 100, page: options.page || 1, locale: (options.locale || "de") as "de" | "en", depth: 1, }) return result as unknown as PaginatedResponse } // Posts export async function getPost(slug: string, locale = "de"): Promise { const result = await cms.posts.getPost(slug, { locale: locale as "de" | "en", depth: 2, }) return result as unknown as Post | null } export async function getPosts(options: { type?: string category?: string series?: string limit?: number page?: number locale?: string featured?: boolean } = {}): Promise> { try { const where: Record = {} if (options.featured) where["isFeatured][equals"] = "true" const result = await cms.posts.getPosts({ type: options.type, category: options.category, series: options.series, limit: options.limit || 10, page: options.page || 1, locale: (options.locale || "de") as "de" | "en", where, }) return result as unknown as PaginatedResponse } catch { return { docs: [], totalDocs: 0, limit: 10, totalPages: 0, page: 1, pagingCounter: 1, hasPrevPage: false, hasNextPage: false, prevPage: null, nextPage: null } } } // Navigation — single document per tenant with mainMenu + footerMenu // Uses contracts Navigation type directly (no bridge needed) export async function getNavigation(): Promise { try { return await cms.navigation.getNavigation({ depth: 2 }) } catch { return null } } // Site Settings export async function getSiteSettings(): Promise { try { const result = await cms.settings.getSiteSettings({ depth: 2 }) return result as unknown as SiteSettings | null } catch { return null } } // SEO Settings (Global) export async function getSeoSettings(): Promise { try { const result = await cms.settings.getSeoSettings() return result as unknown as SeoSettings | null } catch { return null } } // Testimonials export async function getTestimonials(options: { limit?: number locale?: string } = {}): Promise> { const result = await cms.client.getCollection("testimonials", { limit: options.limit || 10, locale: (options.locale || "de") as "de" | "en", depth: 1, }) return result as unknown as PaginatedResponse } // FAQs export async function getFAQs(options: { category?: string limit?: number locale?: string } = {}): Promise> { const result = await cms.client.getCollection("faqs", { limit: options.limit || 50, locale: (options.locale || "de") as "de" | "en", sort: "order", depth: 1, where: options.category ? { "category][equals": options.category } : undefined, }) return result as unknown as PaginatedResponse } // BlogWoman: Favorites export async function getFavorites(options: { category?: string badge?: string limit?: number page?: number locale?: string } = {}): Promise> { try { const where: Record = { "isActive][equals": "true" } if (options.category) where["category][equals"] = options.category if (options.badge) where["badge][equals"] = options.badge const result = await cms.client.getCollection("favorites", { limit: options.limit || 12, page: options.page || 1, locale: (options.locale || "de") as "de" | "en", depth: 1, where, }) return result as unknown as PaginatedResponse } catch { return { docs: [], totalDocs: 0, limit: 12, totalPages: 0, page: 1, pagingCounter: 1, hasPrevPage: false, hasNextPage: false, prevPage: null, nextPage: null } } } export async function getFavorite(slug: string, locale = "de"): Promise { const data = await cms.client.getCollection("favorites", { locale: locale as "de" | "en", depth: 1, where: { "slug][equals": slug, "isActive][equals": "true" }, limit: 1, }) return (data.docs[0] as unknown as Favorite) ?? null } // BlogWoman: Series export async function getSeries(options: { limit?: number locale?: string } = {}): Promise> { try { const result = await cms.client.getCollection("series", { limit: options.limit || 20, locale: (options.locale || "de") as "de" | "en", depth: 2, where: { "isActive][equals": "true" }, }) return result as unknown as PaginatedResponse } catch { return { docs: [], totalDocs: 0, limit: 20, totalPages: 0, page: 1, pagingCounter: 1, hasPrevPage: false, hasNextPage: false, prevPage: null, nextPage: null } } } export async function getSeriesBySlug(slug: string, locale = "de"): Promise { const data = await cms.client.getCollection("series", { locale: locale as "de" | "en", depth: 2, where: { "slug][equals": slug, "isActive][equals": "true" }, limit: 1, }) return (data.docs[0] as unknown as Series) ?? null } // Newsletter Subscription export async function subscribeNewsletter( email: string, firstName?: string, source = "website" ): Promise<{ success: boolean; message?: string }> { return cms.post("/api/newsletter/subscribe", { email, firstName, tenantId: Number(TENANT_ID), source, }) } // Contact Form Submission export async function submitContactForm(data: { name: string email: string phone?: string subject: string message: string formId?: number }): Promise<{ success: boolean; message?: string }> { return cms.post("/api/form-submissions", { form: data.formId || 1, submissionData: [ { field: "name", value: data.name }, { field: "email", value: data.email }, { field: "phone", value: data.phone || "" }, { field: "subject", value: data.subject }, { field: "message", value: data.message }, ], }) }