import { Block, TextBlock, MetricsBlock, DividerBlock, CTABlock, ImageBlock, SpacerBlock, SocialBlock, HeaderBlock, FooterBlock, GlobalStyles, } from '../types' // Render a single block to email-safe HTML (table-based, inline CSS) export function renderBlockToHtml(block: Block, globalStyles: GlobalStyles): string { switch (block.type) { case 'text': return renderTextBlock(block, globalStyles) case 'metrics': return renderMetricsBlock(block) case 'divider': return renderDividerBlock(block) case 'cta': return renderButtonBlock(block) case 'image': return renderImageBlock(block) case 'spacer': return renderSpacerBlock(block) case 'social': return renderSocialBlock(block) case 'header': return renderHeaderBlock(block) case 'footer': return renderFooterBlock(block) default: return '' } } function blockPaddingStyle(block: Block): string { const s = block.style if (!s) return '' const parts: string[] = [] if (s.paddingTop) parts.push(`padding-top:${s.paddingTop}px`) if (s.paddingBottom) parts.push(`padding-bottom:${s.paddingBottom}px`) if (s.paddingLeft) parts.push(`padding-left:${s.paddingLeft}px`) if (s.paddingRight) parts.push(`padding-right:${s.paddingRight}px`) if (s.marginTop) parts.push(`margin-top:${s.marginTop}px`) if (s.marginBottom) parts.push(`margin-bottom:${s.marginBottom}px`) if (s.backgroundColor) parts.push(`background-color:${s.backgroundColor}`) return parts.join(';') } function renderTextBlock(block: TextBlock, globalStyles: GlobalStyles): string { const fontFamily = block.fontFamily || globalStyles.fontFamily const fontSize = block.fontSize ? `${block.fontSize}px` : '16px' const lineHeight = block.lineHeight ? `${block.lineHeight}` : '1.6' const color = block.textColor || '#1f2937' const extraStyle = blockPaddingStyle(block) return `
${block.content}
` } function renderMetricsBlock(block: MetricsBlock): string { const cols = block.columns || 2 const extraStyle = blockPaddingStyle(block) const title = block.title ? `
${block.title}
` : '' const cells = block.metrics .map((m) => { const changeColor = m.changeType === 'positive' ? '#16a34a' : m.changeType === 'negative' ? '#dc2626' : '#6b7280' const changeHtml = m.change ? `
${m.change}
` : '' return `
${m.value}
${m.label}
${changeHtml} ` }) .join('') return `${title}${cells}
` } function renderDividerBlock(block: DividerBlock): string { const extraStyle = blockPaddingStyle(block) if (block.dividerStyle === 'space') { return `
` } const color = block.color || '#d1d5db' const thickness = block.thickness || 1 const width = block.width || 100 return `
` } function renderButtonBlock(block: CTABlock): string { const bg = block.buttonColor || '#2563eb' const color = block.textColor || '#ffffff' const radius = block.borderRadius ?? 6 const paddingH = block.paddingH ?? 24 const paddingV = block.paddingV ?? 12 const extraStyle = blockPaddingStyle(block) const align = block.alignment || 'center' return `
${block.text}
` } function renderImageBlock(block: ImageBlock): string { if (!block.url) return '' const width = block.width || 100 const align = block.alignment || 'center' const extraStyle = blockPaddingStyle(block) const captionHtml = block.caption ? `
${block.caption}
` : '' const imgTag = `${block.alt || ''}` const linked = block.linkUrl ? `${imgTag}` : imgTag return `
${linked}${captionHtml}
` } function renderSpacerBlock(block: SpacerBlock): string { const height = block.height || 32 return `
 
` } function renderSocialBlock(block: SocialBlock): string { const align = block.alignment || 'center' const size = block.iconSize || 24 const extraStyle = blockPaddingStyle(block) // Using text-based fallback icons for email compatibility const platformLabels: Record = { linkedin: 'LinkedIn', twitter: 'Twitter', facebook: 'Facebook', instagram: 'Instagram', youtube: 'YouTube', github: 'GitHub', website: 'Website', } const platformColors: Record = { linkedin: '#0A66C2', twitter: '#1DA1F2', facebook: '#1877F2', instagram: '#E4405F', youtube: '#FF0000', github: '#333333', website: '#6b7280', } const links = block.links .filter((l) => l.url) .map((l) => { const label = platformLabels[l.platform] || l.platform const color = platformColors[l.platform] || '#6b7280' return `${label}` }) .join('') if (!links) return '' return `
${links}
` } function renderHeaderBlock(block: HeaderBlock): string { const align = block.alignment || 'center' const extraStyle = blockPaddingStyle(block) const logo = block.logoUrl ? `${block.companyName}` : '' return `
${logo}${block.companyName}
` } function renderFooterBlock(block: FooterBlock): string { const align = block.alignment || 'center' const extraStyle = blockPaddingStyle(block) const addressHtml = block.address ? `
${block.address}
` : '' const unsubHtml = block.showUnsubscribe ? `
Unsubscribe from these emails
` : '' return `
${block.companyName}
${addressHtml} ${unsubHtml}
` }