import { type BlockObjectResponse } from '@notionhq/client/build/src/api-endpoints' import clsx from 'clsx' import Image from 'next/image' import { type FC } from 'react' import Callout, { CalloutIcon } from '@/components/server/Callout' import CodeSnippet, { SyncCodeSnippet } from '@/components/server/CodeSnippet' import List from '@/components/server/List' import RichText from '@/components/server/RichText' import TeX, { SyncTeX } from '@/components/server/TeX' import { type Block, type BlockType } from '@/lib/notion/types' import extractCurrentListItems from '@/lib/notion/utils/extractCurrentListItems' import getProxiedAssetUrl from '@/lib/notion/utils/getProxiedAssetUrl' import richTextAsPlainText from '@/lib/notion/utils/richTextToPlainText' export const blockRenderMap: { [T in BlockType]: FC<{ block: Block }> } = { paragraph: ({ block }) => (

), heading_1: ({ block }) => ( <>

{/* @ts-expect-error TODO find a way to fix this type */} {block.has_children && } ), heading_2: ({ block }) => ( <>

{/* @ts-expect-error TODO find a way to fix this type */} {block.has_children && } ), heading_3: ({ block }) => ( <>

{/* @ts-expect-error TODO find a way to fix this type */} {block.has_children && } ), image: ({ block }) => { const caption = block.image.caption const altText = caption[0]?.plain_text.startsWith('alt: ') ? richTextAsPlainText(caption).substring(5) : richTextAsPlainText(caption) return (
{altText} 0, })} src={getProxiedAssetUrl({ blockId: block.id, lastEditedTime: block.last_edited_time, })} width={9999} // TODO height={9999} // TODO /> {block.image.caption.length > 0 && (
)}
) }, bulleted_list_item: ({ block }) => (
  • ), numbered_list_item: ({ block }) => (
  • ), quote: ({ block }) => (
    ), toggle: ({ block }) => (
    {/* @ts-expect-error TODO find a way to fix this type */} {block.children && }
    ), callout: ({ block }) => ( ), // @ts-expect-error Server Component equation: ({ block }) => , divider: () => (
    ), code: ({ block }) => ( // @ts-expect-error Server Component ), // TODO? table_of_contents: ({ block }) => <>, column_list: ({ block }) => <>, column: ({ block }) => <>, link_to_page: ({ block }) => <>, table: ({ block }) => <>, table_row: ({ block }) => <>, embed: ({ block }) => <>, bookmark: ({ block }) => <>, video: ({ block }) => <>, pdf: ({ block }) => <>, file: ({ block }) => <>, audio: ({ block }) => <>, link_preview: ({ block }) => <>, breadcrumb: ({ block }) => <>, synced_block: ({ block }) => <>, template: ({ block }) => <>, to_do: ({ block }) => <>, child_page: ({ block }) => <>, child_database: ({ block }) => <>, unsupported: ({ block }) => <>, } export const rssBlockRenderMap: typeof blockRenderMap = { ...blockRenderMap, paragraph: ({ block }) => (

    ), heading_1: ({ block }) => ( <>

    {/* @ts-expect-error TODO find a way to fix this type */} {block.has_children && } ), heading_2: ({ block }) => ( <>

    {/* @ts-expect-error TODO find a way to fix this type */} {block.has_children && } ), heading_3: ({ block }) => ( <>

    {/* @ts-expect-error TODO find a way to fix this type */} {block.has_children && } ), image: ({ block }) => { const caption = block.image.caption const altText = caption[0]?.plain_text.startsWith('alt: ') ? richTextAsPlainText(caption).substring(5) : richTextAsPlainText(caption) return (
    {/* eslint-disable-next-line @next/next/no-img-element */} {altText} 0, })} src={getProxiedAssetUrl({ blockId: block.id, lastEditedTime: block.last_edited_time, withBaseUrl: true, })} /> {block.image.caption.length > 0 && (
    )}
    ) }, bulleted_list_item: ({ block }) => (
  • ), numbered_list_item: ({ block }) => (
  • ), quote: ({ block }) => (
    ), toggle: ({ block }) => (
    {/* @ts-expect-error TODO find a way to fix this type */} {block.children && }
    ), callout: ({ block }) => ( ), equation: ({ block }) => , code: ({ block }) => ( ), } export const RenderBlockList = ({ blockList, rss = false, }: { blockList: BlockObjectResponse[] rss?: boolean }) => { return ( <> {blockList.map((block, index, list) => { const isListItem = block.type === 'bulleted_list_item' || block.type === 'numbered_list_item' if (!isListItem) return else if (list[index - 1].type !== block.type) return ( {extractCurrentListItems({ list, currentIndex: index }).map( (listItem) => ( ), )} ) })} ) } export function RenderBlock({ block, rss = false, }: { block: BlockObjectResponse rss?: boolean }) { const Component = (rss ? rssBlockRenderMap : blockRenderMap)[block.type] // @ts-expect-error we know this is correct because `block.type` is the name we want to use as a key for `blockRenderMap` return }