diff --git a/src/assets/icons/signup/arrow-down.svg b/src/assets/icons/auth/arrow-down.svg similarity index 100% rename from src/assets/icons/signup/arrow-down.svg rename to src/assets/icons/auth/arrow-down.svg diff --git a/src/assets/icons/signup/auth-checkbox.svg b/src/assets/icons/auth/auth-checkbox.svg similarity index 100% rename from src/assets/icons/signup/auth-checkbox.svg rename to src/assets/icons/auth/auth-checkbox.svg diff --git a/src/assets/icons/signup/back-button.svg b/src/assets/icons/auth/back-button.svg similarity index 100% rename from src/assets/icons/signup/back-button.svg rename to src/assets/icons/auth/back-button.svg diff --git a/src/assets/icons/signup/check-icon.svg b/src/assets/icons/auth/check-icon.svg similarity index 100% rename from src/assets/icons/signup/check-icon.svg rename to src/assets/icons/auth/check-icon.svg diff --git a/src/assets/icons/signup/eye-close.svg b/src/assets/icons/auth/eye-close.svg similarity index 100% rename from src/assets/icons/signup/eye-close.svg rename to src/assets/icons/auth/eye-close.svg diff --git a/src/assets/icons/signup/eye-open.svg b/src/assets/icons/auth/eye-open.svg similarity index 100% rename from src/assets/icons/signup/eye-open.svg rename to src/assets/icons/auth/eye-open.svg diff --git a/src/assets/icons/signup/google.svg b/src/assets/icons/auth/google.svg similarity index 100% rename from src/assets/icons/signup/google.svg rename to src/assets/icons/auth/google.svg diff --git a/src/assets/icons/signup/kakao.svg b/src/assets/icons/auth/kakao.svg similarity index 100% rename from src/assets/icons/signup/kakao.svg rename to src/assets/icons/auth/kakao.svg diff --git a/src/assets/icons/common/NECT.svg b/src/assets/icons/common/NECT.svg deleted file mode 100644 index 8145f18..0000000 --- a/src/assets/icons/common/NECT.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/assets/icons/common/logo.svg b/src/assets/icons/common/logo.svg deleted file mode 100644 index 85d04a7..0000000 --- a/src/assets/icons/common/logo.svg +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/assets/icons/common/nect-logo.svg b/src/assets/icons/common/nect-logo.svg new file mode 100644 index 0000000..5ccfeef --- /dev/null +++ b/src/assets/icons/common/nect-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/auth/login/AuthForm.tsx b/src/components/auth/login/AuthForm.tsx index fe6e187..becf379 100644 --- a/src/components/auth/login/AuthForm.tsx +++ b/src/components/auth/login/AuthForm.tsx @@ -1,26 +1,49 @@ import Button from '@/components/common/Button' import Input from '@/components/common/Input' -import SignupIcon from '@/assets/icons/signup/auth-checkbox.svg?react' -import EyeClosed from '@/assets/icons/signup/eye-close.svg?react' -import EyeOpen from '@/assets/icons/signup/eye-open.svg?react' -import CheckIcon from '@/assets/icons/signup/check-icon.svg?react' +import SignupIcon from '@/assets/icons/auth/auth-checkbox.svg?react' +import EyeClosed from '@/assets/icons/auth/eye-close.svg?react' +import EyeOpen from '@/assets/icons/auth/eye-open.svg?react' +import CheckIcon from '@/assets/icons/auth/check-icon.svg?react' import { useState } from 'react' -import { type LoginFormType } from '@/utils/validate' import { useLoginForm } from '@/hooks/useForm' +import { useNavigate } from 'react-router' const AuthForm = () => { const [showPassword, setShowPassword] = useState(false) - const { register, handleSubmit, errors, watch, isValid, isDirty } = useLoginForm() + const [loginError, setLoginError] = useState('') + const navigate = useNavigate() + // 유효성 검사용 + const { register, handleSubmit, errors, watch } = useLoginForm() + + // 폼 데이터 감시 + const email = watch('email') + const password = watch('password') const isAuthLogin = watch('autoLogin') - const onSubmit = (data: LoginFormType) => { - console.log('🍀 로그인 폼 제출 성공~!', data) + // 이메일과 비밀번호가 모두 입력되었는지 확인 (버튼 활성/비활성화용) + const isFormFilled = email && password + + // 폼 제출 (로그인 버튼 클릭) + const onSubmit = () => { + setLoginError('') + + // 나중에 api연결로 대체 + try { + if (email === 'test@naver.com' && password === 'qwerty1!') { + console.log('로그인 성공!', email, password) + navigate('/') + } else { + setLoginError('가입되지 않은 계정이거나, 아이디/비밀번호가 일치하지 않습니다.') + } + } catch { + setLoginError('가입되지 않은 계정이거나, 아이디/비밀번호가 일치하지 않습니다.') + } } return ( -
+
{/* 이메일 */} @@ -57,7 +80,7 @@ const AuthForm = () => {
{/* 자동 로그인 */} -
) diff --git a/src/components/auth/login/AuthHeader.tsx b/src/components/auth/login/AuthHeader.tsx index 3ea47fa..787d0c1 100644 --- a/src/components/auth/login/AuthHeader.tsx +++ b/src/components/auth/login/AuthHeader.tsx @@ -1,14 +1,10 @@ -import NectIcon from '@/assets/icons/common/logo.svg?react' -import NECT from '@/assets/icons/common/NECT.svg?react' +import NectLogoIcon from '@/assets/icons/common/nect-logo.svg?react' const AuthHeader = () => { return ( <> -
-
- - -
+
+
모든 창작자를 잇는 연결
diff --git a/src/components/auth/login/SocialLogin.tsx b/src/components/auth/login/SocialLogin.tsx index 9ad285d..ae6b218 100644 --- a/src/components/auth/login/SocialLogin.tsx +++ b/src/components/auth/login/SocialLogin.tsx @@ -1,5 +1,5 @@ -import GoogleIcon from '@/assets/icons/signup/google.svg?react' -import KakaoIcon from '@/assets/icons/signup/kakao.svg?react' +import GoogleIcon from '@/assets/icons/auth/google.svg?react' +import KakaoIcon from '@/assets/icons/auth/kakao.svg?react' import Button from '@/components/common/Button' const SocialLogin = () => { @@ -13,13 +13,13 @@ const SocialLogin = () => {
{/* 소셜 로그인 */} -
+
- diff --git a/src/components/auth/onboarding/steps/Step3.tsx b/src/components/auth/onboarding/steps/Step3.tsx index 1a35f27..fc99636 100644 --- a/src/components/auth/onboarding/steps/Step3.tsx +++ b/src/components/auth/onboarding/steps/Step3.tsx @@ -6,7 +6,7 @@ import TagButton from '@/components/common/TagButton' import type { OnboardingFormType } from '@/utils/validate' import { useState } from 'react' import { useFormContext } from 'react-hook-form' -import CheckIcon from '@/assets/icons/signup/check-icon.svg?react' +import CheckIcon from '@/assets/icons/auth/check-icon.svg?react' const skillsTitle = ['디자인', '개발', '기획', '마케팅', '기타'] const skillsDetail: Record = { diff --git a/src/components/common/Accordion.tsx b/src/components/common/Accordion.tsx index b8512c3..921340c 100644 --- a/src/components/common/Accordion.tsx +++ b/src/components/common/Accordion.tsx @@ -1,6 +1,6 @@ import { useRef, useState } from 'react' import { cn } from '@/utils/cn' -import ArrowDownIcon from '@/assets/icons/signup/arrow-down.svg?react' +import ArrowDownIcon from '@/assets/icons/auth/arrow-down.svg?react' import { useOutsideClick } from '@/hooks/useOutsideClick' interface IAccordion { diff --git a/src/components/common/BackButton.tsx b/src/components/common/BackButton.tsx index c3e347f..cc32ca0 100644 --- a/src/components/common/BackButton.tsx +++ b/src/components/common/BackButton.tsx @@ -1,4 +1,4 @@ -import BackButtonIcon from '../../assets/icons/signup/back-button.svg?react' +import BackButtonIcon from '@/assets/icons/auth/back-button.svg?react' interface IBackButton { onClick?: () => void diff --git a/src/components/common/Button.tsx b/src/components/common/Button.tsx index 098aa89..e9949ed 100644 --- a/src/components/common/Button.tsx +++ b/src/components/common/Button.tsx @@ -14,9 +14,9 @@ const Button = ({ size = 'md', color = 'onboarding', fullWidth = false, classNam const base = 'rounded-12 transition-colors duration-300 ease-in-out flex items-center justify-center' const colors = { - auth: 'title-2 bg-primary-500-normal text-neutral-000 disabled:bg-primary-150-light disabled:text-primary-300-light hover:bg-primary-600-normal duration-300 ease-in-out', + auth: 'title-2 bg-primary-500-normal text-neutral-000 font-medium disabled:font-normal disabled:bg-primary-200-light', socialLogin: - 'w-full h-14 title-2 text-neutral-900 py-3.5 border border-neutral-700 flex justify-center items-center gap-2.5 hover:bg-neutral-200 duration-200 ease-in-out', + 'w-full h-14 title-2 text-neutral-900 py-3.5 border border-neutral-300 rounded-12 flex justify-center items-center gap-3', onboarding: 'bg-primary-500-normal text-white hover:bg-primary-600-normal disabled:bg-primary-300-light disabled:text-primary-50-light disabled:cursor-not-allowed', } diff --git a/src/components/common/Input.tsx b/src/components/common/Input.tsx index cc56915..703bdf1 100644 --- a/src/components/common/Input.tsx +++ b/src/components/common/Input.tsx @@ -1,6 +1,6 @@ import { forwardRef } from 'react' import { cn } from '@/utils/cn' -import CheckIcon from '@/assets/icons/signup/check-icon.svg?react' +import CheckIcon from '@/assets/icons/auth/check-icon.svg?react' type InputType = 'auth' | 'onboarding' @@ -16,7 +16,7 @@ const Input = forwardRef( const statusColor = error ? 'text-status-error' : 'text-status-success' const baseStyles = { - auth: 'w-full h-14 px-4 py-3.5 rounded-10 border-[1.5px] border-neutral-200 bg-neutral-100 focus:border-primary-500-normal focus:outline-none title-2 placeholder:text-neutral-300', + auth: 'w-full h-14 px-4 py-3.5 rounded-[12px] border-[1.5px] border-neutral-200 text-neutral-900 bg-neutral-100 focus:border-primary-500-normal focus:outline-none title-2 placeholder:text-neutral-300', onboarding: 'w-75 h-13.5 bg-primary-50-light px-5 py-2.5 rounded-10 border-2 border-primary-200-light focus:border-primary-400-normal focus:outline-none duration-200 ease-in-out placeholder:body-1 placeholder:text-neutral-400 text-neutral-900', } diff --git a/src/hooks/useForm.ts b/src/hooks/useForm.ts index 112674c..dbf1005 100644 --- a/src/hooks/useForm.ts +++ b/src/hooks/useForm.ts @@ -12,9 +12,11 @@ export const useLoginForm = () => { setError, clearErrors, watch, + getValues, } = useForm({ resolver: zodResolver(loginSchema), - mode: 'onChange', + mode: 'onSubmit', + reValidateMode: 'onSubmit', }) return { @@ -27,6 +29,7 @@ export const useLoginForm = () => { setError, clearErrors, watch, + getValues, } } diff --git a/src/index.css b/src/index.css index 1797e5b..2489dd1 100644 --- a/src/index.css +++ b/src/index.css @@ -105,6 +105,8 @@ button:disabled { --color-danger-600: #666666; --color-danger-700: #ec2d30; + --color-social-kakao: #fee500; + --shadow-inner-neutral-1: inset 0 1.3px 3px 0 rgba(228, 228, 228, 0.2), inset 0 3px 6px 0 rgba(228, 228, 228, 0.2); --shadow-inner-neutral-2: inset -1px 2.5px 4px 0 rgba(228, 228, 228, 0.2); --shadow-drop-neutral-1: 0 6px 20px 0 rgba(228, 228, 228, 1); diff --git a/src/pages/auth/LoginPage.tsx b/src/pages/auth/LoginPage.tsx index 9ab45f2..415f594 100644 --- a/src/pages/auth/LoginPage.tsx +++ b/src/pages/auth/LoginPage.tsx @@ -4,7 +4,7 @@ import SocialLogin from '@/components/auth/login/SocialLogin' const LoginPage = () => { return ( -
+
{/* 상단 - 헤더 */} diff --git a/src/utils/validate.ts b/src/utils/validate.ts index c449373..9ff99d7 100644 --- a/src/utils/validate.ts +++ b/src/utils/validate.ts @@ -1,11 +1,10 @@ import { z } from 'zod' -// 로그인 const emailSchema = z .string() - .min(1, '아이디에 @를 포함한 이메일 형식으로 작성해주세요.') - .email('아이디에 @를 포함한 이메일 형식으로 작성해주세요.') -const passwordSchema = z.string().min(6, '') + .min(1, '@를 포함한 이메일 형식의 아이디를 입력해주세요.') + .email('@를 포함한 이메일 형식의 아이디를 입력해주세요.') +const passwordSchema = z.string().min(1, '') // 로그인 스키마 export const loginSchema = z.object({