Skip to content

Commit f9abb87

Browse files
authored
Merge pull request #74 from oodd-team/feat/OD-67
[OD-67] 로그인 여부에 따른 로그인 페이지로 리디렉션 구현
2 parents 2176e4d + 455c969 commit f9abb87

8 files changed

Lines changed: 202 additions & 39 deletions

File tree

src/App.tsx

Lines changed: 72 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,92 @@
11
import React from 'react';
2-
import { BrowserRouter, Route, Routes } from 'react-router-dom';
2+
import { BrowserRouter, Route, Routes, Navigate } from 'react-router-dom';
33
import Home from './pages/Home';
4+
import Login from './pages/Login';
5+
import SignUp from './pages/SignUp';
6+
import LoginComplete from './pages/Login/components/LoginComplete';
7+
import TermsAgreement from './pages/TermsAgreement';
8+
import KakaoCallback from './pages/Login/components/Kakao/KakaoCallback';
9+
import NaverCallback from './pages/Login/components/Naver/NaverCallback';
10+
411
import MyPage from './pages/MyPage';
5-
import MyPost from './pages/MyPost';
612
import ProfileEdit from './pages/ProfileEdit';
713
import AccountSetting from './pages/AccountSetting';
814
import AccountEdit from './pages/AccountEdit';
915
import AccountCancel from './pages/AccountCancel';
1016
import Verification from './pages/verification';
11-
import Login from './pages/Login';
12-
import SignUp from './pages/SignUp';
17+
1318
import ProfileViewer from './pages/ProfileViewer';
14-
import Chats from './pages/Chats';
15-
import ChatRoom from './pages/Chats/ChatRoom';
19+
20+
import Post from './pages/Post';
21+
import MyPost from './pages/MyPost';
22+
import PostUpload from './pages/PostUpload';
1623
import PostImageSelect from './pages/PostImageSelect';
1724
import PostInstaConnect from './pages/PostInstaConnect';
1825
import PostInstaFeedSelect from './pages/PostInstaFeedSelect';
19-
import PostUpload from './pages/PostUpload';
20-
import Post from './pages/Post';
21-
import KakaoCallback from './pages/Login/components/Kakao/KakaoCallback';
22-
import NaverCallback from './pages/Login/components/Naver/NaverCallback';
23-
import LoginComplete from './pages/Login/components/LoginComplete';
24-
import TermsAgreement from './pages/TermsAgreement';
26+
27+
import Chats from './pages/Chats';
28+
import ChatRoom from './pages/Chats/ChatRoom';
29+
30+
import NotFound from './pages/NotFound';
31+
32+
const ProtectedRoute = ({ children }: { children: JSX.Element }) => {
33+
const isAuthenticated = Boolean(localStorage.getItem('new_jwt_token'));
34+
return isAuthenticated ? children : <Navigate to="/login" />;
35+
};
36+
37+
// 인증이 필요한 페이지 배열
38+
const protectedRoutes = [
39+
{ path: '/', element: <Home /> },
40+
41+
// 사용자 프로필 및 계정 관리
42+
{ path: '/mypage', element: <MyPage /> },
43+
{ path: '/profile/edit', element: <ProfileEdit /> },
44+
{ path: '/account-setting', element: <AccountSetting /> },
45+
{ path: '/account-edit', element: <AccountEdit /> },
46+
{ path: '/account-cancel', element: <AccountCancel /> },
47+
{ path: '/verification', element: <Verification /> },
48+
{ path: '/users/:userId', element: <ProfileViewer /> },
49+
50+
{ path: '/post/:postId', element: <Post /> },
51+
{ path: '/my-post/:postId', element: <MyPost /> },
52+
{ path: '/upload', element: <PostUpload /> },
53+
{ path: '/image-select', element: <PostImageSelect /> },
54+
{ path: '/insta-connect', element: <PostInstaConnect /> },
55+
{ path: '/insta-feed-select', element: <PostInstaFeedSelect /> },
56+
57+
// 메시지/채팅
58+
{ path: '/chats', element: <Chats /> },
59+
{ path: '/chats/:chatRoomId', element: <ChatRoom /> },
60+
];
61+
62+
// 인증이 필요 없는 페이지 배열
63+
const publicRoutes = [
64+
{ path: '/login', element: <Login /> },
65+
{ path: '/signup', element: <SignUp /> },
66+
{ path: '/login/complete', element: <LoginComplete /> },
67+
{ path: '/terms-agreement', element: <TermsAgreement /> },
68+
69+
// 콜백
70+
{ path: '/auth/kakao/callback', element: <KakaoCallback /> },
71+
{ path: '/auth/naver/callback', element: <NaverCallback /> },
72+
];
2573

