-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[권주현] Week19 #493
The head ref may contain hidden characters: "part3-\uAD8C\uC8FC\uD604-tanstack"
[권주현] Week19 #493
Changes from all commits
c104336
6d4f19c
fd621f1
e46f767
2ee2123
5a34214
45fcff1
bda92f4
1112228
79b0587
5cc47fb
27be6a7
5623f94
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,4 @@ | ||
import { CODEIT_BASE_URL } from "@/constants"; | ||
import { FormValues } from "./common/Auth/Form"; | ||
import { | ||
FolderData, | ||
LinkData, | ||
Comment on lines
3
to
4
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 타입 또는 인터페이스를 선언할 때, 해당 타입들이 특정 데이터의 타입임을 표현하고 있는데요. |
||
|
@@ -9,6 +8,7 @@ import { | |
Response, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NextJS에서 이미 서버 리스폰스 객체를 위한 Response라는 예약어가 사용되고 있을텐데요, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 예약어는 NextResponse로 설정되어 있어 충돌은 없지만 Response라는 단어가 너무 포괄적인 단어라 수정해야 할 듯 합니다. |
||
UserData, | ||
} from "./types/api"; | ||
import { FormValues } from "./types/form"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 앞으로 form value들이 굉장히 다양하게 존재하게 될 텐데요. |
||
|
||
interface TokenProp { | ||
token: string; | ||
|
@@ -134,70 +134,72 @@ export async function getLinksByFolderId({ | |
|
||
// POST | ||
|
||
export async function postEmailCheck(email: string): Promise<void | string> { | ||
const response = await fetch(`${CODEIT_BASE_URL}/check-email`, { | ||
export async function postEmailCheck(email: string): Promise<boolean | string> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 크게 프로젝트 아키텍쳐를 레이어로 나누어보면, 네트워크 요청을 전담하는 controller layer와 비즈니스 로직을 담당하는 service layer, 그리고 결과물을 사용자에게 보여주고 ui interaction을 처리하는 ui layer로 구분해볼 수 있어요. 여기서 지금 작성된 코드를 살펴보면, ui 레이어에서 바로 필요한 데이터를 받아와 활용하기 어려워보여요. |
||
const response = await fetch(`${CODEIT_BASE_URL}/users/check-email`, { | ||
method: "POST", | ||
headers: { | ||
"Content-Type": "application/json", | ||
}, | ||
body: JSON.stringify({ email }), | ||
}); | ||
const result = await response.json(); | ||
|
||
if (response.status === 409) { | ||
const data = await response.json(); | ||
return data.error.message; | ||
return result.message; | ||
} | ||
|
||
if (!response.ok) { | ||
throw new Error("잘못된 요청입니다."); | ||
} | ||
|
||
return; | ||
return result; | ||
} | ||
|
||
interface postData { | ||
data: { | ||
accessToken: string; | ||
refreshToken: string; | ||
}; | ||
data: | ||
| { | ||
accessToken: string; | ||
refreshToken: string; | ||
} | ||
| { message: string }; | ||
} | ||
Comment on lines
158
to
165
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kuum97 또한, 서버에서 반환되는 응답이 data type이거나 오류인경우 message: string으로 반환된다면, 이를 공통적으로 활용할 수 있는 |
||
|
||
export async function postSignup({ | ||
email, | ||
password, | ||
}: FormValues): Promise<postData> { | ||
const response = await fetch(`${CODEIT_BASE_URL}/sign-up`, { | ||
}: FormValues): Promise<postData | void> { | ||
const response = await fetch(`${CODEIT_BASE_URL}/auth/sign-up`, { | ||
method: "POST", | ||
headers: { | ||
"Content-Type": "application/json", | ||
}, | ||
body: JSON.stringify({ email, password }), | ||
}); | ||
const data = await response.json(); | ||
|
||
if (!response.ok) { | ||
return data.error.message; | ||
throw new Error("잘못된 요청입니다."); | ||
} | ||
|
||
return data; | ||
} | ||
Comment on lines
167
to
182
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. success 여부에 따라 응답을 반환해주어 ui layer에서 성공적인지 아닌지를 명시적으로 활용할 수 있도록 해주는게 좋아요. 또한 |
||
|
||
export async function postSignin({ | ||
email, | ||
password, | ||
}: FormValues): Promise<postData> { | ||
const response = await fetch(`${CODEIT_BASE_URL}/sign-in`, { | ||
const response = await fetch(`${CODEIT_BASE_URL}/auth/sign-in`, { | ||
method: "POST", | ||
headers: { | ||
"Content-Type": "application/json", | ||
}, | ||
body: JSON.stringify({ email, password }), | ||
}); | ||
const data = await response.json(); | ||
|
||
if (!response.ok) { | ||
return data.error.message; | ||
throw new Error("잘못된 요청입니다."); | ||
} | ||
|
||
return data; | ||
const result = await response.json(); | ||
|
||
return result; | ||
} | ||
|
||
// 탠스택 쿼리와 미들웨어 api 라우트 구현 |
This file was deleted.
This file was deleted.
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import { useForm } from "react-hook-form"; | ||
import useSignin from "@/hooks/auth/useSignin"; | ||
import { useStoreState } from "@/hooks/state"; | ||
import classNames from "classnames"; | ||
import { FormValues } from "@/types/form"; | ||
import { EMAIL_PATTERN, PW_PATTERN } from "@/constants"; | ||
import { FaEye, FaEyeSlash } from "react-icons/fa"; | ||
import styles from "../Form.module.css"; | ||
|
||
Comment on lines
+5
to
+9
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. absolute path로 import하기로 경정했다면, 모든 요소들에 대해 absolute import를 해주세요 |
||
function SigninForm() { | ||
const { | ||
register, | ||
handleSubmit, | ||
formState: { errors }, | ||
} = useForm<FormValues>({ mode: "onBlur" }); | ||
const { currentType, toggleType } = useStoreState(); | ||
const { handleSignin } = useSignin(); | ||
|
||
return ( | ||
<form | ||
className={styles.formContainer} | ||
onSubmit={handleSubmit(handleSignin)} | ||
> | ||
<div className={styles.inputContainer}> | ||
<label className={styles.inputLabel} htmlFor="email"> | ||
이메일 | ||
</label> | ||
<input | ||
id="email" | ||
type="text" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kuum97 |
||
placeholder="이메일을 입력해 주세요" | ||
className={classNames(styles.inputWrapper, { | ||
[styles.errorBorder]: errors.email, | ||
})} | ||
{...register("email", { | ||
required: "이메일을 입력해 주세요", | ||
pattern: { | ||
value: EMAIL_PATTERN, | ||
message: "올바른 형식의 이메일을 입력해 주세요", | ||
}, | ||
})} | ||
/> | ||
{errors.email && ( | ||
<p className={styles.errorMessage}>{errors.email.message}</p> | ||
)} | ||
</div> | ||
<div className={styles.inputContainer}> | ||
<label className={styles.inputLabel} htmlFor="password"> | ||
비밀번호 | ||
</label> | ||
<input | ||
id="password" | ||
type={currentType} | ||
placeholder="영문, 숫자를 조합해 8자 이상 입력해 주세요" | ||
className={classNames(styles.inputWrapper, { | ||
[styles.errorBorder]: errors.password, | ||
})} | ||
{...register("password", { | ||
required: "비밀번호를 입력해 주세요", | ||
pattern: { | ||
value: PW_PATTERN, | ||
message: "영문, 숫자를 조합해 8자 이상 입력해 주세요", | ||
}, | ||
})} | ||
/> | ||
{errors.password && ( | ||
<p className={styles.errorMessage}>{errors.password.message}</p> | ||
)} | ||
<button className={styles.eyeIcon} type="button" onClick={toggleType}> | ||
{currentType === "password" ? <FaEye /> : <FaEyeSlash />} | ||
</button> | ||
</div> | ||
<button className={styles.submitButton}>로그인</button> | ||
</form> | ||
); | ||
} | ||
|
||
export default SigninForm; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
api 요청 경로 변경 코드입니다.