Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 3 additions & 46 deletions src/apis/http.api.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,9 @@
import axios, { AxiosRequestConfig } from 'axios';

const BASE_URL = import.meta.env.VITE_API_BASE_URL;
const DEFAULT_TIMEOUT = 30000; // 요청 제한 시간

// 토큰 관리 함수
function getToken(): string | null {
return localStorage.getItem('token');
}

function setToken(token: string) {
localStorage.setItem('token', token);
}
import { getToken, removeToken } from '@/utils/token';

function removeToken() {
localStorage.removeItem('token');
}
export const BASE_URL = import.meta.env.VITE_API_BASE_URL;
const DEFAULT_TIMEOUT = 30000; // 요청 제한 시간

export const createClient = (config?: AxiosRequestConfig) => {
const token = getToken(); // 토큰 가져오기
Expand Down Expand Up @@ -61,35 +50,3 @@ export const createClient = (config?: AxiosRequestConfig) => {
};

export const httpClient = createClient();

// 토큰 관련 함수 export
export { setToken, removeToken, getToken };

// 공통 요청 부분

type RequestMethod = 'get' | 'post' | 'put' | 'delete';

export const requestHandler = async <R = undefined, T = undefined>(
method: RequestMethod,
url: string,
payload?: T
) => {
let response;

switch (method) {
case 'post':
response = await httpClient.post<R>(url, payload);
break;
case 'get':
response = await httpClient.get<R>(url);
break;
case 'put':
response = await httpClient.put<R>(url, payload);
break;
case 'delete':
response = await httpClient.delete<R>(url);
break;
}

return response.data;
};
5 changes: 2 additions & 3 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const Header = () => {
const navigate = useNavigate();

const handleLogoClick = () => {
navigate('/'); // 메인 페이지로 이동
navigate('/');
};

return (
Expand Down Expand Up @@ -38,7 +38,6 @@ const HeaderWrapper = styled.div`
justify-content: space-between;
`;

// 클릭 가능한 스타일을 추가한 로고
const Logo = styled.img`
cursor: pointer; // 커서를 클릭 가능한 손가락 모양으로 변경
cursor: pointer;
`;
13 changes: 5 additions & 8 deletions src/components/MenuButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useNavigate } from 'react-router';
import { logout } from '@/hooks/userSlice';
import { useSelector, useDispatch } from 'react-redux';
import { RootState } from '@/store/rootReducer';
import { removeToken } from '@/apis/http.api';
import { removeToken } from '@/utils/token';

const MenuButton = () => {
const [isOpen, setIsOpen] = useState(false);
Expand All @@ -17,17 +17,17 @@ const MenuButton = () => {
const role = useSelector((state: RootState) => state.user.userInfo?.role);

const handleMyPage = () => {
setIsOpen(false); // 드롭다운 먼저 닫기
setIsOpen(false);
navigate('/mypage');
};

const handleAdminPage = () => {
setIsOpen(false); // 드롭다운 먼저 닫기
setIsOpen(false);
navigate('/adminpage');
};

const handleLogin = () => {
setIsOpen(false); // 드롭다운 먼저 닫기
setIsOpen(false);
navigate('/login');
};

Expand All @@ -48,7 +48,6 @@ const MenuButton = () => {

return (
<DropdownContainer>
{/* 햄버거 버튼 */}
<Button onClick={toggleMenu}>
{isOpen ? (
<XMarkIcon className='icon' />
Expand All @@ -57,13 +56,12 @@ const MenuButton = () => {
)}
</Button>

{/* 드롭다운 메뉴 */}
{isOpen && (
<DropdownMenu>
<ul>
<li
onClick={() => {
setIsOpen(false); // 드롭다운 먼저 닫기
setIsOpen(false);
if (isLoggedIn) {
role === 'admin'
? navigate('/adminpage')
Expand All @@ -73,7 +71,6 @@ const MenuButton = () => {
}
}}
>
{/* 아바타 표시 */}
<AvatarContainer>
<Avatar
src={
Expand Down
13 changes: 5 additions & 8 deletions src/hooks/userSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { DecodedToken, UserInfo, UserState } from '@/types/auth';
import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit';
import axios from 'axios';
import { jwtDecode } from 'jwt-decode';
import { BASE_URL } from '@/apis/http.api';

const initialState: UserState = {
isLoggedIn: false,
Expand All @@ -12,21 +13,17 @@ const initialState: UserState = {
error: null,
};

// 실제 서버에 로그인 요청을 보내고 토큰을 받아오는 thunk
export const loginAsync = createAsyncThunk(
'user/loginAsync',
async (
{ email, password }: { email: string; password: string },
{ rejectWithValue }
) => {
try {
const response = await axios.post(
'http://localhost:3333/api/users/login',
{
email,
password,
}
);
const response = await axios.post(`${BASE_URL}/api/users/login`, {
email,
password,
});

if (response.data.success && response.data.token) {
return response.data.token;
Expand Down
8 changes: 4 additions & 4 deletions src/pages/JoinPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,18 @@ function JoinPage() {
watch,
} = useForm<JoinProps>();

const password = watch('password'); // PasswordGuideLines에서 실시간 사용
const password = watch('password');

const onSubmit = async (data: JoinProps) => {
setIsLoading(true);
try {
await join(data); // 회원가입 요청
await join(data);
alert('회원가입이 완료되었습니다!');
navigate('/login'); // 로그인 페이지로 이동
navigate('/login');
} catch (error: any) {
console.error('회원가입 중 에러 발생:', error);
if (error.response?.data?.message) {
alert(error.response.data.message); // 서버에서 반환된 에러 메시지 표시
alert(error.response.data.message);
} else {
alert('회원가입에 실패했습니다. 다시 시도해주세요.');
}
Expand Down
2 changes: 0 additions & 2 deletions src/pages/LoginPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ function LoginPage() {
}
};

// 로그인 상태 확인 후 리다이렉트 처리

return (
<Container>
<InnerWrapper>
Expand Down
13 changes: 6 additions & 7 deletions src/utils/token.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
// 로컬스토리지에서 토큰 가져오기
export const getToken = (): string | null => {
export function getToken(): string | null {
return localStorage.getItem('token');
};
}

export const setToken = (token: string) => {
export function setToken(token: string) {
localStorage.setItem('token', token);
};
}

export const removeToken = () => {
export function removeToken() {
localStorage.removeItem('token');
};
}