import Link from 'next/link'
import type {
DefaultNodeTypes,
SerializedUploadNode,
} from '@payloadcms/richtext-lexical'
import {
type JSXConvertersFunction,
} from '@payloadcms/richtext-lexical/react'
import { Text } from '@/components/retroui'
import { RichTextCodeBlock } from '@/components/RichTextCodeBlock'
const CustomUploadComponent: React.FC<{
node: SerializedUploadNode
}> = ({ node }) => {
if (node.relationTo === 'media') {
const uploadDoc = node.value
if (typeof uploadDoc !== 'object') {
return null
}
const { alt, height, url, width } = uploadDoc
return (
)
}
return null
}
type NodeTypes = DefaultNodeTypes
export const JSXConverters: JSXConvertersFunction = ({
defaultConverters,
}) => {
return {
...defaultConverters,
heading: ({ node, nodesToJSX }) => {
const children = nodesToJSX({ nodes: node.children })
const Tag = node.tag as 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
const classNames: Record = {
h1: '',
h2: 'mb-4 mt-8 lg:text-3xl',
h3: 'mb-4',
h4: 'mb-2',
h5: '',
h6: '',
}
return (
{children}
)
},
paragraph: ({ node, nodesToJSX }) => {
// Handle empty paragraphs as spacing
if (!node.children || node.children.length === 0) {
return
}
const children = nodesToJSX({ nodes: node.children })
return {children}
},
text: ({ node }) => {
const format = node.format ?? 0
let text: React.ReactNode = node.text
// Format is a bitmask: 1=bold, 2=italic, 4=strikethrough, 8=underline, 16=code
if (format & 16) {
// Inline code
text = (
{text}
)
}
if (format & 1) {
text = {text}
}
if (format & 2) {
text = {text}
}
if (format & 4) {
text = {text}
}
if (format & 8) {
text = {text}
}
return <>{text}>
},
list: ({ node, nodesToJSX }) => {
const children = nodesToJSX({ nodes: node.children })
if (node.listType === 'bullet') {
return
}
return {children}
},
listitem: ({ node, nodesToJSX }) => {
const children = nodesToJSX({ nodes: node.children })
return (
{children}
)
},
link: ({ node, nodesToJSX }) => {
const children = nodesToJSX({ nodes: node.children })
const href = node.fields?.url || ''
const isExternal = href.startsWith('http')
const linkClass = 'underline underline-offset-4 hover:decoration-primary'
if (isExternal) {
return (
{children}
)
}
return (
{children}
)
},
quote: ({ node, nodesToJSX }) => {
const children = nodesToJSX({ nodes: node.children })
return (
{children}
)
},
linebreak: () => {
return
},
upload: ({ node }) => {
return
},
// Handle autolink nodes
autolink: ({ node, nodesToJSX }) => {
const children = nodesToJSX({ nodes: (node as any).children })
const href = (node as any).fields?.url || ''
return (
{children}
)
},
// Blocks converter - nested object with slug as key
blocks: {
Code: ({ node }: any) => {
const fields = (node as any).fields
return (
)
},
},
}
}