diff --git a/src/app/(auth)/login/page.tsx b/src/app/(auth)/login/page.tsx new file mode 100644 index 0000000..73a37b2 --- /dev/null +++ b/src/app/(auth)/login/page.tsx @@ -0,0 +1,11 @@ +'use client' + +import LoginForm from '@/app/features/auth/components/LoginForm' + +export default function Login() { + return ( + <> + + + ) +} diff --git a/src/app/auth/page.tsx b/src/app/(auth)/signin/page.tsx similarity index 97% rename from src/app/auth/page.tsx rename to src/app/(auth)/signin/page.tsx index 2184c26..df4921f 100644 --- a/src/app/auth/page.tsx +++ b/src/app/(auth)/signin/page.tsx @@ -54,7 +54,7 @@ export default function MyForm() { hasError={touchedFields.password && !!errors.password} errorMessage={touchedFields.password ? errors.password?.message : ''} /> - + + + ) +} diff --git a/src/app/features/auth/hooks/useAuth.ts b/src/app/features/auth/hooks/useAuth.ts index 6b577e0..d4d1c1e 100644 --- a/src/app/features/auth/hooks/useAuth.ts +++ b/src/app/features/auth/hooks/useAuth.ts @@ -1,5 +1,5 @@ -import { useAuthStore } from '../store/useAuthStore' import { login as loginApi, signup as signupApi } from '../api/authApi' +import { useAuthStore } from '../store/useAuthStore' import { LoginRequest, SignupRequest } from '../types/auth.type' export function useAuth() { @@ -23,6 +23,7 @@ export function useAuth() { function logout() { clearAuthState() + useAuthStore.persist.clearStorage() } return { diff --git a/src/app/features/auth/hooks/useLoginSubmit.ts b/src/app/features/auth/hooks/useLoginSubmit.ts new file mode 100644 index 0000000..da476f9 --- /dev/null +++ b/src/app/features/auth/hooks/useLoginSubmit.ts @@ -0,0 +1,28 @@ +import axios from 'axios' +import { useRouter } from 'next/navigation' +import { toast } from 'sonner' + +import { LoginRequest } from '../types/auth.type' +import { useAuth } from './useAuth' + +export function useLoginSubmit() { + const { login } = useAuth() + const router = useRouter() + + async function submit(data: LoginRequest) { + try { + await login(data) + toast.success('로그인 성공') + router.push('/mydashboard') + } catch (e: unknown) { + if (axios.isAxiosError(e)) { + const message = e.response?.data?.message + toast.error(message ?? '로그인 실패') + } else { + toast.error('알 수 없는 에러 발생') + } + } + } + + return { submit } +} diff --git a/src/app/features/auth/schemas/loginValidation.ts b/src/app/features/auth/schemas/loginValidation.ts new file mode 100644 index 0000000..0cb0c95 --- /dev/null +++ b/src/app/features/auth/schemas/loginValidation.ts @@ -0,0 +1,16 @@ +export const loginValidation = { + email: { + required: '이메일을 입력해 주세요.', + pattern: { + value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, + message: '유효한 이메일 주소를 입력해주세요', + }, + }, + password: { + required: '비밀번호를 입력해 주세요.', + minLength: { + value: 8, + message: '비밀번호는 최소 8자 이상이어야 합니다.', + }, + }, +} diff --git a/src/app/globals.css b/src/app/globals.css index f05ac09..d40de74 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -22,6 +22,10 @@ body { .BG-blue { @apply bg-[#83C8FA] hover:bg-[#5FBBFF] dark:bg-[#228DFF] dark:hover:bg-[#2172C9]; } +.BG-blue-disabled { + @apply cursor-not-allowed bg-[#9FA6B2]; +} + .Text-black { @apply text-[#333236] dark:text-[#FFFFFF]; }