migration wip

This commit is contained in:
2025-12-29 18:18:48 +01:00
parent 292975299d
commit f86785bfb0
182 changed files with 30131 additions and 9321 deletions

View File

@@ -0,0 +1,402 @@
/**
* Content Components Example
* Demonstrates how to use the content components with WordPress data
*/
import React from 'react';
import {
Hero,
Section,
SectionHeader,
SectionContent,
SectionGrid,
FeaturedImage,
ContentRenderer,
Breadcrumbs,
ContentBlock,
RichText,
Avatar,
ImageGallery,
} from './index';
import { Button, Card, CardHeader, CardBody, CardFooter, Grid } from '../ui';
import { Page, Post, Product, getMediaById } from '../../lib/data';
// Example: Hero component with WordPress data
export const ExampleHero: React.FC<{
page: Page;
}> = ({ page }) => {
const featuredMedia = page.featuredImage ? getMediaById(page.featuredImage) : null;
return (
<Hero
title={page.title}
subtitle={page.excerptHtml ? page.excerptHtml.replace(/<[^>]*>/g, '') : undefined}
backgroundImage={featuredMedia?.localPath}
backgroundAlt={featuredMedia?.alt || page.title}
height="lg"
variant="dark"
overlay={true}
overlayOpacity={0.6}
ctaText="Learn More"
ctaLink="#content"
/>
);
};
// Example: Section component for content blocks
export const ExampleSection: React.FC<{
title: string;
content: string;
background?: 'default' | 'light' | 'dark';
}> = ({ title, content, background = 'default' }) => {
return (
<Section background={background} padding="xl">
<SectionHeader title={title} align="center" />
<SectionContent>
<ContentRenderer content={content} />
</SectionContent>
</Section>
);
};
// Example: Featured content grid
export const ExampleContentGrid: React.FC<{
posts: Post[];
}> = ({ posts }) => {
return (
<Section background="light" padding="xl">
<SectionHeader
title="Latest News"
subtitle="Stay updated with our latest developments"
align="center"
/>
<SectionGrid cols={3} gap="md">
{posts.map((post) => {
const featuredMedia = post.featuredImage ? getMediaById(post.featuredImage) : null;
return (
<Card key={post.id} variant="elevated">
{featuredMedia && (
<div className="relative h-48">
<FeaturedImage
src={featuredMedia.localPath}
alt={featuredMedia.alt || post.title}
size="full"
aspectRatio="16:9"
/>
</div>
)}
<CardHeader>
<h3 className="text-xl font-bold">{post.title}</h3>
<small className="text-gray-500">
{new Date(post.datePublished).toLocaleDateString()}
</small>
</CardHeader>
<CardBody>
<RichText
html={post.excerptHtml}
className="text-gray-600 line-clamp-3"
/>
</CardBody>
<CardFooter>
<Button variant="primary" size="sm">
Read More
</Button>
</CardFooter>
</Card>
);
})}
</SectionGrid>
</Section>
);
};
// Example: Product showcase
export const ExampleProductShowcase: React.FC<{
product: Product;
}> = ({ product }) => {
const images = product.images.map((img) => ({
src: img,
alt: product.name,
}));
return (
<Section padding="xl">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
{/* Product Images */}
<div>
{product.featuredImage && (
<FeaturedImage
src={product.featuredImage}
alt={product.name}
size="full"
aspectRatio="4:3"
priority
/>
)}
{images.length > 1 && (
<div className="mt-4">
<ImageGallery images={images.slice(1)} cols={3} />
</div>
)}
</div>
{/* Product Info */}
<div className="space-y-6">
<div>
<h1 className="text-3xl md:text-4xl font-bold mb-2">{product.name}</h1>
<div className="flex items-center gap-3">
<span className="text-2xl font-bold text-primary">
{product.regularPrice} {product.currency}
</span>
{product.salePrice && (
<span className="text-lg text-gray-500 line-through">
{product.salePrice} {product.currency}
</span>
)}
</div>
</div>
<RichText html={product.descriptionHtml} />
{product.categories.length > 0 && (
<div>
<strong>Categories:</strong>
<div className="flex flex-wrap gap-2 mt-2">
{product.categories.map((cat) => (
<span key={cat.id} className="px-3 py-1 bg-gray-100 rounded-full text-sm">
{cat.name}
</span>
))}
</div>
</div>
)}
<div className="flex gap-3">
<Button variant="primary" size="lg">
Add to Cart
</Button>
<Button variant="outline" size="lg">
Contact Sales
</Button>
</div>
</div>
</div>
</Section>
);
};
// Example: Breadcrumbs with WordPress page structure
export const ExampleBreadcrumbs: React.FC<{
page: Page;
ancestors?: Page[];
}> = ({ page, ancestors = [] }) => {
const items = [
...ancestors.map((p) => ({
label: p.title,
href: `/${p.locale}${p.path}`,
})),
{
label: page.title,
},
];
return <Breadcrumbs items={items} />;
};
// Example: Full page layout with all components
export const ExamplePageLayout: React.FC<{
page: Page;
relatedPosts?: Post[];
}> = ({ page, relatedPosts = [] }) => {
const featuredMedia = page.featuredImage ? getMediaById(page.featuredImage) : null;
return (
<div className="min-h-screen">
{/* Hero Section */}
<Hero
title={page.title}
subtitle={page.excerptHtml ? page.excerptHtml.replace(/<[^>]*>/g, '') : undefined}
backgroundImage={featuredMedia?.localPath}
backgroundAlt={featuredMedia?.alt || page.title}
height="md"
variant="dark"
overlay
overlayOpacity={0.5}
/>
{/* Breadcrumbs */}
<Breadcrumbs
items={[
{ label: 'Home', href: '/' },
{ label: page.title },
]}
/>
{/* Main Content */}
<Section padding="xl">
<div className="max-w-4xl mx-auto">
<ContentRenderer content={page.contentHtml} />
</div>
</Section>
{/* Related Posts */}
{relatedPosts.length > 0 && (
<Section background="light" padding="xl">
<SectionHeader title="Related Content" align="center" />
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
{relatedPosts.map((post) => (
<Card key={post.id} variant="bordered">
<CardBody>
<h3 className="text-lg font-bold mb-2">{post.title}</h3>
<RichText
html={post.excerptHtml}
className="text-gray-600 text-sm line-clamp-2"
/>
</CardBody>
<CardFooter>
<Button variant="ghost" size="sm">
Read More
</Button>
</CardFooter>
</Card>
))}
</div>
</Section>
)}
{/* CTA Section */}
<Section background="primary" padding="xl">
<div className="text-center text-white">
<h2 className="text-3xl font-bold mb-4">Ready to Get Started?</h2>
<p className="text-xl mb-6 opacity-90">
Contact us today for more information about our products and services.
</p>
<div className="flex justify-center gap-3">
<Button variant="secondary" size="lg">
Contact Us
</Button>
<Button variant="ghost" size="lg" className="text-white border-white hover:bg-white/10">
View Products
</Button>
</div>
</div>
</Section>
</div>
);
};
// Example: Blog post layout
export const ExampleBlogPost: React.FC<{
post: Post;
author?: {
name: string;
avatar?: string;
};
}> = ({ post, author }) => {
const featuredMedia = post.featuredImage ? getMediaById(post.featuredImage) : null;
return (
<article className="max-w-4xl mx-auto">
{/* Header */}
<header className="mb-8 text-center">
<h1 className="text-4xl md:text-5xl font-bold mb-4">{post.title}</h1>
<div className="flex items-center justify-center gap-4 text-gray-600">
<time dateTime={post.datePublished}>
{new Date(post.datePublished).toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
})}
</time>
{author && (
<div className="flex items-center gap-2">
{author.avatar && <Avatar src={author.avatar} alt={author.name} size="sm" />}
<span>{author.name}</span>
</div>
)}
</div>
</header>
{/* Featured Image */}
{featuredMedia && (
<div className="mb-8">
<FeaturedImage
src={featuredMedia.localPath}
alt={featuredMedia.alt || post.title}
size="full"
aspectRatio="16:9"
priority
/>
</div>
)}
{/* Content */}
<div className="prose prose-lg max-w-none">
<ContentRenderer content={post.contentHtml} />
</div>
</article>
);
};
// Example: Product category grid
export const ExampleProductGrid: React.FC<{
products: Product[];
category?: string;
}> = ({ products, category }) => {
return (
<Section padding="xl">
<SectionHeader
title={category ? `${category} Products` : 'Our Products'}
subtitle="Explore our range of high-quality products"
align="center"
/>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{products.map((product) => {
const image = product.featuredImage || product.images[0];
return (
<Card key={product.id} variant="elevated" className="flex flex-col">
{image && (
<div className="relative">
<FeaturedImage
src={image}
alt={product.name}
size="full"
aspectRatio="4:3"
/>
</div>
)}
<CardHeader>
<h3 className="text-lg font-bold">{product.name}</h3>
<div className="text-primary font-semibold text-lg">
{product.regularPrice} {product.currency}
</div>
</CardHeader>
<CardBody>
<RichText
html={product.shortDescriptionHtml}
className="text-gray-600 text-sm line-clamp-2"
/>
</CardBody>
<CardFooter className="mt-auto">
<Button variant="primary" size="sm" fullWidth>
View Details
</Button>
</CardFooter>
</Card>
);
})}
</div>
</Section>
);
};
export default {
ExampleHero,
ExampleSection,
ExampleContentGrid,
ExampleProductShowcase,
ExampleBreadcrumbs,
ExamplePageLayout,
ExampleBlogPost,
ExampleProductGrid,
};