Skip to content

Commit d1184f6

Browse files
fix(platform): show loading spinner only for selected plan, not all plans (calcom#25290) (calcom#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.
1 parent 342e5ba commit d1184f6

1 file changed

Lines changed: 11 additions & 1 deletion

File tree

  • apps/web/components/settings/platform/pricing/platform-pricing

apps/web/components/settings/platform/pricing/platform-pricing/index.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { useRouter } from "next/navigation";
22
import { usePathname } from "next/navigation";
33
import type { ReactNode } from "react";
4+
import { useState } from "react";
45

56
import { ErrorCode } from "@calcom/lib/errorCodes";
67
import { showToast } from "@calcom/ui/components/toast";
@@ -17,13 +18,16 @@ export const PlatformPricing = ({ teamId, teamPlan, heading }: PlatformPricingPr
1718
const pathname = usePathname();
1819
const currentPage = pathname?.split("/").pop();
1920
const router = useRouter();
21+
const [loadingPlan, setLoadingPlan] = useState<string | null>(null);
22+
2023
const { mutateAsync: createTeamSubscription, isPending: isCreateTeamSubscriptionLoading } =
2124
useSubscribeTeamToStripe({
2225
onSuccess: (redirectUrl: string) => {
2326
router.push(redirectUrl);
2427
},
2528
onError: () => {
2629
showToast(ErrorCode.UnableToSubscribeToThePlatform, "error");
30+
setLoadingPlan(null);
2731
},
2832
teamId,
2933
});
@@ -35,6 +39,7 @@ export const PlatformPricing = ({ teamId, teamPlan, heading }: PlatformPricingPr
3539
},
3640
onError: () => {
3741
showToast(ErrorCode.UnableToSubscribeToThePlatform, "error");
42+
setLoadingPlan(null);
3843
},
3944
teamId,
4045
});
@@ -44,6 +49,8 @@ export const PlatformPricing = ({ teamId, teamPlan, heading }: PlatformPricingPr
4449
return router.push("https://go.cal.com/quote");
4550
}
4651

52+
setLoadingPlan(plan);
53+
4754
if (currentPage === "platform") {
4855
createTeamSubscription({ plan: plan.toLocaleUpperCase() });
4956
} else {
@@ -68,7 +75,10 @@ export const PlatformPricing = ({ teamId, teamPlan, heading }: PlatformPricingPr
6875
description={plan.description}
6976
pricing={plan.pricing}
7077
includes={plan.includes}
71-
isLoading={isCreateTeamSubscriptionLoading || isUpgradeTeamSubscriptionLoading}
78+
isLoading={
79+
loadingPlan === plan.plan &&
80+
(isCreateTeamSubscriptionLoading || isUpgradeTeamSubscriptionLoading)
81+
}
7282
currentPlan={plan.plan.toLocaleLowerCase() === teamPlan}
7383
handleSubscribe={() => handleStripeSubscription(plan.plan)}
7484
/>

0 commit comments

Comments
 (0)