From 526084771ca093477595cca12434407252dc8f2c Mon Sep 17 00:00:00 2001 From: MTG2000 Date: Sat, 4 Jun 2022 11:25:41 +0300 Subject: [PATCH] feat: build protected route --- src/App.tsx | 16 ++++++++-- src/Components/Navbar/Navbar.tsx | 5 --- .../ProtectedRoute/ProtectedRoute.tsx | 31 +++++++++++++++++++ .../pages/PostDetailsPage/PostDetailsPage.tsx | 3 +- .../NotFoundPage/NotFoundPage.stories.tsx | 20 ++++++++++++ .../pages/NotFoundPage/NotFoundPage.tsx | 9 +++--- 6 files changed, 72 insertions(+), 12 deletions(-) create mode 100644 src/Components/ProtectedRoute/ProtectedRoute.tsx create mode 100644 src/features/Shared/pages/NotFoundPage/NotFoundPage.stories.tsx diff --git a/src/App.tsx b/src/App.tsx index efedc02..c225da3 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,11 +1,14 @@ import React, { Suspense, useEffect } from "react"; import Navbar from "src/Components/Navbar/Navbar"; import ModalsContainer from "src/Components/Modals/ModalsContainer/ModalsContainer"; -import { useAppSelector } from './utils/hooks'; +import { useAppDispatch, useAppSelector } from './utils/hooks'; import { Wallet_Service } from "./services"; import { Navigate, Route, Routes } from "react-router-dom"; import { useWrapperSetup } from "./utils/Wrapper"; import LoadingPage from "./Components/LoadingPage/LoadingPage"; +import { useMeQuery } from "./graphql"; +import { setUser } from "./redux/features/user.slice"; +import ProtectedRoute from "./Components/ProtectedRoute/ProtectedRoute"; // Pages const FeedPage = React.lazy(() => import("./features/Posts/pages/FeedPage/FeedPage")) @@ -28,8 +31,17 @@ function App() { isWalletConnected: state.wallet.isConnected, })); + const dispatch = useAppDispatch(); useWrapperSetup() + useMeQuery({ + onCompleted: (data) => { + dispatch(setUser(data.me)) + }, + onError: (error) => { + dispatch(setUser(null)) + }, + }); useEffect(() => { // if (typeof window.webln != "undefined") { @@ -58,7 +70,7 @@ function App() { } /> } /> - } /> + } /> } /> } /> diff --git a/src/Components/Navbar/Navbar.tsx b/src/Components/Navbar/Navbar.tsx index 4bc3308..0fac83f 100644 --- a/src/Components/Navbar/Navbar.tsx +++ b/src/Components/Navbar/Navbar.tsx @@ -52,11 +52,6 @@ export default function Navbar() { const isLargeScreen = useMediaQuery(MEDIA_QUERIES.isLarge) - useMeQuery({ - onCompleted: (data) => { - dispatch(setUser(data.me)) - } - }); useEffect(() => { const nav = document.querySelector("nav"); diff --git a/src/Components/ProtectedRoute/ProtectedRoute.tsx b/src/Components/ProtectedRoute/ProtectedRoute.tsx new file mode 100644 index 0000000..7eabbf6 --- /dev/null +++ b/src/Components/ProtectedRoute/ProtectedRoute.tsx @@ -0,0 +1,31 @@ +import { PropsWithChildren } from "react"; +import { Navigate, Outlet } from "react-router-dom"; +import { useAppSelector } from "src/utils/hooks"; + +interface Props { + isAllowed?: boolean; + notAuthorizedRedirectPath?: string + notAllowedRedirectPath?: string +} + +export default function ProtectedRoute({ + isAllowed = true, + notAuthorizedRedirectPath = '/login', + notAllowedRedirectPath = '/', + children, +}: PropsWithChildren) { + + const user = useAppSelector(state => state.user.me); + + if (user === undefined) return <> + + if (user === null) + return ; + + + if (!isAllowed) { + return ; + } + + return <>{children}; +}; diff --git a/src/features/Posts/pages/PostDetailsPage/PostDetailsPage.tsx b/src/features/Posts/pages/PostDetailsPage/PostDetailsPage.tsx index 423a59d..5c12e93 100644 --- a/src/features/Posts/pages/PostDetailsPage/PostDetailsPage.tsx +++ b/src/features/Posts/pages/PostDetailsPage/PostDetailsPage.tsx @@ -2,6 +2,7 @@ import { Helmet } from 'react-helmet' import { useParams } from 'react-router-dom' import LoadingPage from 'src/Components/LoadingPage/LoadingPage' +import NotFoundPage from 'src/features/Shared/pages/NotFoundPage/NotFoundPage' import { usePostDetailsQuery } from 'src/graphql' import { useAppSelector, } from 'src/utils/hooks' import TrendingCard from '../../Components/TrendingCard/TrendingCard' @@ -32,7 +33,7 @@ export default function PostDetailsPage() { const post = postDetailsQuery.data?.getPostById; if (!post) - return

404

+ return return ( <> diff --git a/src/features/Shared/pages/NotFoundPage/NotFoundPage.stories.tsx b/src/features/Shared/pages/NotFoundPage/NotFoundPage.stories.tsx new file mode 100644 index 0000000..0ed8368 --- /dev/null +++ b/src/features/Shared/pages/NotFoundPage/NotFoundPage.stories.tsx @@ -0,0 +1,20 @@ +import { ComponentStory, ComponentMeta } from '@storybook/react'; +import { ModifyArgs } from 'src/utils/storybook/utils'; +import NotFoundPage from './NotFoundPage'; + +export default { + title: 'Shared/Pages/Not Found Page', + component: NotFoundPage, + argTypes: { + backgroundColor: { control: 'color' }, + } +} as ComponentMeta; + + +const Template: ComponentStory = (args) => + +export const Page = Template.bind({}); +Page.args = { +} + + diff --git a/src/features/Shared/pages/NotFoundPage/NotFoundPage.tsx b/src/features/Shared/pages/NotFoundPage/NotFoundPage.tsx index 1240f07..b135482 100644 --- a/src/features/Shared/pages/NotFoundPage/NotFoundPage.tsx +++ b/src/features/Shared/pages/NotFoundPage/NotFoundPage.tsx @@ -8,11 +8,12 @@ export default function NotFoundPage() { const goBack = () => navigate(-1); return ( -
-

- 404 Not Found... +
+

404

+

+ Not Found...

-

+

The resource you are looking for isn't here anymore, it may have been removed or the url may be invalid.