Skip to content
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
7 changes: 7 additions & 0 deletions src/hooks/auth/useAuth.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { useQueryClient } from "@tanstack/react-query";

import { useCoreMutation } from "@/hooks/customQuery";

import {
Expand All @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions src/hooks/auth/useDeleteMyAccount.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { useNavigate } from "react-router-dom";
import { useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";

Expand All @@ -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);

Expand All @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions src/hooks/auth/useLogout.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { useNavigate } from "react-router-dom";
import { useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";

Expand All @@ -8,18 +7,19 @@ 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();

return useCoreMutation(postLogout, {
userOnSuccess: () => {
toast.success("로그아웃이 완료되었습니다");
queryClient.clear();
useWorkspaceStore.getState().reset();
logout();
nav("/", { replace: true });
window.location.replace("/");
},
userOnError: (error) => {
const apiError = error as IApiErrorResponse;
Expand Down
25 changes: 19 additions & 6 deletions src/layout/main/MainLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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);
}
Comment thread
YermIm marked this conversation as resolved.
return;
}
return;
}

const savedId = savedData?.orgId;
const isExist = workspaces.some((w) => w.orgId === savedId);

// 1. 현재 워크스페이스 조회 API 데이터 (저장된 워크스페이스가 있는 경우)
// 1. 저장된 워크스페이스가 현재 유저 목록에 있으면 선택
Comment thread
YermIm marked this conversation as resolved.
if (savedId !== undefined && isExist) {
const workspace = workspaces.find((w) => w.orgId === savedId);
setSelectedOrgId(savedId);
Expand All @@ -99,6 +111,7 @@ export default function MainLayout() {
savedData,
setSelectedOrgId,
setMyRole,
resetWorkspace,
selectedOrgId,
myRole,
]);
Expand Down
4 changes: 4 additions & 0 deletions src/pages/auth/RedirectPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -37,6 +39,8 @@ export default function RedirectPage() {

if (accessToken) {
deleteCookie("access_token");
queryClient.clear();
useWorkspaceStore.getState().reset();
setAccessToken(accessToken);

toast.success("소셜 로그인되었습니다.");
Expand Down
2 changes: 2 additions & 0 deletions src/store/useWorkspaceStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ interface IWorkspaceState {
myRole: TMemberRole | null;
setSelectedOrgId: (orgId: number) => void;
setMyRole: (role: TMemberRole | null) => void;
reset: () => void;
}

const useWorkspaceStore = create<IWorkspaceState>((set) => ({
selectedOrgId: null,
myRole: null,
setSelectedOrgId: (orgId) => set({ selectedOrgId: orgId }),
setMyRole: (role) => set({ myRole: role }),
reset: () => set({ selectedOrgId: null, myRole: null }),
}));

export default useWorkspaceStore;
Loading