import { useSession } from "next-auth/react";
import { useRouter } from "next/router";
import { useState } from "react";
import { z } from "zod";
import MemberInvitationModal from "@calcom/features/ee/teams/components/MemberInvitationModal";
import { classNames } from "@calcom/lib";
import { WEBAPP_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { inferQueryOutput, trpc } from "@calcom/trpc/react";
import { Icon } from "@calcom/ui";
import { Avatar, Badge, Button } from "@calcom/ui/components";
import { showToast } from "@calcom/ui/v2/core";
import { SkeletonContainer, SkeletonText } from "@calcom/ui/v2/core/skeleton";
const querySchema = z.object({
id: z.string().transform((val) => parseInt(val)),
});
type TeamMember = inferQueryOutput<"viewer.teams.get">["members"][number];
type FormValues = {
members: TeamMember[];
};
const AddNewTeamMembers = () => {
const session = useSession();
const router = useRouter();
const { id: teamId } = router.isReady ? querySchema.parse(router.query) : { id: -1 };
const teamQuery = trpc.useQuery(["viewer.teams.get", { teamId }], { enabled: router.isReady });
if (session.status === "loading" || !teamQuery.data) return ;
return ;
};
const AddNewTeamMembersForm = ({ defaultValues, teamId }: { defaultValues: FormValues; teamId: number }) => {
const { t, i18n } = useLocale();
const [memberInviteModal, setMemberInviteModal] = useState(false);
const utils = trpc.useContext();
const router = useRouter();
const inviteMemberMutation = trpc.useMutation("viewer.teams.inviteMember", {
async onSuccess() {
await utils.invalidateQueries(["viewer.teams.get"]);
setMemberInviteModal(false);
},
onError: (error) => {
showToast(error.message, "error");
},
});
const publishTeamMutation = trpc.useMutation("viewer.teams.publish", {
onSuccess(data) {
router.push(data.url);
},
onError: (error) => {
showToast(error.message, "error");
},
});
return (
<>
{defaultValues.members.map((member, index) => (
))}
setMemberInviteModal(true)}
className="mt-6 w-full justify-center">
{t("add_team_member")}
setMemberInviteModal(false)}
onSubmit={(values) => {
inviteMemberMutation.mutate({
teamId,
language: i18n.language,
role: values.role.value,
usernameOrEmail: values.emailOrUsername,
sendEmailInvitation: values.sendInviteEmail,
});
}}
members={defaultValues.members}
/>
{
publishTeamMutation.mutate({ teamId });
}}>
{t("team_publish")}
>
);
};
export default AddNewTeamMembers;
const AddNewTeamMemberSkeleton = () => {
return (
);
};
const PendingMemberItem = (props: { member: TeamMember; index: number; teamId: number }) => {
const { member, index, teamId } = props;
const { t } = useLocale();
const utils = trpc.useContext();
const removeMemberMutation = trpc.useMutation("viewer.teams.removeMember", {
async onSuccess() {
await utils.invalidateQueries(["viewer.teams.get"]);
showToast("Member removed", "success");
},
async onError(err) {
showToast(err.message, "error");
},
});
return (
{member.name || member.email || t("team_member")}
{/* Assume that the first member of the team is the creator */}
{index === 0 &&
{t("you")} }
{!member.accepted &&
{t("pending")} }
{member.role === "MEMBER" &&
{t("member")} }
{member.role === "ADMIN" &&
{t("admin")} }
{member.username ? (
{`${WEBAPP_URL}/${member.username}`}
) : (
{t("not_on_cal")}
)}
{member.role !== "OWNER" && (
{
removeMemberMutation.mutate({ teamId, memberId: member.id });
}}
/>
)}
);
};