내 강좌실 생성11
This commit is contained in:
@@ -7,6 +7,7 @@ import RadioOff from '../../public/svg/radio_off';
|
||||
import RadioOn from '../../public/svg/radio_on';
|
||||
import CheckOff from '../../public/svg/check_off';
|
||||
import CheckOn from '../../public/svg/check_on';
|
||||
import ChevronSmall from '../../public/svg/chevron_small';
|
||||
|
||||
const imgRiCheckboxCircleLine = "http://localhost:3845/assets/e4c498605e2559d2764a3112ae9a9019e6ad798e.svg";
|
||||
const imgFormkitRadio = "http://localhost:3845/assets/ea30a9a80d95ced4bfb1174d3a8475a4a1dbbabb.svg";
|
||||
@@ -46,6 +47,7 @@ export default function RegisterPage() {
|
||||
const [isVerificationSent, setIsVerificationSent] = useState(false);
|
||||
const [isVerificationComplete, setIsVerificationComplete] = useState(false);
|
||||
const [verificationError, setVerificationError] = useState('');
|
||||
const [activeSelect, setActiveSelect] = useState<string | null>(null);
|
||||
|
||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
|
||||
const { name, value } = e.target;
|
||||
@@ -66,6 +68,32 @@ export default function RegisterPage() {
|
||||
setVerificationCode('');
|
||||
setIsVerificationComplete(false);
|
||||
}
|
||||
// 비밀번호 확인 실시간 검증
|
||||
if (name === 'passwordConfirm' && value && formData.password && value !== formData.password) {
|
||||
setErrors((prev) => ({
|
||||
...prev,
|
||||
passwordConfirm: '비밀번호와 일치하지 않아요.',
|
||||
}));
|
||||
} else if (name === 'passwordConfirm' && value && formData.password && value === formData.password) {
|
||||
setErrors((prev) => ({
|
||||
...prev,
|
||||
passwordConfirm: '',
|
||||
}));
|
||||
}
|
||||
// 비밀번호가 변경되면 비밀번호 확인도 다시 검증
|
||||
if (name === 'password' && formData.passwordConfirm) {
|
||||
if (formData.passwordConfirm !== value) {
|
||||
setErrors((prev) => ({
|
||||
...prev,
|
||||
passwordConfirm: '비밀번호와 일치하지 않아요.',
|
||||
}));
|
||||
} else {
|
||||
setErrors((prev) => ({
|
||||
...prev,
|
||||
passwordConfirm: '',
|
||||
}));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handlePhoneChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
@@ -258,7 +286,7 @@ export default function RegisterPage() {
|
||||
name="name"
|
||||
value={formData.name}
|
||||
onChange={handleChange}
|
||||
className={`flex-1 h-[42px] px-[10px] text-[18px] font-medium rounded-[8px] border border-[#b9b9b9] placeholder:text-[#b9b9b9] bg-white ${errors.name ? 'border-[#E85D5D] text-[#E85D5D]' : 'text-[#515151]'}`}
|
||||
className={`flex-1 h-[42px] px-[10px] text-[18px] font-medium rounded-[8px] border placeholder:text-[#b9b9b9] bg-white focus:border-[#1669CA] focus:outline-none ${errors.name ? 'border-[#E85D5D] text-[#E85D5D]' : 'border-[#b9b9b9] text-[#515151]'}`}
|
||||
placeholder="이름을 입력해 주세요."
|
||||
/>
|
||||
</div>
|
||||
@@ -279,7 +307,7 @@ export default function RegisterPage() {
|
||||
value={formData.phone}
|
||||
onChange={handlePhoneChange}
|
||||
maxLength={11}
|
||||
className={`flex-1 h-[42px] px-[10px] text-[18px] font-medium rounded-[8px] border border-[#b9b9b9] placeholder:text-[#b9b9b9] bg-white ${errors.phone ? 'border-[#E85D5D] text-[#E85D5D]' : 'text-[#515151]'}`}
|
||||
className={`flex-1 h-[42px] px-[10px] text-[18px] font-medium rounded-[8px] border placeholder:text-[#b9b9b9] bg-white focus:border-[#1669CA] focus:outline-none ${errors.phone ? 'border-[#E85D5D] text-[#E85D5D]' : 'border-[#b9b9b9] text-[#515151]'}`}
|
||||
placeholder="-없이 입력해 주세요."
|
||||
/>
|
||||
</div>
|
||||
@@ -299,7 +327,7 @@ export default function RegisterPage() {
|
||||
name="email"
|
||||
value={formData.email}
|
||||
onChange={handleChange}
|
||||
className={`h-[42px] px-[10px] text-[18px] font-medium rounded-[8px] border border-[#b9b9b9] placeholder:text-[#b9b9b9] bg-white w-[401px] ${errors.email ? 'border-[#E85D5D] text-[#E85D5D]' : 'text-[#515151]'}`}
|
||||
className={`h-[42px] px-[10px] text-[18px] font-medium rounded-[8px] border placeholder:text-[#b9b9b9] bg-white w-[401px] focus:border-[#1669CA] focus:outline-none ${errors.email ? 'border-[#E85D5D] text-[#E85D5D]' : 'border-[#b9b9b9] text-[#515151]'}`}
|
||||
placeholder="이메일을 입력해 주세요."
|
||||
/>
|
||||
<button
|
||||
@@ -325,7 +353,7 @@ export default function RegisterPage() {
|
||||
type="text"
|
||||
value={verificationCode}
|
||||
onChange={handleVerificationCodeChange}
|
||||
className="h-[42px] px-[10px] text-[18px] font-medium rounded-[8px] border border-[#1669ca] text-[#515151] bg-white w-[401px]"
|
||||
className="h-[42px] px-[10px] text-[18px] font-medium rounded-[8px] border border-[#1669ca] text-[#515151] bg-white w-[401px] focus:border-[#1669CA] focus:outline-none"
|
||||
placeholder="인증번호를 입력해 주세요."
|
||||
/>
|
||||
<button
|
||||
@@ -372,7 +400,7 @@ export default function RegisterPage() {
|
||||
name="password"
|
||||
value={formData.password}
|
||||
onChange={handleChange}
|
||||
className={`flex-1 h-[42px] px-[10px] text-[18px] font-medium rounded-[8px] border border-[#b9b9b9] placeholder:text-[#b9b9b9] bg-white ${errors.password ? 'border-[#E85D5D] text-[#E85D5D]' : 'text-[#515151]'}`}
|
||||
className={`flex-1 h-[42px] px-[10px] text-[18px] font-medium rounded-[8px] border placeholder:text-[#b9b9b9] bg-white focus:border-[#1669CA] focus:outline-none ${errors.password ? 'border-[#E85D5D] text-[#E85D5D]' : 'border-[#b9b9b9] text-[#515151]'}`}
|
||||
placeholder="8~16자의 영문/숫자/특수문자를 조합해서 입력해 주세요."
|
||||
/>
|
||||
</div>
|
||||
@@ -392,11 +420,19 @@ export default function RegisterPage() {
|
||||
name="passwordConfirm"
|
||||
value={formData.passwordConfirm}
|
||||
onChange={handleChange}
|
||||
className={`flex-1 h-[42px] px-[10px] text-[18px] font-medium rounded-[8px] border border-[#b9b9b9] placeholder:text-[#b9b9b9] bg-white ${errors.passwordConfirm ? 'border-[#E85D5D] text-[#E85D5D]' : 'text-[#515151]'}`}
|
||||
className={`flex-1 h-[42px] px-[10px] text-[18px] font-medium rounded-[8px] border placeholder:text-[#b9b9b9] bg-white text-[#000000] focus:outline-none ${formData.passwordConfirm && formData.password && formData.passwordConfirm !== formData.password
|
||||
? 'border-[#E61A1A] focus:border-[#E61A1A]'
|
||||
: errors.passwordConfirm
|
||||
? 'border-[#E85D5D] focus:border-[#1669CA]'
|
||||
: 'border-[#b9b9b9] focus:border-[#1669CA]'
|
||||
}`}
|
||||
placeholder="비밀번호를 다시 입력해 주세요."
|
||||
/>
|
||||
</div>
|
||||
{errors.passwordConfirm && (
|
||||
{formData.passwordConfirm && formData.password && formData.passwordConfirm !== formData.password && (
|
||||
<p className="text-[13px] text-[#E61A1A] ml-[193px] mt-[16px]">비밀번호와 일치하지 않아요.</p>
|
||||
)}
|
||||
{errors.passwordConfirm && formData.passwordConfirm === formData.password && (
|
||||
<p className="text-[13px] text-[#E85D5D] ml-[193px] mt-[16px]">{errors.passwordConfirm}</p>
|
||||
)}
|
||||
</div>
|
||||
@@ -441,55 +477,58 @@ export default function RegisterPage() {
|
||||
name="birthYear"
|
||||
value={formData.birthYear}
|
||||
onChange={handleChange}
|
||||
className="w-full h-[42px] px-[10px] text-[18px] font-medium border border-[#b9b9b9] rounded-[8px] bg-white text-[#515151] appearance-none pr-[30px]"
|
||||
onFocus={() => setActiveSelect('birthYear')}
|
||||
onBlur={() => setActiveSelect(null)}
|
||||
className="w-full h-[42px] px-[10px] pr-[30px] text-[18px] font-medium border border-[#b9b9b9] rounded-[8px] bg-white text-[#515151] appearance-none focus:border-[#1669CA] focus:outline-none"
|
||||
style={{ color: formData.birthYear ? '#515151' : '#b9b9b9' }}
|
||||
>
|
||||
<option value="" className="text-[#b9b9b9]">년도</option>
|
||||
<option value="" style={{ color: '#b9b9b9' }}>년도</option>
|
||||
{[...Array(100)].map((_, idx) => {
|
||||
const year = new Date().getFullYear() - idx;
|
||||
return <option key={year} value={year}>{year}</option>
|
||||
return <option key={year} value={year} style={{ color: '#515151' }}>{year}</option>
|
||||
})}
|
||||
</select>
|
||||
<img
|
||||
src={imgLsiconDownFilled}
|
||||
alt=""
|
||||
className="absolute right-[10px] top-1/2 -translate-y-1/2 w-[16px] h-[16px] pointer-events-none"
|
||||
/>
|
||||
<div className={`absolute right-[10px] top-1/2 -translate-y-1/2 pointer-events-none transition-transform ${activeSelect === 'birthYear' ? 'rotate-180' : ''}`}>
|
||||
<ChevronSmall />
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative flex-1">
|
||||
<select
|
||||
name="birthMonth"
|
||||
value={formData.birthMonth}
|
||||
onChange={handleChange}
|
||||
className="w-full h-[42px] px-[10px] text-[18px] font-medium border border-[#b9b9b9] rounded-[8px] bg-white text-[#515151] appearance-none pr-[30px]"
|
||||
onFocus={() => setActiveSelect('birthMonth')}
|
||||
onBlur={() => setActiveSelect(null)}
|
||||
className="w-full h-[42px] px-[10px] pr-[30px] text-[18px] font-medium border border-[#b9b9b9] rounded-[8px] bg-white text-[#515151] appearance-none focus:border-[#1669CA] focus:outline-none"
|
||||
style={{ color: formData.birthMonth ? '#515151' : '#b9b9b9' }}
|
||||
>
|
||||
<option value="" className="text-[#b9b9b9]">월</option>
|
||||
<option value="" style={{ color: '#b9b9b9' }}>월</option>
|
||||
{[...Array(12)].map((_, idx) => (
|
||||
<option key={idx + 1} value={idx + 1}>{idx + 1}</option>
|
||||
<option key={idx + 1} value={idx + 1} style={{ color: '#515151' }}>{idx + 1}</option>
|
||||
))}
|
||||
</select>
|
||||
<img
|
||||
src={imgLsiconDownFilled}
|
||||
alt=""
|
||||
className="absolute right-[10px] top-1/2 -translate-y-1/2 w-[16px] h-[16px] pointer-events-none"
|
||||
/>
|
||||
<div className={`absolute right-[10px] top-1/2 -translate-y-1/2 pointer-events-none transition-transform ${activeSelect === 'birthMonth' ? 'rotate-180' : ''}`}>
|
||||
<ChevronSmall />
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative flex-1">
|
||||
<select
|
||||
name="birthDay"
|
||||
value={formData.birthDay}
|
||||
onChange={handleChange}
|
||||
className="w-full h-[42px] px-[10px] text-[18px] font-medium border border-[#b9b9b9] rounded-[8px] bg-white text-[#515151] appearance-none pr-[30px]"
|
||||
onFocus={() => setActiveSelect('birthDay')}
|
||||
onBlur={() => setActiveSelect(null)}
|
||||
className="w-full h-[42px] px-[10px] pr-[30px] text-[18px] font-medium border border-[#b9b9b9] rounded-[8px] bg-white text-[#515151] appearance-none focus:border-[#1669CA] focus:outline-none"
|
||||
style={{ color: formData.birthDay ? '#515151' : '#b9b9b9' }}
|
||||
>
|
||||
<option value="" className="text-[#b9b9b9]">일</option>
|
||||
<option value="" style={{ color: '#b9b9b9' }}>일</option>
|
||||
{[...Array(31)].map((_, idx) => (
|
||||
<option key={idx + 1} value={idx + 1}>{idx + 1}</option>
|
||||
<option key={idx + 1} value={idx + 1} style={{ color: '#515151' }}>{idx + 1}</option>
|
||||
))}
|
||||
</select>
|
||||
<img
|
||||
src={imgLsiconDownFilled}
|
||||
alt=""
|
||||
className="absolute right-[10px] top-1/2 -translate-y-1/2 w-[16px] h-[16px] pointer-events-none"
|
||||
/>
|
||||
<div className={`absolute right-[10px] top-1/2 -translate-y-1/2 pointer-events-none transition-transform ${activeSelect === 'birthDay' ? 'rotate-180' : ''}`}>
|
||||
<ChevronSmall />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user