728x90
반응형
회원 가입시에 유효성 검사가 많이 없어 추가로 몇가지 구현했습니다
import React, { useState } from 'react';
import { supabase } from 'shared/supabase';
import { Link, useNavigate } from 'react-router-dom';
import { StyledSignup, StyledForm, StyledInput, StyledButton, StyledH1, StyledLabel } from './styles';
interface FormData {
email: string;
password: string;
displayName: string;
}
const isValidConfirmPassword = (password: string, confirmPassword: string) => {
// 비밀번호 확인 검사
return password === confirmPassword;
};
const isValidEmail = (email: string) => {
// 이메일 형식 검사
const re =
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(String(email).toLowerCase());
};
const isValidPassword = (password: string) => {
// 비밀번호 길이 검사
return password.length >= 6;
};
const isValidDisplayName = (displayName: string) => {
// 닉네임 길이 검사
return displayName.length >= 2 && displayName.length <= 10;
};
function Signup() {
const navigate = useNavigate();
const [confirmPassword, setConfirmPassword] = useState('');
const [formData, setFormData] = useState<FormData>({
email: '',
password: '',
displayName: ''
});
const [errors, setErrors] = useState<Record<string, string>>({});
const handleConfirmPasswordChange = (e: React.ChangeEvent<HTMLInputElement>) => {
// 비밀번호 확인 변경 핸들러
setConfirmPassword(e.target.value);
};
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setFormData({
...formData,
[e.target.name]: e.target.value
});
};
const handleSignup = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
if (!isValidEmail(formData.email)) {
alert('유효한 이메일 형식이 아닙니다.');
return;
}
if (!isValidPassword(formData.password)) {
alert('비밀번호는 최소 6자리 이상이어야 합니다.');
return;
}
if (!isValidConfirmPassword(formData.password, confirmPassword)) {
alert('비밀번호와 비밀번호 확인이 일치하지 않습니다.');
return;
}
if (!isValidDisplayName(formData.displayName)) {
alert('닉네임은 최소 2자리, 최대 10자리로 작성해주세요.');
return;
}
try {
const { data, error } = await supabase.auth.signUp({
email: formData.email,
password: formData.password,
options: {
data: {
displayName: formData.displayName
}
}
});
if (error) {
console.error(error.name);
alert('중복된 이메일 입니다 다른 이메일을 사용해주세요');
}
if (error) {
console.error(error);
alert('ID와 password를 확인해주세요');
} else {
console.log(data);
alert('회원가입을 환영합니다');
navigate('/login');
}
} catch (error) {
console.error(error);
alert('An error occurred during signup');
}
};
return (
<StyledSignup>
<StyledH1>회원 가입</StyledH1>
<StyledForm onSubmit={handleSignup}>
{/* <div>
<label htmlFor="displayname">이메일</label>
<input type="displayname" id="displayname" name="displayname" value={formData.displayname} onChange={handleChange} />
{errors.displayname && <p>{errors.displayname}</p>}
</div> */}
<StyledLabel htmlFor="email">이메일</StyledLabel>
<StyledInput
placeholder="이메일"
type="email"
id="email"
name="email"
value={formData.email}
onChange={handleChange}
/>
{errors.email && <p>{errors.email}</p>}
<StyledLabel htmlFor="password">비밀번호</StyledLabel>
<StyledInput
placeholder="비밀번호"
type="password"
id="password"
name="password"
value={formData.password}
onChange={handleChange}
/>
{errors.password && <p>{errors.password}</p>}
<StyledLabel htmlFor="confirmPassword">비밀번호 확인</StyledLabel>
<StyledInput
placeholder="비밀번호 확인"
type="password"
id="confirmPassword"
name="confirmPassword"
value={confirmPassword}
onChange={handleConfirmPasswordChange}
/>
{errors.confirmPassword && <p>{errors.confirmPassword}</p>}
<StyledLabel htmlFor="displayName">닉네임</StyledLabel>
<StyledInput
placeholder="닉네임"
type="text"
id="displayName"
name="displayName"
value={formData.displayName}
onChange={handleChange}
/>
{errors.displayName && <p>{errors.displayName}</p>}
<StyledButton type="submit">가입하기</StyledButton>
</StyledForm>
<Link to="/login">
<StyledButton>로그인 하러 가기</StyledButton>
</Link>
</StyledSignup>
);
}
export default Signup;
수파베이스 signup error 중에 error.name 가 중복 이메일 오류 더군요.튜터님이 유효성 검사를 좀더
세분화 해서 알려줬으면 한다는 피드백이있어 따로 분리해서 alert을 만들었습니다
이렇게 4가지 종류가 더있는데 그냥 error 해놓아도 다 잡긴하지만
ux를 위해서라면 나머지 error.cause error.message error.stack error.status
각 오류마다 따로 alert을 만들어 놓아도 좋을거같습니다


