import React, { useState, ReactElement } from "react"; import { observer } from "mobx-react-lite"; import Image from "next/image"; import Link from "next/link"; import { useRouter } from "next/router"; import { useTheme } from "next-themes"; import useSWR, { mutate } from "swr"; import { CheckCircle2 } from "lucide-react"; import type { IWorkspaceMemberInvitation } from "@plane/types"; // services import { Button, TOAST_TYPE, setToast } from "@plane/ui"; import { EmptyState } from "@/components/common"; import { PageHead } from "@/components/core"; import { MEMBER_ACCEPTED } from "@/constants/event-tracker"; import { ROLE } from "@/constants/workspace"; import { truncateText } from "@/helpers/string.helper"; import { getUserRole } from "@/helpers/user.helper"; import { useEventTracker, useUser, useWorkspace } from "@/hooks/store"; import { UserAuthWrapper } from "@/layouts/auth-layout"; import DefaultLayout from "@/layouts/default-layout"; import { NextPageWithLayout } from "@/lib/types"; import { UserService } from "@/services/user.service"; import { WorkspaceService } from "@/services/workspace.service"; // hooks // layouts // ui // images import emptyInvitation from "public/empty-state/invitation.svg"; import BlackHorizontalLogo from "public/plane-logos/black-horizontal-with-blue-logo.svg"; import WhiteHorizontalLogo from "public/plane-logos/white-horizontal-with-blue-logo.svg"; // helpers // types // constants // components // services const workspaceService = new WorkspaceService(); const userService = new UserService(); const UserInvitationsPage: NextPageWithLayout = observer(() => { // states const [invitationsRespond, setInvitationsRespond] = useState([]); const [isJoiningWorkspaces, setIsJoiningWorkspaces] = useState(false); // store hooks const { captureEvent, joinWorkspaceMetricGroup } = useEventTracker(); const { currentUser, currentUserSettings } = useUser(); const { fetchWorkspaces } = useWorkspace(); // router const router = useRouter(); // next-themes const { theme } = useTheme(); const { data: invitations } = useSWR("USER_WORKSPACE_INVITATIONS", () => workspaceService.userWorkspaceInvitations()); const redirectWorkspaceSlug = currentUserSettings?.workspace?.last_workspace_slug || currentUserSettings?.workspace?.fallback_workspace_slug || ""; const handleInvitation = (workspace_invitation: IWorkspaceMemberInvitation, action: "accepted" | "withdraw") => { if (action === "accepted") { setInvitationsRespond((prevData) => [...prevData, workspace_invitation.id]); } else if (action === "withdraw") { setInvitationsRespond((prevData) => prevData.filter((item: string) => item !== workspace_invitation.id)); } }; const submitInvitations = () => { if (invitationsRespond.length === 0) { setToast({ type: TOAST_TYPE.ERROR, title: "Error!", message: "Please select at least one invitation.", }); return; } setIsJoiningWorkspaces(true); workspaceService .joinWorkspaces({ invitations: invitationsRespond }) .then(() => { mutate("USER_WORKSPACES"); const firstInviteId = invitationsRespond[0]; const invitation = invitations?.find((i) => i.id === firstInviteId); const redirectWorkspace = invitations?.find((i) => i.id === firstInviteId)?.workspace; joinWorkspaceMetricGroup(redirectWorkspace?.id); captureEvent(MEMBER_ACCEPTED, { member_id: invitation?.id, // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain role: getUserRole(invitation?.role!), project_id: undefined, accepted_from: "App", state: "SUCCESS", element: "Workspace invitations page", }); userService .updateUser({ last_workspace_id: redirectWorkspace?.id }) .then(() => { setIsJoiningWorkspaces(false); fetchWorkspaces().then(() => { router.push(`/${redirectWorkspace?.slug}`); }); }) .catch(() => { setToast({ type: TOAST_TYPE.ERROR, title: "Error!", message: "Something went wrong, Please try again.", }); setIsJoiningWorkspaces(false); }); }) .catch(() => { captureEvent(MEMBER_ACCEPTED, { project_id: undefined, accepted_from: "App", state: "FAILED", element: "Workspace invitations page", }); setToast({ type: TOAST_TYPE.ERROR, title: "Error!", message: "Something went wrong, Please try again.", }); setIsJoiningWorkspaces(false); }); }; return ( <>
{theme === "light" ? ( Plane black logo ) : ( Plane white logo )}
{currentUser?.email}
{invitations ? ( invitations.length > 0 ? (
We see that someone has invited you to

Join a workspace

{invitations.map((invitation) => { const isSelected = invitationsRespond.includes(invitation.id); return (
handleInvitation(invitation, isSelected ? "withdraw" : "accepted")} >
{invitation.workspace.logo && invitation.workspace.logo.trim() !== "" ? ( {invitation.workspace.name} ) : ( {invitation.workspace.name[0]} )}
{truncateText(invitation.workspace.name, 30)}

{ROLE[invitation.role]}

); })}
) : (
router.push("/"), }} />
) ) : null}
); }); UserInvitationsPage.getLayout = function getLayout(page: ReactElement) { return ( {page} ); }; export default UserInvitationsPage;