Fix button roundtrip in editor, alignment persistence, and test email rendering

This commit is contained in:
Dwindi Ramadhana
2026-01-17 13:10:50 +07:00
parent 0e9ace902d
commit 6d2136d3b5
61 changed files with 8287 additions and 866 deletions

View File

@@ -1,4 +1,5 @@
import { cn } from '@/lib/utils';
import { SharedContentLayout } from '@/components/SharedContentLayout';
interface ImageTextSectionProps {
id: string;
@@ -7,6 +8,7 @@ interface ImageTextSectionProps {
title?: string;
text?: string;
image?: string;
elementStyles?: Record<string, any>;
}
export function ImageTextSection({
@@ -16,60 +18,87 @@ export function ImageTextSection({
title,
text,
image,
}: ImageTextSectionProps) {
cta_text,
cta_url,
elementStyles,
styles,
}: ImageTextSectionProps & { styles?: Record<string, any>, cta_text?: string, cta_url?: string }) {
const isImageLeft = layout === 'image-left' || layout === 'left';
const isImageRight = layout === 'image-right' || layout === 'right';
// Helper to get text styles (including font family)
const getTextStyles = (elementName: string) => {
const styles = elementStyles?.[elementName] || {};
return {
classNames: cn(
styles.fontSize,
styles.fontWeight,
{
'font-sans': styles.fontFamily === 'secondary',
'font-serif': styles.fontFamily === 'primary',
}
),
style: {
color: styles.color,
textAlign: styles.textAlign,
backgroundColor: styles.backgroundColor,
borderColor: styles.borderColor,
borderWidth: styles.borderWidth,
borderRadius: styles.borderRadius,
}
};
};
const titleStyle = getTextStyles('title');
const textStyle = getTextStyles('text');
const buttonStyle = getTextStyles('button');
const imageStyle = elementStyles?.['image'] || {};
// Height preset support
const heightPreset = styles?.heightPreset || 'default';
const heightMap: Record<string, string> = {
'default': 'py-12 md:py-24',
'small': 'py-8 md:py-16',
'medium': 'py-16 md:py-32',
'large': 'py-24 md:py-48',
'screen': 'min-h-screen py-20 flex items-center',
};
const heightClasses = heightMap[heightPreset] || 'py-12 md:py-24';
return (
<section
id={id}
className={cn(
'wn-section wn-image-text',
`wn-image-text--${layout}`,
`wn-scheme--${colorScheme}`,
'py-16 md:py-24',
heightClasses,
{
'bg-white': colorScheme === 'default',
'bg-muted': colorScheme === 'muted',
'bg-primary/5': colorScheme === 'primary',
}
)}
>
<div className="container mx-auto px-4">
<div className={cn(
'flex flex-col md:flex-row items-center gap-8 md:gap-16',
{
'md:flex-row-reverse': isImageRight,
}
)}>
{/* Image */}
{image && (
<div className="w-full md:w-1/2">
<img
src={image}
alt={title || 'Section image'}
className="w-full h-auto rounded-xl shadow-lg"
/>
</div>
)}
{/* Content */}
<div className="w-full md:w-1/2">
{title && (
<h2 className="text-3xl md:text-4xl font-bold mb-6">
{title}
</h2>
)}
{text && (
<div
className="prose prose-lg text-gray-600"
dangerouslySetInnerHTML={{ __html: text }}
/>
)}
</div>
</div>
</div>
<SharedContentLayout
title={title}
text={text}
image={image}
imagePosition={isImageRight ? 'right' : 'left'}
containerWidth={styles?.contentWidth === 'full' ? 'full' : 'contained'}
titleStyle={titleStyle.style}
titleClassName={titleStyle.classNames}
textStyle={textStyle.style}
textClassName={textStyle.classNames}
imageStyle={{
backgroundColor: imageStyle.backgroundColor,
objectFit: imageStyle.objectFit,
}}
buttons={cta_text && cta_url ? [{ text: cta_text, url: cta_url }] : []}
buttonStyle={{
classNames: buttonStyle.classNames,
style: buttonStyle.style
}}
/>
</section>
);
}