From 080144d606196f078a42f6a8dd5066e37d67a01f Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Fri, 13 Mar 2026 08:29:44 -0500 Subject: [PATCH] feat(web): project list and mission dashboard views Add projects page with grid layout of project cards showing status, description, and creation date. Include active mission status section that fetches from the coord API with stat cards for mission ID, phase, task progress, and status. Components: ProjectCard, MissionStatus, StatCard Refs #30 Co-Authored-By: Claude Opus 4.6 --- .../web/src/app/(dashboard)/projects/page.tsx | 96 +++++++++++++++++++ .../src/components/projects/project-card.tsx | 44 +++++++++ docs/TASKS.md | 4 +- 3 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 apps/web/src/app/(dashboard)/projects/page.tsx create mode 100644 apps/web/src/components/projects/project-card.tsx diff --git a/apps/web/src/app/(dashboard)/projects/page.tsx b/apps/web/src/app/(dashboard)/projects/page.tsx new file mode 100644 index 0000000..a5b3510 --- /dev/null +++ b/apps/web/src/app/(dashboard)/projects/page.tsx @@ -0,0 +1,96 @@ +'use client'; + +import { useCallback, useEffect, useState } from 'react'; +import { api } from '@/lib/api'; +import type { Project } from '@/lib/types'; +import { ProjectCard } from '@/components/projects/project-card'; + +export default function ProjectsPage(): React.ReactElement { + const [projects, setProjects] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + api('/api/projects') + .then(setProjects) + .catch(() => {}) + .finally(() => setLoading(false)); + }, []); + + const handleProjectClick = useCallback((project: Project) => { + console.log('Project clicked:', project.id); + }, []); + + return ( +
+
+

Projects

+
+ + {loading ? ( +

Loading projects...

+ ) : projects.length === 0 ? ( +
+

No projects yet

+

+ Projects will appear here when created via the gateway API +

+
+ ) : ( +
+ {projects.map((project) => ( + + ))} +
+ )} + + {/* Mission status section */} + +
+ ); +} + +function MissionStatus(): React.ReactElement { + const [mission, setMission] = useState | null>(null); + const [loading, setLoading] = useState(true); + + useEffect(() => { + api>('/api/coord/status') + .then(setMission) + .catch(() => setMission(null)) + .finally(() => setLoading(false)); + }, []); + + return ( +
+

Active Mission

+ {loading ? ( +

Loading mission status...

+ ) : !mission ? ( +
+

No active mission detected

+
+ ) : ( +
+
+ + + + +
+
+ )} +
+ ); +} + +function StatCard({ label, value }: { label: string; value: string }): React.ReactElement { + return ( +
+

{label}

+

{value}

+
+ ); +} diff --git a/apps/web/src/components/projects/project-card.tsx b/apps/web/src/components/projects/project-card.tsx new file mode 100644 index 0000000..8e740a2 --- /dev/null +++ b/apps/web/src/components/projects/project-card.tsx @@ -0,0 +1,44 @@ +'use client'; + +import { cn } from '@/lib/cn'; +import type { Project } from '@/lib/types'; + +interface ProjectCardProps { + project: Project; + onClick: (project: Project) => void; +} + +const statusColors: Record = { + active: 'bg-success/20 text-success', + paused: 'bg-warning/20 text-warning', + completed: 'bg-blue-600/20 text-blue-400', + archived: 'bg-gray-600/20 text-gray-400', +}; + +export function ProjectCard({ project, onClick }: ProjectCardProps): React.ReactElement { + return ( + + ); +} diff --git a/docs/TASKS.md b/docs/TASKS.md index f50cc2c..dc4feda 100644 --- a/docs/TASKS.md +++ b/docs/TASKS.md @@ -32,8 +32,8 @@ | P3-001 | done | Phase 3 | apps/web scaffold — Next.js 16 + BetterAuth + Tailwind | #82 | #26 | | P3-002 | done | Phase 3 | Auth pages — login, registration, SSO redirect | #83 | #27 | | P3-003 | done | Phase 3 | Chat UI — conversations, messages, streaming | #84 | #28 | -| P3-004 | in-progress | Phase 3 | Task management — list view + kanban board | — | #29 | -| P3-005 | not-started | Phase 3 | Project & mission views — dashboard + PRD viewer | — | #30 | +| P3-004 | done | Phase 3 | Task management — list view + kanban board | #86 | #29 | +| P3-005 | in-progress | Phase 3 | Project & mission views — dashboard + PRD viewer | — | #30 | | P3-006 | not-started | Phase 3 | Settings — provider config, profile, integrations | — | #31 | | P3-007 | not-started | Phase 3 | Admin panel — user management, RBAC | — | #32 | | P3-008 | not-started | Phase 3 | Verify Phase 3 — web dashboard functional E2E | — | #33 |