2022-04-26 10:01:57 -07:00
|
|
|
import React from 'react';
|
2022-04-26 11:36:08 -07:00
|
|
|
import { Redirect, Route, useHistory, RouteProps, RouteComponentProps, match as MatchType } from 'react-router-dom';
|
2022-04-26 10:01:57 -07:00
|
|
|
|
2022-04-28 16:18:55 -07:00
|
|
|
import SidebarNavigation from 'soapbox/components/sidebar-navigation';
|
|
|
|
import { Layout } from 'soapbox/components/ui';
|
2022-04-26 10:01:57 -07:00
|
|
|
import { useOwnAccount, useSettings } from 'soapbox/hooks';
|
|
|
|
|
|
|
|
import BundleColumnError from '../components/bundle_column_error';
|
|
|
|
import ColumnForbidden from '../components/column_forbidden';
|
|
|
|
import ColumnLoading from '../components/column_loading';
|
|
|
|
import ColumnsArea from '../components/columns_area';
|
|
|
|
import BundleContainer from '../containers/bundle_container';
|
|
|
|
|
|
|
|
type PageProps = {
|
|
|
|
params?: MatchType['params'],
|
|
|
|
layout?: any,
|
|
|
|
};
|
|
|
|
|
2022-04-26 11:36:08 -07:00
|
|
|
interface IWrappedRoute extends RouteProps {
|
2022-04-26 10:01:57 -07:00
|
|
|
component: (...args: any[]) => any,
|
2022-04-26 11:36:08 -07:00
|
|
|
page?: React.ComponentType<PageProps>,
|
|
|
|
content?: React.ReactNode,
|
|
|
|
componentParams?: Record<string, any>,
|
|
|
|
layout?: any,
|
2022-04-26 10:01:57 -07:00
|
|
|
publicRoute?: boolean,
|
|
|
|
staffOnly?: boolean,
|
|
|
|
adminOnly?: boolean,
|
|
|
|
developerOnly?: boolean,
|
|
|
|
}
|
|
|
|
|
|
|
|
const WrappedRoute: React.FC<IWrappedRoute> = ({
|
|
|
|
component,
|
|
|
|
page: Page,
|
|
|
|
content,
|
|
|
|
componentParams = {},
|
|
|
|
layout,
|
|
|
|
publicRoute = false,
|
|
|
|
staffOnly = false,
|
|
|
|
adminOnly = false,
|
|
|
|
developerOnly = false,
|
|
|
|
...rest
|
|
|
|
}) => {
|
|
|
|
const history = useHistory();
|
|
|
|
|
|
|
|
const account = useOwnAccount();
|
|
|
|
const settings = useSettings();
|
|
|
|
|
|
|
|
const renderComponent = ({ match }: RouteComponentProps) => {
|
|
|
|
if (Page) {
|
|
|
|
return (
|
|
|
|
<BundleContainer fetchComponent={component} loading={renderLoading} error={renderError}>
|
|
|
|
{Component =>
|
|
|
|
(
|
|
|
|
<Page params={match.params} layout={layout} {...componentParams}>
|
|
|
|
<Component params={match.params} {...componentParams}>
|
|
|
|
{content}
|
|
|
|
</Component>
|
|
|
|
</Page>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
</BundleContainer>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<BundleContainer fetchComponent={component} loading={renderLoading} error={renderError}>
|
|
|
|
{Component =>
|
|
|
|
(
|
|
|
|
<ColumnsArea layout={layout}>
|
|
|
|
<Component params={match.params} {...componentParams}>
|
|
|
|
{content}
|
|
|
|
</Component>
|
|
|
|
</ColumnsArea>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
</BundleContainer>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2022-04-28 16:18:55 -07:00
|
|
|
const renderWithLayout = (children: JSX.Element) => (
|
|
|
|
<>
|
|
|
|
<Layout.Main>
|
|
|
|
{children}
|
|
|
|
</Layout.Main>
|
2022-04-26 10:01:57 -07:00
|
|
|
|
2022-04-28 16:18:55 -07:00
|
|
|
<Layout.Aside />
|
|
|
|
</>
|
|
|
|
);
|
2022-04-26 10:01:57 -07:00
|
|
|
|
2022-04-28 16:18:55 -07:00
|
|
|
const renderLoading = () => renderWithLayout(<ColumnLoading />);
|
|
|
|
const renderForbidden = () => renderWithLayout(<ColumnForbidden />);
|
|
|
|
const renderError = (props: any) => renderWithLayout(<BundleColumnError {...props} />);
|
2022-04-26 10:01:57 -07:00
|
|
|
|
|
|
|
const loginRedirect = () => {
|
|
|
|
const actualUrl = encodeURIComponent(`${history.location.pathname}${history.location.search}`);
|
|
|
|
return <Redirect to={`/login?redirect_uri=${actualUrl}`} />;
|
|
|
|
};
|
|
|
|
|
|
|
|
const authorized = [
|
|
|
|
account || publicRoute,
|
|
|
|
developerOnly ? settings.get('isDeveloper') : true,
|
|
|
|
staffOnly ? account && account.staff : true,
|
|
|
|
adminOnly ? account && account.admin : true,
|
|
|
|
].every(c => c);
|
|
|
|
|
|
|
|
if (!authorized) {
|
|
|
|
if (!account) {
|
|
|
|
return loginRedirect();
|
|
|
|
} else {
|
|
|
|
return renderForbidden();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-28 16:18:55 -07:00
|
|
|
const renderBody = (props: RouteComponentProps) => {
|
|
|
|
return (
|
|
|
|
<Layout>
|
|
|
|
<Layout.Sidebar>
|
|
|
|
<SidebarNavigation />
|
|
|
|
</Layout.Sidebar>
|
|
|
|
|
|
|
|
{renderComponent(props)}
|
|
|
|
</Layout>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
return <Route {...rest} render={renderBody} />;
|
2022-04-26 10:01:57 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
export {
|
|
|
|
WrappedRoute,
|
|
|
|
};
|