diff --git a/src/apis/api.ts b/src/apis/api.ts index 7760c56e..d1b7ab9b 100644 --- a/src/apis/api.ts +++ b/src/apis/api.ts @@ -1,3 +1,4 @@ +import { useAuthStore } from "@/store/auth-store"; import axios, { AxiosError } from "axios"; const api = axios.create({ @@ -63,6 +64,7 @@ api.interceptors.response.use( if (!errorResponse) return Promise.reject(error); if (errorResponse.code === "REFRESH_TOKEN_NOT_FOUND") { + useAuthStore.getState().setSignedOut(); console.clear(); } diff --git a/src/apis/auth/mutation/use-sign-in.ts b/src/apis/auth/mutation/use-sign-in.ts index bb0b0fdc..66914cc6 100644 --- a/src/apis/auth/mutation/use-sign-in.ts +++ b/src/apis/auth/mutation/use-sign-in.ts @@ -1,10 +1,17 @@ +import { useAuthStore } from "@/store/auth-store"; import { SignInRequest } from "@/types/auth"; -import { useMutation } from "@tanstack/react-query"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; import { signInUser } from "../auth.api"; const useSignIn = () => { + const queryClient = useQueryClient(); + return useMutation({ mutationFn: (data: SignInRequest) => signInUser(data), + onMutate: async () => { + queryClient.clear(); + }, + onSuccess: () => useAuthStore.getState().setSignedIn(), }); }; diff --git a/src/apis/auth/mutation/use-sign-out.ts b/src/apis/auth/mutation/use-sign-out.ts index 958efacd..38135950 100644 --- a/src/apis/auth/mutation/use-sign-out.ts +++ b/src/apis/auth/mutation/use-sign-out.ts @@ -3,6 +3,7 @@ import queryKeys from "@/apis/query-keys"; import { useToastStore } from "@/store/toast-store"; import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { useAuthStore } from "@/store/auth-store"; import { useRouter } from "next/navigation"; import { signOutUser } from "../auth.api"; @@ -15,7 +16,7 @@ const useSignOut = () => { mutationFn: () => signOutUser(), onSuccess: () => { queryClient.removeQueries({ queryKey: queryKeys.user.all }); - + useAuthStore.getState().setSignedOut(); router.push("/"); toast({ diff --git a/src/components/section/gathering/detail/sidebar.tsx b/src/components/section/gathering/detail/sidebar.tsx index 3a4f4c17..6ecb56e6 100644 --- a/src/components/section/gathering/detail/sidebar.tsx +++ b/src/components/section/gathering/detail/sidebar.tsx @@ -2,7 +2,6 @@ import useJoinGathering from "@/apis/gathering/mutation/use-join-gathering"; import useLeaveGathering from "@/apis/gathering/mutation/use-leave-gathering"; -import useGetUserInfo from "@/apis/user/query/use-get-user-info"; import { Information } from "@/components/section"; import { Button, UpdateGatheringModal } from "@/components/ui"; import LikeButton from "@/components/ui/button/like-button"; @@ -12,6 +11,7 @@ import { GATHERING_MODAL_MESSAGES, } from "@/constants/modal-message"; import { GATHERING_SUCCESS_MESSAGES } from "@/constants/success-message"; +import { useAuthStore } from "@/store/auth-store"; import { useModalStore } from "@/store/modal-store"; import { useToastStore } from "@/store/toast-store"; import type { GetGatheringDetailResponse } from "@/types/gathering"; @@ -38,7 +38,7 @@ const SideBar = ({ data, isOwner }: SideBarProps) => { size="size-9" /> {isOwner ? ( -
+
{ const { alertModal } = useModalStore(); const { mutate: joinGathering } = useJoinGathering(); - const { data: user } = useGetUserInfo(); - const isSignedIn = !!user; + const isSignedIn = useAuthStore((state) => state.authStatus); const handleClick = () => { if (!isSignedIn) { diff --git a/src/components/ui/button/auth-status-button.tsx b/src/components/ui/button/auth-status-button.tsx index aae9872f..d08b2a94 100644 --- a/src/components/ui/button/auth-status-button.tsx +++ b/src/components/ui/button/auth-status-button.tsx @@ -2,6 +2,7 @@ import useSignOut from "@/apis/auth/mutation/use-sign-out"; import useGetUserInfo from "@/apis/user/query/use-get-user-info"; import { Button, Dropdown, Profile } from "@/components/ui"; +import { useAuthStore } from "@/store/auth-store"; import { cn } from "@/utils/cn"; import { useRouter } from "next/navigation"; @@ -11,33 +12,35 @@ interface AuthStatusButtonProps { const AuthStatusButton = ({ className }: AuthStatusButtonProps) => { const { data: user } = useGetUserInfo(); - const isSignedIn = !!user; const router = useRouter(); const { mutate: signOut } = useSignOut(); + const isSignedIn = useAuthStore((state) => state.authStatus); if (isSignedIn) { return ( - - } - items={[ - { - text: "마이페이지", - onClick: () => router.push("/my-page"), - }, - { - text: "로그아웃", - onClick: signOut, - }, - ]} - itemClassName="hover:text-gray-neutral-700 text-gray-neutral-500 justify-center" - contentAlign="end" - /> + user && ( + + } + items={[ + { + text: "마이페이지", + onClick: () => router.push("/my-page"), + }, + { + text: "로그아웃", + onClick: signOut, + }, + ]} + itemClassName="hover:text-gray-neutral-700 text-gray-neutral-500 justify-center" + contentAlign="end" + /> + ) ); } else { return ( diff --git a/src/components/ui/button/like-button.tsx b/src/components/ui/button/like-button.tsx index 0f81c97f..374673e2 100644 --- a/src/components/ui/button/like-button.tsx +++ b/src/components/ui/button/like-button.tsx @@ -1,8 +1,8 @@ "use client"; -import useGetUserInfo from "@/apis/user/query/use-get-user-info"; import { HeartFill, HeartLine } from "@/assets/icons"; import { AUTH_MODAL_MESSAGES } from "@/constants/modal-message"; +import { useAuthStore } from "@/store/auth-store"; import { useModalStore } from "@/store/modal-store"; import { cn } from "@/utils/cn"; import { useRouter } from "next/navigation"; @@ -16,8 +16,7 @@ interface LikeButtonProps { const LikeButton = ({ liked, onClick, size }: LikeButtonProps) => { const router = useRouter(); const { alertModal } = useModalStore(); - const { data: user } = useGetUserInfo(); - const isSignedIn = !!user; + const isSignedIn = useAuthStore((state) => state.authStatus); const handleClick = (e: React.MouseEvent) => { e.preventDefault(); diff --git a/src/components/ui/modal/gathering/form/create-gathering-modal.tsx b/src/components/ui/modal/gathering/form/create-gathering-modal.tsx index 3470a9d5..10067244 100644 --- a/src/components/ui/modal/gathering/form/create-gathering-modal.tsx +++ b/src/components/ui/modal/gathering/form/create-gathering-modal.tsx @@ -7,6 +7,7 @@ import { Button, ModalWrapper } from "@/components/ui"; import GatheringForm from "@/components/ui/modal/gathering/form/gathering-form"; import { AUTH_MODAL_MESSAGES } from "@/constants/modal-message"; import { GATHERING_SUCCESS_MESSAGES } from "@/constants/success-message"; +import { useAuthStore } from "@/store/auth-store"; import { useModalStore } from "@/store/modal-store"; import { useToastStore } from "@/store/toast-store"; import { GatheringFormData, GatheringFormInput } from "@/types/gathering"; @@ -18,16 +19,15 @@ const CreateGathering = () => { const router = useRouter(); const { toast } = useToastStore(); const { alertModal } = useModalStore(); - + const { data: user } = useGetUserInfo(); const [open, setOpen] = useState(false); const { mutate: createGathering, isPending: isLoading } = useCreateGathering(); - const { data: user } = useGetUserInfo(); - const isSignedIn = !!user; + const isSignedIn = useAuthStore((state) => state.authStatus); const handleOpenChange = (open: boolean) => { - if (open && !isSignedIn) { + if (open && !isSignedIn && user) { alertModal({ ...AUTH_MODAL_MESSAGES.LOGIN_REQUIRED, onConfirm: () => { diff --git a/src/components/ui/side-menu/side-menu.tsx b/src/components/ui/side-menu/side-menu.tsx index 2ee2b019..f7bf9879 100644 --- a/src/components/ui/side-menu/side-menu.tsx +++ b/src/components/ui/side-menu/side-menu.tsx @@ -1,5 +1,6 @@ import useSignOut from "@/apis/auth/mutation/use-sign-out"; import useGetUserInfo from "@/apis/user/query/use-get-user-info"; +import { useAuthStore } from "@/store/auth-store"; import useSideMenuStore from "@/store/side-menu-store"; import { cn } from "@/utils/cn"; import { useRouter } from "next/navigation"; @@ -10,7 +11,7 @@ const SideMenu = () => { const { data: user } = useGetUserInfo(); const { isOpen, toggleSideMenu } = useSideMenuStore(); const router = useRouter(); - const isSignedIn = !!user; + const isSignedIn = useAuthStore((state) => state.authStatus); const { mutate: signOut } = useSignOut(); useEffect(() => { if (isOpen) { @@ -44,7 +45,7 @@ const SideMenu = () => { >
- {isSignedIn && ( + {user && ( )}
diff --git a/src/store/auth-store.ts b/src/store/auth-store.ts new file mode 100644 index 00000000..3fa9d046 --- /dev/null +++ b/src/store/auth-store.ts @@ -0,0 +1,24 @@ +import { create } from "zustand"; +import { persist } from "zustand/middleware"; + +type AuthState = { + authStatus: boolean; + setSignedIn: () => void; + setSignedOut: () => void; +}; + +export const useAuthStore = create()( + persist( + (set) => ({ + authStatus: false, + setSignedIn: () => set({ authStatus: true }), + setSignedOut: () => set({ authStatus: false }), + }), + { + name: "auth-store", + partialize: (state) => ({ + authStatus: state.authStatus, + }), + } + ) +);