diff --git a/components/Input.tsx b/components/Input.tsx index 2e177a6..31a4d7f 100644 --- a/components/Input.tsx +++ b/components/Input.tsx @@ -1,4 +1,5 @@ import { useValidation } from 'hooks/useValidation'; +import Image from 'next/image'; import React, { useState } from 'react'; import { format } from 'date-fns'; @@ -15,6 +16,7 @@ interface InputFieldProps { width?: string; onValidation?: (isValid: boolean) => void; ref?: React.Ref; + disabled?: boolean; } function InputField({ @@ -28,6 +30,7 @@ function InputField({ width, onValidation, ref, + disabled, ...props }: InputFieldProps) { const { errorMessage, validate } = useValidation({ @@ -36,6 +39,7 @@ function InputField({ }); const [showDayPicker, setShowDayPicker] = useState(false); + const [showPassword, setShowPassword] = useState(false); const handleFocus = () => { if ( @@ -53,39 +57,34 @@ function InputField({ }; const handleBlur = () => { - if (typeof layout === 'string' && layout === 'vertical') { + if (value) { const error = validate(value); - const isValid = !error && typeof value === 'string' && value.length > 0; + const isValid = !error && value.length > (type === 'name' ? 1 : 0); onValidation?.(isValid); } }; const handleChange = (e: React.ChangeEvent) => { + const newValue = e.target.value.trim(); onChange(e); - if ( - typeof layout === 'string' && - layout === 'vertical' && - typeof errorMessage === 'string' && - errorMessage.length > 0 - ) { - const error = validate(e.target.value); - const isValid = - !error && - typeof e.target.value === 'string' && - e.target.value.length > 0; - onValidation?.(isValid); - } + const error = validate(newValue); + const isValid = !error && newValue.length > (type === 'name' ? 1 : 0); + onValidation?.(isValid); }; const getInputType = () => { if (type === 'name') { return 'text'; - } else if (type === 'passwordConfirm') { - return 'password'; + } else if (type === 'passwordConfirm' || type === 'password') { + return showPassword ? 'text' : 'password'; } return type; }; + const togglePasswordVisibility = () => { + setShowPassword(!showPassword); + }; + //스타일에 따른 클래스 const variantClass = { containerVertical: 'flex flex-col gap-[10px]', @@ -111,7 +110,7 @@ function InputField({ errorMessage.length > 0 ? variantClass.error : variantClass.normal - }`; + } ${disabled ? 'opacity-50 pointer-events-none' : ''}`; return (
0 && ( )} - - {typeof layout === 'string' && - layout === 'vertical' && - typeof errorMessage === 'string' && - errorMessage.length > 0 && ( - {errorMessage} +
+ + {(type === 'password' || type === 'passwordConfirm') && ( + )} +
+ {errorMessage && ( + {errorMessage} + )} {typeof showDayPicker === 'boolean' && showDayPicker && (
diff --git a/hooks/useValidation.tsx b/hooks/useValidation.tsx index 481b21f..9bb3580 100644 --- a/hooks/useValidation.tsx +++ b/hooks/useValidation.tsx @@ -35,7 +35,7 @@ export function useValidation({ type, compareValue }: UseValidationProps) { } break; case 'name': - if (value.length < 1 || value.length > 10) { + if (value.length <= 1 || value.length > 10) { return '1자 이상 10자 이하로 작성해주세요.'; } break; diff --git a/pages/signup/index.tsx b/pages/signup/index.tsx index c6e4808..9cfc62d 100644 --- a/pages/signup/index.tsx +++ b/pages/signup/index.tsx @@ -12,6 +12,7 @@ function SignUp() { const [password, setPassword] = useState(''); const [passwordConfirm, setPasswordConfirm] = useState(''); const [isSubmitting, setIsSubmitting] = useState(false); + const [isCompleted, setIsCompleted] = useState(false); const [name, setName] = useState(''); const [snackbarOpen, setSnackbarOpen] = useState(false); const [snackbarMessage, setSnackbarMessage] = useState(''); @@ -19,10 +20,10 @@ function SignUp() { 'success' ); const [validFields, setValidFields] = useState({ - name: '', - email: '', - password: '', - passwordConfirm: '', + name: false, + email: false, + password: false, + passwordConfirm: false, }); const router = useRouter(); @@ -53,7 +54,7 @@ function SignUp() { const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); - if (isSubmitting || !isFormValid) return; + if (isSubmitting || !isFormValid || isCompleted) return; setIsSubmitting(true); @@ -65,6 +66,7 @@ function SignUp() { name, }); + setIsCompleted(true); // 회원가입 성공 시 스낵바 표시 setSnackbarMessage('회원가입이 완료되었습니다'); setSnackbarSeverity('success'); @@ -106,6 +108,7 @@ function SignUp() { onChange={handleNameChange} placeholder="이름을 입력해 주세요" onValidation={(isValid) => handleValidation('name', isValid)} + disabled={isCompleted} /> handleValidation('email', isValid)} + disabled={isCompleted} /> handleValidation('password', isValid)} + disabled={isCompleted} /> handleValidation('passwordConfirm', isValid) } + disabled={isCompleted} />