diff --git a/src/modules/error-book/actions.ts b/src/modules/error-book/actions.ts index 639daf6..d5a5802 100644 --- a/src/modules/error-book/actions.ts +++ b/src/modules/error-book/actions.ts @@ -58,16 +58,14 @@ export async function getErrorBookItemsAction( } } - const status = params.status && params.status !== "all" - ? (z.enum(["new", "learning", "mastered", "archived"]).safeParse(params.status).success - ? (params.status as "new" | "learning" | "mastered" | "archived") - : undefined) + const statusParse = z.enum(["new", "learning", "mastered", "archived"]).safeParse(params.status) + const status = params.status && params.status !== "all" && statusParse.success + ? statusParse.data : undefined - const sourceType = params.sourceType && params.sourceType !== "all" - ? (z.enum(["exam", "homework", "manual"]).safeParse(params.sourceType).success - ? (params.sourceType as "exam" | "homework" | "manual") - : undefined) + const sourceTypeParse = z.enum(["exam", "homework", "manual"]).safeParse(params.sourceType) + const sourceType = params.sourceType && params.sourceType !== "all" && sourceTypeParse.success + ? sourceTypeParse.data : undefined const data = await getErrorBookItems({ diff --git a/src/modules/error-book/components/add-error-book-dialog.tsx b/src/modules/error-book/components/add-error-book-dialog.tsx index 40326ed..5dcd71e 100644 --- a/src/modules/error-book/components/add-error-book-dialog.tsx +++ b/src/modules/error-book/components/add-error-book-dialog.tsx @@ -3,6 +3,7 @@ import { useState, useTransition, useEffect } from "react" import { Plus } from "lucide-react" import { toast } from "sonner" +import { useTranslations } from "next-intl" import { Dialog, @@ -23,53 +24,44 @@ import { SelectValue, } from "@/shared/components/ui/select" import { Textarea } from "@/shared/components/ui/textarea" -import { getQuestionsAction } from "@/modules/questions/actions" import { createErrorBookItemAction } from "../actions" import { COMMON_ERROR_TAGS } from "../types" -export function AddErrorBookDialog() { +interface QuestionOption { + id: string + preview: string +} + +interface AddErrorBookDialogProps { + /** 预加载的题目选项(若提供则直接使用,不再调用 onLoadQuestions) */ + questionOptions?: QuestionOption[] + /** 懒加载题目选项的回调(对话框打开时调用) */ + onLoadQuestions?: () => Promise +} + +export function AddErrorBookDialog({ + questionOptions: questionOptionsProp, + onLoadQuestions, +}: AddErrorBookDialogProps) { + const t = useTranslations("error-book") const [open, setOpen] = useState(false) const [isPending, startTransition] = useTransition() const [questionId, setQuestionId] = useState("") const [note, setNote] = useState("") const [errorTags, setErrorTags] = useState([]) - const [questionOptions, setQuestionOptions] = useState>([]) + const [loadedOptions, setLoadedOptions] = useState([]) - function extractPreview(content: unknown): string { - if (typeof content === "string") return content.slice(0, 60) - if (Array.isArray(content)) { - const texts: string[] = [] - for (const node of content) { - if (typeof node === "string") texts.push(node) - else if (typeof node === "object" && node !== null) { - const n = node as Record - if (typeof n.text === "string") texts.push(n.text) - } - } - return texts.join("").slice(0, 60) - } - return "题目" - } + const questionOptions = questionOptionsProp ?? loadedOptions useEffect(() => { - if (open && questionOptions.length === 0) { - getQuestionsAction({ pageSize: 100 }) - .then((res) => { - if (res.success && res.data) { - setQuestionOptions( - res.data.data.map((q) => ({ - id: q.id, - preview: extractPreview(q.content), - })) - ) - } + if (open && onLoadQuestions && loadedOptions.length === 0 && !questionOptionsProp) { + onLoadQuestions() + .then((options) => { + setLoadedOptions(options) }) .catch(() => {}) } - }, [open, questionOptions.length]) + }, [open, onLoadQuestions, loadedOptions.length, questionOptionsProp]) function toggleTag(tag: string) { setErrorTags((prev) => @@ -79,7 +71,7 @@ export function AddErrorBookDialog() { function handleSubmit() { if (!questionId) { - toast.error("请选择题目") + toast.error(t("messages.selectQuestion")) return } startTransition(async () => { @@ -90,13 +82,13 @@ export function AddErrorBookDialog() { ) const res = await createErrorBookItemAction(undefined, formData) if (res.success) { - toast.success(res.message ?? "已添加") + toast.success(res.message ?? t("messages.addedShort")) setOpen(false) setQuestionId("") setNote("") setErrorTags([]) } else { - toast.error(res.message ?? "添加失败") + toast.error(res.message ?? t("messages.addFailed")) } }) } @@ -106,23 +98,23 @@ export function AddErrorBookDialog() { - 添加错题 + {t("addDialog.title")} - 从题库中选择题目,添加到你的错题本。你也可以在完成作业/考试后自动采集。 + {t("addDialog.description")}
- +