Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/apis/userApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ const userApi = {
: '';
return response;
}),
postUserInfoForSignUp: methodFormat(async ({ userInfo }) => {
postUserInfoForSignUp: methodFormat(async (userInfo) => {
console.log('signup', userInfo);
const options = {
params: {
userId: userInfo.userId,
Expand Down
26 changes: 14 additions & 12 deletions src/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,18 @@ const methodFormat = (callbackfunc: Function) => {
return method;
};

interface IValidationResult<T> {
export interface IValidationResult<T> {
userId: T;
password: T;
username: T;
email: T;
passwordConfirm: T;
}

const validate = (value: string, formType: string) => {
let isValidate = true;
const userIdRegex = /^[a-z][a-z\d]{3,11}$/;
const userIdNumberRegex = /[0-9]/;
const userIdRegex = [/^[a-z]/, /\d/, /^.{3,11}$/];
const passwordRegexArr = [/^.{8,15}$/, /\d/, /[a-zA-Z]/, /[\\*!&]/];
// const usernameRegex = /^[a-z][a-z\d]{2,}$/;
const usernameRegex = /^[ㄱ-ㅎ|ㅏ-ㅣ|가-힣|a-z|0-9]{2,20}$/;
const emailRegex = /^[\w]{4,}@[\w]+(\.[\w]+){1,3}$/;
const errorMessage = {
Expand All @@ -49,17 +48,20 @@ const validate = (value: string, formType: string) => {
username: '닉네임은 2글자 이상입니다.',
email: '이메일 형식이 아닙니다. 다시 입력해주세요.',
};
const validtaionResult: IValidationResult<string | undefined> = {
userId: undefined,
password: undefined,
username: undefined,
email: undefined,
const validtaionResult: IValidationResult<string> = {
userId: '',
password: '',
username: '',
email: '',
passwordConfirm: ''
};

if (formType === 'userId') {
if (!(userIdRegex.test(value) || userIdNumberRegex.test(value))) {
isValidate = false;
}
userIdRegex.forEach((el) => {
if (!el.test(value)) {
isValidate = false;
}
})
}
if (formType === 'password') {
passwordRegexArr.forEach((el) => {
Expand Down
45 changes: 26 additions & 19 deletions src/hooks/useForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,56 +4,63 @@ import userApi from '../apis/userApi';

import { validate } from 'common/utils';

interface InitialValue<T> {
export interface InitialValue<T> {
[index: string]: T | undefined;
userId: T;
username?: T;
phoneNumber?: T;
name?: T;
password: T;
email: T;
passwordConfirm: T;
}

const useForm = (initialValues: InitialValue<string>) => {
const [values, setValues] = useState(initialValues);
const [errors, setErrors] = useState({});
const [errors, setErrors] = useState({
userId: '',
password: '',
username: '',
email: '',
passwordConfirm: ''
});

const handleChange = (
event: ChangeEvent<HTMLInputElement>,
formType: string,
) => {
const { name, value } = event.target;

setValues((prevState) => ({
...prevState,
[name]: value,
}));
setErrors((prevState) => ({
...prevState,
...validate(values[formType], formType),
}));
if (name === 'passwordConfirm' && value !== values.password) setErrors((prev) => ({...prev, [name]: '비밀번호가 일치하지 않습니다.'}))
else setErrors((prev) => ({...prev, [name]: validate(value, name)[name]}));
setValues((prev) => ({...prev, [name]: value }));
};

const handleSubmit = (event: FormEvent) => {
const isValidate = Object.keys(errors).length === 0;
console.log(errors);
const handleSubmit = (e: FormEvent) => {
e.preventDefault()
let isValidate = true;
Object.values(errors).forEach((errorMsg) => {
if (errorMsg !== '') isValidate = false;
})
if (isValidate) {
console.log(values);
userApi
.postUserInfoForSignUp({
userId: values.userId,
userPassword: values.password,
userPasswordCheck: values.passwordConfirm,
userEmail: values.email,
userName: values.name,
userPhoneNumber: values.phoneNumber,
userName: values.username,
userProfileImg: undefined
})
.then((res) => console.log(res))
.catch((err) => console.log(err));
} else {
alert('회원가입 형식이 올바르지 않습니다. 다시 확인해주세요.');
console.log('회원가입 형식이 올바르지 않습니다. 다시 확인해주세요.');
}
event.preventDefault();
};

return {
values,
setValues,
handleChange,
handleSubmit,
errors,
Expand Down
61 changes: 20 additions & 41 deletions src/pages/SignUp/SignUpInput.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { ChangeEvent, useState } from 'react';
import styled, { css } from 'styled-components/macro';

import { type PayloadType } from './index';

import { validate } from 'common/utils';
import { IValidationResult } from 'common/utils';

interface SizeType<T> {
width: T;
Expand All @@ -12,60 +10,41 @@ interface SizeType<T> {
interface Props extends SizeType<string> {
type: string;
title: string;
setText: Function;
formType: string;
reqId: string;
limit: number;
placeholder: string;
}

interface ResultType {
isValid: boolean | undefined;
error: '';
formType: string;
onChange: (e: ChangeEvent<HTMLInputElement>) => void;
errors: IValidationResult<string>;
}

function SignUpInput({
type,
width = '100%',
height = 'auto',
title,
setText,
formType,
reqId,
limit,
placeholder,
formType,
onChange,
errors,
}: Props) {
const [result, setResult] = useState<ResultType>({
isValid: undefined,
error: '',
});
const [count, setCount] = useState(0);

function handleChange(e: ChangeEvent<HTMLInputElement>) {
setCount(e.target.value.length);
const validateResult = validate(e.target.value, formType);
setText((prevState: PayloadType) => ({
...prevState,
[reqId]: e.target.value,
}));

if (validateResult[formType] !== '')
setResult({ isValid: false, error: validateResult[formType] });
else setResult({ isValid: true, error: '' });
if (e.target.value.length === 0)
setResult({ isValid: undefined, error: '' });
}

return (
<StyledWrapper className="signup-input-wrapper">
<Section isValid={result.isValid}>
<Section error={errors[formType]}>
<StyledInput
name={formType}
type={type}
width={width}
height={height}
onChange={(e) => handleChange(e)}
onChange={(e) => {
onChange(e);
setCount(e.target.value.length);
}}
maxLength={limit}
placeholder={placeholder}
autoComplete="off"
/>
<Header>
<span>{title}</span>
Expand All @@ -74,7 +53,7 @@ function SignUpInput({
</span>
</Header>
</Section>
<Description isValid={result.isValid}>{result.error}</Description>
<Description error={errors[formType]}>{errors[formType]}</Description>
</StyledWrapper>
);
}
Expand All @@ -84,17 +63,17 @@ export default SignUpInput;
const StyledWrapper = styled.div`
display: grid;
`;
const Section = styled.div<{ isValid: boolean | undefined }>`
const Section = styled.div<{ error: string }>`
display: grid;
grid-template-rows: 0 1fr;
height: 54.5px;
${(props) => {
switch (props.isValid) {
case true:
switch (props.error.length > 0) {
case false:
return css`
border: 1px solid #cf990c;
`;
case false:
case true:
return css`
border: 1px solid red;
`;
Expand Down Expand Up @@ -142,7 +121,7 @@ const Header = styled.header`
overflow: hidden;
}
`;
const Description = styled.p<{ isValid: boolean | undefined }>`
const Description = styled.p<{ error: string }>`
height: 2vh;
color: #e50303;
font-size: 12px;
Expand Down
Loading