diff --git a/src/hooks/auth/useAuth.ts b/src/hooks/auth/useAuth.ts index 10204a99..f2effb8d 100644 --- a/src/hooks/auth/useAuth.ts +++ b/src/hooks/auth/useAuth.ts @@ -1,3 +1,5 @@ +import { useQueryClient } from "@tanstack/react-query"; + import { useCoreMutation } from "@/hooks/customQuery"; import { @@ -11,15 +13,20 @@ import { verifySMS, } from "@/api/auth/auth"; import useAuthStore from "@/store/useAuthStore"; +import useWorkspaceStore from "@/store/useWorkspaceStore"; export const useAuth = () => { const { login: loginAction } = useAuthStore(); + const queryClient = useQueryClient(); const useLogin = useCoreMutation(login, { userOnSuccess: (response, vars) => { + queryClient.clear(); + useWorkspaceStore.getState().reset(); loginAction(vars.email, response.data.accessToken); }, }); + const useSignUp = useCoreMutation(signUp); const useSendCode = useCoreMutation(sendEmail); const useCheckCode = useCoreMutation(verifyEmail); diff --git a/src/hooks/auth/useDeleteMyAccount.ts b/src/hooks/auth/useDeleteMyAccount.ts index 555a643c..75b5118d 100644 --- a/src/hooks/auth/useDeleteMyAccount.ts +++ b/src/hooks/auth/useDeleteMyAccount.ts @@ -1,4 +1,3 @@ -import { useNavigate } from "react-router-dom"; import { useQueryClient } from "@tanstack/react-query"; import { toast } from "sonner"; @@ -8,9 +7,9 @@ import { useCoreMutation } from "@/hooks/customQuery"; import { deleteMyAccount } from "@/api/auth/auth"; import useAuthStore from "@/store/useAuthStore"; +import useWorkspaceStore from "@/store/useWorkspaceStore"; export function useDeleteMyAccount() { - const nav = useNavigate(); const queryClient = useQueryClient(); const logout = useAuthStore((s) => s.logout); @@ -20,8 +19,9 @@ export function useDeleteMyAccount() { "회원 탈퇴가 완료되었습니다. 30일 후 계정이 완전히 삭제됩니다", ); queryClient.clear(); + useWorkspaceStore.getState().reset(); logout(); - nav("/", { replace: true }); + window.location.replace("/"); }, userOnError: (error) => { const apiError = error as IApiErrorResponse; diff --git a/src/hooks/auth/useLogout.ts b/src/hooks/auth/useLogout.ts index aa58c752..6236b153 100644 --- a/src/hooks/auth/useLogout.ts +++ b/src/hooks/auth/useLogout.ts @@ -1,4 +1,3 @@ -import { useNavigate } from "react-router-dom"; import { useQueryClient } from "@tanstack/react-query"; import { toast } from "sonner"; @@ -8,9 +7,9 @@ import { useCoreMutation } from "@/hooks/customQuery"; import { postLogout } from "@/api/auth/auth"; import useAuthStore from "@/store/useAuthStore"; +import useWorkspaceStore from "@/store/useWorkspaceStore"; export function useLogout() { - const nav = useNavigate(); const logout = useAuthStore((s) => s.logout); const queryClient = useQueryClient(); @@ -18,8 +17,9 @@ export function useLogout() { userOnSuccess: () => { toast.success("로그아웃이 완료되었습니다"); queryClient.clear(); + useWorkspaceStore.getState().reset(); logout(); - nav("/", { replace: true }); + window.location.replace("/"); }, userOnError: (error) => { const apiError = error as IApiErrorResponse; diff --git a/src/layout/main/MainLayout.tsx b/src/layout/main/MainLayout.tsx index 5b850984..d420afb2 100644 --- a/src/layout/main/MainLayout.tsx +++ b/src/layout/main/MainLayout.tsx @@ -44,6 +44,7 @@ export default function MainLayout() { const setSelectedOrgId = useWorkspaceStore((s) => s.setSelectedOrgId); const setMyRole = useWorkspaceStore((s) => s.setMyRole); + const resetWorkspace = useWorkspaceStore((s) => s.reset); const myRole = useWorkspaceStore((s) => s.myRole); const savedWorkspaceQuery = useCoreQuery( @@ -66,21 +67,32 @@ export default function MainLayout() { ); useEffect(() => { - if (!workspaces?.length || !savedWorkspaceQuery.isFetched) return; + // undefined: 로딩 중 / []: 워크스페이스 없음(유효한 결과) + if (!workspaces || !savedWorkspaceQuery.isFetched) return; - // orgId는 있는데 myRole만 null/불일치인 경우(새로고침 등) 역할 동기화 + if (workspaces.length === 0) { + if (selectedOrgId !== null || myRole !== null) { + resetWorkspace(); + } + return; + } + + // 현재 유저 목록에 있는 orgId만 유지 (+ role 동기화) + // 목록에 없으면 return하지 않고 아래 saved/current 초기화로 계속 if (selectedOrgId !== null) { const workspace = workspaces.find((w) => w.orgId === selectedOrgId); - if (workspace && myRole !== workspace.myRole) { - setMyRole(workspace.myRole); + if (workspace) { + if (myRole !== workspace.myRole) { + setMyRole(workspace.myRole); + } + return; } - return; } const savedId = savedData?.orgId; const isExist = workspaces.some((w) => w.orgId === savedId); - // 1. 현재 워크스페이스 조회 API 데이터 (저장된 워크스페이스가 있는 경우) + // 1. 저장된 워크스페이스가 현재 유저 목록에 있으면 선택 if (savedId !== undefined && isExist) { const workspace = workspaces.find((w) => w.orgId === savedId); setSelectedOrgId(savedId); @@ -99,6 +111,7 @@ export default function MainLayout() { savedData, setSelectedOrgId, setMyRole, + resetWorkspace, selectedOrgId, myRole, ]); diff --git a/src/pages/auth/RedirectPage.tsx b/src/pages/auth/RedirectPage.tsx index b9a7e41c..6671f560 100644 --- a/src/pages/auth/RedirectPage.tsx +++ b/src/pages/auth/RedirectPage.tsx @@ -8,7 +8,9 @@ import { getSafeReturnUrl, } from "@/utils/auth/returnUrl"; +import { queryClient } from "@/lib/queryClient"; import useAuthStore from "@/store/useAuthStore"; +import useWorkspaceStore from "@/store/useWorkspaceStore"; export default function RedirectPage() { const navigate = useNavigate(); @@ -37,6 +39,8 @@ export default function RedirectPage() { if (accessToken) { deleteCookie("access_token"); + queryClient.clear(); + useWorkspaceStore.getState().reset(); setAccessToken(accessToken); toast.success("소셜 로그인되었습니다."); diff --git a/src/store/useWorkspaceStore.ts b/src/store/useWorkspaceStore.ts index 8d8288f0..c5671389 100644 --- a/src/store/useWorkspaceStore.ts +++ b/src/store/useWorkspaceStore.ts @@ -7,6 +7,7 @@ interface IWorkspaceState { myRole: TMemberRole | null; setSelectedOrgId: (orgId: number) => void; setMyRole: (role: TMemberRole | null) => void; + reset: () => void; } const useWorkspaceStore = create((set) => ({ @@ -14,6 +15,7 @@ const useWorkspaceStore = create((set) => ({ myRole: null, setSelectedOrgId: (orgId) => set({ selectedOrgId: orgId }), setMyRole: (role) => set({ myRole: role }), + reset: () => set({ selectedOrgId: null, myRole: null }), })); export default useWorkspaceStore;