import { getPayload } from 'payload'; import configPromise from '@payload-config'; import { mapSlugToFileSlug } from './slugs'; import { config } from '@/lib/config'; export interface ProductFrontmatter { title: string; sku: string; description: string; categories: string[]; images: string[]; focalX?: number; focalY?: number; isFallback?: boolean; } export interface ProductData { slug: string; frontmatter: ProductFrontmatter; content: any; // Lexical AST from Payload application?: any; // Lexical AST for Application field } export async function getProductMetadata( slug: string, locale: string, ): Promise | null> { const payload = await getPayload({ config: configPromise }); const fileSlug = await mapSlugToFileSlug(slug, locale); const result = await payload.find({ collection: 'products', where: { and: [ { slug: { equals: fileSlug } }, ...(!config.showDrafts ? [{ _status: { equals: 'published' } }] : []), ], }, locale: locale as any, depth: 1, limit: 1, }); if (result.docs.length > 0) { const doc = result.docs[0]; // Process Images const resolvedImages = ((doc.images as any[]) || []) .map((img) => (typeof img === 'string' ? img : img.url)) .filter(Boolean); if (resolvedImages.length === 0) return null; return { slug: doc.slug, frontmatter: { title: doc.title, sku: doc.sku, description: doc.description, categories: Array.isArray(doc.categories) ? doc.categories.map((c: any) => c.category) : [], images: resolvedImages, }, }; } return null; } export async function getProductBySlug(slug: string, locale: string): Promise { try { const payload = await getPayload({ config: configPromise }); const fileSlug = await mapSlugToFileSlug(slug, locale); const result = await payload.find({ collection: 'products', where: { and: [ { slug: { equals: fileSlug } }, ...(!config.showDrafts ? [{ _status: { equals: 'published' } }] : []), ], }, locale: locale as any, depth: 1, limit: 1, }); if (result.docs.length > 0) { const doc = result.docs[0]; // Map Images correctly from resolved Media docs const resolvedImages = ((doc.images as any[]) || []) .map((img) => (typeof img === 'string' ? img : img.url)) .filter(Boolean); if (resolvedImages.length === 0) return null; return { slug: doc.slug, frontmatter: { title: doc.title, sku: doc.sku, description: doc.description, categories: Array.isArray(doc.categories) ? doc.categories.map((c: any) => c.category) : [], images: resolvedImages, focalX: Array.isArray(doc.images) && doc.images.length > 0 && typeof doc.images[0] === 'object' ? doc.images[0].focalX : 50, focalY: Array.isArray(doc.images) && doc.images.length > 0 && typeof doc.images[0] === 'object' ? doc.images[0].focalY : 50, }, content: doc.content, application: doc.application, }; } return null; } catch (error) { console.error(`[Payload] getProductBySlug failed for ${slug}:`, error); return null; } } export async function getAllProductSlugs(locale: string): Promise { try { const payload = await getPayload({ config: configPromise }); const result = await payload.find({ collection: 'products', where: { ...(!config.showDrafts ? { _status: { equals: 'published' } } : {}), }, locale: locale as any, pagination: false, }); return result.docs.map((doc) => doc.slug); } catch (error) { console.error(`[Payload] getAllProductSlugs failed for ${locale}:`, error); return []; } } export async function getAllProducts(locale: string): Promise { try { const payload = await getPayload({ config: configPromise }); const selectFields = { title: true, slug: true, sku: true, description: true, categories: true, images: true, } as const; const result = await payload.find({ collection: 'products', where: { ...(!config.showDrafts ? { _status: { equals: 'published' } } : {}), }, locale: locale as any, depth: 1, pagination: false, select: selectFields, }); console.log(`[Payload] getAllProducts for ${locale}: Found ${result.docs.length} docs`); let products: ProductData[] = result.docs.map((doc) => { const resolvedImages = ((doc.images as any[]) || []) .map((img) => (typeof img === 'string' ? img : img.url)) .filter(Boolean) as string[]; const plainCategories = Array.isArray(doc.categories) ? doc.categories.map((c: any) => String(c.category)) : []; return { slug: String(doc.slug), frontmatter: { title: String(doc.title), sku: doc.sku ? String(doc.sku) : '', description: doc.description ? String(doc.description) : '', categories: plainCategories, images: resolvedImages, focalX: Array.isArray(doc.images) && doc.images.length > 0 && typeof doc.images[0] === 'object' ? doc.images[0].focalX : 50, focalY: Array.isArray(doc.images) && doc.images.length > 0 && typeof doc.images[0] === 'object' ? doc.images[0].focalY : 50, }, content: null, application: null, }; }); // Filter out products with 0 images (data integrity check to prevent 404s) products = products.filter((p) => p.frontmatter.images && p.frontmatter.images.length > 0); return products; } catch (error) { console.error(`[Payload] getAllProducts failed for ${locale}:`, error); return []; } } export async function getAllProductsMetadata(locale: string): Promise[]> { const products = await getAllProducts(locale); return products.map((p) => ({ slug: p.slug, frontmatter: p.frontmatter, })); }