From 4c99f89462332d4ee1b0c71c1d09da7a1fbfbb5e Mon Sep 17 00:00:00 2001 From: Lukas May Date: Fri, 6 Mar 2026 14:34:34 +0100 Subject: [PATCH] feat: Improve RegisterProjectDialog UX for long-running clone MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add Loader2 spinner with "Cloning repository…" label while pending - Keep Cancel button always enabled (no disabled gate) - Map INTERNAL_SERVER_ERROR to user-friendly clone failure message - Invalidate listProjects cache on success so new card appears immediately Co-Authored-By: Claude Sonnet 4.6 --- .../src/components/RegisterProjectDialog.tsx | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/apps/web/src/components/RegisterProjectDialog.tsx b/apps/web/src/components/RegisterProjectDialog.tsx index e0b42b9..f3b2937 100644 --- a/apps/web/src/components/RegisterProjectDialog.tsx +++ b/apps/web/src/components/RegisterProjectDialog.tsx @@ -10,6 +10,7 @@ import { import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; +import { Loader2 } from "lucide-react"; import { toast } from "sonner"; import { trpc } from "@/lib/trpc"; @@ -27,13 +28,20 @@ export function RegisterProjectDialog({ const [defaultBranch, setDefaultBranch] = useState("main"); const [error, setError] = useState(null); + const utils = trpc.useUtils(); + const registerMutation = trpc.registerProject.useMutation({ onSuccess: () => { onOpenChange(false); toast.success("Project registered"); + void utils.listProjects.invalidate(); }, onError: (err) => { - setError(err.message); + if (err.data?.code === "INTERNAL_SERVER_ERROR") { + setError("Failed to clone repository. Check the URL and try again."); + } else { + setError(err.message); + } }, }); @@ -109,7 +117,14 @@ export function RegisterProjectDialog({ Cancel