Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
14 changes: 14 additions & 0 deletions src/api/auth/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import type {
IEmailSendRequest,
IEmailSendResponse,
IEmailVerifyRequest,
ILoginRequest,
ILoginResponse,
ISignUpRequest,
ISignUpResponse,
} from "../../types/auth/auth";
Expand Down Expand Up @@ -40,3 +42,15 @@ export const signUp = async (
);
return responseData;
};

// 로그인
export const login = async (
data: ILoginRequest,
): Promise<ICommonResponse<ILoginResponse>> => {
const { data: responseData } = await axiosInstance.post(
"/api/auth/login",
data,
);

return responseData;
};
4 changes: 3 additions & 1 deletion src/hooks/auth/useAuth.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { useCoreMutation } from "@/hooks/customQuery";

import { sendEmail, signUp, verifyEmail } from "@/api/auth/auth";
import { login, sendEmail, signUp, verifyEmail } from "@/api/auth/auth";

export const useAuth = () => {
const useSendCode = useCoreMutation(sendEmail);
const useCheckCode = useCoreMutation(verifyEmail);
const useSignUp = useCoreMutation(signUp);
const useLogin = useCoreMutation(login);

return {
useSendCode,
useCheckCode,
useSignUp,
useLogin,
};
};
24 changes: 19 additions & 5 deletions src/pages/auth/Login.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import { type SubmitHandler, useForm } from "react-hook-form";
import { Link } from "react-router-dom";
import { Link, useNavigate } from "react-router-dom";
import { zodResolver } from "@hookform/resolvers/zod";
import { toast } from "sonner";
import type { z } from "zod";

import { loginSchema } from "@/utils/validation";

import { useAuth } from "@/hooks/auth/useAuth";

import CommonAuthInput from "@/components/auth/common/CommonAuthInput";
import Button from "@/components/common/Button";

import GoogleIcon from "@/assets/auth/social/google.svg?react";
import KakaoIcon from "@/assets/auth/social/kakao.svg?react";
import NaverIcon from "@/assets/auth/social/naver.svg?react";
import useAuthStore from "@/store/useAuthStore";

type TLoginFormValues = z.infer<typeof loginSchema>;

Expand All @@ -25,11 +28,22 @@ export default function Login() {
resolver: zodResolver(loginSchema),
});

const navigate = useNavigate();
const { useLogin } = useAuth();
const { login: loginAction } = useAuthStore();

const onSubmit: SubmitHandler<TLoginFormValues> = (data) => {
// 임시 로그인 처리
console.log("Login submit:", data);
toast.success("로그인 성공!", {
description: `이메일: ${data.email}`,
useLogin.mutate(data, {
onSuccess: (response) => {
const { accessToken } = response.data;
localStorage.setItem("accessToken", accessToken);
loginAction(data.email);
navigate("/");
},
onError: (error: any) => {
console.error("Login error:", error);
toast.error(error.response?.data?.message || "로그인에 실패했습니다.");
},
});
};

Expand Down
2 changes: 1 addition & 1 deletion src/routes/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Error from "@/pages/common/Error";

function AuthGuard({ children }: { children: React.ReactNode }) {
// 실제 인증 상태 확인 로직으로 대체 예정
const isAuthenticated = false;
const isAuthenticated = true;

if (!isAuthenticated) {
return <Navigate to="/signup" replace />;
Expand Down
9 changes: 9 additions & 0 deletions src/store/useAuthStore.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
import { create } from "zustand";

interface IAuthState {
isLoggedIn: boolean;
email: string;
password: string;
socialId: number;
login: (email: string) => void;
logout: () => void;
setEmail: (email: string) => void;
setPassword: (password: string) => void;
setSocialId: (socialId: number) => void;
resetAuth: () => void;
}

const useAuthStore = create<IAuthState>((set) => ({
isLoggedIn: false,
email: "",
password: "",
socialId: -1,
login: (email) => set({ isLoggedIn: true, email }),
logout: () => {
localStorage.removeItem("accessToken");
set({ isLoggedIn: false, email: "", password: "", socialId: -1 });
},
setEmail: (email) => set({ email }),
setPassword: (password) => set({ password }),
setSocialId: (socialId) => set({ socialId }),
Expand Down
13 changes: 13 additions & 0 deletions src/types/auth/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,16 @@ export interface ISignUpResponse {
userId: number;
createdAt: string;
}

// 로그인 요청 타입
export interface ILoginRequest {
email: string;
password: string;
}

// 로그인 응답 타입
export interface ILoginResponse {
grantType: string;
accessToken: string;
accessTokenExpiresIn: number;
}