feat: Page Editor Phase 1 - React DynamicPageRenderer
- Add DynamicPageRenderer component for structural pages and CPT content - Add 6 section components: - HeroSection with multiple layout variants - ContentSection for rich text/HTML content - ImageTextSection with image-left/right layouts - FeatureGridSection with grid-2/3/4 layouts - CTABannerSection with color schemes - ContactFormSection with webhook POST and redirect - Add dynamic routes to App.tsx for /:slug and /:pathBase/:slug - Build customer-spa successfully
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
interface FeatureItem {
|
||||
title?: string;
|
||||
description?: string;
|
||||
icon?: string;
|
||||
}
|
||||
|
||||
interface FeatureGridSectionProps {
|
||||
id: string;
|
||||
layout?: string;
|
||||
colorScheme?: string;
|
||||
heading?: string;
|
||||
items?: FeatureItem[];
|
||||
}
|
||||
|
||||
export function FeatureGridSection({
|
||||
id,
|
||||
layout = 'grid-3',
|
||||
colorScheme = 'default',
|
||||
heading,
|
||||
items = [],
|
||||
}: FeatureGridSectionProps) {
|
||||
const gridCols = {
|
||||
'grid-2': 'md:grid-cols-2',
|
||||
'grid-3': 'md:grid-cols-3',
|
||||
'grid-4': 'md:grid-cols-2 lg:grid-cols-4',
|
||||
}[layout] || 'md:grid-cols-3';
|
||||
|
||||
return (
|
||||
<section
|
||||
id={id}
|
||||
className={cn(
|
||||
'wn-section wn-feature-grid',
|
||||
`wn-feature-grid--${layout}`,
|
||||
`wn-scheme--${colorScheme}`,
|
||||
'py-16 md:py-24',
|
||||
{
|
||||
'bg-white': colorScheme === 'default',
|
||||
'bg-muted': colorScheme === 'muted',
|
||||
'bg-primary text-primary-foreground': colorScheme === 'primary',
|
||||
}
|
||||
)}
|
||||
>
|
||||
<div className="container mx-auto px-4">
|
||||
{heading && (
|
||||
<h2 className="text-3xl md:text-4xl font-bold text-center mb-12">
|
||||
{heading}
|
||||
</h2>
|
||||
)}
|
||||
|
||||
<div className={cn('grid gap-8', gridCols)}>
|
||||
{items.map((item, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={cn(
|
||||
'wn-feature-grid__item',
|
||||
'p-6 rounded-xl',
|
||||
{
|
||||
'bg-white shadow-lg': colorScheme !== 'primary',
|
||||
'bg-white/10': colorScheme === 'primary',
|
||||
}
|
||||
)}
|
||||
>
|
||||
{item.icon && (
|
||||
<span className="wn-feature-grid__icon text-4xl mb-4 block">
|
||||
{item.icon}
|
||||
</span>
|
||||
)}
|
||||
|
||||
{item.title && (
|
||||
<h3 className="wn-feature-grid__item-title text-xl font-semibold mb-3">
|
||||
{item.title}
|
||||
</h3>
|
||||
)}
|
||||
|
||||
{item.description && (
|
||||
<p className={cn(
|
||||
'wn-feature-grid__item-desc',
|
||||
{
|
||||
'text-gray-600': colorScheme !== 'primary',
|
||||
'text-white/80': colorScheme === 'primary',
|
||||
}
|
||||
)}>
|
||||
{item.description}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user