Skip to content

Commit

Permalink
added private routes
Browse files Browse the repository at this point in the history
  • Loading branch information
Onvix24 committed Jan 28, 2024
1 parent 9f456da commit 96b1096
Show file tree
Hide file tree
Showing 9 changed files with 51 additions and 38 deletions.
8 changes: 5 additions & 3 deletions src/app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ import { useTheme } from "app/providers/ThemeProvider";
import { AppRouter } from "app/providers/router";
import { Navbar } from "widgets/Navbar";
import { Sidebar } from "widgets/Sidebar";
import { useDispatch } from "react-redux";
import { userActions } from "entities/User";
import { useDispatch, useSelector } from "react-redux";
import { getUserMounted, userActions } from "entities/User";
import "./App.scss";

const App = () => {
const { theme } = useTheme();
const dispatch = useDispatch();

const mounted = useSelector(getUserMounted);

useEffect(() => {
dispatch(userActions.initAuthData());
}, [dispatch]);
Expand All @@ -22,7 +24,7 @@ const App = () => {
<Navbar/>
<div className="content-page">
<Sidebar/>
<AppRouter/>
{mounted && <AppRouter />}
</div>
</Suspense>
</div>
Expand Down
48 changes: 20 additions & 28 deletions src/app/providers/router/ui/AppRouter.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,32 @@
import { getUserAuthData } from "entities/User";
import React, { Suspense, memo, useMemo } from "react";
import { useSelector } from "react-redux";
import { Suspense, memo, useCallback } from "react";
import { Route, Routes } from "react-router-dom";
import { routeConfig } from "shared/config/routeConfig/routeConfig";
import { AppRoutesProps, routeConfig } from "shared/config/routeConfig/routeConfig";
import { PageLoader } from "widgets/PageLoader/ui/PageLoader";
import { RequireAuth } from "./requireAuth";

const AppRouter = () => {

const isAuth = useSelector(getUserAuthData);
const renderWithWrapper = useCallback((route: AppRoutesProps) => {

const element=(
<Suspense fallback={<PageLoader/>}>
<div className="page-wrapper">
{route.element}
</div>
</Suspense>
);

const routes = useMemo(
() => {
return Object.values(routeConfig).filter(route => {
if(route.authOnly && !isAuth) {
return false;
}

return true;
});
}, [isAuth]);
return (
<Route
key={route.path}
path={route.path}
element={route.authOnly ? <RequireAuth>{element}</RequireAuth> : element }
/>);
}, []);

return (
<Routes>
{
routes.map(({ path, element }) => (
<Route key={path}
path={path}
element={(
<Suspense fallback={<PageLoader/>}>
<div className="page-wrapper">
{element}
</div>
</Suspense>
)}
/>
))}
{Object.values(routeConfig).map(renderWithWrapper)}
</Routes>
);
};
Expand Down
15 changes: 15 additions & 0 deletions src/app/providers/router/ui/requireAuth.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { getUserAuthData } from "entities/User";
import { useSelector } from "react-redux";
import { Navigate, useLocation } from "react-router-dom";
import { RoutePath } from "shared/config/routeConfig/routeConfig";

export function RequireAuth({ children }: { children: JSX.Element }) {
const auth = useSelector(getUserAuthData);
const location = useLocation();

if (!auth) {
return <Navigate to={RoutePath.main} state={{ from: location }} replace />;
}

return children;
}
4 changes: 3 additions & 1 deletion src/entities/User/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ export {
User,
UserSchema,
getUserAuthData
};
};

export { getUserMounted } from "./model/selectors/getUserMounted/getUserMounted";
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { StateSchema } from "app/providers/StoreProvider";

export const getUserMounted = (state: StateSchema) => state.user._mounted;
2 changes: 2 additions & 0 deletions src/entities/User/model/slice/userSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { User, UserSchema } from "../types/user";
import { USER_LOCALSTORAGE_KEY } from "shared/const/localStorage";

const initialState: UserSchema = {
_mounted: false
};

export const userSlice = createSlice({
Expand All @@ -18,6 +19,7 @@ export const userSlice = createSlice({
if(user) {
state.authData = JSON.parse(user);
}
state._mounted = true;
},
logout: (state) => {
state.authData = undefined;
Expand Down
2 changes: 2 additions & 0 deletions src/entities/User/model/types/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ export interface User {

export interface UserSchema {
authData?: User;

_mounted: boolean;
}
5 changes: 0 additions & 5 deletions src/pages/MainPage/ui/MainPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@ import { Input } from "shared/ui/Input/Input";

const MainPage = () => {
const { t } = useTranslation("main");
const [value, setValue] = useState("");

const onChange = (val: string) => {
setValue(val);
};

return (
<div>
Expand Down
2 changes: 1 addition & 1 deletion src/shared/config/routeConfig/routeConfig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { AboutPage } from "pages/AboutPage";
import { NotFoundPage } from "pages/NotFoundPage";
import { ProfilePage } from "pages/ProfilePage";

type AppRoutesProps = RouteProps & {
export type AppRoutesProps = RouteProps & {
authOnly?: boolean;
}

Expand Down

0 comments on commit 96b1096

Please sign in to comment.