Skip to content

Instantly share code, notes, and snippets.

@createdbymahmood
Created May 28, 2021 10:11
Show Gist options
  • Save createdbymahmood/c66ce1d839735d913fa5714b60f4dbd5 to your computer and use it in GitHub Desktop.
Save createdbymahmood/c66ce1d839735d913fa5714b60f4dbd5 to your computer and use it in GitHub Desktop.
import RouteFactory from 'app/routes';
export default function App() {
return <RouteFactory />;
}
import { ComponentType } from 'react';
/* components */
import { Route } from '@components/Route';
import { Spinner } from '@components/Spinner';
/* modules */
import { useCurrentUser } from '@hooks/api';
import { Redirect, RouteComponentProps } from 'react-router';
/* helpers */
import { routeTo } from 'helpers/ts/routeTo';
/* assets */
/* services */
/* constants */
/* types */
import { $ElementProps } from '@entities/gobal';
import { History } from 'history';
type Props = $ElementProps<typeof Route> & {
component: ComponentType;
};
export const PrivateRoute = ({ component: Component, ...rest }: Props) => {
const { data, isLoading, isError } = useCurrentUser({
retry: false,
staleTime: 10 * 60 * 1000, // 10 mins
});
const UnauthorizedRedirectionConfig: History.LocationDescriptor = {
pathname: routeTo('home'),
state: { from: rest.location },
};
if (isLoading) {
return <Spinner />;
}
if (isError) {
return <Redirect to={UnauthorizedRedirectionConfig} />;
}
const authState = !isLoading && data;
const renderComponent = (props: RouteComponentProps) => {
if (authState) {
return <Component {...props} />;
}
return <Redirect to={UnauthorizedRedirectionConfig} />;
};
return <Route {...rest} render={renderComponent} />;
};
/* components */
/* modules */
import { Route as ReactRouterRoute, RouteProps } from 'react-router-dom';
/* helpers */
/* assets */
/* services */
/* constants */
/* types */
type Props = RouteProps;
export const Route = (props: Props) => {
return <ReactRouterRoute {...props} />;
};
export const ROUTES = {
home: '/home',
dashboard: '/dashboard',
error: '/error',
};
import { Redirect, Switch } from 'react-router-dom';
import { Route as RouteComponent, PrivateRoute } from '@components';
/* helpers */
import { map, uniqueId } from 'lodash/fp';
import { Route, routes } from './routes';
export default function RouteFactory() {
return <Switch>{renderRoutes(routes)}</Switch>;
}
const renderRoutes = map<Route, JSX.Element>(route => {
const { component: Component, path, to, config } = route;
const key = uniqueId(`route-${path}`);
if (to || !Component) {
return <Redirect key={key} from={path} to={to as string} />;
}
if (config.private) {
return (
<PrivateRoute key={key} path={path} component={Component} exact />
);
}
return <RouteComponent key={key} path={path} component={Component} exact />;
});
import { ComponentType } from 'react';
import { ROUTES } from 'constants/routes';
/* pages */
import Home from '@pages/Home';
import Dashboard from '@pages/Dashboard';
export type Route = {
path: string;
component?: ComponentType;
to?: string;
config: {
private: boolean;
};
};
export const routes: Route[] = [
{
path: ROUTES.home,
component: Home,
config: {
private: false,
},
},
{
path: ROUTES.dashboard,
component: Dashboard,
config: {
private: true,
},
},
{
path: '*',
to: ROUTES.home,
config: {
private: false,
},
},
];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment