diff --git a/packages/web/src/components/InitiativeCard.tsx b/packages/web/src/components/InitiativeCard.tsx index d10c5eb..f4db5c9 100644 --- a/packages/web/src/components/InitiativeCard.tsx +++ b/packages/web/src/components/InitiativeCard.tsx @@ -1,5 +1,4 @@ import { MoreHorizontal, Eye, Bot } from "lucide-react"; -import type { Initiative } from "@codewalk-district/shared"; import { Card } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { @@ -13,8 +12,18 @@ import { StatusBadge } from "@/components/StatusBadge"; import { ProgressBar } from "@/components/ProgressBar"; import { trpc } from "@/lib/trpc"; +/** Initiative shape as returned by tRPC (Date serialized to string over JSON) */ +export interface SerializedInitiative { + id: string; + name: string; + description: string | null; + status: "active" | "completed" | "archived"; + createdAt: string; + updatedAt: string; +} + interface InitiativeCardProps { - initiative: Initiative; + initiative: SerializedInitiative; onView: () => void; onSpawnArchitect: (mode: "discuss" | "breakdown") => void; onDelete: () => void; diff --git a/packages/web/src/components/InitiativeList.tsx b/packages/web/src/components/InitiativeList.tsx new file mode 100644 index 0000000..e54ec5d --- /dev/null +++ b/packages/web/src/components/InitiativeList.tsx @@ -0,0 +1,90 @@ +import { AlertCircle, Plus } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import { InitiativeCard } from "@/components/InitiativeCard"; +import { trpc } from "@/lib/trpc"; + +interface InitiativeListProps { + statusFilter?: "all" | "active" | "completed" | "archived"; + onCreateNew: () => void; + onViewInitiative: (id: string) => void; + onSpawnArchitect: ( + initiativeId: string, + mode: "discuss" | "breakdown", + ) => void; + onDeleteInitiative: (id: string) => void; +} + +export function InitiativeList({ + statusFilter = "all", + onCreateNew, + onViewInitiative, + onSpawnArchitect, + onDeleteInitiative, +}: InitiativeListProps) { + const initiativesQuery = trpc.listInitiatives.useQuery( + statusFilter === "all" ? undefined : { status: statusFilter }, + ); + + // Loading state + if (initiativesQuery.isLoading) { + return ( +
+ Failed to load initiatives: {initiativesQuery.error.message} +
+ ++ No initiatives yet +
++ Create your first initiative to start planning and executing work. +
+ +