-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #448 from jisurk/part3-우지석-week14
[우지석] Week14
- Loading branch information
Showing
36 changed files
with
2,394 additions
and
954 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
// components/EmailInput.tsx | ||
|
||
import React, { useState, useEffect } from "react"; | ||
import classNames from "classnames/bind"; | ||
import styles from "@/styles/signin.module.scss"; | ||
|
||
interface EmailInputProps { | ||
value: string; | ||
onChange: (value: string) => void; | ||
error?: string; | ||
} | ||
|
||
export const emailCheck = (email: string) => { | ||
const emailForm = | ||
/^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/i; | ||
return emailForm.test(email); | ||
}; | ||
|
||
export function EmailInput({ value, onChange, error }: EmailInputProps) { | ||
const cx = classNames.bind(styles); | ||
const [isFocused, setIsFocused] = useState(false); | ||
const [emailErrorText, setEmailErrorText] = useState(""); | ||
|
||
useEffect(() => { | ||
setEmailErrorText(error || ""); | ||
}, [error]); | ||
|
||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => { | ||
const emailInput = e.target.value; | ||
onChange(emailInput); | ||
}; | ||
|
||
const handleBlur = () => { | ||
setIsFocused(false); | ||
if (value) { | ||
if (!emailCheck(value)) { | ||
setEmailErrorText("올바른 이메일 주소가 아닙니다."); | ||
} else { | ||
setEmailErrorText(""); | ||
} | ||
} else { | ||
setEmailErrorText("이메일을 입력해 주세요."); | ||
} | ||
}; | ||
|
||
const handleFocus = () => { | ||
setIsFocused(true); | ||
}; | ||
|
||
const isError = !isFocused && (error || emailErrorText); | ||
|
||
return ( | ||
<div className={cx("input__section")}> | ||
<label className={cx("text")}> | ||
이메일 <br /> | ||
</label> | ||
<input | ||
id="email" | ||
placeholder="이메일을 입력해 주세요." | ||
className={cx("user-input", { "error-input": isError })} | ||
type="email" | ||
name="email" | ||
value={value} | ||
onChange={handleChange} | ||
onBlur={handleBlur} | ||
onFocus={handleFocus} | ||
/> | ||
<div | ||
id="email-errorText" | ||
className={cx("errortext", { error: !isError })} | ||
> | ||
{emailErrorText} | ||
</div> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import React, { useState } from "react"; | ||
import classNames from "classnames/bind"; | ||
import styles from "@/styles/signin.module.scss"; | ||
|
||
interface PasswordInputProps { | ||
value: string; | ||
onChange: (value: string) => void; | ||
onBlur?: () => void; | ||
error?: string; | ||
id?: string; | ||
} | ||
|
||
export function PasswordInput({ | ||
value, | ||
onChange, | ||
onBlur, | ||
error, | ||
id, | ||
}: PasswordInputProps) { | ||
const cx = classNames.bind(styles); | ||
const [isFocused, setIsFocused] = useState(false); | ||
const [errorText, setErrorText] = useState(""); | ||
|
||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => { | ||
onChange(e.target.value); | ||
}; | ||
|
||
const handleBlur = () => { | ||
setIsFocused(false); | ||
if (onBlur) { | ||
onBlur(); | ||
} | ||
if (!value) { | ||
setErrorText("비밀번호를 입력해 주세요."); | ||
} else { | ||
setErrorText(""); | ||
} | ||
}; | ||
|
||
const handleFocus = () => { | ||
setIsFocused(true); | ||
}; | ||
|
||
const isError = !isFocused && (error || errorText); | ||
|
||
return ( | ||
<div className={cx("input__section", "password-section")}> | ||
<label className={cx("text")}> | ||
비밀번호 <br /> | ||
</label> | ||
<input | ||
id={id || "password"} | ||
placeholder="비밀번호를 입력해 주세요." | ||
className={cx("user-input", { "error-input": isError })} | ||
type="password" | ||
name="password" | ||
value={value} | ||
onChange={handleChange} | ||
onBlur={handleBlur} | ||
onFocus={handleFocus} | ||
/> | ||
<div | ||
id="password-errorText" | ||
className={cx("errortext", { error: !isError })} | ||
> | ||
{error || errorText} | ||
</div> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import React, { useState } from "react"; | ||
import { useRouter } from "next/router"; | ||
import axios from "axios"; | ||
import { EmailInput } from "./EmailInput"; | ||
import { PasswordInput } from "./PasswordInput"; | ||
import styles from "@/styles/signin.module.scss"; | ||
import classNames from "classnames/bind"; | ||
|
||
export function SignIn() { | ||
const cx = classNames.bind(styles); | ||
const [email, setEmail] = useState(""); | ||
const [password, setPassword] = useState(""); | ||
const [emailError, setEmailError] = useState(""); | ||
const [passwordError, setPasswordError] = useState(""); | ||
const router = useRouter(); | ||
const handleSubmit = async (e: React.FormEvent) => { | ||
e.preventDefault(); | ||
setEmailError(""); | ||
setPasswordError(""); | ||
const data = { email, password }; | ||
try { | ||
const response = await axios.post( | ||
"https://bootcamp-api.codeit.kr/api/sign-in", | ||
data | ||
); | ||
if (response.status === 200) { | ||
router.push("/folder"); | ||
} | ||
} catch (error: any) { | ||
if (error.response) { | ||
if (error.response.status === 400) { | ||
setEmailError("이메일을 확인해 주세요."); | ||
setPasswordError("비밀번호를 확인해 주세요."); | ||
} | ||
} | ||
} | ||
}; | ||
return ( | ||
<form className={cx("input")} onSubmit={handleSubmit}> | ||
<EmailInput value={email} onChange={setEmail} error={emailError} /> | ||
<PasswordInput | ||
value={password} | ||
onChange={setPassword} | ||
error={passwordError} | ||
/> | ||
<button type="submit" id="btn" className={cx("signin", "button")}> | ||
로그인 | ||
</button> | ||
</form> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import React, { useState } from "react"; | ||
import { useRouter } from "next/router"; | ||
import axios from "axios"; | ||
import { EmailInput, emailCheck } from "./EmailInput"; | ||
import { SignUpPassword, isValidPassword } from "./SignUpPassword"; | ||
import styles from "@/styles/signup.module.scss"; | ||
import classNames from "classnames/bind"; | ||
|
||
export function SignUp() { | ||
const cx = classNames.bind(styles); | ||
const [email, setEmail] = useState(""); | ||
const [password, setPassword] = useState(""); | ||
const [confirmPassword, setConfirmPassword] = useState(""); | ||
const [emailError, setEmailError] = useState(""); | ||
const router = useRouter(); | ||
|
||
const signUp = async (e: React.FormEvent) => { | ||
e.preventDefault(); | ||
const emailChecked = emailCheck(email); | ||
const validPassword = isValidPassword(password); | ||
const passwordMatch = password === confirmPassword; | ||
|
||
if (emailChecked && validPassword && passwordMatch) { | ||
const checkEmailUrl = "https://bootcamp-api.codeit.kr/api/check-email"; | ||
const checkEmailData = { email }; | ||
try { | ||
const checkEmailResponse = await axios.post( | ||
checkEmailUrl, | ||
checkEmailData | ||
); | ||
if (checkEmailResponse.status === 409) { | ||
setEmailError("이미 사용 중인 이메일입니다."); | ||
console.log("hello~"); | ||
return; | ||
} else { | ||
setEmailError(""); | ||
} | ||
|
||
const signUpUrl = "https://bootcamp-api.codeit.kr/api/sign-up"; | ||
const signUpData = { email, password }; | ||
const signUpResponse = await axios.post(signUpUrl, signUpData); | ||
if (signUpResponse.status === 200) { | ||
router.push("/folder"); | ||
} | ||
} catch (error) { | ||
console.log("Error:", error); | ||
console.log("hello2"); | ||
} | ||
} | ||
}; | ||
|
||
return ( | ||
<form className={cx("signup__form")} onSubmit={signUp}> | ||
<EmailInput value={email} onChange={setEmail} error={emailError} /> | ||
<SignUpPassword | ||
password={password} | ||
confirmPassword={confirmPassword} | ||
onPasswordChange={setPassword} | ||
onConfirmPasswordChange={setConfirmPassword} | ||
/> | ||
<button type="submit" className={cx("signup__button")}> | ||
회원가입 | ||
</button> | ||
</form> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import React, { useState } from "react"; | ||
import { PasswordInput } from "./PasswordInput"; | ||
|
||
interface SignUpPasswordProps { | ||
password: string; | ||
confirmPassword: string; | ||
onBlur?: () => void; | ||
onPasswordChange: (value: string) => void; | ||
onConfirmPasswordChange: (value: string) => void; | ||
} | ||
|
||
export const isValidPassword = (password: string) => { | ||
const passwordForm = /(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$/; | ||
return passwordForm.test(password); | ||
}; | ||
|
||
export function SignUpPassword({ | ||
password, | ||
confirmPassword, | ||
onPasswordChange, | ||
onConfirmPasswordChange, | ||
}: SignUpPasswordProps) { | ||
const [passwordError, setPasswordError] = useState(""); | ||
const [confirmPasswordError, setConfirmPasswordError] = useState(""); | ||
|
||
const validatePassword = () => { | ||
const validPassword = isValidPassword(password); | ||
if (!validPassword) { | ||
setPasswordError("비밀번호는 영문,숫자 조합 8자 이상 입력해 주세요."); | ||
} else { | ||
setPasswordError(""); | ||
} | ||
}; | ||
|
||
const checkPassword = () => { | ||
if (password !== confirmPassword) { | ||
setConfirmPasswordError("비밀번호가 일치하지 않아요."); | ||
} else { | ||
setConfirmPasswordError(""); | ||
} | ||
}; | ||
|
||
return ( | ||
<> | ||
<PasswordInput | ||
value={password} | ||
onChange={onPasswordChange} | ||
onBlur={validatePassword} | ||
error={passwordError} | ||
/> | ||
<PasswordInput | ||
value={confirmPassword} | ||
onChange={onConfirmPasswordChange} | ||
onBlur={checkPassword} | ||
error={confirmPasswordError} | ||
id="password-confirm" | ||
/> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
$(document).ready(function () { | ||
$(".password-section i").on("click", function () { | ||
$("input").toggleClass("active"); | ||
if ($("input").hasClass("active")) { | ||
$(this) | ||
.attr("class", "fa fa-eye-slash fa-lg") | ||
.prev("input") | ||
.attr("type", "text"); | ||
} else { | ||
$(this) | ||
.attr("class", "fa fa-eye fa-lg") | ||
.prev("input") | ||
.attr("type", "password"); | ||
} | ||
}); | ||
}); |
Oops, something went wrong.