From 5efb4d4e8bbf48b19c231a238ae384339d2ad02e Mon Sep 17 00:00:00 2001 From: Lukas May Date: Thu, 5 Feb 2026 09:01:45 +0100 Subject: [PATCH] feat(21-01): wire toast notifications into all mutation flows - SpawnArchitectDropdown: toast.success on spawn, toast.error on failure - ActionMenu: toast.success on archive, toast.error on failure - CreateInitiativeDialog: toast.success on creation - Inbox: toast.success/error for resumeAgent and respondToMessage mutations - Replace all console.error-only mutation error handling with user-visible toasts --- packages/web/src/components/ActionMenu.tsx | 6 ++++-- .../web/src/components/CreateInitiativeDialog.tsx | 2 ++ .../web/src/components/SpawnArchitectDropdown.tsx | 11 +++++++---- packages/web/src/routes/inbox.tsx | 9 +++++++++ 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/packages/web/src/components/ActionMenu.tsx b/packages/web/src/components/ActionMenu.tsx index 2713446..3adcf29 100644 --- a/packages/web/src/components/ActionMenu.tsx +++ b/packages/web/src/components/ActionMenu.tsx @@ -7,6 +7,7 @@ import { DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; +import { toast } from "sonner"; import { trpc } from "@/lib/trpc"; interface ActionMenuProps { @@ -21,9 +22,10 @@ export function ActionMenu({ initiativeId, onDelete }: ActionMenuProps) { onSuccess: () => { utils.listInitiatives.invalidate(); onDelete?.(); + toast.success("Initiative archived"); }, - onError: (err) => { - console.error("Failed to archive initiative:", err.message); + onError: () => { + toast.error("Failed to archive initiative"); }, }); diff --git a/packages/web/src/components/CreateInitiativeDialog.tsx b/packages/web/src/components/CreateInitiativeDialog.tsx index d059d9f..6e43198 100644 --- a/packages/web/src/components/CreateInitiativeDialog.tsx +++ b/packages/web/src/components/CreateInitiativeDialog.tsx @@ -11,6 +11,7 @@ import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; +import { toast } from "sonner"; import { trpc } from "@/lib/trpc"; interface CreateInitiativeDialogProps { @@ -32,6 +33,7 @@ export function CreateInitiativeDialog({ onSuccess: () => { utils.listInitiatives.invalidate(); onOpenChange(false); + toast.success("Initiative created"); }, onError: (err) => { setError(err.message); diff --git a/packages/web/src/components/SpawnArchitectDropdown.tsx b/packages/web/src/components/SpawnArchitectDropdown.tsx index e54bb97..8466a8a 100644 --- a/packages/web/src/components/SpawnArchitectDropdown.tsx +++ b/packages/web/src/components/SpawnArchitectDropdown.tsx @@ -7,6 +7,7 @@ import { DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; +import { toast } from "sonner"; import { trpc } from "@/lib/trpc"; interface SpawnArchitectDropdownProps { @@ -26,9 +27,10 @@ export function SpawnArchitectDropdown({ setOpen(false); setSuccessText("Spawned!"); setTimeout(() => setSuccessText(null), 2000); + toast.success("Architect spawned"); }, - onError: (err) => { - console.error("Failed to spawn discuss architect:", err.message); + onError: () => { + toast.error("Failed to spawn architect"); }, }); @@ -37,9 +39,10 @@ export function SpawnArchitectDropdown({ setOpen(false); setSuccessText("Spawned!"); setTimeout(() => setSuccessText(null), 2000); + toast.success("Architect spawned"); }, - onError: (err) => { - console.error("Failed to spawn breakdown architect:", err.message); + onError: () => { + toast.error("Failed to spawn architect"); }, }); diff --git a/packages/web/src/routes/inbox.tsx b/packages/web/src/routes/inbox.tsx index 87730e4..e2d842c 100644 --- a/packages/web/src/routes/inbox.tsx +++ b/packages/web/src/routes/inbox.tsx @@ -4,6 +4,7 @@ import { AlertCircle, ChevronLeft } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Card } from "@/components/ui/card"; import { Skeleton } from "@/components/Skeleton"; +import { toast } from "sonner"; import { trpc } from "@/lib/trpc"; import { InboxList } from "@/components/InboxList"; import { QuestionForm } from "@/components/QuestionForm"; @@ -39,6 +40,10 @@ function InboxPage() { void utils.listWaitingAgents.invalidate(); void utils.listMessages.invalidate(); setSelectedAgentId(null); + toast.success("Answer submitted"); + }, + onError: () => { + toast.error("Failed to submit answer"); }, }); @@ -47,6 +52,10 @@ function InboxPage() { void utils.listWaitingAgents.invalidate(); void utils.listMessages.invalidate(); setSelectedAgentId(null); + toast.success("Response sent"); + }, + onError: () => { + toast.error("Failed to send response"); }, });