diff --git a/frontend/src/pages/Project.tsx b/frontend/src/pages/Project.tsx
index 47b70a3..b2cd875 100644
--- a/frontend/src/pages/Project.tsx
+++ b/frontend/src/pages/Project.tsx
@@ -1,4 +1,4 @@
-import { useCallback } from 'react';
+import { useCallback, useState } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { cn } from '@/lib/utils';
import { useProjectCache, useProjectSprintsCache } from '@/hooks/useProjectsCache';
@@ -6,8 +6,18 @@ import { useSprintEvents } from '@/hooks/useSprintEvents';
import { Card, CardContent } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
+import { Input } from '@/components/ui/input';
+import { Label } from '@/components/ui/label';
import { Skeleton } from '@/components/ui/skeleton';
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+} from '@/components/ui/dialog';
import { IssueListPanel } from '@/components/IssueListPanel';
import {
FolderGit2,
@@ -18,9 +28,10 @@ import {
MessageCircleQuestion,
ChevronRight,
Clock,
+ Plus,
Settings,
} from 'lucide-react';
-import type { Sprint } from '@/services/sprints';
+import { sprintsService, type Sprint } from '@/services/sprints';
const STATUS_ICON: Record = {
running: Loader2,
@@ -53,6 +64,11 @@ export default function Project() {
const { project, loading: projectLoading } = useProjectCache(projectId ?? null);
const { sprints, refresh: refreshSprints } = useProjectSprintsCache(projectId ?? null);
+ const [showCreate, setShowCreate] = useState(false);
+ const [newName, setNewName] = useState('');
+ const [creating, setCreating] = useState(false);
+ const [createError, setCreateError] = useState(null);
+
const latestSprint = sprints[0] ?? null;
const agentStatus = latestSprint?.currentAgentStatus;
const isAgentActive = agentStatus === 'running' || agentStatus === 'waiting';
@@ -68,6 +84,23 @@ export default function Project() {
refreshSprints();
}, [refreshSprints]);
+ const handleCreate = async (e: React.FormEvent) => {
+ e.preventDefault();
+ if (!projectId || !newName.trim()) return;
+ setCreating(true);
+ setCreateError(null);
+ try {
+ await sprintsService.create(projectId, { name: newName.trim(), description: '' });
+ refreshSprints();
+ setShowCreate(false);
+ setNewName('');
+ } catch (err) {
+ setCreateError(err instanceof Error ? err.message : 'Failed to create iteration');
+ } finally {
+ setCreating(false);
+ }
+ };
+
const activeSprints = sprints.filter(
(s) => s.currentAgentStatus === 'running' || s.currentAgentStatus === 'waiting',
);
@@ -178,16 +211,31 @@ export default function Project() {
-
-
- Iterations
+ Issues
+
+
+
+
+
+
+ Iterations
+
+
+
{activeSprints.length > 0 && (
@@ -233,6 +281,56 @@ export default function Project() {
)}
+
+
);
}
From c34a38e2e31d6964da34e1bfef15b39bbcf29076 Mon Sep 17 00:00:00 2001
From: eipasteur <85672662+eipasteur@users.noreply.github.com>
Date: Thu, 21 May 2026 16:35:21 -0700
Subject: [PATCH 09/11] fix(project-home): align Issues/Iterations headers and
tighten title spacing
The two columns were drifting vertically because their headers had
different heights (the Issues h3 was its natural height, while the
Iterations row was a flex container sized by the Start button).
- Wrap both titles in 'flex items-center justify-between h-7' so they
share the same fixed height as the Start button.
- Reduce the column space-y from 4 to 2 so the title sits closer to
the panel underneath.
---
frontend/src/pages/Project.tsx | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/frontend/src/pages/Project.tsx b/frontend/src/pages/Project.tsx
index b2cd875..f645fac 100644
--- a/frontend/src/pages/Project.tsx
+++ b/frontend/src/pages/Project.tsx
@@ -211,10 +211,12 @@ export default function Project() {