From 67e1445f98cf47c020dc92b059d74a9de3d9308a Mon Sep 17 00:00:00 2001 From: cfngc4594 Date: Sun, 6 Apr 2025 17:40:29 +0800 Subject: [PATCH] refactor(problemset): use Dockview components with dynamic params in description form --- .../new/components/description-form.tsx | 94 +++++++++++++------ 1 file changed, 65 insertions(+), 29 deletions(-) diff --git a/src/components/features/dashboard/admin/problemset/new/components/description-form.tsx b/src/components/features/dashboard/admin/problemset/new/components/description-form.tsx index 1de34b0..1bd49e2 100644 --- a/src/components/features/dashboard/admin/problemset/new/components/description-form.tsx +++ b/src/components/features/dashboard/admin/problemset/new/components/description-form.tsx @@ -10,8 +10,9 @@ import { FormLabel, FormMessage, } from "@/components/ui/form"; -import { useEffect } from "react"; import { useForm } from "react-hook-form"; +import type { editor } from "monaco-editor"; +import { useEffect, useState } from "react"; import { useRouter } from "next/navigation"; import DockView from "@/components/dockview"; import { ArrowRightIcon } from "lucide-react"; @@ -20,6 +21,7 @@ import MdxPreview from "@/components/mdx-preview"; import { zodResolver } from "@hookform/resolvers/zod"; import { ScrollArea } from "@/components/ui/scroll-area"; import MarkdownEditor from "@/components/markdown-editor"; +import type { DockviewApi, IDockviewPanelProps } from "dockview"; import { useNewProblemStore } from "@/app/(app)/dashboard/@admin/problemset/new/store"; import { problemSchema } from "@/components/features/dashboard/admin/problemset/new/schema"; import { newProblemMetadataSchema } from "@/components/features/dashboard/admin/problemset/new/components/metadata-form"; @@ -28,9 +30,7 @@ export const newProblemDescriptionSchema = problemSchema.pick({ description: true, }); -type NewProblemDescriptionSchema = z.infer< - typeof newProblemDescriptionSchema ->; +type NewProblemDescriptionSchema = z.infer; export default function NewProblemDescriptionForm() { const { @@ -43,6 +43,7 @@ export default function NewProblemDescriptionForm() { setData, } = useNewProblemStore(); const router = useRouter(); + const [dockApi, setDockApi] = useState(); const form = useForm({ resolver: zodResolver(newProblemDescriptionSchema), @@ -71,6 +72,22 @@ export default function NewProblemDescriptionForm() { } }, [difficulty, displayId, hydrated, published, router, title]); + const descriptionValue = form.watch("description"); + + useEffect(() => { + if (!dockApi) return; + + const mdxPanel = dockApi.getPanel("MdxPreview"); + if (mdxPanel) { + mdxPanel.api.updateParameters({ source: descriptionValue }); + } + + const editorPanel = dockApi.getPanel("MarkdownEditor"); + if (editorPanel) { + editorPanel.api.updateParameters({ value: descriptionValue }); + } + }, [dockApi, descriptionValue]); + return (
+ ) => ( +
+
+ + + +
+
+ ), + MarkdownEditor: ( + props: IDockviewPanelProps<{ + value: string; + onChange: ( + value: string | undefined, + ev: editor.IModelContentChangedEvent + ) => void; + }> + ) => ( + + ), + }} options={[ { id: "MdxPreview", - title: "Mdx Preview", component: "MdxPreview", - tabComponent: "MdxPreview", - icon: "FileTextIcon", - node: ( -
-
- - - -
-
- ), + title: "Mdx Preview", + params: { source: field.value }, }, { id: "MarkdownEditor", - title: "Markdown Editor", component: "MarkdownEditor", - tabComponent: "MarkdownEditor", - icon: "FileTextIcon", - node: ( - - ), - position: { referencePanel: "MdxPreview", direction: "right" }, + title: "Markdown Editor", + params: { + value: field.value, + onChange: (value: string | undefined) => { + field.onChange(value); + }, + }, + position: { + referencePanel: "MdxPreview", + direction: "right", + }, }, ]} + onApiReady={setDockApi} />