Update ChooseYourPlan page with new trial period options (#9628)
### Context - Update /plan-required page to let users get free trial without credit card plan - Update usePageChangeEffectNavigateLocation to redirect paused and canceled subscription (suspended workspace) to /settings/billing page ### To do - [x] Update usePageChangeEffectNavigateLocation test - [x] Update ChooseYourPlan sb test closes #9520 --------- Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
This commit is contained in:
@ -17,12 +17,14 @@ export const InformationBanner = ({
|
||||
buttonTitle,
|
||||
buttonIcon,
|
||||
buttonOnClick,
|
||||
isButtonDisabled = false,
|
||||
}: {
|
||||
message: string;
|
||||
variant?: BannerVariant;
|
||||
buttonTitle?: string;
|
||||
buttonIcon?: IconComponent;
|
||||
buttonOnClick?: () => void;
|
||||
isButtonDisabled?: boolean;
|
||||
}) => {
|
||||
return (
|
||||
<StyledBanner variant={variant}>
|
||||
@ -35,6 +37,7 @@ export const InformationBanner = ({
|
||||
size="small"
|
||||
inverted
|
||||
onClick={buttonOnClick}
|
||||
disabled={isButtonDisabled}
|
||||
/>
|
||||
)}
|
||||
</StyledBanner>
|
||||
|
||||
@ -1,6 +1,13 @@
|
||||
import { InformationBannerBillingSubscriptionPaused } from '@/information-banner/components/billing/InformationBannerBillingSubscriptionPaused';
|
||||
import { InformationBannerFailPaymentInfo } from '@/information-banner/components/billing/InformationBannerFailPaymentInfo';
|
||||
import { InformationBannerNoBillingSubscription } from '@/information-banner/components/billing/InformationBannerNoBillingSubscription';
|
||||
import { InformationBannerReconnectAccountEmailAliases } from '@/information-banner/components/reconnect-account/InformationBannerReconnectAccountEmailAliases';
|
||||
import { InformationBannerReconnectAccountInsufficientPermissions } from '@/information-banner/components/reconnect-account/InformationBannerReconnectAccountInsufficientPermissions';
|
||||
import { useIsWorkspaceActivationStatusSuspended } from '@/workspace/hooks/useIsWorkspaceActivationStatusSuspended';
|
||||
import { useSubscriptionStatus } from '@/workspace/hooks/useSubscriptionStatus';
|
||||
import styled from '@emotion/styled';
|
||||
import { isDefined } from 'twenty-ui';
|
||||
import { SubscriptionStatus } from '~/generated-metadata/graphql';
|
||||
|
||||
const StyledInformationBannerWrapper = styled.div`
|
||||
height: 40px;
|
||||
@ -12,10 +19,30 @@ const StyledInformationBannerWrapper = styled.div`
|
||||
`;
|
||||
|
||||
export const InformationBannerWrapper = () => {
|
||||
const subscriptionStatus = useSubscriptionStatus();
|
||||
const isWorkspaceSuspended = useIsWorkspaceActivationStatusSuspended();
|
||||
|
||||
const displayBillingSubscriptionPausedBanner =
|
||||
isWorkspaceSuspended && subscriptionStatus === SubscriptionStatus.Paused;
|
||||
|
||||
const displayBillingSubscriptionCanceledBanner =
|
||||
isWorkspaceSuspended && !isDefined(subscriptionStatus);
|
||||
|
||||
const displayFailPaymentInfoBanner =
|
||||
subscriptionStatus === SubscriptionStatus.PastDue ||
|
||||
subscriptionStatus === SubscriptionStatus.Unpaid;
|
||||
|
||||
return (
|
||||
<StyledInformationBannerWrapper>
|
||||
<InformationBannerReconnectAccountInsufficientPermissions />
|
||||
<InformationBannerReconnectAccountEmailAliases />
|
||||
{displayBillingSubscriptionPausedBanner && (
|
||||
<InformationBannerBillingSubscriptionPaused />
|
||||
)}
|
||||
{displayBillingSubscriptionCanceledBanner && (
|
||||
<InformationBannerNoBillingSubscription />
|
||||
)}
|
||||
{displayFailPaymentInfoBanner && <InformationBannerFailPaymentInfo />}
|
||||
</StyledInformationBannerWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
import { InformationBanner } from '@/information-banner/components/InformationBanner';
|
||||
import { AppPath } from '@/types/AppPath';
|
||||
import { SettingsPath } from '@/types/SettingsPath';
|
||||
import { isDefined } from 'twenty-ui';
|
||||
import { useBillingPortalSessionQuery } from '~/generated/graphql';
|
||||
|
||||
export const InformationBannerBillingSubscriptionPaused = () => {
|
||||
const { data, loading } = useBillingPortalSessionQuery({
|
||||
variables: {
|
||||
returnUrlPath: `${AppPath.Settings}/${SettingsPath.Billing}`,
|
||||
},
|
||||
});
|
||||
|
||||
const openBillingPortal = () => {
|
||||
if (isDefined(data) && isDefined(data.billingPortalSession.url)) {
|
||||
window.location.replace(data.billingPortalSession.url);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<InformationBanner
|
||||
variant="danger"
|
||||
message={'Trial expired. Please update your billing details'}
|
||||
buttonTitle="Update"
|
||||
buttonOnClick={() => openBillingPortal()}
|
||||
isButtonDisabled={loading || !isDefined(data)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,29 @@
|
||||
import { InformationBanner } from '@/information-banner/components/InformationBanner';
|
||||
import { AppPath } from '@/types/AppPath';
|
||||
import { SettingsPath } from '@/types/SettingsPath';
|
||||
import { isDefined } from 'twenty-ui';
|
||||
import { useBillingPortalSessionQuery } from '~/generated/graphql';
|
||||
|
||||
export const InformationBannerFailPaymentInfo = () => {
|
||||
const { data, loading } = useBillingPortalSessionQuery({
|
||||
variables: {
|
||||
returnUrlPath: `${AppPath.Settings}/${SettingsPath.Billing}`,
|
||||
},
|
||||
});
|
||||
|
||||
const openBillingPortal = () => {
|
||||
if (isDefined(data) && isDefined(data.billingPortalSession.url)) {
|
||||
window.location.replace(data.billingPortalSession.url);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<InformationBanner
|
||||
variant="danger"
|
||||
message={'Last payment failed. Please update your billing details.'}
|
||||
buttonTitle="Update"
|
||||
buttonOnClick={() => openBillingPortal()}
|
||||
isButtonDisabled={loading || !isDefined(data)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,21 @@
|
||||
import { BILLING_CHECKOUT_SESSION_DEFAULT_VALUE } from '@/billing/constants/BillingCheckoutSessionDefaultValue';
|
||||
import { useHandleCheckoutSession } from '@/billing/hooks/useHandleCheckoutSession';
|
||||
import { InformationBanner } from '@/information-banner/components/InformationBanner';
|
||||
|
||||
export const InformationBannerNoBillingSubscription = () => {
|
||||
const { handleCheckoutSession, isSubmitting } = useHandleCheckoutSession({
|
||||
recurringInterval: BILLING_CHECKOUT_SESSION_DEFAULT_VALUE.interval,
|
||||
plan: BILLING_CHECKOUT_SESSION_DEFAULT_VALUE.plan,
|
||||
requirePaymentMethod: true,
|
||||
});
|
||||
|
||||
return (
|
||||
<InformationBanner
|
||||
variant="danger"
|
||||
message={`Your workspace does not have an active subscription`}
|
||||
buttonTitle="Subscribe"
|
||||
buttonOnClick={() => handleCheckoutSession()}
|
||||
isButtonDisabled={isSubmitting}
|
||||
/>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user