-
Notifications
You must be signed in to change notification settings - Fork 3
Feat/101/login signup api #106
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
Changes from 6 commits
7343b4b
950aefe
e92d30f
efea2dd
90b90c0
ad5a1db
ebe4eff
41be5f2
25feb82
5b4097e
541da83
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 |
|---|---|---|
|
|
@@ -2,27 +2,33 @@ import { fetchApi } from '@/src/utils/api'; | |
| import { LoginRequest, LoginResponse, SignupRequest, SignupResponse, User } from '@/src/types/auth'; | ||
|
|
||
| export function signupUser(data: SignupRequest): Promise<{ data: SignupResponse }> { | ||
| return fetchApi<{ data: SignupResponse }>('/signup', { | ||
| return fetchApi<{ data: SignupResponse; headers: Headers }>('/auths/signup', { | ||
| method: 'POST', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| }, | ||
| body: JSON.stringify(data), | ||
| }).then((response) => { | ||
| const token = response.headers.get('Authorization'); | ||
| return { data: { token } }; | ||
| }); | ||
| } | ||
|
|
||
| export function loginUser(data: LoginRequest): Promise<{ data: LoginResponse }> { | ||
| return fetchApi<{ data: LoginResponse }>('/login', { | ||
| return fetchApi<{ data: LoginResponse; headers: Headers }>('/auths/login', { | ||
| method: 'POST', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| }, | ||
| body: JSON.stringify(data), | ||
| }).then((response) => { | ||
| const token = response.headers.get('Authorization'); | ||
| return { data: { token } }; | ||
|
Comment on lines
+18
to
+26
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. π οΈ Refactor suggestion μ½λ μ€λ³΅μ μ κ±°νκ³ μ€λ₯ μ²λ¦¬λ₯Ό κ°μ ν΄μΌ ν©λλ€
λ€μκ³Ό κ°μ κ°μ μ μ μν©λλ€:
const extractAuthToken = (headers: Headers) => {
const token = headers.get('Authorization');
if (!token) {
throw new Error('μΈμ¦ ν ν°μ΄ μμ΅λλ€');
}
return token;
};
}).then((response) => {
- const token = response.headers.get('Authorization');
+ const token = extractAuthToken(response.headers);
return { data: { token } };
}); |
||
| }); | ||
| } | ||
|
|
||
| export function getUser(): Promise<{ data: User }> { | ||
| return fetchApi<{ data: User }>('/user/1', { | ||
| return fetchApi<{ data: User }>('/auths/user', { | ||
| method: 'GET', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,36 +1,38 @@ | ||
| import { ApiError } from 'next/dist/server/api-utils'; | ||
| import { useMutation, useQueryClient } from '@tanstack/react-query'; | ||
| import { getUser, loginUser, signupUser } from '@/src/_apis/auth/auth-apis'; | ||
| import { useAuthStore } from '@/src/store/use-auth-store'; | ||
| import { ApiError } from '@/src/utils/api'; | ||
| import { transformKeysToCamel } from '@/src/utils/transform-keys'; | ||
| import { LoginRequest, LoginResponse, SignupRequest, SignupResponse, User } from '@/src/types/auth'; | ||
|
|
||
| export function usePostSignupQuery() { | ||
| const queryClient = useQueryClient(); | ||
| const { login } = useAuthStore(); | ||
| const { login, setUser } = useAuthStore(); | ||
|
|
||
| return useMutation<{ data: SignupResponse }, ApiError, SignupRequest>({ | ||
| mutationFn: signupUser, | ||
| onSuccess: async (response) => { | ||
| // TODO: tokenκ°μΌλ‘ μμ , const { token } = response.data; | ||
| const token = 'dummyToken123'; | ||
| const token = response.data.token?.replace(/^Bearer\s/, ''); | ||
| if (token) await login(token); | ||
|
|
||
| const user: User = await queryClient.fetchQuery(getUserQuery()); | ||
| login(user, token); | ||
| setUser(user); | ||
| }, | ||
| }); | ||
| } | ||
|
|
||
| export function usePostLoginQuery() { | ||
| const queryClient = useQueryClient(); | ||
| const { login } = useAuthStore(); | ||
| const { login, setUser } = useAuthStore(); | ||
|
||
|
|
||
| return useMutation<{ data: LoginResponse }, ApiError, LoginRequest>({ | ||
| mutationFn: loginUser, | ||
| onSuccess: async (response) => { | ||
| // TODO: tokenκ°μΌλ‘ μμ , const { token } = response.data; | ||
| const token = 'dummyToken123'; | ||
| const token = response.data.token?.replace(/^Bearer\s/, ''); | ||
| if (token) await login(token); | ||
|
|
||
| const user: User = await queryClient.fetchQuery(getUserQuery()); | ||
| login(user, token); | ||
| setUser(user); | ||
| }, | ||
| }); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -19,15 +19,13 @@ export default function LoginPage() { | |||||||||||||||||||||||||||||||||||||||||||||||||||
| router.push('/'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| onError: (error) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (error.statusCode === 404) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| setError('email', { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: 'manual', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| message: 'μ΄λ©μΌ κ³μ μ΄ μ‘΄μ¬νμ§ μμ΅λλ€', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else if (error.statusCode === 401) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| setError('password', { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: 'manual', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| message: 'μλͺ»λ λΉλ°λ²νΈμ λλ€', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (error.status === 401) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { validationErrors } = error.detail; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Object.keys(validationErrors).forEach((key) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| setError(key as 'email' | 'password', { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: 'manual', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| message: validationErrors[key], | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (error.status === 401) { | |
| const { validationErrors } = error.detail; | |
| Object.keys(validationErrors).forEach((key) => { | |
| setError(key as 'email' | 'password', { | |
| type: 'manual', | |
| message: validationErrors[key], | |
| }); | |
| if (error.status === 401) { | |
| const validationErrors = error.detail?.validationErrors; | |
| if (validationErrors) { | |
| (Object.entries(validationErrors) as [keyof LoginFormValues, string][]).forEach( | |
| ([field, message]) => { | |
| setError(field, { | |
| type: 'manual', | |
| message, | |
| }); | |
| } | |
| ); | |
| } else { | |
| setError('password', { | |
| type: 'manual', | |
| message: 'λ‘κ·ΈμΈμ μ€ν¨νμ΅λλ€. λ€μ μλν΄ μ£ΌμΈμ.', | |
| }); | |
| } | |
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -14,18 +14,21 @@ export default function LoginPage() { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { mutate: postSignup } = usePostSignupQuery(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const handleSubmit = async (data: SignupFormValues) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| postSignup(data, { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { confirmPassword, ...requestData } = data; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| postSignup(requestData, { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onSuccess: () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| router.push('/'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onError: (error) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (error.statusCode === 400) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // TODO: parameter μ²λ¦¬ ν message μ²λ¦¬ νμΈ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // const { parameter } = error.parameter; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // setError(parameter, { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // type: 'manual', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // message: error.message, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (error.status === 400) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { validationErrors } = error.detail; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Object.keys(validationErrors).forEach((key) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setError(key as 'email', { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: 'manual', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| message: validationErrors[key], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+24
to
+31
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. π οΈ Refactor suggestion μλ¬ μ²λ¦¬ λ‘μ§ κ°μ μ΄ νμν©λλ€ νμ¬ κ΅¬νλ μλ¬ μ²λ¦¬μ λͺ κ°μ§ κ°μ μ΄ νμν©λλ€:
λ€μκ³Ό κ°μ΄ κ°μ νλ κ²μ μ μν©λλ€: if (error.status === 400) {
const { validationErrors } = error.detail;
- Object.keys(validationErrors).forEach((key) => {
- setError(key as 'email', {
- type: 'manual',
- message: validationErrors[key],
- });
- });
+ try {
+ Object.entries(validationErrors).forEach(([key, message]) => {
+ if (key in formMethods.getValues()) {
+ setError(key as keyof SignupFormValues, {
+ type: 'manual',
+ message: String(message),
+ });
+ }
+ });
+ } catch (e) {
+ console.error('μ ν¨μ± κ²μ¬ μλ¬ μ²λ¦¬ μ€ λ¬Έμ κ° λ°μνμ΅λλ€:', e);
+ setError('root', {
+ type: 'manual',
+ message: 'νμκ°μ
μ²λ¦¬ μ€ λ¬Έμ κ° λ°μνμ΅λλ€. λ€μ μλν΄ μ£ΌμΈμ.',
+ });
+ }
+} else {
+ setError('root', {
+ type: 'manual',
+ message: 'μλ² μ€λ₯κ° λ°μνμ΅λλ€. μ μ ν λ€μ μλν΄ μ£ΌμΈμ.',
+ });
}π Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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.
ν ν° μΆμΆ μ μ€λ₯ μ²λ¦¬ λ‘μ§μ΄ νμν©λλ€
νμ¬ κ΅¬νμμλ λ€μκ³Ό κ°μ μ μ¬μ μΈ λ¬Έμ κ° μμ΅λλ€:
λ€μκ³Ό κ°μ΄ κ°μ νλ κ²μ μ μν©λλ€:
}).then((response) => { const token = response.headers.get('Authorization'); + if (!token) { + throw new Error('μΈμ¦ ν ν°μ΄ μμ΅λλ€'); + } return { data: { token } }; });π Committable suggestion