mirror of
https://github.com/aljazceru/landscape-template.git
synced 2026-01-21 15:24:22 +01:00
feat: navbar layout, show createStory btn always, enchance protected route to redirect to the route that he came from, remove navbar in create story page
Fixes #74
This commit is contained in:
61
src/App.tsx
61
src/App.tsx
@@ -1,5 +1,4 @@
|
||||
import React, { Suspense, useEffect } from "react";
|
||||
import Navbar from "src/Components/Navbar/Navbar";
|
||||
import ModalsContainer from "src/Components/Modals/ModalsContainer/ModalsContainer";
|
||||
import { useAppDispatch, useAppSelector } from './utils/hooks';
|
||||
import { Wallet_Service } from "./services";
|
||||
@@ -10,23 +9,30 @@ import { useMeQuery } from "./graphql";
|
||||
import { setUser } from "./redux/features/user.slice";
|
||||
import ProtectedRoute from "./Components/ProtectedRoute/ProtectedRoute";
|
||||
import { Helmet } from "react-helmet";
|
||||
import { NavbarLayout } from "./utils/routing/layouts";
|
||||
import { Loadable } from "./utils/routing";
|
||||
|
||||
|
||||
|
||||
// Pages
|
||||
const FeedPage = React.lazy(() => import("./features/Posts/pages/FeedPage/FeedPage"))
|
||||
const PostDetailsPage = React.lazy(() => import("./features/Posts/pages/PostDetailsPage/PostDetailsPage"))
|
||||
const CreatePostPage = React.lazy(() => import("./features/Posts/pages/CreatePostPage/CreatePostPage"))
|
||||
const PreviewPostPage = React.lazy(() => import("./features/Posts/pages/PreviewPostPage/PreviewPostPage"))
|
||||
const FeedPage = Loadable(React.lazy(() => import("./features/Posts/pages/FeedPage/FeedPage")))
|
||||
const PostDetailsPage = Loadable(React.lazy(() => import("./features/Posts/pages/PostDetailsPage/PostDetailsPage")))
|
||||
const CreatePostPage = Loadable(React.lazy(() => import("./features/Posts/pages/CreatePostPage/CreatePostPage")))
|
||||
const PreviewPostPage = Loadable(React.lazy(() => import("./features/Posts/pages/PreviewPostPage/PreviewPostPage")))
|
||||
|
||||
const HottestPage = Loadable(React.lazy(() => import("src/features/Projects/pages/HottestPage/HottestPage")))
|
||||
const CategoryPage = Loadable(React.lazy(() => import("src/features/Projects/pages/CategoryPage/CategoryPage")))
|
||||
const ExplorePage = Loadable(React.lazy(() => import("src/features/Projects/pages/ExplorePage")))
|
||||
|
||||
const HackathonsPage = Loadable(React.lazy(() => import("./features/Hackathons/pages/HackathonsPage/HackathonsPage")))
|
||||
|
||||
const DonatePage = Loadable(React.lazy(() => import("./features/Donations/pages/DonatePage/DonatePage")))
|
||||
const LoginPage = Loadable(React.lazy(() => import("./features/Auth/pages/LoginPage/LoginPage")))
|
||||
const LogoutPage = Loadable(React.lazy(() => import("./features/Auth/pages/LogoutPage/LogoutPage")))
|
||||
const ProfilePage = Loadable(React.lazy(() => import("./features/Profiles/pages/ProfilePage/ProfilePage")))
|
||||
|
||||
const HottestPage = React.lazy(() => import("src/features/Projects/pages/HottestPage/HottestPage"))
|
||||
const CategoryPage = React.lazy(() => import("src/features/Projects/pages/CategoryPage/CategoryPage"))
|
||||
const ExplorePage = React.lazy(() => import("src/features/Projects/pages/ExplorePage"))
|
||||
|
||||
const HackathonsPage = React.lazy(() => import("./features/Hackathons/pages/HackathonsPage/HackathonsPage"))
|
||||
|
||||
const DonatePage = React.lazy(() => import("./features/Donations/pages/DonatePage/DonatePage"))
|
||||
const LoginPage = React.lazy(() => import("./features/Auth/pages/LoginPage/LoginPage"))
|
||||
const LogoutPage = React.lazy(() => import("./features/Auth/pages/LogoutPage/LogoutPage"))
|
||||
const ProfilePage = React.lazy(() => import("./features/Profiles/pages/ProfilePage/ProfilePage"))
|
||||
|
||||
function App() {
|
||||
const { isWalletConnected } = useAppSelector(state => ({
|
||||
@@ -76,27 +82,30 @@ function App() {
|
||||
|
||||
/>
|
||||
</Helmet>
|
||||
<Navbar />
|
||||
<Suspense fallback={<LoadingPage />}>
|
||||
<Routes>
|
||||
<Route path="/products/hottest" element={<HottestPage />} />
|
||||
<Route path="/products/category/:id" element={<CategoryPage />} />
|
||||
<Route path="/products" element={<ExplorePage />} />
|
||||
|
||||
<Route path="/blog/post/:type/:id/*" element={<PostDetailsPage />} />
|
||||
<Route path="/blog/preview-post/:type" element={<PreviewPostPage />} />
|
||||
<Route path="/blog/create-post" element={<ProtectedRoute><CreatePostPage /></ProtectedRoute>} />
|
||||
<Route path="/blog" element={<FeedPage />} />
|
||||
|
||||
<Route path="/hackathons" element={<HackathonsPage />} />
|
||||
<Route element={<NavbarLayout />}>
|
||||
<Route path="/products/hottest" element={<HottestPage />} />
|
||||
<Route path="/products/category/:id" element={<CategoryPage />} />
|
||||
<Route path="/products" element={<ExplorePage />} />
|
||||
|
||||
<Route path="/donate" element={<DonatePage />} />
|
||||
<Route path="/blog/post/:type/:id/*" element={<PostDetailsPage />} />
|
||||
<Route path="/blog" element={<FeedPage />} />
|
||||
|
||||
<Route path="/profile/:id/*" element={<ProfilePage />} />
|
||||
<Route path="/login" element={<LoginPage />} />
|
||||
<Route path="/logout" element={<LogoutPage />} />
|
||||
<Route path="/hackathons" element={<HackathonsPage />} />
|
||||
|
||||
<Route path="/donate" element={<DonatePage />} />
|
||||
|
||||
<Route path="/profile/:id/*" element={<ProfilePage />} />
|
||||
<Route path="/login" element={<LoginPage />} />
|
||||
<Route path="/logout" element={<LogoutPage />} />
|
||||
|
||||
<Route path="/" element={<Navigate to="/products" />} />
|
||||
</Route>
|
||||
|
||||
<Route path="/" element={<Navigate to="/products" />} />
|
||||
</Routes>
|
||||
</Suspense>
|
||||
<ModalsContainer />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { PropsWithChildren } from "react";
|
||||
import { Navigate, } from "react-router-dom";
|
||||
import { Navigate, useLocation } from "react-router-dom";
|
||||
import { useAppSelector } from "src/utils/hooks";
|
||||
|
||||
interface Props {
|
||||
@@ -17,10 +17,14 @@ export default function ProtectedRoute({
|
||||
|
||||
const user = useAppSelector(state => state.user.me);
|
||||
|
||||
const location = useLocation();
|
||||
|
||||
|
||||
|
||||
if (user === undefined) return <></>
|
||||
|
||||
if (user === null)
|
||||
return <Navigate to={notAuthorizedRedirectPath} replace />;
|
||||
return <Navigate to={notAuthorizedRedirectPath} replace state={{ from: location.pathname }} />;
|
||||
|
||||
|
||||
if (!isAllowed) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useCallback, useEffect, useState } from "react"
|
||||
import { Helmet } from "react-helmet";
|
||||
import { Grid } from "react-loader-spinner";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useNavigate, useLocation } from "react-router-dom";
|
||||
import { useMeQuery } from "src/graphql"
|
||||
import { CONSTS } from "src/utils";
|
||||
import { QRCodeSVG } from 'qrcode.react';
|
||||
@@ -9,6 +9,7 @@ import { IoRocketOutline } from "react-icons/io5";
|
||||
import Button from "src/Components/Button/Button";
|
||||
import { FiCopy } from "react-icons/fi";
|
||||
import useCopyToClipboard from "src/utils/hooks/useCopyToClipboard";
|
||||
import { getPropertyFromUnknown, } from "src/utils/helperFunctions";
|
||||
|
||||
|
||||
|
||||
@@ -58,6 +59,7 @@ const useLnurlQuery = () => {
|
||||
export default function LoginPage() {
|
||||
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
const { loadingLnurl, data: { lnurl, session_token }, error } = useLnurlQuery();
|
||||
@@ -75,7 +77,10 @@ export default function LoginPage() {
|
||||
setIsLoggedIn(true);
|
||||
meQuery.stopPolling();
|
||||
setTimeout(() => {
|
||||
navigate('/')
|
||||
const cameFrom = getPropertyFromUnknown(location.state, 'from');
|
||||
const navigateTo = cameFrom ? cameFrom : '/'
|
||||
|
||||
navigate(navigateTo)
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
|
||||
@@ -79,14 +79,13 @@ export default function FeedPage() {
|
||||
top: `${navHeight + 16}px`,
|
||||
maxHeight: `calc(100vh - ${navHeight}px - 16px)`,
|
||||
}}>
|
||||
{isLoggedIn &&
|
||||
<Button
|
||||
href='/blog/create-post'
|
||||
color='primary'
|
||||
fullWidth
|
||||
>
|
||||
Write a story
|
||||
</Button>}
|
||||
<Button
|
||||
href='/blog/create-post'
|
||||
color='primary'
|
||||
fullWidth
|
||||
>
|
||||
Write a story
|
||||
</Button>
|
||||
<div className="my-24"></div>
|
||||
<div className="my-24"></div>
|
||||
<PopularTagsFilter
|
||||
|
||||
@@ -102,4 +102,10 @@ export function capitalize(s?: string) {
|
||||
return s && s[0].toUpperCase() + s.slice(1);
|
||||
}
|
||||
|
||||
export const withHttp = (url: string) => !/^https?:\/\//i.test(url) ? `http://${url}` : url;
|
||||
export const withHttp = (url: string) => !/^https?:\/\//i.test(url) ? `http://${url}` : url;
|
||||
|
||||
export function getPropertyFromUnknown<Value = string>(obj: unknown, prop: string | number | symbol): Value | null {
|
||||
if (typeof obj === 'object' && obj !== null && prop in obj)
|
||||
return (obj as any)[prop as any] as Value;
|
||||
return null
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
export * from './routes'
|
||||
export * from './routes'
|
||||
export * from './loadable'
|
||||
9
src/utils/routing/layouts/NavbarLayout.tsx
Normal file
9
src/utils/routing/layouts/NavbarLayout.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import { Outlet, } from 'react-router-dom';
|
||||
import Navbar from "src/Components/Navbar/Navbar";
|
||||
|
||||
export const NavbarLayout = () => {
|
||||
return <>
|
||||
<Navbar />
|
||||
<Outlet />
|
||||
</>
|
||||
};
|
||||
2
src/utils/routing/layouts/index.ts
Normal file
2
src/utils/routing/layouts/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
export * from './NavbarLayout'
|
||||
8
src/utils/routing/loadable.tsx
Normal file
8
src/utils/routing/loadable.tsx
Normal file
@@ -0,0 +1,8 @@
|
||||
import { Suspense } from "react";
|
||||
import LoadingPage from "src/Components/LoadingPage/LoadingPage";
|
||||
|
||||
export const Loadable = (Component: any, Loading = LoadingPage) => (props: any) => (
|
||||
<Suspense fallback={<Loading />}>
|
||||
<Component {...props} />
|
||||
</Suspense>
|
||||
);
|
||||
Reference in New Issue
Block a user