-
Notifications
You must be signed in to change notification settings - Fork 0
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 #2 from TEAM-ALOM/feature/config
config: 폴더 구조 세팅, style 세팅 및 react query jotai 설치 등
- Loading branch information
Showing
53 changed files
with
1,053 additions
and
165 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
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
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,95 @@ | ||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
import axios, { AxiosInstance, type AxiosResponse } from 'axios'; | ||
import { type CommonHttpClient, type CommonHttpResponse } from './httpClient'; | ||
import { | ||
CommonHttpException, | ||
SpecificHttpException, | ||
UnauthorizedException, | ||
UnknownHttpException, | ||
isAuthenticationErrorCode, | ||
isCommonErrorCode, | ||
} from './httpErrors'; | ||
|
||
/** axios config */ | ||
export const axiosClient = axios.create({ | ||
baseURL: import.meta.env.VITE_API_URL, | ||
withCredentials: true, | ||
timeout: 15000, | ||
}); | ||
|
||
/** interceptor config */ | ||
axiosClient.interceptors.response.use( | ||
response => { | ||
return response.data; | ||
}, | ||
error => { | ||
if (axios.isAxiosError(error) && error.response) { | ||
const response = error.response as AxiosResponse< | ||
CommonHttpResponse<unknown> | ||
>; | ||
const errors = response.data.errors; | ||
|
||
// 전역 에러는 첫 에러를 중점으로 처리하기 | ||
const errorCodeOfFisrtError = errors?.[0].errorCode; | ||
|
||
// 인증 에러 | ||
if (isAuthenticationErrorCode(errorCodeOfFisrtError)) { | ||
return Promise.reject( | ||
new UnauthorizedException('UnauthorizedException'), | ||
); | ||
} | ||
|
||
// 글로벌 에러 처리 | ||
if (isCommonErrorCode(errorCodeOfFisrtError)) { | ||
return Promise.reject(new CommonHttpException('CommonHttpException')); | ||
} | ||
|
||
// 각 도메인의 에러 | ||
if (errors) { | ||
return Promise.reject( | ||
new SpecificHttpException('SpecificHttpException', errors), | ||
); | ||
} | ||
} | ||
|
||
// 진짜 알 수 없는 에러 | ||
console.error(error); | ||
return Promise.reject(new UnknownHttpException('UnknownHttpException')); | ||
}, | ||
); | ||
|
||
class CommonHttpAxiosClientImpl implements CommonHttpClient { | ||
constructor(private readonly client: AxiosInstance) {} | ||
|
||
async get<T = any>(url: string, config?: any): Promise<T> { | ||
const response = await this.client.get<T>(url, config); | ||
return response.data; | ||
} | ||
|
||
async post<T = any, D = any>( | ||
url: string, | ||
data?: D, | ||
config?: any, | ||
): Promise<T> { | ||
const response = await this.client.post<T>(url, data, config); | ||
return response.data; | ||
} | ||
|
||
async patch<T = any, D = any>( | ||
url: string, | ||
data?: D, | ||
config?: any, | ||
): Promise<T> { | ||
const response = await this.client.patch<T>(url, data, config); | ||
return response.data; | ||
} | ||
|
||
async delete<T = any>(url: string, config?: any): Promise<T> { | ||
const response = await this.client.delete<T>(url, config); | ||
return response.data; | ||
} | ||
} | ||
|
||
export const httpClient: CommonHttpClient = new CommonHttpAxiosClientImpl( | ||
axiosClient, | ||
); |
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,23 @@ | ||
/** 넓은 타입 정의를 위해 */ | ||
|
||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
import { CommonHttpErrorScheme } from './httpErrors'; | ||
|
||
export type CommonHttpResponseStatus = 'success' | 'fail' | 'error'; | ||
|
||
export interface CommonHttpResponse<T> { | ||
apiVersion: string; | ||
timestamp: string; | ||
status: CommonHttpResponseStatus; | ||
statusCode: number; | ||
message?: string; | ||
errors?: Array<CommonHttpErrorScheme>; | ||
data: T; | ||
} | ||
|
||
export interface CommonHttpClient { | ||
get<T = any>(url: string, config?: any): Promise<T>; | ||
post<T = any, D = any>(url: string, data?: D, config?: any): Promise<T>; | ||
patch<T = any, D = any>(url: string, data?: D, config?: any): Promise<T>; | ||
delete<T = any>(url: string, config?: any): Promise<T>; | ||
} |
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,69 @@ | ||
import { type ValueOf } from '@/utils/types/utilTypes'; | ||
|
||
export type CommonHttpErrorScheme = { | ||
field?: string; | ||
errorCode: CommonHttpErrorCodeType; | ||
message: string; | ||
}; | ||
|
||
export const CommonHttpErrorCode = { | ||
INTERNAL_SERVER_ERROR: 'INTERNAL_SERVER_ERROR', | ||
AUTHENTICATION_ERROR: 'AUTHENTICATION_ERROR', | ||
AUTHORIZATION_ERROR: 'AUTHORIZATION_ERROR', | ||
INVALID_REQUEST: 'INVALID_REQUEST', | ||
RESOURCE_NOT_FOUND: 'RESOURCE_NOT_FOUND', | ||
SERVICE_UNAVAILABLE: 'SERVICE_UNAVAILABLE', | ||
} as const; | ||
|
||
export type CommonHttpErrorCodeType = ValueOf<typeof CommonHttpErrorCode>; | ||
|
||
export type AuthenticationErrorCode = Extract< | ||
CommonHttpErrorCodeType, | ||
'AUTHENTICATION_ERROR' | 'AUTHORIZATION_ERROR' | ||
>; | ||
|
||
export const isCommonErrorCode = ( | ||
errorCode: string | undefined, | ||
): errorCode is CommonHttpErrorCodeType => { | ||
return Object.values(CommonHttpErrorCode).includes(errorCode as never); | ||
}; | ||
|
||
export const isAuthenticationErrorCode = ( | ||
errorCode: string | undefined, | ||
): errorCode is AuthenticationErrorCode => { | ||
return ['AUTHENTICATION_ERROR', 'AUTHORIZATION_ERROR'].includes( | ||
errorCode as never, | ||
); | ||
}; | ||
|
||
// 각 기능에서 사용 될 구분 가능한 http 에러 | ||
export class SpecificHttpException extends Error { | ||
constructor( | ||
message: string, | ||
public errors: Array<CommonHttpErrorScheme>, | ||
) { | ||
super(message); | ||
this.name = 'SpecificHttpException'; | ||
} | ||
} | ||
|
||
export class UnauthorizedException extends Error { | ||
constructor(message: string) { | ||
super(message); | ||
this.name = 'UnauthorizedException'; | ||
} | ||
} | ||
|
||
export class CommonHttpException extends Error { | ||
constructor(message: string) { | ||
super(message); | ||
this.name = 'CommonHttpException'; | ||
} | ||
} | ||
|
||
export class UnknownHttpException extends Error { | ||
constructor(message: string) { | ||
super(message); | ||
this.name = 'UnknownHttpException'; | ||
} | ||
} |
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 @@ | ||
export { httpClient } from './axios.config'; |
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,8 @@ | ||
export type PageParam = { | ||
page: number; | ||
size: number; | ||
}; | ||
|
||
export type PageResponse<T> = { | ||
list: T[]; | ||
} & PageParam; |
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,3 @@ | ||
export const Toast = () => { | ||
return; | ||
}; |
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,45 @@ | ||
import { type ReactNode, useRef } from 'react'; | ||
import { | ||
QueryCache, | ||
QueryClient, | ||
QueryClientProvider, | ||
} from '@tanstack/react-query'; | ||
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; | ||
import { | ||
SpecificHttpException, | ||
UnauthorizedException, | ||
} from '@/configs/http-client/httpErrors'; | ||
|
||
export const QueryProvider = ({ children }: { children: ReactNode }) => { | ||
const queryClient = useRef( | ||
new QueryClient({ | ||
defaultOptions: { | ||
queries: { | ||
staleTime: 1000 * 60 * 5, | ||
gcTime: 1000 * 60 * 10, | ||
refetchOnWindowFocus: false, | ||
refetchOnReconnect: false, | ||
retry: false, | ||
retryOnMount: false, | ||
}, | ||
}, | ||
queryCache: new QueryCache({ | ||
onError: (error: unknown) => { | ||
if (error instanceof UnauthorizedException) { | ||
return; | ||
} | ||
if (error instanceof SpecificHttpException) { | ||
return; | ||
} | ||
}, | ||
}), | ||
}), | ||
); | ||
|
||
return ( | ||
<QueryClientProvider client={queryClient.current}> | ||
<ReactQueryDevtools initialIsOpen={false} /> | ||
{children} | ||
</QueryClientProvider> | ||
); | ||
}; |
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,4 @@ | ||
export interface Store<T> { | ||
get: () => T; | ||
set: (value: T) => void; | ||
} |
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,5 @@ | ||
export type User = { | ||
userName: string; | ||
userId: string; | ||
isAdmin: boolean; | ||
}; |
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,4 @@ | ||
export type UserLoginDto = { | ||
userId: string; | ||
password: string; | ||
}; |
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,5 @@ | ||
export type UserRegisterDto = { | ||
userId: string; | ||
password: string; | ||
userName: string; | ||
}; |
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,5 @@ | ||
export class UserValidationException extends Error { | ||
constructor(message: string) { | ||
super(message); | ||
} | ||
} |
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,3 @@ | ||
export const MAX_USER_NAME_LENGTH = 10; | ||
export const MAX_USER_ID_LENGTH = 10; | ||
export const MIN_USER_PASSWORD_LENGTH = 8; |
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,5 @@ | ||
import { httpClient } from '@/configs/http-client'; | ||
import { User } from '../../models/user'; | ||
|
||
export const API_CHECK_LOGIN = 'v1/auth/check-login'; | ||
export const checkLoginRequest = () => httpClient.post<User>(API_CHECK_LOGIN); |
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,8 @@ | ||
import { httpClient } from '@/configs/http-client'; | ||
import { User } from '../../models/user'; | ||
import { UserLoginDto } from '../../models/userLoginDto'; | ||
|
||
export const API_LOGIN = 'v1/auth/login'; | ||
|
||
export const sendLoginRequest = async (userLoginDto: UserLoginDto) => | ||
httpClient.post<User>(API_LOGIN, userLoginDto); |
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,5 @@ | ||
import { httpClient } from '@/configs/http-client'; | ||
|
||
export const API_LOGOUT = 'v1/auth/logout'; | ||
|
||
export const sendLogoutRequest = async () => httpClient.post(API_LOGOUT); |
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,12 @@ | ||
import { MIN_USER_PASSWORD_LENGTH } from '../models/validationPolicy'; | ||
|
||
export const validatePasswordInput = (password: string) => { | ||
return password.length >= MIN_USER_PASSWORD_LENGTH; | ||
}; | ||
|
||
export const validateRePasswordInput = ( | ||
password: string, | ||
rePassword: string, | ||
) => { | ||
return validatePasswordInput(password) && password === rePassword; | ||
}; |
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,5 @@ | ||
import { MAX_USER_ID_LENGTH } from '../models/validationPolicy'; | ||
|
||
export const validateUserIdInput = (userId: string) => { | ||
return userId.length > 0 && userId.length <= MAX_USER_ID_LENGTH; | ||
}; |
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,5 @@ | ||
import { MAX_USER_NAME_LENGTH } from '../models/validationPolicy'; | ||
|
||
export const validateUserNameInput = (userName: string) => { | ||
return userName.length > 0 && userName.length <= MAX_USER_NAME_LENGTH; | ||
}; |
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,9 @@ | ||
import { type ReactNode } from 'react'; | ||
|
||
export const CardLayout = ({ children }: { children: ReactNode }) => { | ||
return ( | ||
<div className='flex items-center justify-center min-h-screen'> | ||
{children} | ||
</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,33 @@ | ||
import { useState } from 'react'; | ||
import { useInputState } from '@/utils/react/hooks/useInputState'; | ||
import { validatePasswordInput } from '../../services/validatePasswordInput'; | ||
import { validateUserIdInput } from '../../services/validateUserIdInput'; | ||
|
||
export const useLoginFormState = () => { | ||
const [userId, handleUserIdChange] = useInputState(''); | ||
const [password, handlePasswordChange] = useInputState(''); | ||
|
||
const isUserIdValid = validateUserIdInput(userId); | ||
const isPasswordValid = validatePasswordInput(password); | ||
|
||
const isFormValid = isUserIdValid && isPasswordValid; | ||
const [isFormDirty, setIsFormDirty] = useState<boolean>(false); | ||
|
||
return { | ||
userId: { | ||
value: userId, | ||
onChange: handleUserIdChange, | ||
isValid: isUserIdValid, | ||
}, | ||
password: { | ||
value: password, | ||
onChange: handlePasswordChange, | ||
isValid: isPasswordValid, | ||
}, | ||
form: { | ||
isValid: isFormValid, | ||
isDirty: isFormDirty, | ||
setIsDirty: setIsFormDirty, | ||
}, | ||
} as const; | ||
}; |
Oops, something went wrong.