diff --git a/editor.planx.uk/src/components/AuthenticatedLayout.tsx b/editor.planx.uk/src/components/AuthenticatedLayout.tsx deleted file mode 100644 index de5adc1556..0000000000 --- a/editor.planx.uk/src/components/AuthenticatedLayout.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import React from "react"; -import { DndProvider } from "react-dnd"; -import { HTML5Backend } from "react-dnd-html5-backend"; -import { View } from "react-navi"; - -import Header from "./Header"; - -const Layout: React.FC = () => ( - <> -
- - - - -); - -export default Layout; diff --git a/editor.planx.uk/src/index.tsx b/editor.planx.uk/src/index.tsx index e1e46e621b..ba91f8afe2 100644 --- a/editor.planx.uk/src/index.tsx +++ b/editor.planx.uk/src/index.tsx @@ -13,7 +13,6 @@ import jwtDecode from "jwt-decode"; import { getCookie, setCookie } from "lib/cookie"; import ErrorPage from "pages/ErrorPage"; import { AnalyticsProvider } from "pages/FlowEditor/lib/analyticsProvider"; -import { useStore } from "pages/FlowEditor/lib/store"; import React, { Suspense, useEffect } from "react"; import { createRoot } from "react-dom/client"; import { NotFoundBoundary, Router, useLoadingRoute, View } from "react-navi"; @@ -47,7 +46,6 @@ const hasJWT = (): boolean | void => { ], ) > 0 ) { - useStore.getState().initUserStore(jwt); return true; } } catch (e) {} diff --git a/editor.planx.uk/src/pages/FlowEditor/lib/store/user.ts b/editor.planx.uk/src/pages/FlowEditor/lib/store/user.ts index ca4685e5d8..8191b184f2 100644 --- a/editor.planx.uk/src/pages/FlowEditor/lib/store/user.ts +++ b/editor.planx.uk/src/pages/FlowEditor/lib/store/user.ts @@ -16,7 +16,7 @@ export interface UserStore { setUser: (user: User) => void; getUser: () => User; canUserEditTeam: (teamSlug: Team["slug"]) => boolean; - initUserStore: (jwt: string) => void; + initUserStore: (jwt: string) => Promise; } export const userStore: StateCreator = ( @@ -53,11 +53,13 @@ export const userStore: StateCreator = ( return ( get().isPlatformAdmin || teamSlug === "templates" || - get().teams.filter((team) => team.role === "teamEditor" && team.team.slug === teamSlug).length > 0 + get().teams.filter( + (team) => team.role === "teamEditor" && team.team.slug === teamSlug, + ).length > 0 ); }, - async initUserStore (jwt: string) { + async initUserStore(jwt: string) { const email = (jwtDecode(jwt) as any)["email"]; const users = await client.query({ query: gql` diff --git a/editor.planx.uk/src/pages/layout/AuthenticatedLayout.tsx b/editor.planx.uk/src/pages/layout/AuthenticatedLayout.tsx new file mode 100644 index 0000000000..028fb10a4c --- /dev/null +++ b/editor.planx.uk/src/pages/layout/AuthenticatedLayout.tsx @@ -0,0 +1,14 @@ +import React, { PropsWithChildren } from "react"; +import { DndProvider } from "react-dnd"; +import { HTML5Backend } from "react-dnd-html5-backend"; + +import Header from "../../components/Header"; + +const Layout: React.FC = ({ children }) => ( + <> +
+ {children} + +); + +export default Layout; diff --git a/editor.planx.uk/src/routes/authenticated.tsx b/editor.planx.uk/src/routes/authenticated.tsx index 62f33b339a..d4a5806b5e 100644 --- a/editor.planx.uk/src/routes/authenticated.tsx +++ b/editor.planx.uk/src/routes/authenticated.tsx @@ -3,18 +3,18 @@ import { compose, lazy, mount, route, withData, withView } from "navi"; import { useStore } from "pages/FlowEditor/lib/store"; import React from "react"; -import AuthenticatedLayout from "../components/AuthenticatedLayout"; import { client } from "../lib/graphql"; import GlobalSettingsView from "../pages/GlobalSettings"; import Teams from "../pages/Teams"; import { makeTitle } from "./utils"; +import { authenticatedView } from "./views/authenticated"; const editorRoutes = compose( withData(() => ({ username: useStore.getState().getUser().firstName, })), - withView(() => ), + withView(authenticatedView), mount({ "/": route(async () => { diff --git a/editor.planx.uk/src/routes/views/authenticated.tsx b/editor.planx.uk/src/routes/views/authenticated.tsx new file mode 100644 index 0000000000..24b8470f78 --- /dev/null +++ b/editor.planx.uk/src/routes/views/authenticated.tsx @@ -0,0 +1,24 @@ +import { getCookie } from "lib/cookie"; +import { redirect } from "navi"; +import { useStore } from "pages/FlowEditor/lib/store"; +import React from "react"; +import { View } from "react-navi"; + +import AuthenticatedLayout from "../../pages/layout/AuthenticatedLayout"; + +/** + * View wrapper for all authenticated routes + * Parses JWT and inits user store + */ +export const authenticatedView = async () => { + const jwt = getCookie("jwt"); + if (!jwt) return redirect("/login"); + + await useStore.getState().initUserStore(jwt); + + return ( + + + + ); +};