fix(platform): show loading spinner only for selected plan, not all plans (#25290) (#25292)

## Problem
When users clicked on a plan card in the Cal.com Platform pricing UI, the loading
spinner would appear on ALL plan cards simultaneously instead of just the selected one.
This gave a confusing UX impression that all plans were being processed at the same time.

## Solution
Track the currently loading plan using a `loadingPlan` state variable that stores
which plan the user clicked on, rather than relying solely on the pending state from
the mutation hook.

## Changes
- Added `loadingPlan` state to track which specific plan is loading
- Update `loadingPlan` when a plan subscription is initiated
- Reset `loadingPlan` on error to ensure UI returns to normal state
- Modified `isLoading` prop condition to check if the current plan matches
  the `loadingPlan` before showing the spinner

This ensures that only the plan card the user clicked on displays the loading indicator,
while other plans remain in their normal state.
This commit is contained in:
Piyanshu Saini authored and GitHub committed 2025-11-20 15:25:12 +00:00
1 parent 342e5baca2
commit d1184f65e2
1 file changed
+11 -1
@@ -1,6 +1,7 @@
import { useRouter } from "next/navigation";
import { usePathname } from "next/navigation";
import type { ReactNode } from "react";
import { useState } from "react";
import { ErrorCode } from "@calcom/lib/errorCodes";
import { showToast } from "@calcom/ui/components/toast";
@@ -17,6 +18,8 @@ export const PlatformPricing = ({ teamId, teamPlan, heading }: PlatformPricingPr
const pathname = usePathname();
const currentPage = pathname?.split("/").pop();
const router = useRouter();
const [loadingPlan, setLoadingPlan] = useState<string | null>(null);
const { mutateAsync: createTeamSubscription, isPending: isCreateTeamSubscriptionLoading } =
useSubscribeTeamToStripe({
onSuccess: (redirectUrl: string) => {
@@ -24,6 +27,7 @@ export const PlatformPricing = ({ teamId, teamPlan, heading }: PlatformPricingPr
},
onError: () => {
showToast(ErrorCode.UnableToSubscribeToThePlatform, "error");
setLoadingPlan(null);
},
teamId,
});
@@ -35,6 +39,7 @@ export const PlatformPricing = ({ teamId, teamPlan, heading }: PlatformPricingPr
},
onError: () => {
showToast(ErrorCode.UnableToSubscribeToThePlatform, "error");
setLoadingPlan(null);
},
teamId,
});
@@ -44,6 +49,8 @@ export const PlatformPricing = ({ teamId, teamPlan, heading }: PlatformPricingPr
return router.push("https://go.cal.com/quote");
}
setLoadingPlan(plan);
if (currentPage === "platform") {
createTeamSubscription({ plan: plan.toLocaleUpperCase() });
} else {
@@ -68,7 +75,10 @@ export const PlatformPricing = ({ teamId, teamPlan, heading }: PlatformPricingPr
description={plan.description}
pricing={plan.pricing}
includes={plan.includes}
isLoading={isCreateTeamSubscriptionLoading || isUpgradeTeamSubscriptionLoading}
isLoading={
loadingPlan === plan.plan &&
(isCreateTeamSubscriptionLoading || isUpgradeTeamSubscriptionLoading)
}
currentPlan={plan.plan.toLocaleLowerCase() === teamPlan}
handleSubscribe={() => handleStripeSubscription(plan.plan)}
/>