import { useCallback, useEffect, useState } from "react"; import { useParams, useSearchParams } from "react-router-dom"; import { apiClient } from "../api/client"; import { getRepositoryStatus, listRepositories, type GitRepository, type GitStatus, } from "../api/git-repositories"; import { listToolTypes, type ToolType } from "../api/tool-types"; type WorkspaceStatus = "loading" | "ready" | "error" | "empty"; export interface Project { id: string; name: string; description?: string | null; } export const useRepoWorkspace = () => { const { projectId } = useParams<{ projectId: string }>(); const [searchParams, setSearchParams] = useSearchParams(); const [status, setStatus] = useState("loading"); const [project, setProject] = useState(null); const [repositories, setRepositories] = useState([]); const [selectedRepoId, setSelectedRepoId] = useState( searchParams.get("repo") ); const [branches, setBranches] = useState([]); const [currentBranch, setCurrentBranch] = useState("main"); const [gitStatus, setGitStatus] = useState(null); const [toolTypes, setToolTypes] = useState([]); const loadProject = useCallback(async () => { if (!projectId) return; try { const response = await apiClient.get(`/projects/${projectId}`); setProject(response.data); } catch { setProject(null); } }, [projectId]); const loadRepositories = useCallback(async () => { if (!projectId) return; setStatus("loading"); try { const data = await listRepositories(projectId); setRepositories(data); if (data.length === 0) { setStatus("empty"); } else { setStatus("ready"); if (!selectedRepoId) { setSelectedRepoId(data[0].id); const newParams = new URLSearchParams(searchParams); newParams.set("repo", data[0].id); setSearchParams(newParams, { replace: true }); } } } catch { setRepositories([]); setStatus("error"); } }, [projectId, selectedRepoId, searchParams, setSearchParams]); const loadBranches = useCallback(async () => { if (!projectId || !selectedRepoId) return; try { const response = await apiClient.get( `/projects/${projectId}/repositories/${selectedRepoId}/branches` ); const branchList = response.data.branches.map((b: { name: string }) => b.name); setBranches(branchList); const defaultBranch = response.data.default_branch; if (defaultBranch) setCurrentBranch(defaultBranch); } catch { setBranches([]); } }, [projectId, selectedRepoId]); const loadGitStatus = useCallback(async () => { if (!projectId || !selectedRepoId) return; try { const data = await getRepositoryStatus(projectId, selectedRepoId); setGitStatus(data); } catch { setGitStatus(null); } }, [projectId, selectedRepoId]); const loadToolTypes = useCallback(async () => { try { const data = await listToolTypes(); setToolTypes(data); } catch { setToolTypes([]); } }, []); useEffect(() => { void loadProject(); void loadRepositories(); void loadToolTypes(); }, [loadProject, loadRepositories, loadToolTypes]); useEffect(() => { void loadBranches(); void loadGitStatus(); }, [loadBranches, loadGitStatus]); const handleRepoChange = (repoId: string) => { setSelectedRepoId(repoId); const newParams = new URLSearchParams(searchParams); newParams.set("repo", repoId); newParams.delete("branch"); newParams.delete("path"); setSearchParams(newParams); }; const handleBranchChange = (branch: string) => { setCurrentBranch(branch); const newParams = new URLSearchParams(searchParams); newParams.set("branch", branch); setSearchParams(newParams); }; const selectedRepo = repositories.find((r) => r.id === selectedRepoId); return { projectId, project, status, repositories, selectedRepoId, selectedRepo, branches, currentBranch, gitStatus, toolTypes, handleRepoChange, handleBranchChange, loadGitStatus, loadBranches, loadRepositories, }; };