refactor(creater): optimize problem-creater

-为 edit-description-panel 和 edit-solution-panel 组件添加 Card 组件包装,提升视觉效果
- 用 CoreEditor 组件替换原有的 Textarea,增强编辑功能
- 优化组件结构,提高可维护性和可扩展性
This commit is contained in:
fly6516 2025-06-16 22:41:48 +08:00
parent 794872105f
commit 712813eee6
2 changed files with 122 additions and 104 deletions

View File

@ -3,9 +3,10 @@
import { useState } from "react"; import { useState } from "react";
import { Label } from "@/components/ui/label"; import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import MdxPreview from "@/components/mdx-preview"; import MdxPreview from "@/components/mdx-preview";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {CoreEditor} from "@/components/core-editor";
interface EditDescriptionPanelProps { interface EditDescriptionPanelProps {
problemId: string; problemId: string;
@ -19,57 +20,65 @@ export const EditDescriptionPanel = ({
const [viewMode, setViewMode] = useState<'edit' | 'preview' | 'compare'>('edit'); const [viewMode, setViewMode] = useState<'edit' | 'preview' | 'compare'>('edit');
return ( return (
<div className="space-y-6"> <Card className="w-full">
<div className="space-y-2"> <CardHeader>
<Label htmlFor="title"></Label> <CardTitle></CardTitle>
<Input </CardHeader>
id="title" <CardContent>
value={title} <div className="space-y-6">
onChange={(e) => setTitle(e.target.value)} <div className="space-y-2">
placeholder="输入题目标题" <Label htmlFor="title"></Label>
/> <Input
</div> id="title"
<div className="flex space-x-2"> value={title}
<Button onChange={(e) => setTitle(e.target.value)}
type="button" placeholder="输入题目标题"
variant={viewMode === 'edit' ? 'default' : 'outline'} />
onClick={() => setViewMode('edit')} </div>
> <div className="flex space-x-2">
<Button
</Button> type="button"
<Button variant={viewMode === 'edit' ? 'default' : 'outline'}
type="button" onClick={() => setViewMode('edit')}
variant={viewMode === 'preview' ? 'default' : 'outline'} >
onClick={() => setViewMode(viewMode === 'preview' ? 'edit' : 'preview')}
> </Button>
{viewMode === 'preview' ? '取消' : '预览'} <Button
</Button> type="button"
<Button variant={viewMode === 'preview' ? 'default' : 'outline'}
type="button" onClick={() => setViewMode(viewMode === 'preview' ? 'edit' : 'preview')}
variant={viewMode === 'compare' ? 'default' : 'outline'} >
onClick={() => setViewMode('compare')} {viewMode === 'preview' ? '取消' : '预览'}
> </Button>
<Button
</Button> type="button"
</div> variant={viewMode === 'compare' ? 'default' : 'outline'}
onClick={() => setViewMode('compare')}
>
</Button>
</div>
<div className={viewMode === 'compare' ? "grid grid-cols-2 gap-6" : "flex flex-col gap-6"}> <div className={viewMode === 'compare' ? "grid grid-cols-2 gap-6" : "flex flex-col gap-6"}>
<div className={viewMode === 'edit' || viewMode === 'compare' ? "block" : "hidden"}> <div className={viewMode === 'edit' || viewMode === 'compare' ? "block" : "hidden"}>
<Textarea <div className="relative h-[600px]">
id="description" <CoreEditor
value={content} value={content}
onChange={(e) => setContent(e.target.value)} onChange={setContent}
placeholder="输入题目详细描述..." language="markdown"
className="min-h-[300px]" className="absolute inset-0 rounded-md border border-input"
/> />
</div>
</div>
<div className={viewMode === 'preview' || viewMode === 'compare' ? "block" : "hidden"}>
<MdxPreview source={content} />
</div>
</div>
<Button></Button>
</div> </div>
</CardContent>
<div className={viewMode === 'preview' || viewMode === 'compare' ? "block" : "hidden"}> </Card>
<MdxPreview source={content} />
</div>
</div>
<Button></Button>
</div>
); );
}; };

View File

@ -3,9 +3,10 @@
import { useState } from "react"; import { useState } from "react";
import { Label } from "@/components/ui/label"; import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import MdxPreview from "@/components/mdx-preview"; import MdxPreview from "@/components/mdx-preview";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {CoreEditor} from "@/components/core-editor";
interface EditSolutionPanelProps { interface EditSolutionPanelProps {
problemId: string; problemId: string;
@ -19,57 +20,65 @@ export const EditSolutionPanel = ({
const [viewMode, setViewMode] = useState<'edit' | 'preview' | 'compare'>('edit'); const [viewMode, setViewMode] = useState<'edit' | 'preview' | 'compare'>('edit');
return ( return (
<div className="space-y-6"> <Card className="w-full">
<div className="space-y-2"> <CardHeader>
<Label htmlFor="solution-title"></Label> <CardTitle></CardTitle>
<Input </CardHeader>
id="solution-title" <CardContent>
value={title} <div className="space-y-6">
onChange={(e) => setTitle(e.target.value)} <div className="space-y-2">
placeholder="输入题解标题" <Label htmlFor="solution-title"></Label>
/> <Input
</div> id="solution-title"
<div className="flex space-x-2"> value={title}
<Button onChange={(e) => setTitle(e.target.value)}
type="button" placeholder="输入题解标题"
variant={viewMode === 'edit' ? 'default' : 'outline'} />
onClick={() => setViewMode('edit')} </div>
> <div className="flex space-x-2">
<Button
</Button> type="button"
<Button variant={viewMode === 'edit' ? 'default' : 'outline'}
type="button" onClick={() => setViewMode('edit')}
variant={viewMode === 'preview' ? 'default' : 'outline'} >
onClick={() => setViewMode(viewMode === 'preview' ? 'edit' : 'preview')}
> </Button>
{viewMode === 'preview' ? '取消' : '预览'} <Button
</Button> type="button"
<Button variant={viewMode === 'preview' ? 'default' : 'outline'}
type="button" onClick={() => setViewMode(viewMode === 'preview' ? 'edit' : 'preview')}
variant={viewMode === 'compare' ? 'default' : 'outline'} >
onClick={() => setViewMode('compare')} {viewMode === 'preview' ? '取消' : '预览'}
> </Button>
<Button
</Button> type="button"
</div> variant={viewMode === 'compare' ? 'default' : 'outline'}
onClick={() => setViewMode('compare')}
>
</Button>
</div>
<div className={viewMode === 'compare' ? "grid grid-cols-2 gap-6" : "flex flex-col gap-6"}> <div className={viewMode === 'compare' ? "grid grid-cols-2 gap-6" : "flex flex-col gap-6"}>
<div className={viewMode === 'edit' || viewMode === 'compare' ? "block" : "hidden"}> <div className={viewMode === 'edit' || viewMode === 'compare' ? "block" : "hidden"}>
<Textarea <div className="relative h-[600px]">
id="solution-content" <CoreEditor
value={content} value={content}
onChange={(e) => setContent(e.target.value)} onChange={setContent}
placeholder="输入详细题解内容..." language="markdown"
className="min-h-[300px]" className="absolute inset-0 rounded-md border border-input"
/> />
</div>
</div>
<div className={viewMode === 'preview' || viewMode === 'compare' ? "block" : "hidden"}>
<MdxPreview source={content} />
</div>
</div>
<Button></Button>
</div> </div>
</CardContent>
<div className={viewMode === 'preview' || viewMode === 'compare' ? "block" : "hidden"}> </Card>
<MdxPreview source={content} />
</div>
</div>
<Button></Button>
</div>
); );
}; };