add PublicRoute, AdminRouter (wrappers for react-router-dom's Route), Link, NotFoundPage
This commit is contained in:
parent
81d8eccb08
commit
8c8296fb74
|
@ -0,0 +1,50 @@
|
|||
import React, { forwardRef, RefObject } from 'react';
|
||||
import {
|
||||
Link as RRDLink,
|
||||
LinkProps as RRDLinkProps,
|
||||
generatePath,
|
||||
} from 'react-router-dom';
|
||||
import { Link as MUILink, LinkProps as MUILinkProps } from '@material-ui/core';
|
||||
|
||||
export type Props = MUILinkProps &
|
||||
RRDLinkProps & {
|
||||
params?: { [paramName: string]: string | number | boolean | undefined };
|
||||
};
|
||||
|
||||
const CustomizedRRDLink = forwardRef(
|
||||
(
|
||||
{ children, params, to, ...props }: Props,
|
||||
ref:
|
||||
| ((instance: HTMLAnchorElement | null) => void)
|
||||
| RefObject<HTMLAnchorElement>
|
||||
| null
|
||||
| undefined
|
||||
) => (
|
||||
<RRDLink
|
||||
{...props}
|
||||
to={params && typeof to === 'string' ? generatePath(to, params) : to}
|
||||
ref={ref}
|
||||
>
|
||||
{children}
|
||||
</RRDLink>
|
||||
)
|
||||
);
|
||||
|
||||
const Link = forwardRef(
|
||||
(
|
||||
{ children, ...props }: Props,
|
||||
ref:
|
||||
| ((instance: HTMLAnchorElement | null) => void)
|
||||
| RefObject<HTMLAnchorElement>
|
||||
| null
|
||||
| undefined
|
||||
) => {
|
||||
return (
|
||||
<MUILink {...props} ref={ref} component={CustomizedRRDLink}>
|
||||
{children}
|
||||
</MUILink>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default Link;
|
|
@ -0,0 +1,4 @@
|
|||
export enum Role {
|
||||
Admin = 'admin',
|
||||
User = 'user',
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
export const ROUTE = {
|
||||
SIGN_IN_PAGE: '/',
|
||||
DASHBOARD_PAGE: '/dashboard',
|
||||
};
|
||||
|
||||
export const PUBLIC_ROUTES = [ROUTE.SIGN_IN_PAGE];
|
||||
export const ADMIN_ROUTES = Object.values(ROUTE).filter(
|
||||
route => !PUBLIC_ROUTES.includes(route)
|
||||
);
|
|
@ -0,0 +1,15 @@
|
|||
import { Switch, Route } from 'react-router-dom';
|
||||
import { ROUTE } from '../config/routing';
|
||||
import DashboardPage from './DashboardPage/DashboardPage';
|
||||
|
||||
function AdminRoutes() {
|
||||
return (
|
||||
<Switch>
|
||||
<Route exact path={ROUTE.DASHBOARD_PAGE}>
|
||||
<DashboardPage />
|
||||
</Route>
|
||||
</Switch>
|
||||
);
|
||||
}
|
||||
|
||||
export default AdminRoutes;
|
|
@ -1,22 +1,27 @@
|
|||
import { Route, Switch } from 'react-router-dom';
|
||||
import PublicRoute from '../libs/router/PublicRoute';
|
||||
import AdminRoute from '../libs/router/AdminRoute';
|
||||
import AppLoading from './AppLoading';
|
||||
import SignInPage from './SignInPage/SignInPage';
|
||||
import NotFoundPage from './NotFoundPage/NotFoundPage';
|
||||
import AdminRoutes from './AdminRoutes';
|
||||
import { ROUTE, ADMIN_ROUTES } from '../config/routing';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="App">
|
||||
<header className="App-header">
|
||||
<p>
|
||||
Edit <code>src/App.tsx</code> and save to reload.
|
||||
</p>
|
||||
<a
|
||||
className="App-link"
|
||||
href="https://reactjs.org"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Learn React
|
||||
</a>
|
||||
</header>
|
||||
</div>
|
||||
<AppLoading>
|
||||
<Switch>
|
||||
<PublicRoute exact path={ROUTE.SIGN_IN_PAGE}>
|
||||
<SignInPage />
|
||||
</PublicRoute>
|
||||
<AdminRoute exact path={ADMIN_ROUTES}>
|
||||
<AdminRoutes />
|
||||
</AdminRoute>
|
||||
<Route path="*">
|
||||
<NotFoundPage />
|
||||
</Route>
|
||||
</Switch>
|
||||
</AppLoading>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
const DashboardPage = () => {
|
||||
return <div>DashboardPage</div>;
|
||||
};
|
||||
|
||||
export default DashboardPage;
|
|
@ -0,0 +1,39 @@
|
|||
import React from 'react';
|
||||
import { ROUTE } from 'config/routing';
|
||||
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import { Container, Typography } from '@material-ui/core';
|
||||
import Link from 'common/Link/Link';
|
||||
|
||||
const NotFoundPage = () => {
|
||||
const classes = useStyles();
|
||||
|
||||
return (
|
||||
<main>
|
||||
<Container className={classes.container}>
|
||||
<Typography gutterBottom variant="h1">
|
||||
Nie znaleziono strony
|
||||
</Typography>
|
||||
<Typography gutterBottom variant="h4">
|
||||
Wygląda na to, że kliknąłeś uszkodzony link lub wpisałeś adres URL,
|
||||
który nie istnieje.
|
||||
</Typography>
|
||||
<Typography variant="h4">
|
||||
<Link to={ROUTE.SIGN_IN_PAGE}>Wróć na stronę główną</Link>
|
||||
</Typography>
|
||||
</Container>
|
||||
</main>
|
||||
);
|
||||
};
|
||||
|
||||
const useStyles = makeStyles(() => ({
|
||||
container: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
textAlign: 'center',
|
||||
minHeight: '100vh',
|
||||
},
|
||||
}));
|
||||
|
||||
export default NotFoundPage;
|
|
@ -0,0 +1,5 @@
|
|||
const SignInPage = () => {
|
||||
return <div>SignInPage</div>;
|
||||
};
|
||||
|
||||
export default SignInPage;
|
|
@ -1,4 +0,0 @@
|
|||
declare enum UserRole {
|
||||
Admin = "admin",
|
||||
User = "user",
|
||||
}
|
|
@ -3,7 +3,6 @@ import ReactDOM from 'react-dom';
|
|||
import { BrowserRouter } from 'react-router-dom';
|
||||
import { ApolloProvider } from '@apollo/client';
|
||||
import App from './features/App';
|
||||
import AppLoading from './features/AppLoading';
|
||||
import { AuthProvider } from './libs/auth';
|
||||
import ThemeProvider from './libs/material-ui/ThemeProvider';
|
||||
import TokenStorage from './libs/tokenstorage/TokenStorage';
|
||||
|
@ -18,9 +17,7 @@ ReactDOM.render(
|
|||
<ApolloProvider client={createClient(API_URI, tokenStorage)}>
|
||||
<ThemeProvider>
|
||||
<AuthProvider tokenStorage={tokenStorage}>
|
||||
<AppLoading>
|
||||
<App />
|
||||
</AppLoading>
|
||||
<App />
|
||||
</AuthProvider>
|
||||
</ThemeProvider>
|
||||
</ApolloProvider>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { gql } from "@apollo/client";
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const MUTATION_SIGN_IN = gql`
|
||||
mutation signIn(
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import TokenStorage from '../tokenstorage/TokenStorage';
|
||||
import { Role } from 'config/app';
|
||||
|
||||
export type User = {
|
||||
id: number;
|
||||
displayName: string;
|
||||
role: UserRole;
|
||||
role: Role;
|
||||
email: string;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
import { Route, Redirect, RouteProps } from 'react-router-dom';
|
||||
import { isNil } from 'lodash';
|
||||
import { useAuth } from '../auth';
|
||||
import { Role } from 'config/app';
|
||||
import { ROUTE } from 'config/routing';
|
||||
|
||||
const AdminRoute = ({ children, ...rest }: RouteProps) => {
|
||||
const { user } = useAuth();
|
||||
return (
|
||||
<Route {...rest}>
|
||||
{!isNil(user) && user.role === Role.Admin ? (
|
||||
children
|
||||
) : (
|
||||
<Redirect to={ROUTE.DASHBOARD_PAGE} />
|
||||
)}
|
||||
</Route>
|
||||
);
|
||||
};
|
||||
|
||||
export default AdminRoute;
|
|
@ -0,0 +1,15 @@
|
|||
import { Route, Redirect, RouteProps } from 'react-router-dom';
|
||||
import { isNil } from 'lodash';
|
||||
import { useAuth } from '../auth';
|
||||
import { ROUTE } from '../../config/routing';
|
||||
|
||||
const PublicRoute = ({ children, ...rest }: RouteProps) => {
|
||||
const { user } = useAuth();
|
||||
return (
|
||||
<Route {...rest}>
|
||||
{isNil(user) ? children : <Redirect to={ROUTE.DASHBOARD_PAGE} />}
|
||||
</Route>
|
||||
);
|
||||
};
|
||||
|
||||
export default PublicRoute;
|
Reference in New Issue