diff --git a/src/App.tsx b/src/App.tsx index 81d070de..119f4515 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,59 +1,92 @@ import React from 'react'; -import { BrowserRouter, Route, Routes } from 'react-router-dom'; +import { BrowserRouter, Route, Routes, Navigate } from 'react-router-dom'; import Home from './pages/Home'; +import Login from './pages/Login'; +import SignUp from './pages/SignUp'; +import LoginComplete from './pages/Login/components/LoginComplete'; +import TermsAgreement from './pages/TermsAgreement'; +import KakaoCallback from './pages/Login/components/Kakao/KakaoCallback'; +import NaverCallback from './pages/Login/components/Naver/NaverCallback'; + import MyPage from './pages/MyPage'; -import MyPost from './pages/MyPost'; import ProfileEdit from './pages/ProfileEdit'; import AccountSetting from './pages/AccountSetting'; import AccountEdit from './pages/AccountEdit'; import AccountCancel from './pages/AccountCancel'; import Verification from './pages/verification'; -import Login from './pages/Login'; -import SignUp from './pages/SignUp'; + import ProfileViewer from './pages/ProfileViewer'; -import Chats from './pages/Chats'; -import ChatRoom from './pages/Chats/ChatRoom'; + +import Post from './pages/Post'; +import MyPost from './pages/MyPost'; +import PostUpload from './pages/PostUpload'; import PostImageSelect from './pages/PostImageSelect'; import PostInstaConnect from './pages/PostInstaConnect'; import PostInstaFeedSelect from './pages/PostInstaFeedSelect'; -import PostUpload from './pages/PostUpload'; -import Post from './pages/Post'; -import KakaoCallback from './pages/Login/components/Kakao/KakaoCallback'; -import NaverCallback from './pages/Login/components/Naver/NaverCallback'; -import LoginComplete from './pages/Login/components/LoginComplete'; -import TermsAgreement from './pages/TermsAgreement'; + +import Chats from './pages/Chats'; +import ChatRoom from './pages/Chats/ChatRoom'; + +import NotFound from './pages/NotFound'; + +const ProtectedRoute = ({ children }: { children: JSX.Element }) => { + const isAuthenticated = Boolean(localStorage.getItem('new_jwt_token')); + return isAuthenticated ? children : ; +}; + +// 인증이 필요한 페이지 배열 +const protectedRoutes = [ + { path: '/', element: }, + + // 사용자 프로필 및 계정 관리 + { path: '/mypage', element: }, + { path: '/profile/edit', element: }, + { path: '/account-setting', element: }, + { path: '/account-edit', element: }, + { path: '/account-cancel', element: }, + { path: '/verification', element: }, + { path: '/users/:userId', element: }, + + { path: '/post/:postId', element: }, + { path: '/my-post/:postId', element: }, + { path: '/upload', element: }, + { path: '/image-select', element: }, + { path: '/insta-connect', element: }, + { path: '/insta-feed-select', element: }, + + // 메시지/채팅 + { path: '/chats', element: }, + { path: '/chats/:chatRoomId', element: }, +]; + +// 인증이 필요 없는 페이지 배열 +const publicRoutes = [ + { path: '/login', element: }, + { path: '/signup', element: }, + { path: '/login/complete', element: }, + { path: '/terms-agreement', element: }, + + // 콜백 + { path: '/auth/kakao/callback', element: }, + { path: '/auth/naver/callback', element: }, +]; const App: React.FC = () => { return ( - } /> - } /> - } /> - } /> - } /> - } /> - - } /> - } /> - } /> - - } /> - }> - } /> - } /> - - } /> - } /> - } /> - } /> - - } /> - } /> - } /> - - }> - }> + {/* 인증이 필요한 페이지 */} + {protectedRoutes.map(({ path, element }) => ( + {element}} /> + ))} + + {/* 인증이 필요 없는 페이지 */} + {publicRoutes.map(({ path, element }) => ( + + ))} + + {/* 없는 페이지에 대한 처리 */} + } /> ); diff --git a/src/assets/default/snsIcon/kakao 2.svg b/src/assets/default/snsIcon/kakao 2.svg new file mode 100644 index 00000000..9724ba4a --- /dev/null +++ b/src/assets/default/snsIcon/kakao 2.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/default/snsIcon/naver 2.svg b/src/assets/default/snsIcon/naver 2.svg new file mode 100644 index 00000000..186eb32e --- /dev/null +++ b/src/assets/default/snsIcon/naver 2.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/pages/NotFound/index.tsx b/src/pages/NotFound/index.tsx new file mode 100644 index 00000000..4c879a1f --- /dev/null +++ b/src/pages/NotFound/index.tsx @@ -0,0 +1,44 @@ +import { useNavigate } from 'react-router-dom'; +import { OODDFrame } from '../../components/Frame/Frame'; +import { NotFoundContainer, TextContainer, ButtonContainer, StyledButton } from './styles'; +import { StyledText } from '../../components/Text/StyledText'; +import theme from '../../styles/theme'; + +const NotFound = () => { + const navigate = useNavigate(); + + return ( + + + + + 404 ERROR + + 죄송합니다. 페이지를 찾을 수 없습니다. +
+ 페이지의 주소가 잘못 입력되었거나, + + 요청하신 페이지의 주소가 변경, 삭제되어 찾을 수 없습니다. + +
+
+ + + 메인으로 + + navigate(-1)} + className="prev" + $textTheme={{ style: 'body2-regular' }} + color={theme.colors.white} + > + 이전으로 + + +
+
+ ); +}; + +export default NotFound; diff --git a/src/pages/NotFound/styles.tsx b/src/pages/NotFound/styles.tsx new file mode 100644 index 00000000..ec172fb8 --- /dev/null +++ b/src/pages/NotFound/styles.tsx @@ -0,0 +1,49 @@ +import styled from 'styled-components'; +import { StyledText } from '../../components/Text/StyledText'; + +export const NotFoundContainer = styled.div` + display: flex; + height: 80%; + flex-direction: column; + justify-content: center; + align-items: center; +`; + +export const TextContainer = styled.div` + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 10px; + + div { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + } +`; + +export const ButtonContainer = styled.div` + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + gap: 16px; + margin: 20px; +`; + +export const StyledButton = styled(StyledText)` + display: inline-block; + text-align: center; + padding: 6px 16px; + border: 1px solid ${({ theme }) => theme.colors.pink3}; + border-radius: 8px; + cursor: pointer; + text-decoration: none; + + &.prev { + background-color: ${({ theme }) => theme.colors.pink3}; + color: ${({ theme }) => theme.colors.white}; + } +`; diff --git a/src/recoil/Home/FeedsAtom.ts b/src/recoil/Home/FeedsAtom.ts new file mode 100644 index 00000000..4afa2de9 --- /dev/null +++ b/src/recoil/Home/FeedsAtom.ts @@ -0,0 +1,7 @@ +import { atom } from 'recoil'; +import { PostSummary } from '../../apis/post/dto'; + +export const FeedsAtom = atom({ + key: 'FeedsAtom', + default: [], +}); diff --git a/src/recoil/Home/MatchingCommentBottomSheetAtom.ts b/src/recoil/Home/MatchingCommentBottomSheetAtom.ts new file mode 100644 index 00000000..181aaa7a --- /dev/null +++ b/src/recoil/Home/MatchingCommentBottomSheetAtom.ts @@ -0,0 +1,12 @@ +import { atom } from 'recoil'; +import { MatchingInfoDto } from '../../pages/Home/dto'; + +export const IsMatchingCommentBottomSheetOpenAtom = atom({ + key: 'isMatchingCommentBottomSheetOpenAtom', + default: false, +}); + +export const MatchingInfoAtom = atom({ + key: 'matchingInfoAtom', + default: null, +}); diff --git a/src/recoil/Home/SelectedTagsAtom.ts b/src/recoil/Home/SelectedTagsAtom.ts new file mode 100644 index 00000000..0c460ef3 --- /dev/null +++ b/src/recoil/Home/SelectedTagsAtom.ts @@ -0,0 +1,6 @@ +import { atom } from 'recoil'; + +export const SelectedTagsAtom = atom({ + key: 'SelectedTagsAtom', + default: [], +});