feat: Improve RegisterProjectDialog UX for long-running clone

- 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 <noreply@anthropic.com>
This commit is contained in:
Lukas May
2026-03-06 14:34:34 +01:00
parent d867a5f397
commit 4c99f89462

View File

@@ -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<string | null>(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
</Button>
<Button type="submit" disabled={!canSubmit}>
{registerMutation.isPending ? "Registering..." : "Register"}
{registerMutation.isPending ? (
<>
<Loader2 className="animate-spin mr-2 h-4 w-4" />
Cloning repository
</>
) : (
"Register"
)}
</Button>
</DialogFooter>
</form>