From 1cc365e56f7429ae6ad1fbc70cd2c115222b7e15 Mon Sep 17 00:00:00 2001 From: Romit <85230081+romitg2@users.noreply.github.com> Date: Wed, 22 Apr 2026 16:04:12 +0530 Subject: [PATCH] refactor: drop orphan team/org SSR & page helpers (#28952) The /org/[orgSlug]/[user] and /team/[slug] routes were removed in the Cal.diy fork (#28903/#28904) but their SSR helpers and Team screen component were left behind. No route, component, or test still imports them (verified with ripgrep). Deleting them removes dead code and makes it clearer that team/org pages are gone. --- apps/web/components/team/screens/Team.tsx | 93 ------ .../[user]/[type]/getServerSideProps.tsx | 55 ---- .../[orgSlug]/[user]/getServerSideProps.tsx | 36 --- .../team/[slug]/[type]/getServerSideProps.tsx | 305 ------------------ .../lib/team/[slug]/getServerSideProps.tsx | 149 --------- 5 files changed, 638 deletions(-) delete mode 100644 apps/web/components/team/screens/Team.tsx delete mode 100644 apps/web/lib/org/[orgSlug]/[user]/[type]/getServerSideProps.tsx delete mode 100644 apps/web/lib/org/[orgSlug]/[user]/getServerSideProps.tsx delete mode 100644 apps/web/lib/team/[slug]/[type]/getServerSideProps.tsx delete mode 100644 apps/web/lib/team/[slug]/getServerSideProps.tsx diff --git a/apps/web/components/team/screens/Team.tsx b/apps/web/components/team/screens/Team.tsx deleted file mode 100644 index 105e06d737..0000000000 --- a/apps/web/components/team/screens/Team.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import { useLocale } from "@calcom/lib/hooks/useLocale"; -import { useRouterQuery } from "@calcom/lib/hooks/useRouterQuery"; -import { markdownToSafeHTML } from "@calcom/lib/markdownToSafeHTML"; -import type { UserProfile } from "@calcom/types/UserProfile"; -import { UserAvatar } from "@calcom/ui/components/avatar"; -import Link from "next/link"; - -type TeamWithMembers = { - id: number; - name: string; - slug: string | null; - logoUrl?: string | null; - bio?: string | null; - members: { - id: number; - name: string | null; - bio?: string | null; - username?: string | null; - avatar?: string | null; - }[]; -}; - -type TeamType = Omit, "inviteToken">; -type MembersType = TeamType["members"]; -type MemberType = Pick & { - username: string | null; - organizationId?: number | null; - avatarUrl: string | null; -} & { - profile: Omit; - safeBio: string | null; - bookerUrl: string; -}; - -const Member = ({ member, teamName }: { member: MemberType; teamName: string | null }) => { - const routerQuery = useRouterQuery(); - const { t } = useLocale(); - const isBioEmpty = !member.bio || !member.bio.replace("


", "").length; - - // We don't want to forward orgSlug and user which are route params to the next route - const { slug: _slug, orgSlug: _orgSlug, user: _user, ...queryParamsToForward } = routerQuery; - - return ( - -
- -
-

{member.name}

-
- {!isBioEmpty ? ( -
- ) : ( - t("user_from_team", { user: member.name, team: teamName }) - )} -
-
-
- - ); -}; - -const Members = ({ members, teamName }: { members: MemberType[]; teamName: string | null }) => { - if (!members || members.length === 0) { - return null; - } - - return ( -
- {members.map((member) => { - return member.username !== null && ; - })} -
- ); -}; - -const Team = ({ members, teamName }: { members: MemberType[]; teamName: string | null }) => { - return ( -
- -
- ); -}; - -export default Team; diff --git a/apps/web/lib/org/[orgSlug]/[user]/[type]/getServerSideProps.tsx b/apps/web/lib/org/[orgSlug]/[user]/[type]/getServerSideProps.tsx deleted file mode 100644 index 81522501e9..0000000000 --- a/apps/web/lib/org/[orgSlug]/[user]/[type]/getServerSideProps.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import slugify from "@calcom/lib/slugify"; -import prisma from "@calcom/prisma"; -import { getServerSideProps as GSSTeamTypePage } from "@lib/team/[slug]/[type]/getServerSideProps"; -import { getServerSideProps as GSSUserTypePage } from "@server/lib/[user]/[type]/getServerSideProps"; -import type { GetServerSidePropsContext } from "next"; -import z from "zod"; - -const paramsSchema = z.object({ - orgSlug: z.string().transform((s) => slugify(s)), - user: z.string(), - type: z.string().transform((s) => slugify(s)), -}); - -export const getServerSideProps = async (ctx: GetServerSidePropsContext) => { - const { user: teamOrUserSlugOrDynamicGroup, orgSlug, type } = paramsSchema.parse(ctx.params); - const team = await prisma.team.findFirst({ - where: { - slug: slugify(teamOrUserSlugOrDynamicGroup), - parentId: { - not: null, - }, - parent: { slug: orgSlug }, - }, - select: { - id: true, - }, - }); - - if (team) { - const params = { slug: teamOrUserSlugOrDynamicGroup, type }; - return GSSTeamTypePage({ - ...ctx, - params: { - ...ctx.params, - ...params, - }, - query: { - ...ctx.query, - ...params, - }, - }); - } - const params = { user: teamOrUserSlugOrDynamicGroup, type }; - return GSSUserTypePage({ - ...ctx, - params: { - ...ctx.params, - ...params, - }, - query: { - ...ctx.query, - ...params, - }, - }); -}; diff --git a/apps/web/lib/org/[orgSlug]/[user]/getServerSideProps.tsx b/apps/web/lib/org/[orgSlug]/[user]/getServerSideProps.tsx deleted file mode 100644 index b22e22dc5c..0000000000 --- a/apps/web/lib/org/[orgSlug]/[user]/getServerSideProps.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import prisma from "@calcom/prisma"; -import { getServerSideProps as GSSTeamPage } from "@lib/team/[slug]/getServerSideProps"; -import { getServerSideProps as GSSUserPage } from "@server/lib/[user]/getServerSideProps"; -import type { GetServerSidePropsContext } from "next"; - -export const getServerSideProps = async (ctx: GetServerSidePropsContext) => { - const team = await prisma.team.findFirst({ - where: { - slug: ctx.query.user as string, - parentId: { - not: null, - }, - parent: { slug: ctx.query.orgSlug as string }, - }, - select: { - id: true, - }, - }); - if (team) { - return GSSTeamPage({ - ...ctx, - query: { - slug: ctx.query.user, - ...(ctx.query.orgRedirection !== undefined && { orgRedirection: ctx.query.orgRedirection }), - }, - }); - } - return GSSUserPage({ - ...ctx, - query: { - user: ctx.query.user, - ...(ctx.query.redirect !== undefined && { redirect: ctx.query.redirect }), - ...(ctx.query.orgRedirection !== undefined && { orgRedirection: ctx.query.orgRedirection }), - }, - }); -}; diff --git a/apps/web/lib/team/[slug]/[type]/getServerSideProps.tsx b/apps/web/lib/team/[slug]/[type]/getServerSideProps.tsx deleted file mode 100644 index 92d5999ac6..0000000000 --- a/apps/web/lib/team/[slug]/[type]/getServerSideProps.tsx +++ /dev/null @@ -1,305 +0,0 @@ -import { getServerSession } from "@calcom/features/auth/lib/getServerSession"; -import { getBookingForReschedule } from "@calcom/features/bookings/lib/get-booking"; -import { getBrandingForEventType } from "@calcom/features/profile/lib/getBranding"; -import { shouldHideBrandingForTeamEvent } from "@calcom/features/profile/lib/hideBranding"; -import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage"; -import logger from "@calcom/lib/logger"; -import slugify from "@calcom/lib/slugify"; -import { prisma } from "@calcom/prisma"; -import type { User } from "@calcom/prisma/client"; -import { BookingStatus, RedirectType, SchedulingType } from "@calcom/prisma/enums"; -import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils"; -import { handleOrgRedirect } from "@lib/handleOrgRedirect"; -import type { GetServerSidePropsContext } from "next"; -import { z } from "zod"; - -const paramsSchema = z.object({ - type: z.string().transform((s) => slugify(s)), - slug: z.string().transform((s) => slugify(s)), -}); - -export const getServerSideProps = async (context: GetServerSidePropsContext) => { - const { req, params, query } = context; - const { slug: teamSlug, type: meetingSlug } = paramsSchema.parse(params); - const { rescheduleUid, bookingUid } = query; - const allowRescheduleForCancelledBooking = query.allowRescheduleForCancelledBooking === "true"; - const currentOrgDomain = null; - const isValidOrgDomain = false; - - const redirect = await handleOrgRedirect({ - slugs: [teamSlug], - redirectType: RedirectType.Team, - eventTypeSlug: meetingSlug, - context, - currentOrgDomain: isValidOrgDomain ? currentOrgDomain : null, - }); - - if (redirect) { - return redirect; - } - - const team = await getTeamWithEventsData(teamSlug, meetingSlug, isValidOrgDomain, currentOrgDomain); - - if (!team || !team.eventTypes?.[0]) { - return { notFound: true } as const; - } - - const eventData = team.eventTypes[0]; - - if (eventData.schedulingType === SchedulingType.MANAGED) { - return { notFound: true } as const; - } - - if (rescheduleUid && eventData.disableRescheduling) { - return { redirect: { destination: `/booking/${rescheduleUid}`, permanent: false } }; - } - - const eventTypeId = eventData.id; - const orgSlug = isValidOrgDomain ? currentOrgDomain : null; - const name = team.parent?.name ?? team.name ?? null; - const fromRedirectOfNonOrgLink = context.query.orgRedirection === "true"; - const isUnpublished = team.parent ? !team.parent.slug : !team.slug; - - const crmContactOwnerEmail = query["cal.crmContactOwnerEmail"]; - const crmContactOwnerRecordType = query["cal.crmContactOwnerRecordType"]; - const crmAppSlugParam = query["cal.crmAppSlug"]; - const crmRecordIdParam = query["cal.crmRecordId"]; - const crmLookupDoneParam = query["cal.crmLookupDone"]; - - const crmContactOwnerEmailStr = Array.isArray(crmContactOwnerEmail) - ? crmContactOwnerEmail[0] - : crmContactOwnerEmail; - const crmOwnerRecordTypeStr = Array.isArray(crmContactOwnerRecordType) - ? crmContactOwnerRecordType[0] - : crmContactOwnerRecordType; - const crmAppSlugStr = Array.isArray(crmAppSlugParam) ? crmAppSlugParam[0] : crmAppSlugParam; - const crmRecordIdStr = Array.isArray(crmRecordIdParam) ? crmRecordIdParam[0] : crmRecordIdParam; - - // If crmLookupDone is true, the router already performed the CRM lookup, so skip it here - const crmLookupDone = - (Array.isArray(crmLookupDoneParam) ? crmLookupDoneParam[0] : crmLookupDoneParam) === "true"; - - const needsCrmLookup = - !crmLookupDone && (!crmContactOwnerEmailStr || !crmOwnerRecordTypeStr || !crmAppSlugStr); - - // Run independent queries in parallel — these all depend on team/eventData but not on each other - const log = logger.getSubLogger({ prefix: ["team-event-ssr", `${teamSlug}/${meetingSlug}`] }); - const [eventHostsUserData, crmResult, booking] = await Promise.all([ - getUsersData( - team.isPrivate, - eventTypeId, - eventData.hosts.map((h) => h.user) - ).catch((err) => { - log.error("Failed to get users data", err); - throw err; - }), - Promise.resolve( - null as { email: string; recordType: string; crmAppSlug: string; recordId: string } | null - ), - rescheduleUid - ? getServerSession({ req }) - .then((session) => getBookingForReschedule(`${rescheduleUid}`, session?.user?.id)) - .catch((err) => { - log.error("Failed to get booking for reschedule", err); - throw err; - }) - : Promise.resolve(null), - ]); - - if ( - booking?.status === BookingStatus.CANCELLED && - !allowRescheduleForCancelledBooking && - !eventData.allowReschedulingCancelledBookings - ) { - return { - redirect: { - permanent: false, - destination: `/team/${teamSlug}/${meetingSlug}`, - }, - }; - } - - const teamMemberEmail = crmResult?.email ?? crmContactOwnerEmailStr; - const crmOwnerRecordType = crmResult?.recordType ?? crmOwnerRecordTypeStr; - const crmAppSlug = crmResult?.crmAppSlug ?? crmAppSlugStr; - const crmRecordId = crmResult?.recordId ?? crmRecordIdStr; - - const organizationSettings = {} as { allowSEOIndexing?: boolean }; - const allowSEOIndexing = organizationSettings?.allowSEOIndexing ?? false; - - const useApiV2 = false; - - const branding = getBrandingForEventType({ - eventType: { - team: team.parent ?? team, - users: [], - profile: null, - }, - }); - - return { - props: { - useApiV2, - eventData: { - eventTypeId, - entity: { - fromRedirectOfNonOrgLink, - considerUnpublished: isUnpublished && !fromRedirectOfNonOrgLink, - orgSlug, - teamSlug: team.slug ?? null, - name, - }, - length: eventData.length, - metadata: EventTypeMetaDataSchema.parse(eventData.metadata), - profile: { - image: team.parent - ? getPlaceholderAvatar(team.parent.logoUrl, team.parent.name) - : getPlaceholderAvatar(team.logoUrl, team.name), - name, - username: orgSlug ?? null, - ...branding, - }, - title: eventData.title, - users: eventHostsUserData, - hidden: eventData.hidden, - interfaceLanguage: eventData.interfaceLanguage, - }, - booking, - user: teamSlug, - teamId: team.id, - slug: meetingSlug, - isBrandingHidden: shouldHideBrandingForTeamEvent({ - eventTypeId: eventData.id, - team, - }), - themeBasis: null, - orgBannerUrl: team.parent?.bannerUrl ?? "", - teamMemberEmail, - crmOwnerRecordType, - crmAppSlug, - crmRecordId, - isSEOIndexable: allowSEOIndexing, - }, - }; -}; - -const getTeamWithEventsData = async ( - teamSlug: string, - meetingSlug: string, - isValidOrgDomain: boolean, - currentOrgDomain: string | null -) => { - return await prisma.team.findFirst({ - where: { - ...{ slug: teamSlug }, - parent: isValidOrgDomain && currentOrgDomain ? { slug: currentOrgDomain } : null, - }, - orderBy: { - slug: { sort: "asc", nulls: "last" }, - }, - select: { - id: true, - isPrivate: true, - hideBranding: true, - parent: { - select: { - slug: true, - name: true, - bannerUrl: true, - logoUrl: true, - hideBranding: true, - brandColor: true, - darkBrandColor: true, - theme: true, - organizationSettings: { - select: { - allowSEOIndexing: true, - }, - }, - }, - }, - logoUrl: true, - name: true, - slug: true, - brandColor: true, - darkBrandColor: true, - theme: true, - eventTypes: { - where: { - slug: meetingSlug, - }, - select: { - id: true, - title: true, - isInstantEvent: true, - schedulingType: true, - metadata: true, - length: true, - hidden: true, - disableCancelling: true, - disableRescheduling: true, - allowReschedulingCancelledBookings: true, - interfaceLanguage: true, - hosts: { - take: 3, - select: { - user: { - select: { - name: true, - username: true, - email: true, - }, - }, - }, - }, - }, - }, - isOrganization: true, - organizationSettings: { - select: { - allowSEOIndexing: true, - }, - }, - }, - }); -}; - -const getUsersData = async ( - isPrivateTeam: boolean, - eventTypeId: number, - users: Pick[] -) => { - if (!isPrivateTeam && users.length > 0) { - return users - .filter((user) => user.username) - .map((user) => ({ - username: user.username ?? "", - name: user.name ?? "", - })); - } - if (!isPrivateTeam && users.length === 0) { - const { users: data } = await prisma.eventType.findUniqueOrThrow({ - where: { id: eventTypeId }, - select: { - users: { - take: 1, - select: { - username: true, - name: true, - }, - }, - }, - }); - - return data.length > 0 - ? [ - { - username: data[0].username ?? "", - name: data[0].name ?? "", - }, - ] - : []; - } - - return []; -}; diff --git a/apps/web/lib/team/[slug]/getServerSideProps.tsx b/apps/web/lib/team/[slug]/getServerSideProps.tsx deleted file mode 100644 index c2a6b5cb32..0000000000 --- a/apps/web/lib/team/[slug]/getServerSideProps.tsx +++ /dev/null @@ -1,149 +0,0 @@ -import { IS_CALCOM } from "@calcom/lib/constants"; -import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl"; -import logger from "@calcom/lib/logger"; -import { markdownToSafeHTML } from "@calcom/lib/markdownToSafeHTML"; -import slugify from "@calcom/lib/slugify"; -import { stripMarkdown } from "@calcom/lib/stripMarkdown"; -import prisma from "@calcom/prisma"; -import type { OrganizationSettings, Team } from "@calcom/prisma/client"; -import { RedirectType } from "@calcom/prisma/enums"; -import { teamMetadataSchema } from "@calcom/prisma/zod-utils"; -import { handleOrgRedirect } from "@lib/handleOrgRedirect"; -import type { GetServerSidePropsContext } from "next"; - -const log = logger.getSubLogger({ prefix: ["team/[slug]"] }); - -function getOrgProfileRedirectToVerifiedDomain( - team: { - isOrganization: boolean; - }, - settings: Pick -) { - if (!team.isOrganization) { - return null; - } - // when this is not on a Cal.diy page we don't auto redirect - - // good for diagnosis purposes. - if (!IS_CALCOM) { - return null; - } - - const verifiedDomain = null; - - if (!settings.orgProfileRedirectsToVerifiedDomain || !verifiedDomain) { - return null; - } - - return { - redirect: { - permanent: false, - destination: `https://${verifiedDomain}`, - }, - }; -} - -const getTheLastArrayElement = (value: ReadonlyArray | string | undefined): string | undefined => { - if (value === undefined || typeof value === "string") { - return value; - } - - return value.at(-1); -}; - -export const getServerSideProps = async (context: GetServerSidePropsContext) => { - const slug = getTheLastArrayElement(context.query.slug) ?? getTheLastArrayElement(context.query.orgSlug); - - const currentOrgDomain = null; - const isValidOrgDomain = false; - - // Provided by Rewrite from next.config.js - const isOrgProfile = context.query?.isOrgProfile === "1"; - const organizationsEnabled = false; - - log.debug("getServerSideProps", { - isOrgProfile, - isOrganizationFeatureEnabled: organizationsEnabled, - isValidOrgDomain, - currentOrgDomain, - }); - - const team = null as { metadata: unknown; parent: { slug: string | null } | null; isOrganization: boolean } | null; - - if (slug) { - const redirect = await handleOrgRedirect({ - slugs: [slug], - redirectType: RedirectType.Team, - eventTypeSlug: null, - context, - currentOrgDomain: isValidOrgDomain ? currentOrgDomain : null, - }); - - if (redirect) { - return redirect; - } - } - - const metadata = teamMetadataSchema.parse(team?.metadata ?? {}); - - // Taking care of sub-teams and orgs - if ( - (!isValidOrgDomain && team?.parent) || - (!isValidOrgDomain && !!team?.isOrganization) || - !organizationsEnabled - ) { - return { notFound: true } as const; - } - - if (!team) { - const unpublishedTeam = await prisma.team.findFirst({ - where: { - metadata: { - path: ["requestedSlug"], - equals: slug, - }, - }, - include: { - parent: { - select: { - id: true, - slug: true, - name: true, - isPrivate: true, - isOrganization: true, - metadata: true, - logoUrl: true, - }, - }, - }, - }); - - if (!unpublishedTeam) return { notFound: true } as const; - const teamParent = unpublishedTeam.parent ? getTeamWithoutMetadata(unpublishedTeam.parent) : null; - return { - props: { - considerUnpublished: true, - team: { - ...unpublishedTeam, - parent: teamParent, - createdAt: null, - }, - }, - } as const; - } - - return { notFound: true } as const; -}; - -/** - * Removes metadata from team and just adds requestedSlug - */ -function getTeamWithoutMetadata>(team: T) { - const { metadata, ...rest } = team; - const teamMetadata = teamMetadataSchema.parse(metadata); - return { - ...rest, - ...(typeof teamMetadata?.requestedSlug !== "undefined" - ? { requestedSlug: teamMetadata?.requestedSlug } - : {}), - }; -}