import 'server-only' import { Fragment, type ReactNode } from 'react' import type { Consent } from '@/payload-types' type ConsentNode = { children?: unknown fields?: unknown format?: unknown listType?: unknown newTab?: unknown tag?: unknown text?: unknown type?: unknown url?: unknown } const asNode = (value: unknown): ConsentNode | null => typeof value === 'object' && value !== null ? (value as ConsentNode) : null const childrenOf = (node: ConsentNode): unknown[] => Array.isArray(node.children) ? node.children : [] const safeLink = (value: unknown): string | null => { if (typeof value !== 'string') return null const href = value.trim() if (href.startsWith('/') || href.startsWith('#')) return href try { const url = new URL(href) return ['http:', 'https:', 'mailto:', 'tel:'].includes(url.protocol) ? href : null } catch { return null } } const renderChildren = (node: ConsentNode, key: string, depth: number): ReactNode => childrenOf(node).map((child, index) => renderNode(child, `${key}-${index}`, depth + 1)) const renderText = (node: ConsentNode, key: string): ReactNode => { if (typeof node.text !== 'string') return null let content: ReactNode = node.text const format = typeof node.format === 'number' ? node.format : 0 if (format & 1) content = {content} if (format & 2) content = {content} if (format & 4) content = {content} if (format & 8) content = {content} if (format & 16) content = {content} if (format & 32) content = {content} if (format & 64) content = {content} if (format & 128) content = {content} return {content} } const renderNode = (value: unknown, key: string, depth: number): ReactNode => { if (depth > 40) return null const node = asNode(value) if (!node || typeof node.type !== 'string') return null switch (node.type) { case 'text': return renderText(node, key) case 'linebreak': return
case 'paragraph': return

{renderChildren(node, key, depth)}

case 'heading': { const children = renderChildren(node, key, depth) switch (node.tag) { case 'h2': return

{children}

case 'h3': return

{children}

case 'h4': return

{children}

case 'h5': return
{children}
case 'h6': return
{children}
default: return

{children}

} } case 'quote': return
{renderChildren(node, key, depth)}
case 'list': { const children = renderChildren(node, key, depth) return node.tag === 'ol' || node.listType === 'number' ? (
    {children}
) : ( ) } case 'listitem': return
  • {renderChildren(node, key, depth)}
  • case 'link': case 'autolink': { const fields = asNode(node.fields) const href = safeLink(fields?.url ?? node.url) const children = renderChildren(node, key, depth) if (!href) return {children} const opensNewTab = fields?.newTab === true return ( {children} ) } case 'horizontalrule': return
    default: return {renderChildren(node, key, depth)} } } export const ConsentText = ({ data }: { data: Consent['text'] }) => (
    {data.root.children.map((node, index) => renderNode(node, `consent-${index}`, 0))}
    )