282 lines
7.9 KiB
TypeScript
282 lines
7.9 KiB
TypeScript
/**
|
|
* 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<string, string>;
|
|
};
|
|
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<string, string> => {
|
|
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 = <T extends { translationKey: string; locale: string }>(
|
|
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);
|
|
}; |