import { create } from 'zustand'; import { persist } from 'zustand/middleware'; import { authApi } from '@/lib/api/auth.api'; import { UserDto, LoginDto, SignupDto } from '@/types/auth.types'; /** * 인증 Store 상태 - 인증 관련 값 안올때 확인 * 상태(State)를 중앙에서 관리하는 저장소 * login.page 프론트에서 요청을 받으면 백엔드로 요청을 전송하고 받은 데이터를 저장하고 관리 */ interface AuthState { // 상태 user: UserDto | null; // 현재 로그인한 사용자 정보 accessToken: string | null; // JWT 액세스 토큰 (24시간 유효) isAuthenticated: boolean; // 로그인 여부 // 각 페이지의 호출된 함수 실행 login: (dto: LoginDto) => Promise; // 로그인 signup: (dto: SignupDto) => Promise; // 회원가입 logout: () => Promise; // 로그아웃 loadProfile: () => Promise; // 프로필 불러오기 clearAuth: () => void; // 인증 정보 초기화 (클라이언트에서) } /** * 인증 Store * * @description * JWT 토큰 기반 인증 상태 관리 * - localStorage에 토큰 자동 저장 (persist) * - 로그인/로그아웃/회원가입/토큰 갱신 기능 */ // useAuthStore는 Zustand의 create 함수로 만든 커스텀 스토어 훅 // Zustand import 후 그 반환값을 useAuthStore에 할당 // import { useAuthStore } from "@/store/auth-store"; // 스토어에서 토큰/초기화 사용 export const useAuthStore = create()( persist( // persist 미들웨어로 전체 상태를 자동 저장,복원/ partialize(state)쓰게되면 저장할 필드만 선별하는거라함 // persist미들웨어를 붙이면 set으로 상태를 바꿀때 선택된 필드가 자동으로 localStorage에 저장 (set, get) => ({ // 초기 상태 user: null, accessToken: null, isAuthenticated: false, /** * @description 로그인 페이지에서 백엔드 API로 요청 전송 authApi.login(dto) * 백엔드에서 토큰을 반환하면 프론트에서 로컬 스토리지에 저장 */ login: async (dto: LoginDto) => { try { const response = await authApi.login(dto); // 받아온 결과를 상태에 저장 // Zustand 상태 업데이트 (persist 미들웨어가 자동으로 localStorage에 저장) set({ user: response.user, accessToken: response.accessToken, isAuthenticated: true, }); } catch (error) { console.error('로그인 실패:', error); throw error; } }, /** * 회원가입 */ signup: async (dto: SignupDto) => { try { const response = await authApi.signup(dto); // Zustand 상태 업데이트 (persist 미들웨어가 자동으로 localStorage에 저장) set({ user: response.user, accessToken: response.accessToken, isAuthenticated: true, }); } catch (error) { console.error('회원가입 실패:', error); throw error; } }, /** * 로그아웃 */ logout: async () => { try { await authApi.logout(); } catch (error) { console.error('로그아웃 요청 실패:', error); } finally { // Zustand 상태 초기화 (persist 미들웨어가 자동으로 localStorage에서 삭제) set({ user: null, accessToken: null, isAuthenticated: false, }); } }, /** * 프로필 불러오기 */ loadProfile: async () => { try { const profile = await authApi.getProfile(); set({ user: profile, isAuthenticated: true, }); } catch (error) { console.error('프로필 불러오기 실패:', error); throw error; } }, /** * 인증 정보 초기화 (클라이언트 측) */ clearAuth: () => { // Zustand 상태 초기화 (persist 미들웨어가 자동으로 localStorage에서 삭제) set({ user: null, accessToken: null, isAuthenticated: false, }); }, }), { name: 'auth-storage', // localStorage 키 이름 partialize: (state) => ({ // localStorage에 저장할 필드만 선택 user: state.user, accessToken: state.accessToken, isAuthenticated: state.isAuthenticated, }), } ) );