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.
This commit is contained in:
Romit
2026-04-22 16:04:12 +05:30
committed by GitHub
parent ee16d1d474
commit 1cc365e56f
5 changed files with 0 additions and 638 deletions
-93
View File
@@ -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<NonNullable<TeamWithMembers>, "inviteToken">;
type MembersType = TeamType["members"];
type MemberType = Pick<MembersType[number], "id" | "name" | "bio"> & {
username: string | null;
organizationId?: number | null;
avatarUrl: string | null;
} & {
profile: Omit<UserProfile, "upId">;
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("<p><br></p>", "").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 (
<Link
key={member.id}
href={{ pathname: `${member.bookerUrl}/${member.username}`, query: queryParamsToForward }}>
<div className="group stack-y-2 flex min-h-full flex-col rounded-md border border-subtle bg-default p-4 transition hover:cursor-pointer hover:bg-cal-muted sm:w-80">
<UserAvatar noOrganizationIndicator size="md" user={member} />
<section className="stack-y-1 mt-2 line-clamp-4 w-full">
<p className="font-medium text-default">{member.name}</p>
<div className="line-clamp-3 text-ellipsis font-normal text-sm text-subtle">
{!isBioEmpty ? (
<div
className="wrap-break-word text-sm text-subtle [&_a]:text-blue-500 [&_a]:underline [&_a]:hover:text-blue-600"
// eslint-disable-next-line react/no-danger
// biome-ignore lint/security/noDangerouslySetInnerHtml: Content is sanitized via markdownToSafeHTML
dangerouslySetInnerHTML={{ __html: markdownToSafeHTML(member.bio ?? null) }}
/>
) : (
t("user_from_team", { user: member.name, team: teamName })
)}
</div>
</section>
</div>
</Link>
);
};
const Members = ({ members, teamName }: { members: MemberType[]; teamName: string | null }) => {
if (!members || members.length === 0) {
return null;
}
return (
<section
data-testid="team-members-container"
className="flex flex-col flex-wrap justify-center gap-5 sm:flex-row">
{members.map((member) => {
return member.username !== null && <Member key={member.id} member={member} teamName={teamName} />;
})}
</section>
);
};
const Team = ({ members, teamName }: { members: MemberType[]; teamName: string | null }) => {
return (
<div>
<Members members={members} teamName={teamName} />
</div>
);
};
export default Team;
@@ -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,
},
});
};
@@ -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 }),
},
});
};
@@ -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<User, "username" | "name">[]
) => {
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 [];
};
@@ -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<OrganizationSettings, "orgAutoAcceptEmail" | "orgProfileRedirectsToVerifiedDomain">
) {
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> | 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<T extends Pick<Team, "metadata">>(team: T) {
const { metadata, ...rest } = team;
const teamMetadata = teamMetadataSchema.parse(metadata);
return {
...rest,
...(typeof teamMetadata?.requestedSlug !== "undefined"
? { requestedSlug: teamMetadata?.requestedSlug }
: {}),
};
}