{bottomNavItems.map((item, index) => (
diff --git a/packages/lib/server/getBrand.ts b/packages/lib/server/getBrand.ts
index 60b30b9d5f..7ac0a9cd7d 100644
--- a/packages/lib/server/getBrand.ts
+++ b/packages/lib/server/getBrand.ts
@@ -15,11 +15,18 @@ export const getBrand = async (orgId: number | null) => {
name: true,
slug: true,
metadata: true,
+ isPlatform: true,
},
});
if (!org) {
return null;
}
+
+ // platform orgs don't have a brand nor a domain
+ if (org.isPlatform) {
+ return null;
+ }
+
const metadata = teamMetadataSchema.parse(org.metadata);
const slug = (org.slug || metadata?.requestedSlug) as string;
const fullDomain = getOrgFullOrigin(slug);
diff --git a/packages/lib/server/repository/profile.ts b/packages/lib/server/repository/profile.ts
index 867ad3898f..5a3dcb1478 100644
--- a/packages/lib/server/repository/profile.ts
+++ b/packages/lib/server/repository/profile.ts
@@ -23,6 +23,7 @@ const userSelect = Prisma.validator
()({
startTime: true,
endTime: true,
bufferTime: true,
+ isPlatformManaged: true,
});
const membershipSelect = Prisma.validator()({
@@ -43,6 +44,7 @@ const organizationSelect = {
logoUrl: true,
calVideoLogo: true,
bannerUrl: true,
+ isPlatform: true,
};
export enum LookupTarget {
@@ -329,6 +331,12 @@ export class ProfileRepository {
return null;
}
const user = profile.user;
+ if (profile.organization?.isPlatform && !user.isPlatformManaged) {
+ return {
+ ...this.buildPersonalProfileFromUser({ user }),
+ ...ProfileRepository.getInheritedDataFromUser({ user }),
+ };
+ }
return {
...profile,
...ProfileRepository.getInheritedDataFromUser({ user }),
diff --git a/packages/lib/server/repository/user.ts b/packages/lib/server/repository/user.ts
index cc71c722b1..e9cd304ae1 100644
--- a/packages/lib/server/repository/user.ts
+++ b/packages/lib/server/repository/user.ts
@@ -30,6 +30,7 @@ const teamSelect = Prisma.validator()({
logoUrl: true,
organizationSettings: true,
isOrganization: true,
+ isPlatform: true,
});
const userSelect = Prisma.validator()({
@@ -67,6 +68,7 @@ const userSelect = Prisma.validator()({
locked: true,
movedToProfileId: true,
metadata: true,
+ isPlatformManaged: true,
});
export class UserRepository {
@@ -330,6 +332,15 @@ export class UserRepository {
const profiles = await ProfileRepository.findManyForUser({ id: user.id });
if (profiles.length) {
const profile = profiles[0];
+ // platform org user doesn't need org profile
+ if (profile?.organization?.isPlatform) {
+ return {
+ ...user,
+ nonProfileUsername: user.username,
+ profile: ProfileRepository.buildPersonalProfileFromUser({ user }),
+ };
+ }
+
return {
...user,
username: profile.username,
diff --git a/packages/trpc/server/routers/loggedInViewer/me.handler.ts b/packages/trpc/server/routers/loggedInViewer/me.handler.ts
index c2c216c738..ce0dea1eae 100644
--- a/packages/trpc/server/routers/loggedInViewer/me.handler.ts
+++ b/packages/trpc/server/routers/loggedInViewer/me.handler.ts
@@ -106,6 +106,23 @@ export const meHandler = async ({ ctx, input }: MeOptions) => {
// Destructuring here only makes it more illegible
// pick only the part we want to expose in the API
+
+ const profileData = user.organization?.isPlatform
+ ? {
+ organizationId: null,
+ organization: { id: -1, isPlatform: true, slug: "", isOrgAdmin: false },
+ username: user.username ?? null,
+ profile: ProfileRepository.buildPersonalProfileFromUser({ user }),
+ profiles: [],
+ }
+ : {
+ organizationId: user.profile?.organizationId ?? null,
+ organization: user.organization,
+ username: user.profile?.username ?? user.username ?? null,
+ profile: user.profile ?? null,
+ profiles: allUserEnrichedProfiles,
+ };
+
return {
id: user.id,
name: user.name,
@@ -140,11 +157,7 @@ export const meHandler = async ({ ctx, input }: MeOptions) => {
allowDynamicBooking: user.allowDynamicBooking,
allowSEOIndexing: user.allowSEOIndexing,
receiveMonthlyDigestEmail: user.receiveMonthlyDigestEmail,
- organizationId: user.profile?.organizationId ?? null,
- organization: user.organization,
- username: user.profile?.username ?? user.username ?? null,
- profile: user.profile ?? null,
- profiles: allUserEnrichedProfiles,
+ ...profileData,
secondaryEmails,
sumOfBookings: additionalUserInfo?.bookings.length,
sumOfCalendars: additionalUserInfo?.selectedCalendars.length,
diff --git a/packages/ui/components/icon/icon-list.mjs b/packages/ui/components/icon/icon-list.mjs
index 19196c5378..1e49e05489 100644
--- a/packages/ui/components/icon/icon-list.mjs
+++ b/packages/ui/components/icon/icon-list.mjs
@@ -136,4 +136,5 @@ export const lucideIconList = new Set([
"webhook",
"x",
"zap",
+ "blocks",
]);
diff --git a/packages/ui/components/icon/icon-names.ts b/packages/ui/components/icon/icon-names.ts
index 3862f97fec..43db493bcf 100644
--- a/packages/ui/components/icon/icon-names.ts
+++ b/packages/ui/components/icon/icon-names.ts
@@ -13,6 +13,7 @@ export type IconName =
| "badge-check"
| "ban"
| "bell"
+ | "blocks"
| "bold"
| "book-open-check"
| "book-open"