Add enterprise plan in cloud onboarding (#11100)
Adding a way to switch to enterprise plan during onboarding <img width="409" alt="Screenshot 2025-03-21 at 17 03 19" src="https://github.com/user-attachments/assets/7a8c9ebd-3d77-4875-a141-c30fa5119eff" />
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
import { gql } from '@apollo/client';
|
||||
export type Maybe<T> = T | null;
|
||||
export type InputMaybe<T> = Maybe<T>;
|
||||
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
|
||||
@ -2386,7 +2386,7 @@ export type ValidatePasswordResetTokenQuery = { __typename?: 'Query', validatePa
|
||||
export type BillingBaseProductPricesQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type BillingBaseProductPricesQuery = { __typename?: 'Query', plans: Array<{ __typename?: 'BillingPlanOutput', planKey: BillingPlanKey, baseProduct: { __typename?: 'BillingProductDTO', prices: Array<{ __typename?: 'BillingPriceLicensedDTO', unitAmount: number, stripePriceId: string, recurringInterval: SubscriptionInterval } | { __typename?: 'BillingPriceMeteredDTO' }> } }> };
|
||||
export type BillingBaseProductPricesQuery = { __typename?: 'Query', plans: Array<{ __typename?: 'BillingPlanOutput', planKey: BillingPlanKey, baseProduct: { __typename?: 'BillingProductDTO', name: string, prices: Array<{ __typename?: 'BillingPriceLicensedDTO', unitAmount: number, stripePriceId: string, recurringInterval: SubscriptionInterval } | { __typename?: 'BillingPriceMeteredDTO' }> } }> };
|
||||
|
||||
export type BillingPortalSessionQueryVariables = Exact<{
|
||||
returnUrlPath?: InputMaybe<Scalars['String']>;
|
||||
@ -3859,6 +3859,7 @@ export const BillingBaseProductPricesDocument = gql`
|
||||
plans {
|
||||
planKey
|
||||
baseProduct {
|
||||
name
|
||||
prices {
|
||||
... on BillingPriceLicensedDTO {
|
||||
unitAmount
|
||||
|
||||
@ -5,6 +5,7 @@ export const BILLING_BASE_PRODUCT_PRICES = gql`
|
||||
plans {
|
||||
planKey
|
||||
baseProduct {
|
||||
name
|
||||
prices {
|
||||
... on BillingPriceLicensedDTO {
|
||||
unitAmount
|
||||
|
||||
@ -88,20 +88,43 @@ export const ChooseYourPlan = () => {
|
||||
const billing = useRecoilValue(billingState);
|
||||
const { t } = useLingui();
|
||||
|
||||
const benefits = [
|
||||
t`Full access`,
|
||||
t`Unlimited contacts`,
|
||||
t`Email integration`,
|
||||
t`Custom objects`,
|
||||
t`API & Webhooks`,
|
||||
t`1 000 workflow node executions`,
|
||||
];
|
||||
const [billingCheckoutSession, setBillingCheckoutSession] = useRecoilState(
|
||||
billingCheckoutSessionState,
|
||||
);
|
||||
|
||||
const { data: plans } = useBillingBaseProductPricesQuery();
|
||||
|
||||
const currentPlan = billingCheckoutSession.plan || BillingPlanKey.PRO;
|
||||
|
||||
const getPlanBenefits = (planKey: BillingPlanKey) => {
|
||||
if (planKey === BillingPlanKey.ENTERPRISE) {
|
||||
return [
|
||||
t`Full access`,
|
||||
t`Unlimited contacts`,
|
||||
t`Email integration`,
|
||||
t`Custom objects`,
|
||||
t`API & Webhooks`,
|
||||
t`20 000 workflow node executions`,
|
||||
t`SSO (SAML / OIDC)`,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
t`Full access`,
|
||||
t`Unlimited contacts`,
|
||||
t`Email integration`,
|
||||
t`Custom objects`,
|
||||
t`API & Webhooks`,
|
||||
t`10 000 workflow node executions`,
|
||||
];
|
||||
};
|
||||
|
||||
const benefits = getPlanBenefits(currentPlan);
|
||||
|
||||
const baseProduct = plans?.plans.find(
|
||||
(plan) => plan.planKey === BillingPlanKey.PRO,
|
||||
(plan) => plan.planKey === currentPlan,
|
||||
)?.baseProduct;
|
||||
|
||||
const baseProductPrice = baseProduct?.prices.find(
|
||||
(price): price is BillingPriceLicensedDto =>
|
||||
isBillingPriceLicensed(price) &&
|
||||
@ -116,10 +139,6 @@ export const ChooseYourPlan = () => {
|
||||
(trialPeriod) => trialPeriod.isCreditCardRequired,
|
||||
);
|
||||
|
||||
const [billingCheckoutSession, setBillingCheckoutSession] = useRecoilState(
|
||||
billingCheckoutSessionState,
|
||||
);
|
||||
|
||||
const { handleCheckoutSession, isSubmitting } = useHandleCheckoutSession({
|
||||
recurringInterval: billingCheckoutSession.interval,
|
||||
plan: billingCheckoutSession.plan,
|
||||
@ -133,7 +152,7 @@ export const ChooseYourPlan = () => {
|
||||
billingCheckoutSession.requirePaymentMethod !== withCreditCard
|
||||
) {
|
||||
setBillingCheckoutSession({
|
||||
plan: billingCheckoutSession.plan,
|
||||
plan: currentPlan,
|
||||
interval: baseProductPrice.recurringInterval,
|
||||
requirePaymentMethod: withCreditCard,
|
||||
});
|
||||
@ -141,10 +160,31 @@ export const ChooseYourPlan = () => {
|
||||
};
|
||||
};
|
||||
|
||||
const handleSwitchPlan = (planKey: BillingPlanKey) => {
|
||||
return () => {
|
||||
if (isDefined(baseProductPrice)) {
|
||||
setBillingCheckoutSession({
|
||||
plan: planKey,
|
||||
interval: baseProductPrice.recurringInterval,
|
||||
requirePaymentMethod: billingCheckoutSession.requirePaymentMethod,
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const { signOut } = useAuth();
|
||||
|
||||
const withCreditCardTrialPeriodDuration = withCreditCardTrialPeriod?.duration;
|
||||
|
||||
const alternatePlan =
|
||||
currentPlan === BillingPlanKey.PRO
|
||||
? BillingPlanKey.ENTERPRISE
|
||||
: BillingPlanKey.PRO;
|
||||
|
||||
const alternatePlanName = plans?.plans.find(
|
||||
(plan) => plan.planKey === alternatePlan,
|
||||
)?.baseProduct.name;
|
||||
|
||||
return (
|
||||
isDefined(baseProductPrice) &&
|
||||
isDefined(billing) && (
|
||||
@ -213,6 +253,10 @@ export const ChooseYourPlan = () => {
|
||||
<Trans>Log out</Trans>
|
||||
</ActionLink>
|
||||
<span />
|
||||
<ActionLink onClick={handleSwitchPlan(alternatePlan)}>
|
||||
<Trans>Switch to {alternatePlanName}</Trans>
|
||||
</ActionLink>
|
||||
<span />
|
||||
<ActionLink href={CAL_LINK} target="_blank" rel="noreferrer">
|
||||
<Trans>Book a Call</Trans>
|
||||
</ActionLink>
|
||||
|
||||
@ -85,7 +85,7 @@ export class BillingPlanService {
|
||||
|
||||
if (!baseProduct) {
|
||||
throw new BillingException(
|
||||
'Base product not found, did you run the billing:sync-products command?',
|
||||
'Base product not found, did you run the billing:sync-plans-data command?',
|
||||
BillingExceptionCode.BILLING_PRODUCT_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user