diff --git a/src/app/(app)/problem-editor/[problemId]/page.tsx b/src/app/(app)/problem-editor/[problemId]/page.tsx index 6047c80..3e2be4c 100644 --- a/src/app/(app)/problem-editor/[problemId]/page.tsx +++ b/src/app/(app)/problem-editor/[problemId]/page.tsx @@ -1,11 +1,11 @@ "use client"; import { ProblemFlexLayout } from '@/features/problems/components/problem-flexlayout'; -import { EditDescriptionPanel } from '@/components/creater/edit-description-panel'; -import { EditSolutionPanel } from '@/components/creater/edit-solution-panel'; -import { EditTestcasePanel } from '@/components/creater/edit-testcase-panel'; -import { EditDetailPanel } from '@/components/creater/edit-detail-panel'; -import { EditCodePanel } from '@/components/creater/edit-code-panel'; +import EditDescriptionPanel from '@/components/creater/edit-description-panel'; +import EditSolutionPanel from '@/components/creater/edit-solution-panel'; +import EditTestcasePanel from '@/components/creater/edit-testcase-panel'; +import EditDetailPanel from '@/components/creater/edit-detail-panel'; +import EditCodePanel from '@/components/creater/edit-code-panel'; import { updateProblem } from '@/app/actions/updateProblem'; interface ProblemEditorPageProps { diff --git a/src/app/actions/getProblem.ts b/src/app/actions/getProblem.ts new file mode 100644 index 0000000..271e1fe --- /dev/null +++ b/src/app/actions/getProblem.ts @@ -0,0 +1,58 @@ +// app/actions/get-problem-data.ts +'use server'; + +import prisma from '@/lib/prisma'; +import { serialize } from 'next-mdx-remote/serialize'; + +export async function getProblemData(problemId: string) { + const problem = await prisma.problem.findUnique({ + where: { id: problemId }, + include: { + localizations: true, + templates: true, + testcases: { + include: { inputs: true } + } + } + }); + + if (!problem) { + throw new Error('Problem not found'); + } + + const getContent = (type: string) => + problem.localizations.find(loc => loc.type === type)?.content || ''; + + const rawDescription = getContent('DESCRIPTION'); + + // MDX序列化,给客户端渲染用 + const mdxDescription = await serialize(rawDescription, { + // 可以根据需要添加MDX插件配置 + parseFrontmatter: false, + }); + + return { + id: problem.id, + displayId: problem.displayId, + difficulty: problem.difficulty, + isPublished: problem.isPublished, + timeLimit: problem.timeLimit, + memoryLimit: problem.memoryLimit, + title: getContent('TITLE'), + description: rawDescription, + mdxDescription, // 新增序列化后的字段 + solution: getContent('SOLUTION'), + templates: problem.templates.map(t => ({ + language: t.language, + content: t.content + })), + testcases: problem.testcases.map(tc => ({ + id: tc.id, + expectedOutput: tc.expectedOutput, + inputs: tc.inputs.map(input => ({ + name: input.name, + value: input.value + })) + })) + }; +} diff --git a/src/components/creater/edit-code-panel.tsx b/src/components/creater/edit-code-panel.tsx index faeacfe..5479e92 100644 --- a/src/components/creater/edit-code-panel.tsx +++ b/src/components/creater/edit-code-panel.tsx @@ -1,84 +1,121 @@ -"use client"; +'use client'; -import { useState } from "react"; -import { Label } from "@/components/ui/label"; -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; -import { Button } from "@/components/ui/button"; +import { useEffect, useState } from 'react'; +import { getProblemData } from '@/app/actions/getProblem'; +import { Label } from '@/components/ui/label'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { CoreEditor } from "@/components/core-editor"; interface Template { - id: string; language: string; - code: string; + content: string; } interface EditCodePanelProps { problemId: string; - onUpdate?: (data: { - content: string; - language: 'c' | 'cpp'; // 移除可选标记 - }) => void; + onUpdate?: (data: Template) => Promise<{ success: boolean }>; } -export const EditCodePanel = ({ - problemId, -}: EditCodePanelProps) => { - const [language, setLanguage] = useState("typescript"); - const [templates, setTemplates] = useState([ - { - id: "1", - language: "typescript", - code: `// TypeScript模板示例\nfunction twoSum(nums: number[], target: number): number[] {\n const map = new Map();\n for (let i = 0; i < nums.length; i++) {\n const complement = target - nums[i];\n if (map.has(complement)) {\n return [map.get(complement), i];\n }\n map.set(nums[i], i);\n }\n return [];\n}` - }, - { - id: "2", - language: "python", - code: "# Python模板示例\ndef two_sum(nums, target):\n num_dict = {}\n for i, num in enumerate(nums):\n complement = target - num\n if complement in num_dict:\n return [num_dict[complement], i]\n num_dict[num] = i\n return []" - } - ]); - - const currentTemplate = templates.find(t => t.language === language) || templates[0]; +// 模拟保存函数 +async function saveTemplate(data: Template): Promise<{ success: boolean }> { + try { + console.log('保存模板数据:', data); + await new Promise(resolve => setTimeout(resolve, 500)); + return { success: true }; + } catch { + return { success: false }; + } +} - const handleCodeChange = (value: string | undefined) => { - if (!value) return; - - setTemplates(templates.map(t => - t.language === language - ? { ...t, code: value } - : t - )); +export default function EditCodePanel({ problemId, onUpdate = saveTemplate }: EditCodePanelProps) { + const [codeTemplate, setCodeTemplate] = useState