"use client" import * as React from "react" import EditorJS from "@editorjs/editorjs" import { Post } from "@prisma/client" import { useForm } from "react-hook-form" import Link from "next/link" import TextareaAutosize from "react-textarea-autosize" import * as z from "zod" import { zodResolver } from "@hookform/resolvers/zod" import { useRouter } from "next/navigation" import { postPatchSchema } from "@/lib/validations/post" import { toast } from "@/ui/toast" import { Icons } from "@/components/icons" interface EditorProps { post: Pick } type FormData = z.infer export function Editor({ post }: EditorProps) { const { register, handleSubmit } = useForm({ resolver: zodResolver(postPatchSchema), }) const ref = React.useRef() const router = useRouter() const [isSaving, setIsSaving] = React.useState(false) const [isMounted, setIsMounted] = React.useState(false) async function initializeEditor() { const EditorJS = (await import("@editorjs/editorjs")).default const Header = (await import("@editorjs/header")).default const Embed = (await import("@editorjs/embed")).default const Table = (await import("@editorjs/table")).default const List = (await import("@editorjs/list")).default const Code = (await import("@editorjs/code")).default const LinkTool = (await import("@editorjs/link")).default const InlineCode = (await import("@editorjs/inline-code")).default const body = postPatchSchema.parse(post) if (!ref.current) { const editor = new EditorJS({ holder: "editor", onReady() { ref.current = editor }, placeholder: "Type here to write your post...", inlineToolbar: true, data: body.content, tools: { header: Header, linkTool: LinkTool, list: List, code: Code, inlineCode: InlineCode, table: Table, embed: Embed, }, }) } } React.useEffect(() => { if (typeof window !== "undefined") { setIsMounted(true) } }, []) React.useEffect(() => { if (isMounted) { initializeEditor() return () => { ref.current?.destroy() ref.current = null } } }, [isMounted]) async function onSubmit(data: FormData) { setIsSaving(true) const blocks = await ref.current.save() const response = await fetch(`/api/posts/${post.id}`, { method: "PATCH", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ title: data.title, content: blocks, }), }) setIsSaving(false) if (!response?.ok) { return toast({ title: "Something went wrong.", message: "Your post was not saved. Please try again.", type: "error", }) } router.refresh() return toast({ message: "Your post has been saved.", type: "success", }) } if (!isMounted) { return null } return (
<> Back

{post.published ? "Published" : "Draft"}

Use{" "} Tab {" "} to open the command menu.

) }