Skip to content

Commit

Permalink
Merge pull request #73 from AJD-Archive/feature/72
Browse files Browse the repository at this point in the history
튜토리얼 페이지 & 404 에러 페이지
  • Loading branch information
MyungJiwoo authored Sep 24, 2024
2 parents 4e00eb3 + 06ef924 commit d682404
Show file tree
Hide file tree
Showing 12 changed files with 693 additions and 26 deletions.
169 changes: 149 additions & 20 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
createRoutesFromElements,
Route,
Navigate,
Routes,
} from 'react-router-dom';
import MainPage from './pages/MainPage';
import LoginPage from './pages/LoginPage';
Expand All @@ -20,6 +21,8 @@ import SidePage from './pages/SidePage';
import ChallengeCommunityPage from './pages/ChallengeCommunityPage';
import CreateChallengePage from './pages/CreateChallengePage';
import ChallengeDetailPage from './pages/ChallengeDetailPage';
import TutorialPage from './pages/TutorialPage';
import ErrorPage from './pages/ErrorPage';

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
Expand All @@ -30,6 +33,7 @@ import { ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import './App.css';
import { useSSE } from './hooks/useSSE';
import ProtectedRoute from './components/ProtectedRoute';

const queryClient = new QueryClient();

Expand Down Expand Up @@ -57,35 +61,160 @@ const router = (isLoggedIn: boolean) =>
createBrowserRouter(
createRoutesFromElements(
<Route>
<Route
{/* 기본 라우터를 로그인 페이지로 변경 */}
<Route path="/" element={<LoginPage />} />
{/* <Route
path="/"
element={
isLoggedIn ? (
<Navigate to={`/${localStorage.getItem('LatestBoard') ?? 1}`} replace />
<Navigate to={`/${localStorage.getItem('LatestBoard') ?? 'tutorial'}`} replace />
) : (
<Navigate to="/login" replace />
<LoginPage />
)
}
/>
<Route path="/:id" element={<MainPage />}>
/> */}

{/* 로그인 상관없이 접근 가능한 라우터. 보호되지 않는 라우터 */}
<Route path="/api/oauth2/callback/:provider" element={<OAuthRedirectHandler />} />
<Route path="*" element={<ErrorPage />} />

{/* 보호된 경로들에 ProtectedRoute 적용 */}
<Route
path="/:id"
element={
<ProtectedRoute>
<MainPage />
</ProtectedRoute>
}
>
<Route path="/:id/personalBlock/:blockId" element={<SidePage />} />
</Route>
<Route path="/login" element={<LoginPage />} />
<Route path="/api/oauth2/callback/:provider" element={<OAuthRedirectHandler />} />
<Route path="/createBoard" element={<CreateBoard />} />
<Route path="/createPersonalBoard" element={<CreatePersonalBoard />} />
<Route path="/createPersonalBoard/:id" element={<CreatePersonalBoard />} />
<Route path="/createTeamBoard" element={<CreateTeamBoard />} />
<Route path="/createTeamBoard/:id" element={<CreateTeamBoard />} />
<Route path="/mypage" element={<MyPage />} />
<Route path="/mypage/edit" element={<ProfileEdit />} />
<Route path="/:id/teamdocument" element={<TeamDocumentBoard />}>
<Route path=":documentId" element={<TeamDocument />} />

<Route
path="/createBoard"
element={
<ProtectedRoute>
<CreateBoard />
</ProtectedRoute>
}
/>

<Route
path="/createPersonalBoard"
element={
<ProtectedRoute>
<CreatePersonalBoard />
</ProtectedRoute>
}
/>

<Route
path="/createPersonalBoard/:id"
element={
<ProtectedRoute>
<CreatePersonalBoard />
</ProtectedRoute>
}
/>

<Route
path="/createTeamBoard"
element={
<ProtectedRoute>
<CreateTeamBoard />
</ProtectedRoute>
}
/>

<Route
path="/createTeamBoard/:id"
element={
<ProtectedRoute>
<CreateTeamBoard />
</ProtectedRoute>
}
/>

<Route
path="/mypage"
element={
<ProtectedRoute>
<MyPage />
</ProtectedRoute>
}
/>

<Route
path="/mypage/edit"
element={
<ProtectedRoute>
<ProfileEdit />
</ProtectedRoute>
}
/>

<Route
path="/:id/teamdocument"
element={
<ProtectedRoute>
<TeamDocumentBoard />
</ProtectedRoute>
}
>
<Route
path=":documentId"
element={
<ProtectedRoute>
<TeamDocument />
</ProtectedRoute>
}
/>
</Route>
<Route path="/challenge" element={<ChallengeCommunityPage />} />
<Route path="/challenge/create" element={<CreateChallengePage />} />
<Route path="/challenge/create/:id" element={<CreateChallengePage />} />
<Route path="/challenge/:id" element={<ChallengeDetailPage />} />

<Route
path="/challenge"
element={
<ProtectedRoute>
<ChallengeCommunityPage />
</ProtectedRoute>
}
/>

<Route
path="/challenge/create"
element={
<ProtectedRoute>
<CreateChallengePage />
</ProtectedRoute>
}
/>

<Route
path="/challenge/create/:id"
element={
<ProtectedRoute>
<CreateChallengePage />
</ProtectedRoute>
}
/>

<Route
path="/challenge/:id"
element={
<ProtectedRoute>
<ChallengeDetailPage />
</ProtectedRoute>
}
/>

<Route
path="/tutorial"
element={
<ProtectedRoute>
<TutorialPage />
</ProtectedRoute>
}
/>
</Route>
)
);
Expand Down
12 changes: 12 additions & 0 deletions src/components/ProtectedRoute.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Navigate } from 'react-router-dom';

