From bb2aa599ba3342420ce39f143f2cffc06c9de6a7 Mon Sep 17 00:00:00 2001 From: ditiqi Date: Fri, 24 Jan 2025 11:39:51 +0800 Subject: [PATCH] add --- .../context/LetterEditorContext.tsx | 81 +++-- .../LetterEditor/form/LetterBasicForm.tsx | 280 +++++++++--------- .../models/post/detail/PostCommentCard.tsx | 9 +- .../models/post/detail/PostCommentEditor.tsx | 2 +- .../post/detail/context/PostDetailContext.tsx | 5 +- packages/common/prisma/schema.prisma | 2 +- packages/common/src/select.ts | 1 + 7 files changed, 178 insertions(+), 202 deletions(-) diff --git a/apps/web/src/components/models/post/LetterEditor/context/LetterEditorContext.tsx b/apps/web/src/components/models/post/LetterEditor/context/LetterEditorContext.tsx index 5c6dcd4..b02520a 100644 --- a/apps/web/src/components/models/post/LetterEditor/context/LetterEditorContext.tsx +++ b/apps/web/src/components/models/post/LetterEditor/context/LetterEditorContext.tsx @@ -1,69 +1,48 @@ -import { createContext, useContext, ReactNode, useEffect } from "react"; -import { useForm, FormProvider, SubmitHandler } from "react-hook-form"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { z } from "zod"; +import { createContext, useContext, ReactNode } from "react"; +import { Form, FormInstance } from "antd"; import { api, usePost } from "@nice/client"; -// import { PostDto, PostLevel, PostStatus } from "@nice/common"; -// import { api, usePost } from "@nice/client"; import toast from "react-hot-toast"; import { useNavigate } from "react-router-dom"; -import { Post, PostType } from "@nice/common"; -// 定义帖子表单验证 Schema +import { PostType } from "@nice/common"; -const letterSchema = z.object({ - title: z.string().min(1, "标题不能为空"), - content: z.string().min(1, "内容不能为空"), - resources: z.array(z.string()).nullish(), - isPublic: z.boolean().nullish(), - signature: z.string().nullish(), - meta: z - .object({ - tags: z.array(z.string()).default([]), - signature: z.string().nullish(), - }) - .default({ - tags: [], - signature: null, - }), -}); -// 定义课程表单验证 Schema - -export type LetterFormData = z.infer; +export interface LetterFormData { + title: string; + content: string; + resources?: string[]; + isPublic?: boolean; + signature?: string; + meta: { + tags: string[]; + signature?: string; + }; +} interface LetterEditorContextType { - onSubmit: SubmitHandler; + onSubmit: (values: LetterFormData) => Promise; receiverId?: string; termId?: string; - part?: string; - // course?: PostDto; + form: FormInstance; } + interface LetterFormProviderProps { children: ReactNode; receiverId?: string; termId?: string; - part?: string; } + const LetterEditorContext = createContext(null); + export function LetterFormProvider({ children, receiverId, termId, - // editId, }: LetterFormProviderProps) { const { create } = usePost(); const navigate = useNavigate(); - const methods = useForm({ - resolver: zodResolver(letterSchema), - defaultValues: { - resources: [], - meta: { - tags: [], - }, - }, - }); - const onSubmit: SubmitHandler = async ( - data: LetterFormData - ) => { + const [form] = Form.useForm(); + + const onSubmit = async (data: LetterFormData) => { try { + console.log("data", data); const result = await create.mutateAsync({ data: { type: PostType.POST, @@ -73,6 +52,7 @@ export function LetterFormProvider({ id, })), }, + isPublic: data?.isPublic, ...data, resources: data.resources?.length ? { @@ -83,23 +63,28 @@ export function LetterFormProvider({ : undefined, }, }); - navigate(`/course/${result.id}/detail`, { replace: true }); + navigate(`/${result.id}/detail`, { replace: true }); toast.success("发送成功!"); - - methods.reset(data); + form.resetFields(); } catch (error) { console.error("Error submitting form:", error); toast.error("操作失败,请重试!"); } }; + return ( - {children} + + form={form} + initialValues={{ meta: { tags: [] } }}> + {children} + ); } diff --git a/apps/web/src/components/models/post/LetterEditor/form/LetterBasicForm.tsx b/apps/web/src/components/models/post/LetterEditor/form/LetterBasicForm.tsx index 513d686..d6fc1c0 100644 --- a/apps/web/src/components/models/post/LetterEditor/form/LetterBasicForm.tsx +++ b/apps/web/src/components/models/post/LetterEditor/form/LetterBasicForm.tsx @@ -1,29 +1,18 @@ -import { useFormContext } from "react-hook-form"; -import { motion } from "framer-motion"; -import { - LetterFormData, - useLetterEditor, -} from "../context/LetterEditorContext"; -import { FormQuillInput } from "@web/src/components/common/form/FormQuillInput"; +import { Form, Input, Button, Checkbox, Select } from "antd"; +import { useState } from "react"; +import { useLetterEditor } from "../context/LetterEditorContext"; import { api } from "@nice/client"; import { - UserIcon, - FolderIcon, - HashtagIcon, - DocumentTextIcon, -} from "@heroicons/react/24/outline"; + UserOutlined, + FolderOutlined, + TagOutlined, + FileTextOutlined, +} from "@ant-design/icons"; import FileUploader from "@web/src/components/common/uploader/FileUploader"; -import { FormTags } from "@web/src/components/common/form/FormTags"; -import { FormSignature } from "@web/src/components/common/form/FormSignature"; -import { FormCheckbox } from "@web/src/components/common/form/FormCheckbox"; +import QuillEditor from "@web/src/components/common/editor/quill/QuillEditor"; export function LetterBasicForm() { - const { - handleSubmit, - getValues, - formState: { errors }, - } = useFormContext(); - const { onSubmit, receiverId, termId } = useLetterEditor(); + const { onSubmit, receiverId, termId, form } = useLetterEditor(); const { data: receiver } = api.staff.findFirst.useQuery( { where: { @@ -41,134 +30,137 @@ export function LetterBasicForm() { { enabled: !!termId } ); - const formControls = { - hidden: { opacity: 0, y: 20 }, - visible: (i: number) => ({ - opacity: 1, - y: 0, - transition: { - delay: i * 0.2, - duration: 0.5, - }, - }), + const handleFinish = async (values: any) => { + await onSubmit(values); }; return ( - - {/* 收件人和板块信息行 */} -
- - -
收件人:{receiver?.showname}
-
+
+
+ {/* 收件人和板块信息行 */} +
+
+ +
收件人:{receiver?.showname}
+
- - -
板块:{term?.name}
-
-
- {/* 主题输入框 */} - - - {/* */} - - {/* 标签输入 */} - - - - - {/* 内容输入框 */} - - - - - - - - + +
板块:{term?.name}
+
+
+ + {/* 主题输入框 */} +
+ + + 标题 + (必选) + + } + name="title" + rules={[{ required: true, message: "请输入标题" }]} + labelCol={{ span: 24 }} + wrapperCol={{ span: 24 }}> + + +
+ + {/* 标签输入 */} +
+ + + 标签 + + } + name={["meta", "tags"]} + labelCol={{ span: 24 }} + wrapperCol={{ span: 24 }}> +