fix: prevent billingPortal creation if no active subscription (#9701)
Billing portal is created in settings/billing page even if subscription is canceled, causing server internal error. -> Skip back end request Bonus : display settings/billing page with disabled button even if subscription is canceled --------- Co-authored-by: etiennejouan <jouan.etienne@gmail.com> Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -12,7 +12,6 @@ import {
|
||||
|
||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||
import { SettingsBillingCoverImage } from '@/billing/components/SettingsBillingCoverImage';
|
||||
import { useOnboardingStatus } from '@/onboarding/hooks/useOnboardingStatus';
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { SettingsPath } from '@/types/SettingsPath';
|
||||
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
|
||||
@ -21,8 +20,8 @@ import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModa
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer';
|
||||
import { useSubscriptionStatus } from '@/workspace/hooks/useSubscriptionStatus';
|
||||
import {
|
||||
OnboardingStatus,
|
||||
SubscriptionInterval,
|
||||
SubscriptionStatus,
|
||||
useBillingPortalSessionQuery,
|
||||
useUpdateBillingSubscriptionMutation,
|
||||
} from '~/generated/graphql';
|
||||
@ -59,9 +58,16 @@ export const SettingsBilling = () => {
|
||||
};
|
||||
|
||||
const { enqueueSnackBar } = useSnackBar();
|
||||
const onboardingStatus = useOnboardingStatus();
|
||||
const subscriptionStatus = useSubscriptionStatus();
|
||||
|
||||
const currentWorkspace = useRecoilValue(currentWorkspaceState);
|
||||
const subscriptions = currentWorkspace?.billingSubscriptions;
|
||||
const hasSubscriptions = (subscriptions?.length ?? 0) > 0;
|
||||
|
||||
const subscriptionStatus = useSubscriptionStatus();
|
||||
const hasNotCanceledCurrentSubscription =
|
||||
isDefined(subscriptionStatus) &&
|
||||
subscriptionStatus !== SubscriptionStatus.Canceled;
|
||||
|
||||
const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState);
|
||||
const switchingInfo =
|
||||
currentWorkspace?.currentBillingSubscription?.interval ===
|
||||
@ -75,18 +81,12 @@ export const SettingsBilling = () => {
|
||||
variables: {
|
||||
returnUrlPath: '/settings/billing',
|
||||
},
|
||||
skip: !hasSubscriptions,
|
||||
});
|
||||
|
||||
const billingPortalButtonDisabled =
|
||||
loading || !isDefined(data) || !isDefined(data.billingPortalSession.url);
|
||||
|
||||
const switchIntervalButtonDisabled =
|
||||
onboardingStatus !== OnboardingStatus.COMPLETED;
|
||||
|
||||
const cancelPlanButtonDisabled =
|
||||
billingPortalButtonDisabled ||
|
||||
onboardingStatus !== OnboardingStatus.COMPLETED;
|
||||
|
||||
const openBillingPortal = () => {
|
||||
if (isDefined(data) && isDefined(data.billingPortalSession.url)) {
|
||||
window.location.replace(data.billingPortalSession.url);
|
||||
@ -137,50 +137,46 @@ export const SettingsBilling = () => {
|
||||
>
|
||||
<SettingsPageContainer>
|
||||
<SettingsBillingCoverImage />
|
||||
{isDefined(subscriptionStatus) && (
|
||||
<>
|
||||
<Section>
|
||||
<H2Title
|
||||
title={t`Manage your subscription`}
|
||||
description={t`Edit payment method, see your invoices and more`}
|
||||
/>
|
||||
<Button
|
||||
Icon={IconCreditCard}
|
||||
title={t`View billing details`}
|
||||
variant="secondary"
|
||||
onClick={openBillingPortal}
|
||||
disabled={billingPortalButtonDisabled}
|
||||
/>
|
||||
</Section>
|
||||
<Section>
|
||||
<H2Title
|
||||
title={t`Edit billing interval`}
|
||||
description={t`Switch ${from}`}
|
||||
/>
|
||||
<Button
|
||||
Icon={IconCalendarEvent}
|
||||
title={t`Switch ${to}`}
|
||||
variant="secondary"
|
||||
onClick={openSwitchingIntervalModal}
|
||||
disabled={switchIntervalButtonDisabled}
|
||||
/>
|
||||
</Section>
|
||||
<Section>
|
||||
<H2Title
|
||||
title={t`Cancel your subscription`}
|
||||
description={t`Your workspace will be disabled`}
|
||||
/>
|
||||
<Button
|
||||
Icon={IconCircleX}
|
||||
title={t`Cancel Plan`}
|
||||
variant="secondary"
|
||||
accent="danger"
|
||||
onClick={openBillingPortal}
|
||||
disabled={cancelPlanButtonDisabled}
|
||||
/>
|
||||
</Section>
|
||||
</>
|
||||
)}
|
||||
<Section>
|
||||
<H2Title
|
||||
title={t`Manage your subscription`}
|
||||
description={t`Edit payment method, see your invoices and more`}
|
||||
/>
|
||||
<Button
|
||||
Icon={IconCreditCard}
|
||||
title={t`View billing details`}
|
||||
variant="secondary"
|
||||
onClick={openBillingPortal}
|
||||
disabled={billingPortalButtonDisabled}
|
||||
/>
|
||||
</Section>
|
||||
<Section>
|
||||
<H2Title
|
||||
title={t`Edit billing interval`}
|
||||
description={t`Switch ${from}`}
|
||||
/>
|
||||
<Button
|
||||
Icon={IconCalendarEvent}
|
||||
title={t`Switch ${to}`}
|
||||
variant="secondary"
|
||||
onClick={openSwitchingIntervalModal}
|
||||
disabled={!hasNotCanceledCurrentSubscription}
|
||||
/>
|
||||
</Section>
|
||||
<Section>
|
||||
<H2Title
|
||||
title={t`Cancel your subscription`}
|
||||
description={t`Your workspace will be disabled`}
|
||||
/>
|
||||
<Button
|
||||
Icon={IconCircleX}
|
||||
title={t`Cancel Plan`}
|
||||
variant="secondary"
|
||||
accent="danger"
|
||||
onClick={openBillingPortal}
|
||||
disabled={!hasNotCanceledCurrentSubscription}
|
||||
/>
|
||||
</Section>
|
||||
</SettingsPageContainer>
|
||||
<ConfirmationModal
|
||||
isOpen={isSwitchingIntervalModalOpen}
|
||||
|
||||
Reference in New Issue
Block a user