fix: address onboarding v3 teams redirectfrom onboarding (#24875)

* Address redirect in subdomain for teams v3

* Revert constants
This commit is contained in:
sean-brydon
2025-11-03 15:43:55 +00:00
committed by GitHub
parent cd5b75fe2c
commit dcb47e31ed
5 changed files with 23 additions and 1 deletions
+13
View File
@@ -8,6 +8,7 @@ import { Plan, SubscriptionStatus } from "@calcom/features/ee/billing/repository
import { StripeBillingService } from "@calcom/features/ee/billing/stripe-billing-service";
import { InternalTeamBilling } from "@calcom/features/ee/billing/teams/internal-team-billing";
import stripe from "@calcom/features/ee/payments/server/stripe";
import { WEBAPP_URL } from "@calcom/lib/constants";
import { HttpError } from "@calcom/lib/http-error";
import prisma from "@calcom/prisma";
import { MembershipRole } from "@calcom/prisma/enums";
@@ -20,6 +21,7 @@ const checkoutSessionMetadataSchema = z.object({
teamName: z.string(),
teamSlug: z.string(),
userId: z.string().transform(Number),
isOnboarding: z.string().optional(),
});
const generateRandomString = () => {
@@ -66,6 +68,7 @@ async function getHandler(req: NextRequest) {
teamName: checkoutSession?.metadata?.teamName ?? generateRandomString(),
teamSlug: checkoutSession?.metadata?.teamSlug ?? generateRandomString(),
userId: checkoutSession.metadata.userId,
isOnboarding: checkoutSession.metadata.isOnboarding,
};
const team = await prisma.team.create({
@@ -102,6 +105,16 @@ async function getHandler(req: NextRequest) {
});
}
// Check if this is from onboarding flow and redirect accordingly
const isOnboarding = checkoutSessionMetadata.isOnboarding === "true";
if (isOnboarding) {
// Redirect to event-types for onboarding flow
return NextResponse.redirect(new URL("/onboarding/personal/settings", WEBAPP_URL), {
status: 302,
});
}
// redirect to team screen
return NextResponse.redirect(
new URL(`/settings/teams/${team.id}/onboard-members?event=team_created`, req.nextUrl.origin),
@@ -24,6 +24,7 @@ export function useCreateTeam() {
name: teamDetails.name,
slug: teamDetails.slug,
logo: teamBrand.logo,
isOnboarding: true,
});
// If there's a checkout URL, redirect to Stripe payment
@@ -49,10 +49,12 @@ export const generateTeamCheckoutSession = async ({
teamName,
teamSlug,
userId,
isOnboarding,
}: {
teamName: string;
teamSlug: string;
userId: number;
isOnboarding?: boolean;
}) => {
const [customer, dubCustomer] = await Promise.all([
getStripeCustomerIdFromUserId(userId),
@@ -98,6 +100,7 @@ export const generateTeamCheckoutSession = async ({
teamSlug,
userId,
dubCustomerId: userId, // pass the userId during checkout creation for sales conversion tracking: https://d.to/conversions/stripe
...(isOnboarding !== undefined && { isOnboarding: isOnboarding.toString() }),
},
});
return session;
@@ -22,10 +22,12 @@ const generateCheckoutSession = async ({
teamSlug,
teamName,
userId,
isOnboarding,
}: {
teamSlug: string;
teamName: string;
userId: number;
isOnboarding?: boolean;
}) => {
if (!IS_TEAM_BILLING_ENABLED) {
console.info("Team billing is disabled, not generating a checkout session.");
@@ -36,6 +38,7 @@ const generateCheckoutSession = async ({
teamSlug,
teamName,
userId,
isOnboarding,
});
if (!checkoutSession.url)
@@ -48,7 +51,7 @@ const generateCheckoutSession = async ({
export const createHandler = async ({ ctx, input }: CreateOptions) => {
const { user } = ctx;
const { slug, name } = input;
const { slug, name, isOnboarding } = input;
const isOrgChildTeam = !!user.profile?.organizationId;
// For orgs we want to create teams under the org
@@ -80,6 +83,7 @@ export const createHandler = async ({ ctx, input }: CreateOptions) => {
teamSlug: slug,
teamName: name,
userId: user.id,
isOnboarding,
});
// If there is a checkout session, return it. Otherwise, it means it's disabled.
@@ -10,6 +10,7 @@ export const ZCreateInputSchema = z.object({
.optional()
.nullable()
.transform((v) => v || null),
isOnboarding: z.boolean().optional(),
});
export type TCreateInputSchema = z.infer<typeof ZCreateInputSchema>;