diff --git a/components/home/lovart-home.tsx b/components/home/lovart-home.tsx index 302067c9d..7fecc2bac 100644 --- a/components/home/lovart-home.tsx +++ b/components/home/lovart-home.tsx @@ -28,6 +28,7 @@ import { Settings, Sparkles, Star, + Trash2, Upload, User, Users, @@ -361,6 +362,7 @@ export function LovartHome({ const [tutorialDialogOpen, setTutorialDialogOpen] = useState(false); const [currentTutorialVideo, setCurrentTutorialVideo] = useState(null); const [contactDialogOpen, setContactDialogOpen] = useState(false); + const [deletingProjectId, setDeletingProjectId] = useState(null); const [typedPreviewText, setTypedPreviewText] = useState(""); const [previewCursorVisible, setPreviewCursorVisible] = useState(true); const projectSectionRef = useRef(null); @@ -1086,6 +1088,39 @@ export function LovartHome({ router.push("/canvas?new=1"); }; + const handleDeleteProject = async (projectId: string, projectTitle?: string) => { + if (deletingProjectId === projectId) return; + + const normalizedTitle = String(projectTitle || "").trim() || "未命名画布"; + const confirmed = window.confirm(`确定删除「${normalizedTitle}」吗?删除后不可恢复。`); + if (!confirmed) return; + + setDeletingProjectId(projectId); + try { + const response = await fetch(`/api/canvas/${projectId}`, { + method: "DELETE", + }); + const result = await response.json().catch(() => null); + if (!response.ok || result?.success === false) { + throw new Error(result?.error || "删除画布失败"); + } + + await mutateCanvas((current) => { + if (!current) return current; + return { + ...current, + data: (current.data || []).filter((project) => project.id !== projectId), + }; + }, false); + toast.success("画布已删除"); + } catch (error) { + toast.error(error instanceof Error ? error.message : "删除画布失败"); + await mutateCanvas(); + } finally { + setDeletingProjectId(null); + } + }; + const openAllProjectsInPage = () => { if (!isAuthenticated) { openLoginDialog(); @@ -1749,26 +1784,43 @@ export function LovartHome({ {recentProjects.map((item) => ( - + + + ))} {recentProjects.length === 0 && (