wwwfiberdirekt/src/blocks/FDCodeEmbedBlock/Component.tsx

149 lines
4.6 KiB
TypeScript

'use client'
import React, { useEffect, useRef } from 'react'
import type { FDCodeEmbedBlock as FDCodeEmbedBlockProps } from '@/payload-types'
const maxWidthClasses: Record<string, string> = {
default: 'max-w-[1200px]',
narrow: 'max-w-[800px]',
wide: 'max-w-[1400px]',
full: 'max-w-full',
}
// Navy stays dark. White/gray adapt to OS dark mode.
const bgClasses: Record<string, string> = {
white: 'bg-white dark:bg-fd-navy',
navy: 'bg-fd-navy',
gray: 'bg-fd-surface-alt dark:bg-fd-navy',
yellow: 'bg-fd-yellow',
transparent: 'bg-transparent',
}
/* Priority #5: Responsive radius for embed card wrappers */
const cardRadius = 'rounded-[32px] md:rounded-[50px] lg:rounded-[70px]'
export const FDCodeEmbedBlockComponent: React.FC<FDCodeEmbedBlockProps> = ({
heading,
description,
embedType = 'iframe',
iframeSrc,
iframeTitle = 'Inbäddat formulär',
iframeHeight = '600px',
iframeAllow,
customCode,
sandboxed = true,
maxWidth = 'default',
sectionBackground = 'white',
textColor = 'auto',
embedBackground = 'none',
anchorId,
}) => {
const customCodeRef = useRef<HTMLDivElement>(null)
const isDark = sectionBackground === 'navy'
const headingColor =
textColor === 'white' ? 'text-white'
: textColor === 'navy' ? 'text-fd-navy'
: isDark
? 'text-fd-yellow'
: 'text-fd-navy dark:text-fd-yellow'
const bodyColor =
textColor === 'white' ? 'text-white'
: textColor === 'navy' ? 'text-fd-navy'
: isDark
? 'text-white'
: 'text-fd-navy dark:text-white'
const bgClass = bgClasses[sectionBackground ?? 'white'] || 'bg-white dark:bg-fd-navy'
const containerClass = maxWidthClasses[maxWidth ?? 'default'] || 'max-w-[1200px]'
const embedWrapperClass =
embedBackground === 'card'
? `bg-white dark:bg-white/10 ${cardRadius} shadow-lg p-6 md:p-10 overflow-hidden`
: embedBackground === 'navy-card'
? `bg-fd-navy ${cardRadius} shadow-lg p-6 md:p-10 overflow-hidden`
: ''
useEffect(() => {
if (embedType === 'custom' && !sandboxed && customCode && customCodeRef.current) {
const container = customCodeRef.current
container.innerHTML = customCode
const scripts = container.querySelectorAll('script')
scripts.forEach((oldScript) => {
const newScript = document.createElement('script')
Array.from(oldScript.attributes).forEach((attr) => {
newScript.setAttribute(attr.name, attr.value)
})
newScript.textContent = oldScript.textContent
oldScript.parentNode?.replaceChild(newScript, oldScript)
})
}
}, [embedType, sandboxed, customCode])
const sandboxedSrcDoc = customCode
? `<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body { margin: 0; padding: 0; font-family: system-ui, -apple-system, sans-serif; }
</style>
</head>
<body>${customCode}</body>
</html>`
: ''
return (
<section id={anchorId || undefined} className={`relative w-full py-16 md:py-20 lg:py-[99px] ${bgClass} overflow-hidden`}>
<div className={`relative ${containerClass} mx-auto px-6 md:px-8`}>
{(heading || description) && (
<div className="mb-8 md:mb-12 text-center">
{heading && (
<h2 className={`font-joey-heavy text-fd-h1 mb-4 ${headingColor}`}>
{heading}
</h2>
)}
{description && (
<p className={`font-joey text-fd-body-lg max-w-[800px] mx-auto ${bodyColor}`}>
{description}
</p>
)}
</div>
)}
<div className={embedWrapperClass}>
{embedType === 'iframe' && iframeSrc && (
<iframe
src={iframeSrc}
title={iframeTitle || 'Inbäddat formulär'}
width="100%"
height={iframeHeight || '600px'}
style={{ border: 'none', minHeight: '200px' }}
allow={iframeAllow || undefined}
loading="lazy"
/>
)}
{embedType === 'custom' && sandboxed && customCode && (
<iframe
srcDoc={sandboxedSrcDoc}
title="Anpassad inbäddning"
width="100%"
style={{ border: 'none', minHeight: '200px', height: iframeHeight || '400px' }}
sandbox="allow-scripts allow-forms allow-same-origin allow-popups"
loading="lazy"
/>
)}
{embedType === 'custom' && !sandboxed && (
<div ref={customCodeRef} className="w-full" />
)}
</div>
</div>
</section>
)
}