feat: add project settings page with tabbed layout
- Create SettingsTabLayout component with sidebar navigation - Create ProjectSettingsPage with General settings tab - Create RepositoriesSettingsTab for repo management - Add Members placeholder tab - Update router with settings routes - Add CSS styles for settings layout - Navigate to /projects/:id/settings from workspace header
This commit is contained in:
@@ -11,6 +11,7 @@ import {
|
||||
} from "../api/git_repositories";
|
||||
import { CommitPanel } from "../components/commit-panel";
|
||||
import { GitToolbar } from "../components/git-toolbar";
|
||||
import { WorkspaceHeader } from "../components/workspace-header";
|
||||
|
||||
type WorkspaceStatus = "loading" | "ready" | "error" | "empty";
|
||||
|
||||
@@ -28,11 +29,18 @@ interface FileTreeEntry {
|
||||
} | null;
|
||||
}
|
||||
|
||||
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<WorkspaceStatus>("loading");
|
||||
const [project, setProject] = useState<Project | null>(null);
|
||||
const [repositories, setRepositories] = useState<GitRepository[]>([]);
|
||||
const [selectedRepoId, setSelectedRepoId] = useState<string | null>(
|
||||
searchParams.get("repo")
|
||||
@@ -41,6 +49,16 @@ export const RepoWorkspace = () => {
|
||||
const [currentBranch, setCurrentBranch] = useState<string>("main");
|
||||
const [gitStatus, setGitStatus] = useState<GitStatus | null>(null);
|
||||
|
||||
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;
|
||||
|
||||
@@ -95,8 +113,9 @@ export const RepoWorkspace = () => {
|
||||
}, [projectId, selectedRepoId]);
|
||||
|
||||
useEffect(() => {
|
||||
void loadProject();
|
||||
void loadRepositories();
|
||||
}, [loadRepositories]);
|
||||
}, [loadProject, loadRepositories]);
|
||||
|
||||
useEffect(() => {
|
||||
void loadBranches();
|
||||
@@ -116,20 +135,12 @@ export const RepoWorkspace = () => {
|
||||
|
||||
return (
|
||||
<section className="repo-workspace">
|
||||
<div className="workspace-header">
|
||||
<div className="workspace-title">
|
||||
<h1>Repository Workspace</h1>
|
||||
{selectedRepo && <span className="repo-name">{selectedRepo.name}</span>}
|
||||
</div>
|
||||
<div className="workspace-actions">
|
||||
<Link
|
||||
className="secondary-button"
|
||||
to={`/projects/${projectId}/repositories`}
|
||||
>
|
||||
Manage Repositories
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
{project && (
|
||||
<WorkspaceHeader
|
||||
project={project}
|
||||
currentRepo={selectedRepo || null}
|
||||
/>
|
||||
)}
|
||||
|
||||
{status === "loading" && (
|
||||
<p className="muted">Loading repositories...</p>
|
||||
@@ -160,6 +171,13 @@ export const RepoWorkspace = () => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{project && (
|
||||
<WorkspaceHeader
|
||||
project={project}
|
||||
currentRepo={selectedRepo || null}
|
||||
/>
|
||||
)}
|
||||
|
||||
{status === "ready" && repositories.length > 0 && (
|
||||
<div className="workspace-layout">
|
||||
<aside className="workspace-sidebar">
|
||||
|
||||
Reference in New Issue
Block a user