/** * Data utilities for Next.js WordPress migration */ import wordpressData from '../data/processed/wordpress-data.json'; export interface SiteInfo { title: string; description: string; baseUrl: string; defaultLocale: string; locales: string[]; } export interface TranslationReference { locale: string; id: number; } export interface Page { id: number; translationKey: string; locale: string; slug: string; path: string; title: string; titleHtml: string; contentHtml: string; excerptHtml: string; featuredImage: number | null; updatedAt: string; translation: TranslationReference | null; } export interface Post { id: number; translationKey: string; locale: string; slug: string; path: string; title: string; titleHtml: string; contentHtml: string; excerptHtml: string; featuredImage: number | null; datePublished: string; updatedAt: string; translation: TranslationReference | null; } export interface Product { id: number; translationKey: string; locale: string; slug: string; path: string; name: string; shortDescriptionHtml: string; descriptionHtml: string; images: string[]; featuredImage: string | null; sku: string; regularPrice: string; salePrice: string; currency: string; stockStatus: string; categories: Array<{ id: number; name: string; slug: string }>; attributes: any[]; variations: any[]; updatedAt: string; translation: TranslationReference | null; } export interface ProductCategory { id: number; translationKey: string; locale: string; slug: string; name: string; path: string; description: string; count: number; translation: TranslationReference | null; } export interface Media { id: number; filename: string; url: string; localPath: string; alt: string; width: number | null; height: number | null; mimeType: string | null; } export interface Redirect { source: string; destination: string; permanent: boolean; locale: string; } export interface WordPressData { site: SiteInfo; content: { pages: Page[]; posts: Post[]; products: Product[]; categories: ProductCategory[]; }; assets: { media: Media[]; map: Record; }; redirects: Redirect[]; exportDate: string; } // Load data // Use type assertion to handle the JSON import properly const data = wordpressData as unknown as WordPressData; // Data access functions export const getSiteInfo = (): SiteInfo => data.site; export const getAllPages = (): Page[] => data.content.pages; export const getAllPosts = (): Post[] => data.content.posts; export const getAllProducts = (): Product[] => data.content.products; export const getAllCategories = (): ProductCategory[] => data.content.categories; export const getMediaById = (id: number): Media | undefined => { return data.assets.media.find(m => m.id === id); }; export const getMediaByUrl = (url: string): Media | undefined => { const localPath = data.assets.map[url]; if (!localPath) return undefined; return data.assets.media.find(m => m.localPath === localPath); }; export const getAssetMap = (): Record => { return data.assets?.map || {}; }; export const getRedirects = (): Redirect[] => data.redirects; // Locale-specific queries export const getPagesByLocale = (locale: string): Page[] => { return data.content.pages.filter(p => p.locale === locale); }; export const getPostsByLocale = (locale: string): Post[] => { return data.content.posts.filter(p => p.locale === locale); }; export const getProductsByLocale = (locale: string): Product[] => { return data.content.products.filter(p => p.locale === locale); }; export const getCategoriesByLocale = (locale: string): ProductCategory[] => { return data.content.categories.filter(c => c.locale === locale); }; // Single item queries export const getPageBySlug = (slug: string, locale: string): Page | undefined => { return data.content.pages.find(p => p.slug === slug && p.locale === locale); }; export const getPostBySlug = (slug: string, locale: string): Post | undefined => { return data.content.posts.find(p => p.slug === slug && p.locale === locale); }; export const getProductBySlug = (slug: string, locale: string): Product | undefined => { return data.content.products.find(p => p.slug === slug && p.locale === locale); }; export const getCategoryBySlug = (slug: string, locale: string): ProductCategory | undefined => { return data.content.categories.find(c => c.slug === slug && c.locale === locale); }; // Translation helpers export const getTranslation = ( item: T, targetLocale: string ): T | undefined => { const collection = [ ...getAllPages(), ...getAllPosts(), ...getAllProducts(), ...getAllCategories() ]; const result = collection.find( (i: any) => i.translationKey === item.translationKey && i.locale === targetLocale ); return result as unknown as T | undefined; }; // Asset URL replacement export const replaceAssetUrls = (html: string): string => { let result = html; Object.entries(data.assets.map).forEach(([wpUrl, localPath]) => { result = result.replace(new RegExp(wpUrl, 'g'), localPath); }); return result; }; // Additional functions for product categories export const getProductCategory = (slug: string, locale: string): ProductCategory | undefined => { return data.content.categories.find(c => c.slug === slug && c.locale === locale); }; export const getProductsByCategory = (categoryId: number, locale: string): Product[] => { return data.content.products.filter(p => p.locale === locale && p.categories.some(c => c.id === categoryId) ); }; // Get products by category slug export const getProductsByCategorySlug = (categorySlug: string, locale: string): Product[] => { const category = getCategoryBySlug(categorySlug, locale); if (!category) return []; return getProductsByCategory(category.id, locale); }; // Get related products (same category, excluding current product) export const getRelatedProducts = (product: Product, locale: string, limit: number = 4): Product[] => { if (product.categories.length === 0) return []; // Get first category const firstCategory = product.categories[0]; const categoryProducts = getProductsByCategory(firstCategory.id, locale); // Filter out current product and limit results return categoryProducts .filter(p => p.id !== product.id) .slice(0, limit); }; // Get categories by slugs export const getCategoriesBySlugs = (slugs: string[], locale: string): ProductCategory[] => { return data.content.categories.filter(c => slugs.includes(c.slug) && c.locale === locale ); }; // Locale-specific queries for static generation export const getAllCategorySlugsForLocale = (locale: string): string[] => { return [...new Set(data.content.categories.filter(c => c.locale === locale).map(c => c.slug))]; }; export const getAllPageSlugsForLocale = (locale: string): string[] => { return [...new Set(data.content.pages.filter(p => p.locale === locale).map(p => p.slug))]; }; export const getAllPostSlugsForLocale = (locale: string): string[] => { return [...new Set(data.content.posts.filter(p => p.locale === locale).map(p => p.slug))]; }; export const getAllProductSlugsForLocale = (locale: string): string[] => { return [...new Set(data.content.products.filter(p => p.locale === locale).map(p => p.slug))]; }; // Get items for locale export const getCategoriesForLocale = (locale: string): ProductCategory[] => { return data.content.categories.filter(c => c.locale === locale); }; export const getPagesForLocale = (locale: string): Page[] => { return data.content.pages.filter(p => p.locale === locale); }; export const getPostsForLocale = (locale: string): Post[] => { return data.content.posts.filter(p => p.locale === locale); }; export const getProductsForLocale = (locale: string): Product[] => { return data.content.products.filter(p => p.locale === locale); };