왼쪽은 일단 기능 만들때 대충 만든거였고 오른쪽은 원래 피그마 디자인 처럼 제대로 만들어봤습니다
역시 디자이너....!
import React, { useState } from 'react';
import { supabase } from 'shared/supabase';
import { Link, useNavigate } from 'react-router-dom';
import { StyledSignup, StyledForm, StyledInput, StyledButton, StyledH1, StyledLabel, StInputGroup } from './styles';
interface FormData {
email: string;
password: string;
displayName: string;
}
const isValidPassword = (password: string) => {
// 비밀번호 유효성 검사: 8~16자 영문, 숫자, 특수문자를 조합
const regex = /^(?=.*[A-Za-z])(?=.*\d)(?=.*[$@$!%*#?&])[A-Za-z\d$@$!%*#?&]{8,16}$/;
return regex.test(password);
};
const isValidConfirmPassword = (password: string, confirmPassword: string) => {
// 비밀번호 확인 검사
return password === confirmPassword;
};
const isValidEmail = (email: string) => {
// 이메일 형식 검사
const re =
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(String(email).toLowerCase());
};
const isValidPasswordlength = (password: string) => {
// 비밀번호 길이 검사
return password.length >= 8;
};
const isValidDisplayName = (displayName: string) => {
// 닉네임 길이 검사
return displayName.length >= 2 && displayName.length <= 10;
};
function Signup() {
const navigate = useNavigate();
const [password, setPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');
const [formData, setFormData] = useState<FormData>({
email: '',
password: '',
displayName: ''
});
const [errors, setErrors] = useState<Record<string, string>>({});
const handlePasswordChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setPassword(e.target.value);
};
const handleConfirmPasswordChange = (e: React.ChangeEvent<HTMLInputElement>) => {
// 비밀번호 확인 변경 핸들러
setConfirmPassword(e.target.value);
};
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setFormData({
...formData,
[e.target.name]: e.target.value
});
};
const handleSignup = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
if (!isValidEmail(formData.email)) {
alert('유효한 이메일 형식이 아닙니다.');
return;
}
if (!isValidPassword(formData.password)) {
alert('비밀번호는 8자 이상이며, 영문, 숫자, 특수문자를 모두 포함해야 합니다.');
return;
}
if (!isValidPasswordlength(formData.password)) {
alert('비밀번호는 최소 8자리 이상이어야 합니다.');
return;
}
if (!isValidConfirmPassword(formData.password, confirmPassword)) {
alert('비밀번호와 비밀번호 확인이 일치하지 않습니다.');
return;
}
if (!isValidDisplayName(formData.displayName)) {
alert('닉네임은 최소 2자리, 최대 6자리로 작성해주세요.');
return;
}
try {
const { data, error } = await supabase.auth.signUp({
email: formData.email,
password: formData.password,
options: {
data: {
displayName: formData.displayName
}
}
});
if (error) {
console.error(error.name);
alert('중복된 이메일 입니다 다른 이메일을 사용해주세요');
}
if (error) {
console.error(error);
alert('ID와 password를 확인해주세요');
} else {
console.log(data);
alert('회원가입을 환영합니다');
navigate('/login');
}
} catch (error) {
console.error(error);
alert('An error occurred during signup');
}
};
return (
<StyledSignup>
<StyledH1>회원 가입</StyledH1>
<StyledForm onSubmit={handleSignup}>
<StInputGroup>
{' '}
<StyledLabel htmlFor="displayName">닉네임</StyledLabel>
<StyledInput
placeholder="사용할 닉네임을 적어주세요."
type="text"
id="displayName"
name="displayName"
value={formData.displayName}
onChange={handleChange}
/>
{errors.displayName && <p>{errors.displayName}</p>}
</StInputGroup>
<StInputGroup>
<StyledLabel htmlFor="email">이메일</StyledLabel>
<StyledInput
placeholder="이메일을 입력해 주세요."
type="email"
id="email"
name="email"
value={formData.email}
onChange={handleChange}
/>
{errors.email && <p>{errors.email}</p>}
</StInputGroup>
<StInputGroup>
<StyledLabel htmlFor="password">비밀번호</StyledLabel>
<StyledInput
placeholder="비밀번호를 입력해 주세요."
type="password"
id="password"
name="password"
value={formData.password}
onChange={handleChange}
/>
{errors.password && <p>{errors.password}</p>}
<StyledLabel htmlFor="password">8~16자 영문, 숫자, 특수문자를 조합해 주세요.</StyledLabel>
</StInputGroup>
<StInputGroup>
<StyledLabel htmlFor="confirmPassword">비밀번호 확인</StyledLabel>
<StyledInput
placeholder="비밀번호 확인"
type="password"
id="confirmPassword"
name="confirmPassword"
value={confirmPasswo
유효성 검사를 몇가지 더 추가했는데 정규식은 검색해서 쓰는게 편한거같습니다
728x90
반응형
'Today I Learned (TIL)' 카테고리의 다른 글
24.01.22 최종 프로젝트 중간발표 (1) | 2024.01.22 |
---|---|
24.01.21 (0) | 2024.01.21 |
24.01.19 수파베이스 테이블 정보 업데이트 (0) | 2024.01.19 |
24.01.18 수파 베이스 회원가입 추가 정보 넣기 (0) | 2024.01.18 |
24.01.17 (0) | 2024.01.17 |