diff --git a/apps/web/public/static/locales/en/common.json b/apps/web/public/static/locales/en/common.json
index 51a7c408c3..1b1e382c70 100644
--- a/apps/web/public/static/locales/en/common.json
+++ b/apps/web/public/static/locales/en/common.json
@@ -24,6 +24,7 @@
"rejection_confirmation": "Reject the booking",
"manage_this_event": "Manage this event",
"invite_team_member": "Invite team member",
+ "invite_team_notifcation_badge":"Inv.",
"your_event_has_been_scheduled": "Your event has been scheduled",
"your_event_has_been_scheduled_recurring": "Your recurring event has been scheduled",
"accept_our_license": "Accept our license by changing the .env variable <1>NEXT_PUBLIC_LICENSE_CONSENT1> to '{{agree}}'.",
@@ -1313,6 +1314,7 @@
"password_reset_leading": "If you don't receive an email soon, check that the email address you entered is correct, check your spam folder or reach out to support if the issue persists.",
"password_updated": "Password updated!",
"pending_payment": "Pending payment",
+ "pending_invites":"Pending Invites",
"confirmation_page_rainbow": "Token gate your event with tokens or NFTs on Ethereum, Polygon, and more.",
"not_on_cal": "Not on {{appName}}",
"no_calendar_installed": "No calendar installed",
diff --git a/packages/features/ee/teams/components/TeamList.tsx b/packages/features/ee/teams/components/TeamList.tsx
index d92f32a9fe..9595ab5534 100644
--- a/packages/features/ee/teams/components/TeamList.tsx
+++ b/packages/features/ee/teams/components/TeamList.tsx
@@ -36,19 +36,17 @@ export default function TeamList(props: Props) {
}
return (
-
-
- {props.teams.map((team) => (
- selectAction(action, team?.id as number)}
- isLoading={deleteTeamMutation.isLoading}
- hideDropdown={hideDropdown}
- setHideDropdown={setHideDropdown}
- />
- ))}
-
-
+
+ {props.teams.map((team) => (
+ selectAction(action, team?.id as number)}
+ isLoading={deleteTeamMutation.isLoading}
+ hideDropdown={hideDropdown}
+ setHideDropdown={setHideDropdown}
+ />
+ ))}
+
);
}
diff --git a/packages/features/ee/teams/components/TeamListItem.tsx b/packages/features/ee/teams/components/TeamListItem.tsx
index 44c3f5fdc4..a237d72581 100644
--- a/packages/features/ee/teams/components/TeamListItem.tsx
+++ b/packages/features/ee/teams/components/TeamListItem.tsx
@@ -67,6 +67,7 @@ export default function TeamListItem(props: Props) {
const acceptOrLeaveMutation = trpc.viewer.teams.acceptOrLeave.useMutation({
onSuccess: () => {
utils.viewer.teams.list.invalidate();
+ utils.viewer.teams.listInvites.invalidate();
},
});
@@ -88,12 +89,12 @@ export default function TeamListItem(props: Props) {
if (!team) return <>>;
const teamInfo = (
-
+
{team.name}
@@ -105,7 +106,7 @@ export default function TeamListItem(props: Props) {
);
return (
-
+
{
@@ -140,13 +141,14 @@ export default function TeamListItem(props: Props) {
{isInvitee ? (
<>
-
+
{t("reject")}
{t("accept")}
diff --git a/packages/features/ee/teams/components/TeamsListing.tsx b/packages/features/ee/teams/components/TeamsListing.tsx
index cef6c78434..c3f0e1553a 100644
--- a/packages/features/ee/teams/components/TeamsListing.tsx
+++ b/packages/features/ee/teams/components/TeamsListing.tsx
@@ -1,10 +1,10 @@
-import { useState } from "react";
+import { useState, useMemo } from "react";
import { WEBAPP_URL } from "@calcom/lib/constants";
import { APP_NAME } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
-import { Alert, Button, ButtonGroup } from "@calcom/ui";
+import { Alert, Button, ButtonGroup, Label } from "@calcom/ui";
import { FiUsers, FiRefreshCcw, FiUserPlus, FiMail, FiVideo, FiEyeOff } from "@calcom/ui/components/icon";
import { UpgradeTip } from "../../../tips";
@@ -21,7 +21,8 @@ export function TeamsListing() {
},
});
- const teams = data?.filter((m) => m.accepted) || [];
+ const teams = useMemo(() => data?.filter((m) => m.accepted) || [], [data]);
+ const invites = useMemo(() => data?.filter((m) => !m.accepted) || [], [data]);
const features = [
{
@@ -56,15 +57,19 @@ export function TeamsListing() {
},
];
+ if (isLoading) {
+ return ;
+ }
+
return (
<>
{!!errorMessage && }
+
}
buttons={
@@ -77,7 +82,17 @@ export function TeamsListing() {
}>
-
+ <>
+ {invites.length > 0 && (
+
+
+ {t("pending_invites")}
+
+
+
+ )}
+ {teams.length > 0 && }
+ >
>
);
diff --git a/packages/features/shell/Shell.tsx b/packages/features/shell/Shell.tsx
index 93c95c708e..eab4287ce3 100644
--- a/packages/features/shell/Shell.tsx
+++ b/packages/features/shell/Shell.tsx
@@ -61,6 +61,8 @@ import {
FiArrowLeft,
} from "@calcom/ui/components/icon";
+import { TeamInviteBadge } from "./TeamInviteBadge";
+
/* TODO: Migate this */
export const ONBOARDING_INTRODUCED_AT = dayjs("September 1 2021").toISOString();
@@ -474,6 +476,7 @@ const navigation: NavigationItemType[] = [
href: "/teams",
icon: FiUsers,
onlyDesktop: true,
+ badge: ,
},
{
name: "apps",
diff --git a/packages/features/shell/TeamInviteBadge.tsx b/packages/features/shell/TeamInviteBadge.tsx
new file mode 100644
index 0000000000..95caa319a3
--- /dev/null
+++ b/packages/features/shell/TeamInviteBadge.tsx
@@ -0,0 +1,12 @@
+import { useTeamInvites } from "@calcom/lib/hooks/useHasTeamPlan";
+import { useLocale } from "@calcom/lib/hooks/useLocale";
+import { Badge } from "@calcom/ui";
+
+export function TeamInviteBadge() {
+ const { isLoading, listInvites } = useTeamInvites();
+ const { t } = useLocale();
+
+ if (isLoading || !listInvites || listInvites.length === 0) return null;
+
+ return {t("invite_team_notifcation_badge")} ;
+}
diff --git a/packages/features/tips/UpgradeTip.tsx b/packages/features/tips/UpgradeTip.tsx
index 4b5d14daaf..64c173c288 100644
--- a/packages/features/tips/UpgradeTip.tsx
+++ b/packages/features/tips/UpgradeTip.tsx
@@ -4,14 +4,10 @@ import type { ReactNode } from "react";
import { classNames } from "@calcom/lib";
import { useHasTeamPlan } from "@calcom/lib/hooks/useHasTeamPlan";
import { useLocale } from "@calcom/lib/hooks/useLocale";
-// import isCalcom from "@calcom/lib/isCalcom";
-import { trpc } from "@calcom/trpc/react";
+import isCalcom from "@calcom/lib/isCalcom";
import { EmptyScreen } from "@calcom/ui";
import { FiUsers } from "@calcom/ui/components/icon";
-import TeamList from "../ee/teams/components/TeamList";
-
-const isCalcom = true;
export function UpgradeTip({
dark,
title,
@@ -32,19 +28,16 @@ export function UpgradeTip({
children: JSX.Element;
isParentLoading?: ReactNode;
}) {
- const { data } = trpc.viewer.teams.list.useQuery();
-
- const invites = useMemo(() => data?.filter((m) => !m.accepted) || [], [data]);
const { t } = useLocale();
const { isLoading, hasTeamPlan } = useHasTeamPlan();
if (hasTeamPlan) return children;
+ if (isParentLoading || isLoading) return <>{isParentLoading}>;
+
if (!isCalcom)
return ;
- if (isParentLoading || isLoading) return <>{isParentLoading}>;
-
return (
<>
@@ -63,23 +56,15 @@ export function UpgradeTip({
{buttons}
- {invites.length > 0 && (
-
-
{t("open_invitations")}
-
-
- )}
+
- {invites.length === 0 &&
- features.map((feature) => (
-
- {feature.icon}
-
{feature.title}
-
{feature.description}
-
- ))}
+ {features.map((feature) => (
+
+ {feature.icon}
+
{feature.title}
+
{feature.description}
+
+ ))}
>
diff --git a/packages/lib/hooks/useHasTeamPlan.ts b/packages/lib/hooks/useHasTeamPlan.ts
index 13fd9b6f13..87b51ccf36 100644
--- a/packages/lib/hooks/useHasTeamPlan.ts
+++ b/packages/lib/hooks/useHasTeamPlan.ts
@@ -6,4 +6,10 @@ export function useHasTeamPlan() {
return { isLoading: hasTeam.isLoading, hasTeamPlan: hasTeam.data?.hasTeamPlan || false };
}
+export function useTeamInvites() {
+ const listInvites = trpc.viewer.teams.listInvites.useQuery();
+
+ return { isLoading: listInvites.isLoading, listInvites: listInvites.data };
+}
+
export default useHasTeamPlan;
diff --git a/packages/trpc/server/routers/viewer/teams.tsx b/packages/trpc/server/routers/viewer/teams.tsx
index a08a19ed92..07269ec9f7 100644
--- a/packages/trpc/server/routers/viewer/teams.tsx
+++ b/packages/trpc/server/routers/viewer/teams.tsx
@@ -700,4 +700,15 @@ export const viewerTeamsRouter = router({
});
return { hasTeamPlan: !!hasTeamPlan };
}),
+ listInvites: authedProcedure.query(async ({ ctx }) => {
+ const userId = ctx.user.id;
+ return await ctx.prisma.membership.findMany({
+ where: {
+ user: {
+ id: userId,
+ },
+ accepted: false,
+ },
+ });
+ }),
});