import { useState } from "react"; import { useTranslation } from "react-i18next"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Trash2, ExternalLink, Plus } from "lucide-react"; import { settingsApi } from "@/lib/api"; import { FullScreenPanel } from "@/components/common/FullScreenPanel"; import type { Skill, SkillRepo } from "@/lib/api/skills"; interface RepoManagerPanelProps { repos: SkillRepo[]; skills: Skill[]; onAdd: (repo: SkillRepo) => Promise; onRemove: (owner: string, name: string) => Promise; onClose: () => void; } export function RepoManagerPanel({ repos, skills, onAdd, onRemove, onClose, }: RepoManagerPanelProps) { const { t } = useTranslation(); const [repoUrl, setRepoUrl] = useState(""); const [branch, setBranch] = useState(""); const [error, setError] = useState(""); const getSkillCount = (repo: SkillRepo) => skills.filter( (skill) => skill.repoOwner === repo.owner && skill.repoName === repo.name && (skill.repoBranch || "main") === (repo.branch || "main"), ).length; const parseRepoUrl = ( url: string, ): { owner: string; name: string } | null => { let cleaned = url.trim(); cleaned = cleaned.replace(/^https?:\/\/github\.com\//, ""); cleaned = cleaned.replace(/\.git$/, ""); const parts = cleaned.split("/"); if (parts.length === 2 && parts[0] && parts[1]) { return { owner: parts[0], name: parts[1] }; } return null; }; const handleAdd = async () => { setError(""); const parsed = parseRepoUrl(repoUrl); if (!parsed) { setError(t("skills.repo.invalidUrl")); return; } try { await onAdd({ owner: parsed.owner, name: parsed.name, branch: branch || "main", enabled: true, }); setRepoUrl(""); setBranch(""); } catch (e) { setError(e instanceof Error ? e.message : t("skills.repo.addFailed")); } }; const handleOpenRepo = async (owner: string, name: string) => { try { await settingsApi.openExternal(`https://github.com/${owner}/${name}`); } catch (error) { console.error("Failed to open URL:", error); } }; return ( {/* 添加仓库表单 */}

添加技能仓库

setRepoUrl(e.target.value)} className="mt-2" />
setBranch(e.target.value)} className="mt-2" />
{error && (

{error}

)}
{/* 仓库列表 */}

{t("skills.repo.list")}

{repos.length === 0 ? (

{t("skills.repo.empty")}

) : (
{repos.map((repo) => (
{repo.owner}/{repo.name}
{t("skills.repo.branch")}: {repo.branch || "main"} {t("skills.repo.skillCount", { count: getSkillCount(repo), })}
))}
)}
); }