import { App, Button, Empty, Modal, Space, Table, Tag } from "antd"; import { Copy, FolderPlus, RefreshCw } from "lucide-react"; import { useCallback, useEffect, useState } from "react"; import { PromptDetailDialog } from "@/pages/prompts/components/prompt-detail-dialog"; import { useCopyText } from "@/hooks/use-copy-text"; import { useAssetStore } from "@/stores/use-asset-store"; import { fetchSourcePrompts, refreshSource, type Prompt } from "@/services/api/prompts"; import type { PromptSource } from "@/services/api/prompt-source-presets"; export function PromptSourceContentModal({ source, onClose }: { source: PromptSource | null; onClose: () => void }) { const { message } = App.useApp(); const [items, setItems] = useState([]); const [loading, setLoading] = useState(false); const [detail, setDetail] = useState(null); const copyText = useCopyText(); const addAsset = useAssetStore((state) => state.addAsset); const load = useCallback( async (force: boolean) => { if (!source) return; setLoading(true); try { setItems(force ? await refreshSourceItems(source.id) : await fetchSourcePrompts(source.id)); } catch (error) { message.error(error instanceof Error ? error.message : "拉取提示词失败"); } finally { setLoading(false); } }, [source, message], ); useEffect(() => { if (source) void load(false); else setItems([]); }, [source, load]); const saveAsset = (item: Prompt) => { addAsset({ kind: "text", title: item.title, coverUrl: item.coverUrl, tags: item.tags, source: item.category, data: { content: item.prompt }, metadata: { source: "prompt-library", promptId: item.id, githubUrl: item.githubUrl } }); message.success("已加入我的资产"); }; return ( <>
{source?.name || ""} · 提示词内容
共 {items.length} 条
} > rowKey="id" size="small" loading={loading} dataSource={items} pagination={{ pageSize: 10, showSizeChanger: false, size: "small" }} scroll={{ y: "56vh" }} locale={{ emptyText: }} columns={[ { title: "封面", dataIndex: "coverUrl", width: 72, render: (coverUrl: string) => (coverUrl ? :
), }, { title: "标题", dataIndex: "title", render: (title: string, item) => (
{title}
{item.prompt}
), }, { title: "标签", dataIndex: "tags", width: 200, render: (tags: string[]) => (
{tags.slice(0, 4).map((tag) => ( {tag} ))}
), }, { title: "操作", width: 210, render: (_, item) => ( ), }, ]} /> setDetail(null)} onCopy={(prompt) => copyText(prompt, "提示词已复制")} onSaveAsset={saveAsset} /> ); } async function refreshSourceItems(sourceId: string) { await refreshSource(sourceId); return fetchSourcePrompts(sourceId); }