Signup.js 10.1 KB
Newer Older
한규민's avatar
한규민 committed
1
import { useState } from "react";
Kim, Subin's avatar
Kim, Subin committed
2
import { Redirect } from "react-router-dom";
한규민's avatar
한규민 committed
3
4
import authApi from "../../apis/auth.api.js";
import catchErrors from "../../utils/catchErrors.js";
Kim, Subin's avatar
Kim, Subin committed
5
import styles from "./signup.module.scss";
한규민's avatar
한규민 committed
6
7

const Signup = () => {
한규민's avatar
한규민 committed
8
    const [user, setUser] = useState({
한규민's avatar
한규민 committed
9
        userId: "",
Kim, Subin's avatar
Kim, Subin committed
10
        userName: "",
한규민's avatar
한규민 committed
11
        userEmail: "",
한규민's avatar
한규민 committed
12
13
14
15
16
        userNickName: "",
        userBirthday: "",
        userMbnum: "",
        userPassword: "",
        userRePassword: ""
17
    })
Kim, Subin's avatar
Kim, Subin committed
18
19
    const [startTime, setStartTime] = useState("");
    const [number, setNumber] = useState(null);
한규민's avatar
한규민 committed
20
21
    const [loading, setLoading] = useState(false);
    const [success, setSuccess] = useState(false);
Kim, Subin's avatar
Kim, Subin committed
22
23

    const [mbError, setMbError] = useState(false);
한규민's avatar
한규민 committed
24
    const [error, setError] = useState("");
한규민's avatar
한규민 committed
25
    const [errorMsg, setErrorMsg] = useState({
Kim, Subin's avatar
Kim, Subin committed
26
27
        errorId: false,
        errorName: false,
한규민's avatar
한규민 committed
28
        errorEmail: false,
한규민's avatar
한규민 committed
29
        errorNickName: false,
한규민's avatar
한규민 committed
30
31
32
33
        errorBirthday: false,
        errorMbnum: false,
        errorPassword: false,
    })
Kim, Subin's avatar
Kim, Subin committed
34
    const [confirmMb, setConfirmMb] = useState(false);
한규민's avatar
한규민 committed
35

36
    const handleUserOnChange = (e) => {
한규민's avatar
한규민 committed
37
38
        setUser({
            ...user,
39
40
            [e.target.name]: e.target.value
        })
한규민's avatar
한규민 committed
41
        if (e.target.name === "userBirthday" || e.target.name === "userMbum") {
한규민's avatar
한규민 committed
42
43
44
45
46
            setUser({
                ...user,
                [e.target.name]: String(e.target.value)
            })
        }
한규민's avatar
한규민 committed
47
    }
48

Kim, Subin's avatar
Kim, Subin committed
49
    const handleOnClickMbnum = async (e) => {
한규민's avatar
한규민 committed
50
        e.preventDefault();
한규민's avatar
한규민 committed
51
        try {
Kim, Subin's avatar
Kim, Subin committed
52
            setStartTime("");
한규민's avatar
한규민 committed
53
            setError("");
Kim, Subin's avatar
Kim, Subin committed
54
55
56
57
58
59
            setLoading(true)
            const phone = user.userMbnum;
            const message = await authApi.confirmMbnum(phone);
            if (message.isSuccess) {
                setMbError("보냄");
                setStartTime(message.startTime);
한규민's avatar
한규민 committed
60
            }
한규민's avatar
한규민 committed
61
        } catch (error) {
Kim, Subin's avatar
Kim, Subin committed
62
            catchErrors(error, setError);
한규민's avatar
한규민 committed
63
        } finally {
한규민's avatar
한규민 committed
64
            setLoading(false);
한규민's avatar
한규민 committed
65
        }
한규민's avatar
한규민 committed
66
67
    }

Kim, Subin's avatar
Kim, Subin committed
68
69
    const handleOnChangeMb = (e) => {
        setNumber(String(e.target.value));
한규민's avatar
한규민 committed
70
71
    }

Kim, Subin's avatar
Kim, Subin committed
72
    const handleOnClickMbConfirm = async (e) => {
한규민's avatar
한규민 committed
73
74
        e.preventDefault();
        try {
Kim, Subin's avatar
Kim, Subin committed
75
76
77
78
79
80
81
82
            setError("");
            setLoading(true);
            const confirmNum = { userMbnum: user.userMbnum, number: number, startTime: startTime };
            const message = await authApi.confirmNum(confirmNum);
            setMbError(message);
            if (message === "성공") {
                setConfirmMb(true);
            }
한규민's avatar
한규민 committed
83
84
85
86
        } catch (error) {
            catchErrors(error, setError);
        } finally {
            setLoading(false);
한규민's avatar
한규민 committed
87
        }
한규민's avatar
signup    
한규민 committed
88
    }
한규민's avatar
한규민 committed
89

Kim, Subin's avatar
Kim, Subin committed
90
91
92
    const validationPw = () => {
        if (user.userPassword !== user.userRePassword) return false;
        else return true;
한규민's avatar
한규민 committed
93
    }
한규민's avatar
한규민 committed
94

Kim, Subin's avatar
Kim, Subin committed
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
    const handleOnSummit = async (e) => {
        e.preventDefault();
        try {
            setError("");
            setLoading(true);
            let validPw = validationPw();
            if (confirmMb) {
                if (validPw) {
                    const userData = user;
                    const error = await authApi.signup(userData);
                    if (error === "성공") setSuccess(true);
                    else {
                        setErrorMsg(error);
                        alert("형식에 맞게 다시 작성해주세요");
                    }
                } else throw new Error("비밀번호가 일치하지 않습니다.");
            } else throw new Error("핸드폰 번호를 인증해주세요.");
        } catch (error) {
            catchErrors(error, setError);
        } finally {
            setLoading(false);
한규민's avatar
한규민 committed
116
        }
한규민's avatar
한규민 committed
117
    }
118

한규민's avatar
한규민 committed
119
120
121
    if (success) {
        return <Redirect to="/login" />;
    }
한규민's avatar
한규민 committed
122

한규민's avatar
한규민 committed
123
    return (
한규민's avatar
한규민 committed
124
        <form className={`d-flex col-md-6 col-12 justify-content-center`} onSubmit={handleOnSummit}>
한규민's avatar
한규민 committed
125
            <div className="d-flex flex-column">
한규민's avatar
signup    
한규민 committed
126
127
128
129
                <span className={styles.title}>회원가입</span>
                <div className="d-flex flex-column">
                    <div className={styles.inputContent}>
                        <label className={styles.signupLabel}>아이디</label>
Kim, Subin's avatar
Kim, Subin committed
130
131
132
133
134
135
136
137
                        <input className={`${styles.input} ${styles.inputSize}`} type="text" name="userId" placeholder="5~10자리 사이" onChange={handleUserOnChange} maxLength="10" />
                    </div>
                    {errorMsg.errorId && <p className={styles.errorMsg}>5~10자리 사이로 입력해주세요.</p>}
                </div>
                <div className="d-flex flex-column">
                    <div className={styles.inputContent}>
                        <label className={styles.signupLabel}>이름</label>
                        <input className={`${styles.input} ${styles.inputSize}`} type="text" name="userName" placeholder="이름을 입력해주세요" onChange={handleUserOnChange} maxLength="20" />
한규민's avatar
한규민 committed
138
                    </div>
Kim, Subin's avatar
Kim, Subin committed
139
                    {errorMsg.errorName && <p className={styles.errorMsg}>이름을 입력해주세요</p>}
140
                </div>
한규민's avatar
한규민 committed
141
142
143
                <div className="d-flex flex-column">
                    <div className={styles.inputContent}>
                        <label className={styles.signupLabel}>이메일</label>
Kim, Subin's avatar
Kim, Subin committed
144
                        <input className={`${styles.input} ${styles.inputSize}`} type="email" name="userEmail" placeholder="이메일을 입력해주세요" onChange={handleUserOnChange} maxLength="20" />
한규민's avatar
한규민 committed
145
                    </div>
Kim, Subin's avatar
Kim, Subin committed
146
                    {errorMsg.errorEmail && <p className={styles.errorMsg}>이메일을 입력해주세요</p>}
한규민's avatar
한규민 committed
147
                </div>
한규민's avatar
한규민 committed
148
149
150
                <div className="d-flex flex-column">
                    <div className={styles.inputContent}>
                        <label className={styles.signupLabel}>별명</label>
Kim, Subin's avatar
Kim, Subin committed
151
                        <input className={`${styles.input} ${styles.inputSize}`} type="text" name="userNickName" placeholder="10자리 이내" onChange={handleUserOnChange} maxLength="20" />
한규민's avatar
한규민 committed
152
                    </div>
Kim, Subin's avatar
Kim, Subin committed
153
                    {errorMsg.errorNickName && <p className={styles.errorMsg}>10 이내로 입력해주세요.</p>}
154
                </div>
한규민's avatar
한규민 committed
155
156
157
                <div className="d-flex flex-column">
                    <div className={styles.inputContent}>
                        <label className={styles.signupLabel}>생년월일</label>
Kim, Subin's avatar
Kim, Subin committed
158
                        <input className={`${styles.input} ${styles.inputSize} ${styles.input.placeholder}`} type="number" name="userBirthday" placeholder="6자리(예시: 991225)" onChange={handleUserOnChange} min="0" max="999999" />
한규민's avatar
한규민 committed
159
                    </div>
Kim, Subin's avatar
Kim, Subin committed
160
                    {errorMsg.errorBirthday && <p className={styles.errorMsg}>숫자 6자리를 입력해주세요.</p>}
161
                </div>
한규민's avatar
한규민 committed
162
163
164
                <div className="d-flex flex-column">
                    <div className={styles.inputContent}>
                        <label className={styles.signupLabel}>휴대폰 번호</label>
한규민's avatar
한규민 committed
165
                        <div className="d-flex col-md-auto">
Kim, Subin's avatar
Kim, Subin committed
166
167
168
169
170
171
172
173
174
175
176
177
178
                            <input className={`${styles.input} ${styles.input2}`} type="number" name="userMbnum" placeholder="-없이 11자리 입력" onChange={handleUserOnChange} min="0" max="99999999999" />
                            <button type="button" disabled={loading} className={`rounded-2 mt-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} data-bs-toggle="collapse" data-bs-target="#collapseExample" aria-expanded="false" aria-controls="collapseExample" onClick={handleOnClickMbnum}>인증번호받기</button>
                        </div>
                    </div>
                    {errorMsg.errorMbnum && <p className={styles.errorMsg}>-없이 숫자 11자리를 입력해주세요.</p>}
                    <div className="collapse" id="collapseExample">
                        <div className="d-flex justify-content-between mt-3">
                            <label className={`${styles.confirm}`}>인증하기</label>
                            <div>
                                <input className={`${styles.input} ${styles.input2}`} type="number" placeholder="인증번호를 입력" onChange={handleOnChangeMb} />
                                <button type="button" className={`rounded-2 py-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} onClick={handleOnClickMbConfirm}>확인</button>
                                <button type="button" className={`rounded-2 py-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} onClick={handleOnClickMbnum}>재전송</button>
                            </div>
한규민's avatar
한규민 committed
179
                        </div>
Kim, Subin's avatar
Kim, Subin committed
180
181
182
183
                        {(mbError === "재전송") && <p className={styles.errorMsg}>유효시간이 만료되었습니다. 재전송해주세요.</p>}
                        {(mbError === "보냄") && <p className={styles.errorMsg}>5분이내에 입력해주세요.</p>}
                        {(mbError === "성공") && <p className={styles.errorMsg}>인증되었습니다.</p>}
                        {(mbError === "실패") && <p className={styles.errorMsg}>인증번호를 다시 입력해주세요.</p>}
한규민's avatar
한규민 committed
184
                    </div>
185
                </div>
한규민's avatar
한규민 committed
186
187
188
                <div className="d-flex flex-column">
                    <div className={`${styles.inputContent}`}>
                        <label className={styles.signupLabel}>비밀번호</label>
Kim, Subin's avatar
Kim, Subin committed
189
                        <input className={`${styles.input} ${styles.inputSize}`} type="password" name="userPassword" placeholder="8~11자리 사이" onChange={handleUserOnChange} maxLength="20" />
한규민's avatar
한규민 committed
190
                    </div>
Kim, Subin's avatar
Kim, Subin committed
191
                    {errorMsg.errorPassword && <p className={styles.errorMsg}>8~11자리 사이로 입력해주세요.</p>}
192
                </div>
Kim, Subin's avatar
Kim, Subin committed
193
194
195
                <div className={`d-flex ${styles.inputContent}`}>
                    <label className={styles.signupLabel}>비밀번호 확인</label>
                    <input className={`${styles.input} ${styles.inputSize}`} type="password" name="userRePassword" placeholder="8~11자리 사이" onChange={handleUserOnChange} maxLength="20" />
한규민's avatar
한규민 committed
196
                </div>
한규민's avatar
한규민 committed
197
                <button className={`rounded my-3 py-2 fs-5 ${styles.butterYellowAndBtn} ${styles.btnHover}`} type="submit" disabled={loading}>가입하기</button>
198
            </div>
한규민's avatar
한규민 committed
199
        </form>
한규민's avatar
한규민 committed
200
201
202
203
    )
}

export default Signup