diff --git a/apps/web/components/team/screens/Team.tsx b/apps/web/components/team/screens/Team.tsx index f5353ad8f6..45105809a8 100644 --- a/apps/web/components/team/screens/Team.tsx +++ b/apps/web/components/team/screens/Team.tsx @@ -10,7 +10,6 @@ import { Avatar } from "@calcom/ui"; type TeamType = Omit, "inviteToken">; type MembersType = TeamType["members"]; type MemberType = Pick & { safeBio: string | null }; -type TeamTypeWithSafeHtml = Omit & { members: MemberType[] }; const Member = ({ member, teamName }: { member: MemberType; teamName: string | null }) => { const routerQuery = useRouterQuery(); @@ -58,10 +57,10 @@ const Members = ({ members, teamName }: { members: MemberType[]; teamName: strin ); }; -const Team = ({ team }: { team: TeamTypeWithSafeHtml }) => { +const Team = ({ members, teamName }: { members: MemberType[]; teamName: string | null }) => { return (
- +
); }; diff --git a/apps/web/pages/team/[slug].tsx b/apps/web/pages/team/[slug].tsx index d3efb139fd..94ff7a8159 100644 --- a/apps/web/pages/team/[slug].tsx +++ b/apps/web/pages/team/[slug].tsx @@ -9,7 +9,6 @@ import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomain import EventTypeDescription from "@calcom/features/eventtypes/components/EventTypeDescription"; import { getFeatureFlagMap } from "@calcom/features/flags/server/utils"; import { WEBAPP_URL } from "@calcom/lib/constants"; -import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { useRouterQuery } from "@calcom/lib/hooks/useRouterQuery"; import useTheme from "@calcom/lib/hooks/useTheme"; @@ -126,7 +125,7 @@ function TeamPage({ team, isUnpublished, markdownStrippedBio, isValidOrgDomain }
@@ -135,7 +134,6 @@ function TeamPage({ team, isUnpublished, markdownStrippedBio, isValidOrgDomain } {t("number_member", { count: memberCount, - defaultValue: `${memberCount} member${memberCount > 1 ? "s" : ""}`, })}
@@ -161,14 +159,8 @@ function TeamPage({ team, isUnpublished, markdownStrippedBio, isValidOrgDomain }
-

- {" " + t("org_no_teams_yet", { defaultValue: "This organization has no teams yet" })} -

-

- {t("org_no_teams_yet_description", { - defaultValue: "If you are an administrator, be sure to create teams to be shown here.", - })} -

+

{" " + t("org_no_teams_yet")}

+

{t("org_no_teams_yet_description")}

@@ -221,7 +213,7 @@ function TeamPage({ team, isUnpublished, markdownStrippedBio, isValidOrgDomain }

{t("you_cannot_see_team_members")}

) : ( - + ))} {!showMembers.isOn && team.eventTypes && team.eventTypes.length > 0 && (
@@ -281,9 +273,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) => isTeamView: true, isOrgView: isValidOrgDomain && context.resolvedUrl === "/", }); - const ssr = await ssrInit(context, { - noI18nPreload: isValidOrgDomain && !team?.parent, - }); + const ssr = await ssrInit(context); const metadata = teamMetadataSchema.parse(team?.metadata ?? {}); console.info("gSSP, team/[slug] - ", { isValidOrgDomain, diff --git a/packages/features/ee/teams/pages/team-profile-view.tsx b/packages/features/ee/teams/pages/team-profile-view.tsx index abe7a33efb..f29b438c32 100644 --- a/packages/features/ee/teams/pages/team-profile-view.tsx +++ b/packages/features/ee/teams/pages/team-profile-view.tsx @@ -84,7 +84,7 @@ const ProfileView = () => { }); const { data: team, isLoading } = trpc.viewer.teams.get.useQuery( - { teamId }, + { teamId, includeTeamLogo: true }, { enabled: !!teamId, onError: () => { @@ -95,6 +95,7 @@ const ProfileView = () => { form.setValue("name", team.name || ""); form.setValue("slug", team.slug || ""); form.setValue("bio", team.bio || ""); + form.setValue("logo", team.logo || ""); if (team.slug === null && (team?.metadata as Prisma.JsonObject)?.requestedSlug) { form.setValue("slug", ((team?.metadata as Prisma.JsonObject)?.requestedSlug as string) || ""); } @@ -167,6 +168,7 @@ const ProfileView = () => { name: values.name, slug: values.slug, bio: values.bio, + logo: values.logo, }; objectKeys(variables).forEach((key) => { if (variables[key as keyof typeof variables] === team?.[key]) delete variables[key]; diff --git a/packages/lib/server/queries/teams/index.ts b/packages/lib/server/queries/teams/index.ts index a4102dff4d..0065d4a460 100644 --- a/packages/lib/server/queries/teams/index.ts +++ b/packages/lib/server/queries/teams/index.ts @@ -15,10 +15,11 @@ export async function getTeamWithMembers(args: { slug?: string; userId?: number; orgSlug?: string | null; + includeTeamLogo?: boolean; isTeamView?: boolean; isOrgView?: boolean; }) { - const { id, slug, userId, orgSlug, isTeamView, isOrgView } = args; + const { id, slug, userId, orgSlug, isTeamView, isOrgView, includeTeamLogo } = args; const userSelect = Prisma.validator()({ username: true, email: true, @@ -54,6 +55,7 @@ export async function getTeamWithMembers(args: { id: true, name: true, slug: true, + ...(!!includeTeamLogo ? { logo: true } : {}), bio: true, hideBranding: true, hideBookATeamMember: true, @@ -64,13 +66,11 @@ export async function getTeamWithMembers(args: { id: true, slug: true, name: true, - logo: true, }, }, children: { select: { name: true, - logo: true, slug: true, }, }, @@ -168,9 +168,18 @@ export async function getTeamWithMembers(args: { ...eventType, metadata: EventTypeMetaDataSchema.parse(eventType.metadata), })); - /** Don't leak invite tokens to the frontend */ + // Don't leak invite tokens to the frontend const { inviteTokens, ...teamWithoutInviteTokens } = team; + // Don't leak stripe payment ids + const teamMetadata = teamMetadataSchema.parse(team.metadata); + const { + paymentId: _, + subscriptionId: __, + subscriptionItemId: ___, + ...restTeamMetadata + } = teamMetadata || {}; + return { ...teamWithoutInviteTokens, /** To prevent breaking we only return non-email attached token here, if we have one */ @@ -179,7 +188,7 @@ export async function getTeamWithMembers(args: { token.identifier === "invite-link-for-teamId-" + team.id && token.expires > new Date(new Date().setHours(24)) ), - metadata: teamMetadataSchema.parse(team.metadata), + metadata: restTeamMetadata, eventTypes: !isOrgView ? eventTypes : null, members, }; diff --git a/packages/trpc/server/routers/viewer/teams/get.handler.ts b/packages/trpc/server/routers/viewer/teams/get.handler.ts index 2f2cdd1352..6cc6c52db5 100644 --- a/packages/trpc/server/routers/viewer/teams/get.handler.ts +++ b/packages/trpc/server/routers/viewer/teams/get.handler.ts @@ -18,6 +18,7 @@ export const getHandler = async ({ ctx, input }: GetOptions) => { const team = await getTeamWithMembers({ id: input.teamId, userId: ctx.user.organization?.isOrgAdmin ? undefined : ctx.user.id, + includeTeamLogo: input.includeTeamLogo, }); if (!team) { diff --git a/packages/trpc/server/routers/viewer/teams/get.schema.ts b/packages/trpc/server/routers/viewer/teams/get.schema.ts index b1520391d0..5cae98b514 100644 --- a/packages/trpc/server/routers/viewer/teams/get.schema.ts +++ b/packages/trpc/server/routers/viewer/teams/get.schema.ts @@ -2,6 +2,7 @@ import { z } from "zod"; export const ZGetInputSchema = z.object({ teamId: z.number(), + includeTeamLogo: z.boolean().optional(), }); export type TGetInputSchema = z.infer; diff --git a/packages/ui/components/unpublished-entity/UnpublishedEntity.tsx b/packages/ui/components/unpublished-entity/UnpublishedEntity.tsx index 716be808e6..09789431d6 100644 --- a/packages/ui/components/unpublished-entity/UnpublishedEntity.tsx +++ b/packages/ui/components/unpublished-entity/UnpublishedEntity.tsx @@ -22,13 +22,8 @@ export function UnpublishedEntity(props: UnpublishedEntityProps) { } headline={t("team_is_unpublished", { team: props.name, - defaultValue: `${props.name} is unpublished`, - })} - description={t(`${props.orgSlug ? "org" : "team"}_is_unpublished_description`, { - defaultValue: `This ${ - props.orgSlug ? "organization" : "team" - } link is currently not available. Please contact the organization owner or ask them to publish it.`, })} + description={t(`${props.orgSlug ? "org" : "team"}_is_unpublished_description`)} />
);