96 lines
2.2 KiB
TypeScript
96 lines
2.2 KiB
TypeScript
import React, { useEffect, useState, ReactNode, ComponentType } from "react";
|
|
import styled from "styled-components";
|
|
import { RouteComponentProps, Redirect } from "react-router-dom";
|
|
import colors from "@theme/colors";
|
|
import breakpoints from "@theme/breakpoints";
|
|
import AdminHeader from "@components/AdminHeader";
|
|
import AdminSidebar from "@components/AdminSidebar";
|
|
import { isAuthenticated } from "@utils/auth";
|
|
|
|
const Main = styled.main`
|
|
display: flex;
|
|
color: ${colors.white};
|
|
background-color: ${colors.darkBlue};
|
|
flex-flow: row nowrap;
|
|
justify-content: flex-start;
|
|
align-items: flex-start;
|
|
flex: 1;
|
|
|
|
h1 {
|
|
margin-top: 0;
|
|
}
|
|
|
|
& > div {
|
|
padding: 0 1rem;
|
|
width: 100%;
|
|
max-width: 1000px;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
@media screen and (max-width: ${breakpoints.mobile}) {
|
|
flex-flow: column nowrap;
|
|
|
|
& > nav {
|
|
width: 100%;
|
|
}
|
|
}
|
|
`;
|
|
|
|
|
|
const useShouldRedirect = (enabled = true) => {
|
|
const [redirecting, setRedirect] = useState(false);
|
|
const [completed, setCompleted] = useState(!enabled);
|
|
|
|
useEffect(() => {
|
|
if (enabled) {
|
|
isAuthenticated().then((result) => {
|
|
setRedirect(!result);
|
|
setCompleted(true);
|
|
});
|
|
}
|
|
}, []);
|
|
|
|
return {
|
|
redirecting,
|
|
completed
|
|
};
|
|
}
|
|
|
|
|
|
type PageProps = RouteComponentProps & {
|
|
page: ComponentType;
|
|
requiresAuthentication: boolean;
|
|
}
|
|
|
|
const PageWrapper: React.FC<PageProps> = ({ page, requiresAuthentication, ...props }) => {
|
|
const { path } = props.match;
|
|
const Page = page;
|
|
const { completed, redirecting } = useShouldRedirect(requiresAuthentication);
|
|
|
|
if (redirecting) {
|
|
const loginURL = `/admin/login?next=${path}`;
|
|
return <Redirect to={loginURL} />;
|
|
}
|
|
|
|
// TODO: Loading screen
|
|
if (!completed) {
|
|
return <>Loading</>;
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<AdminHeader />
|
|
<Main>
|
|
<AdminSidebar path={path} />
|
|
<Page {...props} />
|
|
</Main>
|
|
</>
|
|
)
|
|
}
|
|
|
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
const renderPage = (Page: ReactNode, requiresAuthentication = true) => (props: any): JSX.Element => (
|
|
<PageWrapper page={Page} requiresAuthentication={requiresAuthentication} {...props} />
|
|
);
|
|
|
|
export default renderPage; |