import React, { useState, useEffect } from 'react'; import { Loader2, Save, Eye, EyeOff, X, Tag as TagIcon } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Badge } from '@/components/ui/badge'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription, } from '@/components/ui/dialog'; import MonacoEditor from '@monaco-editor/react'; import ReactMarkdown from 'react-markdown'; import { usePromptFilesStore } from '@/stores/promptFilesStore'; import type { PromptFile } from '@/lib/api'; interface PromptFileEditorProps { open: boolean; onOpenChange: (open: boolean) => void; file?: PromptFile; onSuccess: () => void; } export const PromptFileEditor: React.FC = ({ open, onOpenChange, file, onSuccess, }) => { const { createFile, updateFile } = usePromptFilesStore(); const [saving, setSaving] = useState(false); const [showPreview, setShowPreview] = useState(false); const [name, setName] = useState(''); const [description, setDescription] = useState(''); const [content, setContent] = useState(''); const [tags, setTags] = useState([]); const [tagInput, setTagInput] = useState(''); useEffect(() => { if (file) { setName(file.name); setDescription(file.description || ''); setContent(file.content); setTags(file.tags); } else { setName(''); setDescription(''); setContent(''); setTags([]); } }, [file, open]); const handleAddTag = () => { const trimmed = tagInput.trim().toLowerCase(); if (trimmed && !tags.includes(trimmed)) { setTags([...tags, trimmed]); setTagInput(''); } }; const handleRemoveTag = (tag: string) => { setTags(tags.filter((t) => t !== tag)); }; const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === 'Enter') { e.preventDefault(); handleAddTag(); } }; const handleSave = async () => { if (!name.trim()) return; setSaving(true); try { if (file) { await updateFile({ id: file.id, name: name.trim(), description: description.trim() || undefined, content: content, tags, }); } else { await createFile({ name: name.trim(), description: description.trim() || undefined, content: content, tags, }); } onSuccess(); } catch (error) { // Error handling is done in the store } finally { setSaving(false); } }; return ( {file ? '编辑提示词文件' : '创建提示词文件'} {file ? '修改提示词文件的内容和信息' : '创建一个新的提示词文件模板'}
{/* Basic Info */}
setName(e.target.value)} />
setDescription(e.target.value)} />
{/* Tags */}
{tags.map((tag) => ( {tag} handleRemoveTag(tag)} /> ))}
setTagInput(e.target.value)} onKeyDown={handleKeyDown} />
{/* Content Editor */}
{showPreview ? (
{content}
) : (
setContent(value || '')} options={{ minimap: { enabled: false }, scrollBeyondLastLine: false, fontSize: 14, wordWrap: 'on', lineNumbers: 'on', automaticLayout: true, }} />
)}
); }; export default PromptFileEditor;