Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WEB-1404] chore: auth and onboarding improvements #4564

Merged
merged 3 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/ui/src/button/helper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ export const buttonStyling: IButtonStyling = {
disabled: `cursor-not-allowed !bg-custom-primary-60 hover:bg-custom-primary-60`,
},
"accent-primary": {
default: `bg-custom-primary-10 text-custom-primary-100`,
hover: `hover:bg-custom-primary-20 hover:text-custom-primary-200`,
pressed: `focus:bg-custom-primary-20`,
default: `bg-custom-primary-100/20 text-custom-primary-100`,
hover: `hover:bg-custom-primary-100/10 hover:text-custom-primary-200`,
pressed: `focus:bg-custom-primary-100/10`,
disabled: `cursor-not-allowed !text-custom-primary-60`,
},
"outline-primary": {
Expand Down
6 changes: 3 additions & 3 deletions web/components/onboarding/create-or-join-workspaces.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useTheme } from "next-themes";
// types
import { IWorkspaceMemberInvitation, TOnboardingSteps } from "@plane/types";
// components
import { Invitations, OnboardingHeader, SwitchOrDeleteAccountDropdown, CreateWorkspace } from "@/components/onboarding";
import { Invitations, OnboardingHeader, SwitchAccountDropdown, CreateWorkspace } from "@/components/onboarding";
// hooks
import { useUser } from "@/hooks/store";
// assets
Expand Down Expand Up @@ -55,7 +55,7 @@ export const CreateOrJoinWorkspaces: React.FC<Props> = observer((props) => {
<div className="flex items-center justify-between">
<OnboardingHeader currentStep={totalSteps - 1} totalSteps={totalSteps} />
<div className="shrink-0 lg:hidden">
<SwitchOrDeleteAccountDropdown />
<SwitchAccountDropdown />
</div>
</div>
<div className="flex flex-col w-full items-center justify-center p-8 mt-6">
Expand All @@ -79,7 +79,7 @@ export const CreateOrJoinWorkspaces: React.FC<Props> = observer((props) => {
</div>
</div>
<div className="hidden lg:block relative w-2/5 h-screen overflow-hidden px-6 py-10 sm:px-7 sm:py-14 md:px-14 lg:px-28">
<SwitchOrDeleteAccountDropdown />
<SwitchAccountDropdown />
<div className="absolute inset-0 z-0">
<Image
src={resolvedTheme === "dark" ? CreateJoinWorkspaceDark : CreateJoinWorkspace}
Expand Down
4 changes: 2 additions & 2 deletions web/components/onboarding/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ export * from "./profile-setup";
export * from "./create-workspace";
export * from "./invitations";
export * from "./step-indicator";
export * from "./switch-or-delete-account-dropdown";
export * from "./switch-delete-account-modal";
export * from "./switch-account-dropdown";
export * from "./switch-account-modal";
export * from "./header";
6 changes: 3 additions & 3 deletions web/components/onboarding/invite-members.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import InviteMembersDark from "public/onboarding/invite-members-dark.svg";
import InviteMembersLight from "public/onboarding/invite-members-light.svg";
// components
import { OnboardingHeader } from "./header";
import { SwitchOrDeleteAccountDropdown } from "./switch-or-delete-account-dropdown";
import { SwitchAccountDropdown } from "./switch-account-dropdown";

type Props = {
finishOnboarding: () => Promise<void>;
Expand Down Expand Up @@ -366,7 +366,7 @@ export const InviteMembers: React.FC<Props> = (props) => {
{/* Since this will always be the last step */}
<OnboardingHeader currentStep={totalSteps} totalSteps={totalSteps} />
<div className="shrink-0 lg:hidden">
<SwitchOrDeleteAccountDropdown />
<SwitchAccountDropdown />
</div>
</div>
<div className="flex flex-col w-full items-center justify-center p-8 mt-6 md:w-4/5 mx-auto">
Expand Down Expand Up @@ -433,7 +433,7 @@ export const InviteMembers: React.FC<Props> = (props) => {
</div>
</div>
<div className="hidden lg:block relative w-2/5 h-screen overflow-hidden px-6 py-10 sm:px-7 sm:py-14 md:px-14 lg:px-28">
<SwitchOrDeleteAccountDropdown />
<SwitchAccountDropdown />
<div className="absolute inset-0 z-0">
<Image
src={resolvedTheme === "dark" ? InviteMembersDark : InviteMembersLight}
Expand Down
6 changes: 3 additions & 3 deletions web/components/onboarding/profile-setup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Button, Input, Spinner, TOAST_TYPE, setToast } from "@plane/ui";
// components
import { PasswordStrengthMeter } from "@/components/account";
import { UserImageUploadModal } from "@/components/core";
import { OnboardingHeader, SwitchOrDeleteAccountDropdown } from "@/components/onboarding";
import { OnboardingHeader, SwitchAccountDropdown } from "@/components/onboarding";
// constants
import { USER_DETAILS } from "@/constants/event-tracker";
// helpers
Expand Down Expand Up @@ -276,7 +276,7 @@ export const ProfileSetup: React.FC<Props> = observer((props) => {
<div className="flex items-center justify-between">
<OnboardingHeader currentStep={isCurrentStepUserPersonalization ? 2 : 1} totalSteps={totalSteps} />
<div className="shrink-0 lg:hidden">
<SwitchOrDeleteAccountDropdown fullName={`${watch("first_name")} ${watch("last_name")}`} />
<SwitchAccountDropdown fullName={`${watch("first_name")} ${watch("last_name")}`} />
</div>
</div>
<div className="flex flex-col w-full items-center justify-center p-8 mt-6">
Expand Down Expand Up @@ -567,7 +567,7 @@ export const ProfileSetup: React.FC<Props> = observer((props) => {
</div>
</div>
<div className="hidden lg:block relative w-2/5 h-screen overflow-hidden px-6 py-10 sm:px-7 sm:py-14 md:px-14 lg:px-28">
<SwitchOrDeleteAccountDropdown fullName={`${watch("first_name")} ${watch("last_name")}`} />
<SwitchAccountDropdown fullName={`${watch("first_name")} ${watch("last_name")}`} />
<div className="absolute inset-0 z-0">
{profileSetupStep === EProfileSetupSteps.USER_PERSONALIZATION ? (
<Image
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ import { cn } from "@/helpers/common.helper";
// hooks
import { useUser } from "@/hooks/store";
// components
import { SwitchOrDeleteAccountModal } from "./switch-delete-account-modal";
import { SwitchAccountModal } from "./switch-account-modal";

type TSwithOrDeleteAccountDropdownProps = {
type TSwitchAccountDropdownProps = {
fullName?: string;
};

export const SwitchOrDeleteAccountDropdown: FC<TSwithOrDeleteAccountDropdownProps> = observer((props) => {
export const SwitchAccountDropdown: FC<TSwitchAccountDropdownProps> = observer((props) => {
const { fullName } = props;
// states
const [showDeleteAccountModal, setShowDeleteAccountModal] = useState(false);
const [showSwitchAccountModal, setShowSwitchAccountModal] = useState(false);
// store hooks
const { data: user } = useUser();

Expand All @@ -30,7 +30,7 @@ export const SwitchOrDeleteAccountDropdown: FC<TSwithOrDeleteAccountDropdownProp

return (
<div className="flex w-full shrink-0 justify-end">
<SwitchOrDeleteAccountModal isOpen={showDeleteAccountModal} onClose={() => setShowDeleteAccountModal(false)} />
<SwitchAccountModal isOpen={showSwitchAccountModal} onClose={() => setShowSwitchAccountModal(false)} />
<div className="flex items-center gap-x-2 pr-4 z-10">
{user?.avatar && (
<Avatar
Expand Down Expand Up @@ -64,7 +64,7 @@ export const SwitchOrDeleteAccountDropdown: FC<TSwithOrDeleteAccountDropdownProp
"bg-custom-background-80": active,
})
}
onClick={() => setShowDeleteAccountModal(true)}
onClick={() => setShowSwitchAccountModal(true)}
>
Wrong e-mail address?
</Menu.Item>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,31 @@
import React, { useState } from "react";
import { useRouter } from "next/router";
import { useTheme } from "next-themes";
import { mutate } from "swr";
import { Trash2 } from "lucide-react";
import { ArrowRightLeft } from "lucide-react";
import { Dialog, Transition } from "@headlessui/react";
// hooks
// ui
import { Button, TOAST_TYPE, setToast } from "@plane/ui";
// hooks
import { useUser } from "@/hooks/store";
// ui

type Props = {
isOpen: boolean;
onClose: () => void;
};

export const SwitchOrDeleteAccountModal: React.FC<Props> = (props) => {
export const SwitchAccountModal: React.FC<Props> = (props) => {
const { isOpen, onClose } = props;
// states
const [switchingAccount, setSwitchingAccount] = useState(false);
const [isDeactivating, setIsDeactivating] = useState(false);
// router
const router = useRouter();
// store hooks
const { signOut, deactivateAccount } = useUser();
const { data: userData, signOut } = useUser();

const { setTheme } = useTheme();

const handleClose = () => {
setSwitchingAccount(false);
setIsDeactivating(false);
onClose();
};

Expand All @@ -51,32 +48,6 @@ export const SwitchOrDeleteAccountModal: React.FC<Props> = (props) => {
.finally(() => setSwitchingAccount(false));
};

const handleDeactivateAccount = async () => {
setIsDeactivating(true);

await deactivateAccount()
.then(() => {
setToast({
type: TOAST_TYPE.SUCCESS,
title: "Success!",
message: "Account deleted successfully.",
});
mutate("CURRENT_USER_DETAILS", null);
signOut();
setTheme("system");
router.push("/");
handleClose();
})
.catch((err: any) =>
setToast({
type: TOAST_TYPE.ERROR,
title: "Error!",
message: err?.error,
})
)
.finally(() => setIsDeactivating(false));
};

return (
<Transition.Root show={isOpen} as={React.Fragment}>
<Dialog as="div" className="relative z-20" onClose={handleClose}>
Expand Down Expand Up @@ -104,32 +75,30 @@ export const SwitchOrDeleteAccountModal: React.FC<Props> = (props) => {
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-custom-background-100 text-left shadow-custom-shadow-md transition-all sm:my-8 sm:w-[40rem]">
<div className="px-4 pb-4 pt-5 sm:p-6 sm:pb-4">
<div>
<div className="flex items-center gap-x-4">
<div className="grid place-items-center rounded-full bg-red-500/20 p-4">
<Trash2 className="h-6 w-6 text-red-600" aria-hidden="true" />
<div className="p-6 pb-1">
<div className="flex gap-x-4">
<div className="flex items-start">
<div className="grid place-items-center rounded-full bg-custom-primary-100/20 p-4">
<ArrowRightLeft className="h-5 w-5 text-custom-primary-100" aria-hidden="true" />
</div>
</div>
<div className="flex flex-col py-3 gap-y-6">
<Dialog.Title as="h3" className="text-2xl font-medium leading-6 text-onboarding-text-100">
Not the right workspace?
Switch account
</Dialog.Title>
</div>

<div className="mt-6 px-4">
<ul className="list-disc text-base font-normal text-onboarding-text-300">
<li>Delete this account if you have another and won{"'"}t use this account.</li>
<li>Switch to another account if you{"'"}d like to come back to this account another time.</li>
</ul>
{userData?.email && (
<div className="text-base font-normal text-onboarding-text-200">
If you have signed up via <span className="text-custom-primary-100">{userData.email}</span>{" "}
un-intentionally, you can switch your account to a different one from here.
</div>
)}
</div>
</div>
</div>
<div className="mb-2 flex items-center justify-end gap-3 p-4 sm:px-6">
<Button variant="neutral-primary" onClick={handleSwitchAccount} disabled={switchingAccount}>
<Button variant="accent-primary" onClick={handleSwitchAccount} disabled={switchingAccount}>
{switchingAccount ? "Switching..." : "Switch account"}
</Button>
<Button variant="outline-danger" onClick={handleDeactivateAccount} loading={isDeactivating}>
{isDeactivating ? "Deleting..." : "Delete account"}
</Button>
</div>
</Dialog.Panel>
</Transition.Child>
Expand Down
86 changes: 40 additions & 46 deletions web/pages/workspace-invitations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,53 +70,47 @@ const WorkspaceInvitationPage: NextPageWithLayout = observer(() => {

return (
<div className="flex h-full w-full flex-col items-center justify-center px-3">
{invitationDetail ? (
<>
{error ? (
<div className="flex w-full flex-col space-y-4 rounded border border-custom-border-200 bg-custom-background-100 px-4 py-8 text-center shadow-2xl md:w-1/3">
<h2 className="text-xl uppercase">INVITATION NOT FOUND</h2>
</div>
) : (
<>
{invitationDetail.accepted ? (
<>
<EmptySpace
title={`You are already a member of ${invitationDetail.workspace.name}`}
description="Your workspace is where you'll create projects, collaborate on your issues, and organize different streams of work in your Plane account."
>
<EmptySpaceItem Icon={Boxes} title="Continue to home" href="/" />
</EmptySpace>
</>
) : (
<EmptySpace
title={`You have been invited to ${invitationDetail.workspace.name}`}
description="Your workspace is where you'll create projects, collaborate on your issues, and organize different streams of work in your Plane account."
>
<EmptySpaceItem Icon={Check} title="Accept" action={handleAccept} />
<EmptySpaceItem Icon={X} title="Ignore" action={handleReject} />
</EmptySpace>
)}
</>
)}
</>
) : error ? (
<EmptySpace
title="This invitation link is not active anymore."
description="Your workspace is where you'll create projects, collaborate on your issues, and organize different streams of work in your Plane account."
link={{ text: "Or start from an empty project", href: "/" }}
>
{!currentUser ? (
<EmptySpaceItem Icon={User2} title="Sign in to continue" href="/" />
) : (
{invitationDetail && !invitationDetail.responded_at ? (
error ? (
<div className="flex w-full flex-col space-y-4 rounded border border-custom-border-200 bg-custom-background-100 px-4 py-8 text-center shadow-2xl md:w-1/3">
<h2 className="text-xl uppercase">INVITATION NOT FOUND</h2>
</div>
) : (
<EmptySpace
title={`You have been invited to ${invitationDetail.workspace.name}`}
description="Your workspace is where you'll create projects, collaborate on your issues, and organize different streams of work in your Plane account."
>
<EmptySpaceItem Icon={Check} title="Accept" action={handleAccept} />
<EmptySpaceItem Icon={X} title="Ignore" action={handleReject} />
</EmptySpace>
)
) : error || invitationDetail?.responded_at ? (
invitationDetail?.accepted ? (
<EmptySpace
title={`You are already a member of ${invitationDetail.workspace.name}`}
description="Your workspace is where you'll create projects, collaborate on your issues, and organize different streams of work in your Plane account."
>
<EmptySpaceItem Icon={Boxes} title="Continue to home" href="/" />
)}
<EmptySpaceItem Icon={Star} title="Star us on GitHub" href="https://github.com/makeplane" />
<EmptySpaceItem
Icon={Share2}
title="Join our community of active creators"
href="https://discord.com/invite/8SR2N9PAcJ"
/>
</EmptySpace>
</EmptySpace>
) : (
<EmptySpace
title="This invitation link is not active anymore."
description="Your workspace is where you'll create projects, collaborate on your issues, and organize different streams of work in your Plane account."
link={{ text: "Or start from an empty project", href: "/" }}
>
{!currentUser ? (
<EmptySpaceItem Icon={User2} title="Sign in to continue" href="/" />
) : (
<EmptySpaceItem Icon={Boxes} title="Continue to home" href="/" />
)}
<EmptySpaceItem Icon={Star} title="Star us on GitHub" href="https://github.com/makeplane" />
<EmptySpaceItem
Icon={Share2}
title="Join our community of active creators"
href="https://discord.com/invite/A92xrEGCge"
/>
</EmptySpace>
)
) : (
<div className="flex h-full w-full items-center justify-center">
<LogoSpinner />
Expand Down
Loading