diff --git a/web/components/account/deactivate-account-modal.tsx b/web/components/account/deactivate-account-modal.tsx index 22a5d5b89..906ed9682 100644 --- a/web/components/account/deactivate-account-modal.tsx +++ b/web/components/account/deactivate-account-modal.tsx @@ -10,16 +10,12 @@ import { useMobxStore } from "lib/mobx/store-provider"; import { Button } from "@plane/ui"; // hooks import useToast from "hooks/use-toast"; -// services -import { AuthService } from "services/auth.service"; type Props = { isOpen: boolean; onClose: () => void; }; -const authService = new AuthService(); - export const DeactivateAccountModal: React.FC = (props) => { const { isOpen, onClose } = props; @@ -28,7 +24,7 @@ export const DeactivateAccountModal: React.FC = (props) => { const [isDeactivating, setIsDeactivating] = useState(false); const { - user: { deactivateAccount }, + user: { deactivateAccount, signOut }, } = useMobxStore(); const router = useRouter(); @@ -46,8 +42,7 @@ export const DeactivateAccountModal: React.FC = (props) => { const handleSwitchAccount = async () => { setSwitchingAccount(true); - await authService - .signOut() + await signOut() .then(() => { mutate("CURRENT_USER_DETAILS", null); setTheme("system"); diff --git a/web/components/instance/sidebar-dropdown.tsx b/web/components/instance/sidebar-dropdown.tsx index fb89550ed..83ab60e7c 100644 --- a/web/components/instance/sidebar-dropdown.tsx +++ b/web/components/instance/sidebar-dropdown.tsx @@ -12,8 +12,6 @@ import { LogIn, LogOut, Settings, UserCog2 } from "lucide-react"; import { useMobxStore } from "lib/mobx/store-provider"; // hooks import useToast from "hooks/use-toast"; -// services -import { AuthService } from "services/auth.service"; // ui import { Avatar, Tooltip } from "@plane/ui"; @@ -27,15 +25,13 @@ const PROFILE_LINKS = [ }, ]; -const authService = new AuthService(); - export const InstanceSidebarDropdown = observer(() => { const router = useRouter(); // store const { theme: { sidebarCollapsed }, workspace: { workspaceSlug }, - user: { currentUser, currentUserSettings }, + user: { signOut, currentUser, currentUserSettings }, } = useMobxStore(); // hooks const { setToastAlert } = useToast(); @@ -49,8 +45,7 @@ export const InstanceSidebarDropdown = observer(() => { ""; const handleSignOut = async () => { - await authService - .signOut() + await signOut() .then(() => { mutate("CURRENT_USER_DETAILS", null); setTheme("system"); diff --git a/web/components/workspace/sidebar-dropdown.tsx b/web/components/workspace/sidebar-dropdown.tsx index 316e92935..8e8b9100e 100644 --- a/web/components/workspace/sidebar-dropdown.tsx +++ b/web/components/workspace/sidebar-dropdown.tsx @@ -10,8 +10,6 @@ import { Check, ChevronDown, LogOut, Plus, Settings, UserCircle2 } from "lucide- import { useMobxStore } from "lib/mobx/store-provider"; // hooks import useToast from "hooks/use-toast"; -// services -import { AuthService } from "services/auth.service"; // ui import { Avatar, Loader } from "@plane/ui"; // types @@ -46,8 +44,6 @@ const profileLinks = (workspaceSlug: string, userId: string) => [ }, ]; -const authService = new AuthService(); - export const WorkspaceSidebarDropdown = observer(() => { const router = useRouter(); const { workspaceSlug } = router.query; @@ -55,8 +51,8 @@ export const WorkspaceSidebarDropdown = observer(() => { const { theme: { sidebarCollapsed }, workspace: { workspaces, currentWorkspace: activeWorkspace }, - user: { currentUser, updateCurrentUser, isUserInstanceAdmin }, - trackEvent: { setTrackElement } + user: { currentUser, updateCurrentUser, isUserInstanceAdmin, signOut }, + trackEvent: { setTrackElement }, } = useMobxStore(); // hooks const { setToastAlert } = useToast(); @@ -79,8 +75,7 @@ export const WorkspaceSidebarDropdown = observer(() => { }; const handleSignOut = async () => { - await authService - .signOut() + await signOut() .then(() => { mutate("CURRENT_USER_DETAILS", null); setTheme("system"); diff --git a/web/layouts/auth-layout/user-wrapper.tsx b/web/layouts/auth-layout/user-wrapper.tsx index 6b64099fa..2bd6ac8ac 100644 --- a/web/layouts/auth-layout/user-wrapper.tsx +++ b/web/layouts/auth-layout/user-wrapper.tsx @@ -5,22 +5,30 @@ import useSWR from "swr"; import { Spinner } from "@plane/ui"; // store import { useMobxStore } from "lib/mobx/store-provider"; +import { observer } from "mobx-react-lite"; export interface IUserAuthWrapper { children: ReactNode; } -export const UserAuthWrapper: FC = (props) => { +export const UserAuthWrapper: FC = observer((props) => { const { children } = props; // store const { - user: { fetchCurrentUser, fetchCurrentUserInstanceAdminStatus, fetchCurrentUserSettings }, + user: { + currentUser, + currentUserError, + fetchCurrentUser, + fetchCurrentUserInstanceAdminStatus, + fetchCurrentUserSettings, + + }, workspace: { fetchWorkspaces }, } = useMobxStore(); // router const router = useRouter(); // fetching user information - const { data: currentUser, error } = useSWR("CURRENT_USER_DETAILS", () => fetchCurrentUser(), { + useSWR("CURRENT_USER_DETAILS", () => fetchCurrentUser(), { shouldRetryOnError: false, }); // fetching current user instance admin status @@ -36,7 +44,7 @@ export const UserAuthWrapper: FC = (props) => { shouldRetryOnError: false, }); - if (!currentUser && !error) { + if (!currentUser && !currentUserError) { return (
@@ -46,11 +54,11 @@ export const UserAuthWrapper: FC = (props) => { ); } - if (error) { + if (currentUserError) { const redirectTo = router.asPath; router.push(`/?next=${redirectTo}`); return null; } return <>{children}; -}; +}); diff --git a/web/layouts/settings-layout/profile/sidebar.tsx b/web/layouts/settings-layout/profile/sidebar.tsx index 1867f70a3..9a133a994 100644 --- a/web/layouts/settings-layout/profile/sidebar.tsx +++ b/web/layouts/settings-layout/profile/sidebar.tsx @@ -4,8 +4,6 @@ import { Menu, Transition } from "@headlessui/react"; import { LogIn, LogOut, MoveLeft, Plus, User, UserPlus } from "lucide-react"; // mobx store import { useMobxStore } from "lib/mobx/store-provider"; -// services -import { AuthService } from "services/auth.service"; // ui import { Avatar, Tooltip } from "@plane/ui"; import { Fragment } from "react"; @@ -29,8 +27,6 @@ const SIDEBAR_LINKS = [ }, ]; -const authService = new AuthService(); - export const ProfileLayoutSidebar = observer(() => { const router = useRouter(); @@ -41,7 +37,7 @@ export const ProfileLayoutSidebar = observer(() => { const { theme: { sidebarCollapsed, toggleSidebar }, workspace: { workspaces }, - user: { currentUser, currentUserSettings, isUserInstanceAdmin }, + user: { currentUser, currentUserSettings, isUserInstanceAdmin, signOut }, } = useMobxStore(); // redirect url for normal mode @@ -51,8 +47,7 @@ export const ProfileLayoutSidebar = observer(() => { ""; const handleSignOut = async () => { - await authService - .signOut() + await signOut() .then(() => { mutate("CURRENT_USER_DETAILS", null); setTheme("system"); diff --git a/web/store/user.store.ts b/web/store/user.store.ts index 155413a46..4862ecf0e 100644 --- a/web/store/user.store.ts +++ b/web/store/user.store.ts @@ -4,6 +4,7 @@ import { action, observable, runInAction, makeObservable, computed } from "mobx" import { ProjectMemberService, ProjectService } from "services/project"; import { UserService } from "services/user.service"; import { WorkspaceService } from "services/workspace.service"; +import { AuthService } from "services/auth.service"; // interfaces import { IUser, IUserSettings } from "types/users"; import { IWorkspaceMemberMe, IProjectMember, TUserProjectRole, TUserWorkspaceRole } from "types"; @@ -11,6 +12,7 @@ import { RootStore } from "./root"; export interface IUserStore { loader: boolean; + currentUserError: any; isUserLoggedIn: boolean | null; currentUser: IUser | null; @@ -55,6 +57,7 @@ export interface IUserStore { updateCurrentUserTheme: (theme: string) => Promise; deactivateAccount: () => Promise; + signOut: () => Promise; leaveWorkspace: (workspaceSlug: string) => Promise; @@ -64,6 +67,7 @@ export interface IUserStore { class UserStore implements IUserStore { loader: boolean = false; + currentUserError: any = null; isUserLoggedIn: boolean | null = null; currentUser: IUser | null = null; @@ -92,6 +96,7 @@ class UserStore implements IUserStore { workspaceService; projectService; projectMemberService; + authService; constructor(_rootStore: RootStore) { makeObservable(this, { @@ -121,6 +126,7 @@ class UserStore implements IUserStore { leaveWorkspace: action, joinProject: action, leaveProject: action, + signOut: action, // computed currentProjectMemberInfo: computed, currentWorkspaceMemberInfo: computed, @@ -134,6 +140,7 @@ class UserStore implements IUserStore { this.workspaceService = new WorkspaceService(); this.projectService = new ProjectService(); this.projectMemberService = new ProjectMemberService(); + this.authService = new AuthService(); } get currentWorkspaceMemberInfo() { @@ -171,6 +178,7 @@ class UserStore implements IUserStore { const response = await this.userService.currentUser(); if (response) { runInAction(() => { + this.currentUserError = null; this.currentUser = response; this.isUserLoggedIn = true; }); @@ -178,6 +186,7 @@ class UserStore implements IUserStore { return response; } catch (error) { runInAction(() => { + this.currentUserError = error; this.isUserLoggedIn = false; }); throw error; @@ -422,6 +431,19 @@ class UserStore implements IUserStore { throw error; } }; + + signOut = async () => { + try { + await this.authService.signOut(); + runInAction(() => { + this.currentUserError = null; + this.currentUser = null; + this.isUserLoggedIn = false; + }); + } catch (error) { + throw error; + } + }; } export default UserStore;