diff --git a/apps/web/src/components/InitiativeList.tsx b/apps/web/src/components/InitiativeList.tsx index f70c71e..3360678 100644 --- a/apps/web/src/components/InitiativeList.tsx +++ b/apps/web/src/components/InitiativeList.tsx @@ -1,4 +1,5 @@ import { AlertCircle, Plus } from "lucide-react"; +import { motion } from "motion/react"; import { Button } from "@/components/ui/button"; import { Card } from "@/components/ui/card"; import { Skeleton } from "@/components/Skeleton"; @@ -83,12 +84,22 @@ export function InitiativeList({ // Populated state return (
- {initiatives.map((initiative) => ( - ( + onViewInitiative(initiative.id)} - /> + initial={{ opacity: 0, y: 12 }} + animate={{ opacity: 1, y: 0 }} + transition={{ + duration: 0.3, + delay: Math.min(i * 0.05, 0.3), + ease: [0, 0, 0.2, 1], + }} + > + onViewInitiative(initiative.id)} + /> + ))}
); diff --git a/apps/web/src/routes/agents.tsx b/apps/web/src/routes/agents.tsx index 399fe7a..cbe1468 100644 --- a/apps/web/src/routes/agents.tsx +++ b/apps/web/src/routes/agents.tsx @@ -1,5 +1,6 @@ import { useState } from "react"; import { createFileRoute, useNavigate, useSearch } from "@tanstack/react-router"; +import { motion } from "motion/react"; import { AlertCircle, RefreshCw } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Card } from "@/components/ui/card"; @@ -182,7 +183,12 @@ function AgentsPage() { ]; return ( -
+ {/* Header + Filters */}
@@ -195,7 +201,12 @@ function AgentsPage() { Refresh
-
+ {filterOptions.map((opt) => ( ))} -
+
{/* Two-panel layout */} -
+ {/* Left: Agent List */}
{filtered.length === 0 ? ( @@ -227,60 +243,70 @@ function AgentsPage() {

) : ( - filtered.map((agent) => ( - ( + setSelectedAgentId(agent.id)} + initial={{ opacity: 0, y: 12 }} + animate={{ opacity: 1, y: 0 }} + transition={{ + duration: 0.3, + delay: Math.min(i * 0.05, 0.3), + ease: [0, 0, 0.2, 1], + }} > -
-
- - - {agent.name} - -
-
- - {agent.provider} - - - {modeLabel(agent.mode)} - - {/* Action dropdown */} -
e.stopPropagation()}> - + setSelectedAgentId(agent.id)} + > +
+
+ + + {agent.name} + +
+
+ + {agent.provider} + + + {modeLabel(agent.mode)} + + {/* Action dropdown */} +
e.stopPropagation()}> + +
-
-
- - {formatRelativeTime(String(agent.updatedAt))} - - {agent.status === "waiting_for_input" && ( - { - e.stopPropagation(); - handleGoToInbox(); - }} - > - Answer questions → +
+ + {formatRelativeTime(String(agent.updatedAt))} - )} -
- + {agent.status === "waiting_for_input" && ( + { + e.stopPropagation(); + handleGoToInbox(); + }} + > + Answer questions → + + )} +
+ + )) )}
@@ -302,7 +328,7 @@ function AgentsPage() {
)}
-
- + + ); } diff --git a/apps/web/src/routes/inbox.tsx b/apps/web/src/routes/inbox.tsx index 80b5532..d7cc2cb 100644 --- a/apps/web/src/routes/inbox.tsx +++ b/apps/web/src/routes/inbox.tsx @@ -1,5 +1,6 @@ import { useState } from "react"; import { createFileRoute } from "@tanstack/react-router"; +import { motion } from "motion/react"; import { AlertCircle } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Card } from "@/components/ui/card"; @@ -176,10 +177,20 @@ function InboxPage() { })); return ( -
+
{/* Left: Inbox List -- hidden on mobile when agent selected */} -
+ -
+ {/* Right: Detail Panel */} {selectedAgent && ( @@ -251,6 +262,6 @@ function InboxPage() {
)}
- + ); } diff --git a/apps/web/src/routes/initiatives/$id.tsx b/apps/web/src/routes/initiatives/$id.tsx index 9d68368..e8944ae 100644 --- a/apps/web/src/routes/initiatives/$id.tsx +++ b/apps/web/src/routes/initiatives/$id.tsx @@ -1,4 +1,5 @@ import { createFileRoute, useNavigate } from "@tanstack/react-router"; +import { motion } from "motion/react"; import { AlertCircle } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Skeleton } from "@/components/Skeleton"; @@ -99,7 +100,12 @@ function InitiativeDetailPage() { const phases = phasesQuery.data ?? []; return ( -
+ {/* Header */} {/* Tab bar */} -
+ {TABS.map((tab) => (
+
{/* Tab content */} - {activeTab === "content" && } - {activeTab === "plan" && ( - - )} - {activeTab === "execution" && ( - - )} - {activeTab === "review" && } -
+ + {activeTab === "content" && } + {activeTab === "plan" && ( + + )} + {activeTab === "execution" && ( + + )} + {activeTab === "review" && } + + ); } diff --git a/apps/web/src/routes/initiatives/index.tsx b/apps/web/src/routes/initiatives/index.tsx index 52388fb..41c7066 100644 --- a/apps/web/src/routes/initiatives/index.tsx +++ b/apps/web/src/routes/initiatives/index.tsx @@ -1,5 +1,6 @@ import { useState } from "react"; import { createFileRoute, useNavigate } from "@tanstack/react-router"; +import { motion } from "motion/react"; import { Plus } from "lucide-react"; import { Button } from "@/components/ui/button"; import { InitiativeList } from "@/components/InitiativeList"; @@ -31,7 +32,12 @@ function DashboardPage() { ]); return ( -
+ {/* Page header */}

Initiatives

@@ -57,19 +63,25 @@ function DashboardPage() {
{/* Initiative list */} - setCreateDialogOpen(true)} - onViewInitiative={(id) => - navigate({ to: "/initiatives/$id", params: { id } }) - } - /> + + setCreateDialogOpen(true)} + onViewInitiative={(id) => + navigate({ to: "/initiatives/$id", params: { id } }) + } + /> + {/* Create initiative dialog */} -
+ ); }