app/index.tsx (118 lines of code) (raw):
import React, { useEffect, useState } from "react";
import { render } from "react-dom";
import { BrowserRouter, Route, Switch, withRouter } from "react-router-dom";
import NotFoundComponent from "./NotFoundComponent";
import OAuthCallbackComponent from "./login/OAuthCallbackComponent";
import RefreshLoginComponent from "./RefreshLoginComponent";
import StartingUpComponent from "./StartingUpComponent";
import {
Header,
AppSwitcher,
PlutoThemeProvider,
OAuthContextData,
} from "@guardian/pluto-headers";
import LoggedOutComponent from "./LoggedOutComponent";
import { OAuthContextProvider } from "@guardian/pluto-headers";
import { UserContextProvider } from "@guardian/pluto-headers";
import { JwtDataShape, verifyExistingLogin } from "@guardian/pluto-headers";
import { CssBaseline } from "@material-ui/core";
import Wallpaper from "./Wallpaper";
import NewRootComponent from "./NewRootComponent";
import axios from "axios";
import { makeStyles } from "@material-ui/core/styles";
import { SystemNotification } from "@guardian/pluto-headers";
axios.interceptors.request.use(function (config) {
const token = window.localStorage.getItem("pluto:access-token");
if (
config.url?.startsWith("/pluto-core") ||
config.url?.startsWith("/deliverables")
) {
if (token) config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
const useStyles = makeStyles((theme) => ({
rootContainer: {
width: "100vw",
height: "100vh",
overflowX: "hidden",
overflowY: "auto",
},
}));
const App: React.FC = () => {
const [startup, setStartup] = useState(false);
const [userProfile, setUserProfile] = useState<JwtDataShape | undefined>(
undefined
);
const classes = useStyles();
const haveToken = () => {
return window.localStorage.getItem("pluto:access-token");
};
const oAuthConfigLoaded = (oAuthConfig: OAuthContextData) => {
if (haveToken()) {
verifyExistingLogin(oAuthConfig)
.then((profile) => setUserProfile(profile))
.catch((err) =>
console.error("Could not verify existing user profile: ", err)
);
}
};
const logOutIfReferrer = () => {
//If the referring URL contains '/oauth2/callback' the user is trying
//to log in again so the access token should not be cleared.
if (!document.referrer.includes("/oauth2/callback")) {
window.localStorage.removeItem("pluto:access-token");
setUserProfile(undefined);
}
};
return (
<div className={classes.rootContainer}>
<PlutoThemeProvider>
<CssBaseline />
<Wallpaper />
<OAuthContextProvider onLoaded={oAuthConfigLoaded}>
<UserContextProvider
value={{
profile: userProfile,
updateProfile: (newValue) => setUserProfile(newValue),
}}
>
<Header />
{userProfile ? <AppSwitcher /> : undefined}
<Switch>
<Route
exact
path="/logout"
render={() => {
logOutIfReferrer();
return <LoggedOutComponent />;
}}
/>
<Route
path="/refreshlogin"
render={(props) => {
return startup ? (
<StartingUpComponent />
) : (
<RefreshLoginComponent />
);
}}
/>
<Route
exact
path="/oauth2/callback"
component={OAuthCallbackComponent}
/>
<Route exact path="/" component={NewRootComponent} />
<Route path="/" component={NotFoundComponent} />
</Switch>
<SystemNotification />
</UserContextProvider>
</OAuthContextProvider>
</PlutoThemeProvider>
</div>
);
};
const AppWithRouter = withRouter(App);
render(
<BrowserRouter basename="/">
<AppWithRouter />
</BrowserRouter>,
document.getElementById("app")
);