2674
const App: React.FC = () => {
2775
return (
2876
<BrowserRouter>
2977
<Routes>
30-
<Route path="/" element={<Home />} />
31-
<Route path="/chats/:chatRoomId" element={<ChatRoom />} />
32-
<Route path="/mypage" element={<MyPage />} />
33-
<Route path="/my-post/:postId" element={<MyPost />} />
34-
<Route path="/profile/edit" element={<ProfileEdit />} />
35-
<Route path="/account-setting" element={<AccountSetting />} />
36-
37-
<Route path="/account-edit" element={<AccountEdit />} />
38-
<Route path="/account-cancel" element={<AccountCancel />} />
39-
<Route path="/Verification" element={<Verification />} />
40-
41-
<Route path="/login" element={<Login />} />
42-
<Route path="/login/complete" element={<LoginComplete />}></Route>
43-
<Route path="/terms-agreement" element={<TermsAgreement />} />
44-
<Route path="/chats" element={<Chats />} />
45-
46-
<Route path="/image-select" element={<PostImageSelect />} />
47-
<Route path="/insta-connect" element={<PostInstaConnect />} />
48-
<Route path="/insta-feed-select" element={<PostInstaFeedSelect />} />
49-
<Route path="/upload" element={<PostUpload />} />
50-
51-
<Route path="/post/:postId" element={<Post />} />
52-
<Route path="/users/:userId" element={<ProfileViewer />} />
53-
<Route path="signup" element={<SignUp />} />
54-
55-
<Route path="/auth/kakao/callback" element={<KakaoCallback />}></Route>
56-
<Route path="/auth/naver/callback" element={<NaverCallback />}></Route>
78+
{/* 인증이 필요한 페이지 */}
79+
{protectedRoutes.map(({ path, element }) => (
80+
<Route key={path} path={path} element={<ProtectedRoute>{element}</ProtectedRoute>} />
81+
))}
82+
83+
{/* 인증이 필요 없는 페이지 */}
84+
{publicRoutes.map(({ path, element }) => (
85+
<Route key={path} path={path} element={element} />
86+
))}
87+
88+
{/* 없는 페이지에 대한 처리 */}
89+
<Route path="*" element={<NotFound />} />
5790
</Routes>
5891
</BrowserRouter>
5992
);
Lines changed: 5 additions & 0 deletions
Loading
Lines changed: 7 additions & 0 deletions
Loading

src/pages/NotFound/index.tsx

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { useNavigate } from 'react-router-dom';
2+
import { OODDFrame } from '../../components/Frame/Frame';
3+
import { NotFoundContainer, TextContainer, ButtonContainer, StyledButton } from './styles';
4+
import { StyledText } from '../../components/Text/StyledText';
5+
import theme from '../../styles/theme';
6+
7+
const NotFound = () => {
8+
const navigate = useNavigate();
9+
10+
return (
11+
<OODDFrame>
12+
<NotFoundContainer>
13+
<TextContainer>
14+
<StyledText $textTheme={{ style: 'display1-bold' }} color={theme.colors.pink3}>
15+
404 ERROR
16+
</StyledText>
17+
<StyledText $textTheme={{ style: 'headline2-medium' }}>죄송합니다. 페이지를 찾을 수 없습니다.</StyledText>
18+
<div>
19+
<StyledText $textTheme={{ style: 'body2-regular' }}>페이지의 주소가 잘못 입력되었거나,</StyledText>
20+
<StyledText $textTheme={{ style: 'body2-regular' }}>
21+
요청하신 페이지의 주소가 변경, 삭제되어 찾을 수 없습니다.
22+
</StyledText>
23+
</div>
24+
</TextContainer>
25+
<ButtonContainer>
26+
<StyledButton as="a" href="/" $textTheme={{ style: 'body2-regular' }} color={theme.colors.pink3}>
27+
메인으로
28+
</StyledButton>
29+
<StyledButton
30+
as="button"
31+
onClick={() => navigate(-1)}
32+
className="prev"
33+
$textTheme={{ style: 'body2-regular' }}
34+
color={theme.colors.white}
35+
>
36+
이전으로
37+
</StyledButton>
38+
</ButtonContainer>
39+
</NotFoundContainer>
40+
</OODDFrame>
41+
);
42+
};
43+
44+
export default NotFound;

src/pages/NotFound/styles.tsx

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import styled from 'styled-components';
2+
import { StyledText } from '../../components/Text/StyledText';
3+
4+
export const NotFoundContainer = styled.div`
5+
display: flex;
6+
height: 80%;
7+
flex-direction: column;
8+
justify-content: center;
9+
align-items: center;
10+
`;
11+
12+
export const TextContainer = styled.div`
13+
display: flex;
14+
flex-direction: column;
15+
justify-content: center;
16+
align-items: center;
17+
gap: 10px;
18+
19+
div {
20+
display: flex;
21+
flex-direction: column;
22+
justify-content: center;
23+
align-items: center;
24+
}
25+
`;
26+
27+
export const ButtonContainer = styled.div`
28+
display: flex;
29+
flex-direction: row;
30+
justify-content: center;
31+
align-items: center;
32+
gap: 16px;
33+
margin: 20px;
34+
`;
35+
36+
export const StyledButton = styled(StyledText)`
37+
display: inline-block;
38+
text-align: center;
39+
padding: 6px 16px;
40+
border: 1px solid ${({ theme }) => theme.colors.pink3};
41+
border-radius: 8px;
42+
cursor: pointer;
43+
text-decoration: none;
44+
45+
&.prev {
46+
background-color: ${({ theme }) => theme.colors.pink3};
47+
color: ${({ theme }) => theme.colors.white};
48+
}
49+
`;

src/recoil/Home/FeedsAtom.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { atom } from 'recoil';
2+
import { PostSummary } from '../../apis/post/dto';
3+
4+
export const FeedsAtom = atom<PostSummary[] | []>({
5+
key: 'FeedsAtom',
6+
default: [],
7+
});
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { atom } from 'recoil';
2+
import { MatchingInfoDto } from '../../pages/Home/dto';
3+
4+
export const IsMatchingCommentBottomSheetOpenAtom = atom<boolean>({
5+
key: 'isMatchingCommentBottomSheetOpenAtom',
6+
default: false,
7+
});
8+
9+
export const MatchingInfoAtom = atom<MatchingInfoDto | null>({
10+
key: 'matchingInfoAtom',
11+
default: null,
12+
});
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { atom } from 'recoil';
2+
3+
export const SelectedTagsAtom = atom<number[]>({
4+
key: 'SelectedTagsAtom',
5+
default: [],
6+
});

0 commit comments

Comments
 (0)