Files
ai-wpa/components/BlockNoteEditor/BlockNoteEditor.tsx
2025-08-30 18:18:57 +05:30

89 lines
2.4 KiB
TypeScript

/* eslint-disable react-hooks/rules-of-hooks */
'use client'
import '@blocknote/core/fonts/inter.css'
import { BlockNoteView } from '@blocknote/mantine'
import '@blocknote/mantine/style.css'
import { useCreateBlockNote } from '@blocknote/react'
import { Block, BlockNoteEditor, PartialBlock } from '@blocknote/core'
import './styles.css'
interface BlockNoteEditorLocalProps {
onDataChange: (blocks: Block[], html: string) => void
initialContent?: PartialBlock[] | undefined
onImageUpload?: (imageUrl: string) => void
onImageDelete?: (imageUrl: string) => void
}
async function uploadFile(file: File) {
const body = new FormData()
body.append('file', file)
const response = await fetch('/api/topic-content-image', {
method: 'POST',
body: body,
})
const result = await response.json()
if (!result.success) {
throw new Error(result.message || 'Upload failed')
}
return result.data.url
}
export default function BlockNoteEditorLocal({
onDataChange,
initialContent,
onImageUpload,
onImageDelete,
}: BlockNoteEditorLocalProps) {
let editor: BlockNoteEditor
try {
editor = useCreateBlockNote({
initialContent: initialContent,
uploadFile: async (file: File) => {
const url = await uploadFile(file)
if (onImageUpload) {
onImageUpload(url)
}
return url
},
})
} catch (error) {
editor = useCreateBlockNote({
initialContent: undefined,
uploadFile: async (file: File) => {
const url = await uploadFile(file)
if (onImageUpload) {
onImageUpload(url)
}
return url
},
})
}
const handleOnChange = async () => {
const blocks = editor.document
const html = await editor.blocksToFullHTML(blocks)
// Check for deleted images
if (onImageDelete && initialContent) {
const currentImages = blocks
.filter((block) => block.type === 'image')
.map((block) => block.props.url)
const initialImages = initialContent
.filter((block) => block.type === 'image')
.map((block) => block.props.url)
// Find images that were in initialContent but not in current content
const deletedImages = initialImages.filter((url) => !currentImages.includes(url))
deletedImages.forEach((url) => onImageDelete(url))
}
onDataChange(blocks, html)
}
return <BlockNoteView onChange={handleOnChange} editor={editor} className={'block-note-editor'} />
}