plane/web/components/onboarding/invitations.tsx
sriram veeraghanta 5b0066140f chore: format all files in monorepo (#3054)
* chore: format all files in the project

* fix: removing @types/react from dependencies

* fix: adding prettier and eslint config

* chore: format files

* fix: upgrading turbo version

* chore: ignoring warnings and adding todos

* fix: updated the type of bubble menu item in the document editor

* chore: format files

---------

Co-authored-by: Aaryan Khandelwal <aaryankhandu123@gmail.com>
2023-12-10 15:50:45 +05:30

172 lines
6.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState } from "react";
import useSWR, { mutate } from "swr";
// components
import { Button } from "@plane/ui";
// helpers
import { truncateText } from "helpers/string.helper";
// mobx
import { useMobxStore } from "lib/mobx/store-provider";
// services
import { WorkspaceService } from "services/workspace.service";
// contants
import { USER_WORKSPACES, USER_WORKSPACE_INVITATIONS } from "constants/fetch-keys";
import { ROLE } from "constants/workspace";
// types
import { IWorkspaceMemberInvitation } from "types";
// icons
import { CheckCircle2, Search } from "lucide-react";
type Props = {
handleNextStep: () => void;
setTryDiffAccount: () => void;
};
const workspaceService = new WorkspaceService();
export const Invitations: React.FC<Props> = (props) => {
const { handleNextStep, setTryDiffAccount } = props;
const [isJoiningWorkspaces, setIsJoiningWorkspaces] = useState(false);
const [invitationsRespond, setInvitationsRespond] = useState<string[]>([]);
const {
workspace: workspaceStore,
user: { currentUser, updateCurrentUser },
trackEvent: { postHogEventTracker },
} = useMobxStore();
const { data: invitations, mutate: mutateInvitations } = useSWR(USER_WORKSPACE_INVITATIONS, () =>
workspaceService.userWorkspaceInvitations()
);
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 updateLastWorkspace = async () => {
if (!workspaceStore.workspaces) return;
await updateCurrentUser({
last_workspace_id: workspaceStore.workspaces[0].id,
});
};
const submitInvitations = async () => {
if (invitationsRespond.length <= 0) return;
setIsJoiningWorkspaces(true);
await workspaceService
.joinWorkspaces({ invitations: invitationsRespond })
.then(async (res) => {
postHogEventTracker("MEMBER_ACCEPTED", { ...res, state: "SUCCESS", accepted_from: "App" });
await workspaceStore.fetchWorkspaces();
await mutate(USER_WORKSPACES);
await updateLastWorkspace();
await handleNextStep();
await mutateInvitations();
})
.catch((error) => {
console.log(error);
postHogEventTracker("MEMBER_ACCEPTED", { state: "FAILED", accepted_from: "App" });
})
.finally(() => setIsJoiningWorkspaces(false));
};
return invitations && invitations.length > 0 ? (
<div>
<div className="space-y-4 md:w-2/3 ">
<p className="pb-2 text-xl font-semibold sm:text-2xl">Choose a workspace to join </p>
<div>
{invitations &&
invitations.length > 0 &&
invitations.map((invitation) => {
const isSelected = invitationsRespond.includes(invitation.id);
return (
<div
key={invitation.id}
className={`flex cursor-pointer items-center gap-2 rounded border p-3.5 ${
isSelected
? "border-custom-primary-100"
: "border-onboarding-border-200 hover:bg-onboarding-background-300/30"
}`}
onClick={() => handleInvitation(invitation, isSelected ? "withdraw" : "accepted")}
>
<div className="flex-shrink-0">
<div className="grid h-9 w-9 place-items-center rounded">
{invitation.workspace.logo && invitation.workspace.logo !== "" ? (
<img
src={invitation.workspace.logo}
height="100%"
width="100%"
className="rounded"
alt={invitation.workspace.name}
/>
) : (
<span className="grid h-9 w-9 place-items-center rounded bg-gray-700 px-3 py-1.5 uppercase text-white">
{invitation.workspace.name[0]}
</span>
)}
</div>
</div>
<div className="min-w-0 flex-1">
<div className="text-sm font-medium">{truncateText(invitation.workspace.name, 30)}</div>
<p className="text-xs text-custom-text-200">{ROLE[invitation.role]}</p>
</div>
<span className={`flex-shrink-0 ${isSelected ? "text-custom-primary-100" : "text-custom-text-200"}`}>
<CheckCircle2 className="h-5 w-5" />
</span>
</div>
);
})}
</div>
<Button variant="primary" onClick={submitInvitations}>
{isJoiningWorkspaces ? "Joining..." : "Join your team"}
</Button>
</div>
<div className="mt-8 flex items-center justify-between rounded-sm bg-onboarding-background-300/30 px-4 py-3">
<div className="flex items-center">
<Search className="mr-2 h-4 w-4" />
<span className="text-sm text-custom-text-200">Don&apos;t see your workspace?</span>
</div>
<div>
<div
className="rounded-md border border-custom-border-200 bg-onboarding-background-200 py-3 text-center text-sm font-medium text-custom-text-200 hover:cursor-pointer"
onClick={setTryDiffAccount}
>
Try a different email address
</div>
<p className="mt-2 text-xs text-custom-text-300">
Your right e-mail address could be from a Google or GitHub login.
</p>
</div>
</div>
</div>
) : (
<EmptyInvitation email={currentUser!.email} setTryDiffAccount={setTryDiffAccount} />
);
};
const EmptyInvitation = ({ email, setTryDiffAccount }: { email: string; setTryDiffAccount: () => void }) => (
<div className="my-16 items-center justify-center rounded border border-onboarding-border-200 bg-onboarding-background-300/30 px-10 py-5 md:w-4/5 ">
<p className="text-center text-lg font-semibold text-onboarding-text-300">Is your team already on Plane?</p>
<p className="mt-6 text-center text-sm text-onboarding-text-300">
We couldnt find any existing workspaces for the email address {email}
</p>
<div
className="mt-6 rounded-md border border-custom-border-200 bg-onboarding-background-200 py-3 text-center text-sm font-medium text-custom-text-200 hover:cursor-pointer"
onClick={setTryDiffAccount}
>
Try a different email address
</div>
<p className="mt-2 text-center text-xs text-custom-text-300">
Your right e-mail address could be from a Google or GitHub login.
</p>
</div>
);