// * 로그인되지 않았는데 url 조작으로 접근을 방지 (로컬 스토리지에 저장된 토큰 확인)
const ProtectedRoute = ({ children }: { children: JSX.Element }) => {
if (!localStorage.getItem('accessToken')) {
return <Navigate to="/" replace />;
}

return children;
};

export default ProtectedRoute;
2 changes: 1 addition & 1 deletion src/contexts/AuthContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
const login = ({ accessToken, refreshToken }: { accessToken: string; refreshToken: string }) => {
localStorage.setItem('accessToken', accessToken);
localStorage.setItem('refreshToken', refreshToken);
// fetchMemberInfo();
fetchMemberInfo();
};

const logout = async () => {
Expand Down
8 changes: 6 additions & 2 deletions src/contexts/OAuthRedirectHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ interface LoginToken {
}

const OAuthRedirectHandler = () => {
const { provider } = useParams(); // Get the provider from the route parameters
const { provider } = useParams();
const navigate = useNavigate();
const { login } = useAuth();
const [loginToken, setLoginToken] = useState<LoginToken>({
Expand All @@ -30,7 +30,10 @@ const OAuthRedirectHandler = () => {
useEffect(() => {
if (loginToken.accessToken) {
login(loginToken);
navigate('/'); // 기본 대시보드 불러올 라우터로 설정 (가장 마지막에 방문한 대시보드를 기준으로)

// * 마지막에 방문한 대시보드가 있다면 해당 대시보드로 이동, 없다면 튜토리얼 페이지로 이동
const latestBoard = localStorage.getItem('LatestBoard');
navigate(latestBoard ? `/${latestBoard}` : '/tutorial');
}
}, [loginToken, login, navigate]);

Expand All @@ -55,6 +58,7 @@ const OAuthRedirectHandler = () => {
}
};

// * 로그인 처리 중일때 보여질 로딩창
return <Loading />;
};

Expand Down
3 changes: 2 additions & 1 deletion src/hooks/usePersonalDashBoard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ const usePersonalDashBoard = (dashboardId: string | null) => {
const deleteDashboard = async () => {
if (dashboardId) {
await deletePersonalDashboard(dashboardId);
navigate('/');
navigate(`/tutorial`);
localStorage.removeItem('LatestBoard');
}
};

Expand Down
Binary file added src/img/personal_tutorial.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/img/team_tutorial.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 4 additions & 2 deletions src/pages/CreateTeamBoardPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ const CreateTeamBoard = () => {
const deleteDashboard = async () => {
if (dashboardId) {
await deleteTeamDashboard(dashboardId);
navigate('/');
navigate(`/tutorial`);
localStorage.removeItem('LatestBoard');
}
};

Expand All @@ -146,7 +147,8 @@ const CreateTeamBoard = () => {
const quitDashboard = async () => {
if (dashboardId) {
await quitTeamDashboard(dashboardId);
navigate('/');
navigate(`/tutorial`);
localStorage.removeItem('LatestBoard');
}
};

Expand Down
Loading

0 comments on commit d682404

Please sign in to comment.