import { useState } from "react"; import { useQuery, useQueryClient } from "@tanstack/react-query"; import { getSpaces, setCurrentSpace, createSpace, updateSpace, deleteSpace, type Space, } from "../../lib/commands"; import { useUIStore } from "../../store/ui"; import { RepoRegistryModal } from "../dashboard/RepoRegistryModal"; export type Page = "overview" | "dashboard" | "source-library" | "devtools" | "proxy" | "settings" | "health"; const NAV_ITEMS: { id: Page; label: string }[] = [ { id: "overview", label: "仪表盘" }, { id: "dashboard", label: "项目管理" }, { id: "source-library", label: "源码库" }, { id: "devtools", label: "开发环境" }, { id: "proxy", label: "WSL 代理" }, { id: "health", label: "健康中心" }, { id: "settings", label: "设置" }, ]; interface Props { page: Page; onPageChange: (page: Page) => void; } export function Sidebar({ page, onPageChange }: Props) { const [spaceOpen, setSpaceOpen] = useState(true); const [showForm, setShowForm] = useState(undefined); const [deleteTarget, setDeleteTarget] = useState(null); const [showRepoRegistry, setShowRepoRegistry] = useState(false); const qc = useQueryClient(); const showToast = useUIStore((s) => s.showToast); const { data: spaces = [], refetch } = useQuery({ queryKey: ["spaces"], queryFn: getSpaces, }); const currentSpace = spaces.find((s) => s.is_current); const handleSwitch = async (id: string) => { await setCurrentSpace(id); refetch(); qc.invalidateQueries({ queryKey: ["projects"] }); }; const handleDelete = async (space: Space) => { await deleteSpace(space.id); refetch(); showToast("已删除"); setDeleteTarget(null); }; return ( <> {/* 新建/编辑模态框 */} {showForm !== undefined && ( setShowForm(undefined)} onSaved={() => { setShowForm(undefined); refetch(); showToast(showForm ? "已更新" : "已创建"); }} /> )} {/* 仓库管理弹窗 */} {showRepoRegistry && ( setShowRepoRegistry(false)} /> )} {/* 删除确认 */} {deleteTarget && (

删除空间

确定删除空间「{deleteTarget.name}」?该空间下的项目记录不会删除。

)} ); } function SpaceFormModal({ space, onClose, onSaved }: { space: Space | null; onClose: () => void; onSaved: () => void; }) { const [name, setName] = useState(space?.name ?? ""); const [saving, setSaving] = useState(false); const handleSave = async () => { if (!name.trim()) return; setSaving(true); try { if (space) { await updateSpace(space.id, name.trim()); } else { await createSpace(name.trim()); } onSaved(); } finally { setSaving(false); } }; return (

{space ? "编辑空间" : "新建空间"}

setName(e.target.value)} placeholder="笔记本 / 日本服务器 / 公司台式机" className="w-full border border-gray-200 rounded-lg px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-blue-200" autoFocus onKeyDown={(e) => e.key === "Enter" && handleSave()} />
); }