import { useCallback, useEffect, useState } from "react"; import { Link, useParams, useSearchParams } from "react-router-dom"; import { apiClient } from "../api/client"; import type { GitRepository } from "../types/git-repository"; import type { ToolType } from "../types/tool-type"; import { getRepositoryStatus, listRepositories, type GitStatus, } from "../api/git-repositories"; import { WorkspaceSidebar } from "../components/features/git"; import { FileEditor } from "../components/features/git/FileEditor"; import { WorkspaceHeader } from "../components/features/workspace/WorkspaceHeader"; import { GitToolbar } from "../components/features/git/GitToolbar"; import { LoadingState, ErrorState } from "../components/ui"; import { listToolTypes } from "../api/tool-types"; type WorkspaceStatus = "loading" | "ready" | "error" | "empty"; interface Project { id: string; name: string; description?: string | null; } export const RepoWorkspace = () => { 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 selectedRepo = repositories.find((r) => r.id === selectedRepoId); return (
{project && ( )} {status === "loading" && ( )} {status === "error" && ( void loadRepositories()} /> )} {status === "empty" && (

No repositories in this project yet.

Manage Repositories
)} {status === "ready" && repositories.length > 0 && ( <> {selectedRepoId && ( { setCurrentBranch(branch); const newParams = new URLSearchParams(searchParams); newParams.set("branch", branch); setSearchParams(newParams); }} onRefresh={() => { void loadBranches(); void loadGitStatus(); window.dispatchEvent(new CustomEvent("refresh-file-tree")); }} /> )}
{selectedRepoId && ( { void loadGitStatus(); window.dispatchEvent(new CustomEvent("refresh-file-tree")); }} /> )}
{selectedRepoId && ( )}
)}
); };