diff --git a/app/contexts/apollo/apolloClientProvider.tsx b/app/contexts/apollo/apolloClientProvider.tsx index e4f7632..d945b4c 100644 --- a/app/contexts/apollo/apolloClientProvider.tsx +++ b/app/contexts/apollo/apolloClientProvider.tsx @@ -2,6 +2,7 @@ import { getApolloClient } from "~/utils"; import { ApolloProvider } from "@apollo/client"; import { useAuthenticationContext } from "../authentication/authenticationContext"; import { useMemo } from "react"; +import { useSettingsContext } from "../settings/settingsContext"; export const ApolloClientProvider = ({ children, @@ -9,14 +10,15 @@ export const ApolloClientProvider = ({ children: React.ReactNode; }) => { const { user } = useAuthenticationContext(); + const { graphqlUrl } = useSettingsContext(); const client = useMemo(() => { return getApolloClient( - sessionStorage.getItem("graphql_url"), + graphqlUrl, user?.jwt_token, { organization_id: user?.organization_id?.toString() }, window.__APOLLO_STATE__, ); - }, [user?.jwt_token, user?.organization_id]); + }, [user?.jwt_token, user?.organization_id, graphqlUrl]); return {children}; }; diff --git a/app/contexts/index.ts b/app/contexts/index.ts index 9cd1698..fda5a67 100644 --- a/app/contexts/index.ts +++ b/app/contexts/index.ts @@ -1,5 +1,7 @@ export * from "./authentication/authenticationContext"; -export * from "./authentication/AuthenticationClientProvider"; -export * from "./authentication/AuthenticationServerProvider"; +export * from "./authentication/authenticationClientProvider"; +export * from "./authentication/authenticationServerProvider"; export * from "./apollo/apolloClientProvider"; export * from "./apollo/apolloServerProvider"; +export * from "./settings/settingsServerProvider"; +export * from "./settings/settingsClientProvider"; diff --git a/app/contexts/settings/settingsClientProvider.tsx b/app/contexts/settings/settingsClientProvider.tsx new file mode 100644 index 0000000..0c2b76e --- /dev/null +++ b/app/contexts/settings/settingsClientProvider.tsx @@ -0,0 +1,24 @@ +import { useState } from "react"; + +import { SettingsContext } from "./settingsContext"; + +export const SettingsClientProvider = ({ + children, +}: { + children: React.ReactNode; +}) => { + const [graphqlUrl] = useState(window.__GRAPHQLURL__); + const [navBarOpen, setNavBarOpen] = useState(true); + + return ( + + {children} + + ); +}; diff --git a/app/contexts/settings/settingsContext.ts b/app/contexts/settings/settingsContext.ts new file mode 100644 index 0000000..d47bc3a --- /dev/null +++ b/app/contexts/settings/settingsContext.ts @@ -0,0 +1,12 @@ +import React from "react"; +import { Settings } from "~/models/settings"; + +export const SettingsContext = React.createContext({ + graphqlUrl: "", + navBarOpen: false, + setNavBarOpen: () => false, +}); + +export function useSettingsContext() { + return React.useContext(SettingsContext); +} diff --git a/app/contexts/settings/settingsServerProvider.tsx b/app/contexts/settings/settingsServerProvider.tsx new file mode 100644 index 0000000..192ae4e --- /dev/null +++ b/app/contexts/settings/settingsServerProvider.tsx @@ -0,0 +1,21 @@ +import { SettingsContext } from "./settingsContext"; + +export const SettingsServerProvider = ({ + graphqlUrl, + children, +}: { + graphqlUrl: string; + children: React.ReactNode; +}) => { + return ( + {}, + }} + > + {children} + + ); +}; diff --git a/app/entry.client.tsx b/app/entry.client.tsx index e63201e..ca8defd 100644 --- a/app/entry.client.tsx +++ b/app/entry.client.tsx @@ -8,19 +8,25 @@ import { ThemeProvider } from "@material-tailwind/react"; import { RemixBrowser } from "@remix-run/react"; import { startTransition, StrictMode } from "react"; import { hydrateRoot } from "react-dom/client"; -import { ApolloClientProvider, AuthenticationClientProvider } from "./contexts"; +import { + ApolloClientProvider, + AuthenticationClientProvider, + SettingsClientProvider, +} from "./contexts"; startTransition(() => { hydrateRoot( document, - - - - - - - + + + + + + + + + , ); }); diff --git a/app/entry.server.tsx b/app/entry.server.tsx index c241b19..39a2751 100644 --- a/app/entry.server.tsx +++ b/app/entry.server.tsx @@ -17,7 +17,11 @@ import { getDataFromTree } from "@apollo/client/react/ssr"; import { authenticator } from "./services/auth.server"; import type { ReactElement } from "react"; import * as utils from "./utils"; -import { AuthenticationServerProvider, ApolloServerProvider } from "./contexts"; +import { + AuthenticationServerProvider, + ApolloServerProvider, + SettingsServerProvider, +} from "./contexts"; import { User } from "./models/user"; const ABORT_DELAY = 5_000; @@ -169,7 +173,8 @@ async function wrapRemixServerWithApollo( dangerouslySetInnerHTML={{ __html: ` window.__APOLLO_STATE__=${serializeState(initialState)}; - window.__USER_STATE__=${serializeState(user)}`, + window.__USER_STATE__=${serializeState(user)}; + window.__GRAPHQLURL__=${serializeState(process.env.GRAPHQL_SCHEMA_URL)};`, }} /> @@ -195,8 +200,17 @@ function getServerApp( remixServer: ReactElement, ) { return ( - - {remixServer} - + + + + {remixServer} + + + ); } diff --git a/app/models/settings.ts b/app/models/settings.ts index fa063e8..a9e1c83 100644 --- a/app/models/settings.ts +++ b/app/models/settings.ts @@ -1,3 +1,5 @@ export type Settings = { - graphql_url: string; + graphqlUrl: string; + navBarOpen: boolean; + setNavBarOpen: (open: boolean) => void; }; diff --git a/app/routes/_dashboard.tsx b/app/routes/_dashboard.tsx index 3b6f942..97aa6ab 100644 --- a/app/routes/_dashboard.tsx +++ b/app/routes/_dashboard.tsx @@ -1,38 +1,16 @@ -import { Outlet, useLoaderData } from "@remix-run/react"; +import { Outlet } from "@remix-run/react"; import { IconButton } from "@material-tailwind/react"; import { Cog6ToothIcon } from "@heroicons/react/24/solid"; import { Sidenav, DashboardNavbar, Footer } from "~/widgets/layout"; import { getRoutes } from "~/routesData"; -import { authenticator } from "~/services/auth.server"; -import { LoaderFunctionArgs, redirect } from "@remix-run/node"; -import { useEffect } from "react"; -import { Settings } from "~/models/settings"; import { useAuthenticationContext } from "~/contexts/authentication/authenticationContext"; -export async function loader({ request }: LoaderFunctionArgs) { - let user = await authenticator.isAuthenticated(request); - if (!user && request.url.indexOf("/signin") == -1) return redirect("/signin"); //TODO: any danger of infinite loop? - - const settings: Settings = { graphql_url: process.env.GRAPHQL_SCHEMA_URL! }; - return { user, settings }; -} - -function useSettings() { - const data = useLoaderData(); - return data.settings; -} - export default function Dashboard() { - //TODO: change the followings to get value from context + //TODO: change the followings to get value from settings context const sidenavType = getRoutes == null ? "dark" : "white"; // this fake comparison is to avoid TS error only. - const settings = useSettings(); const { user } = useAuthenticationContext(); - useEffect(() => { - sessionStorage.setItem("graphql_url", settings.graphql_url); - }, [settings.graphql_url]); - return (
(); - return data.settings; -} - export default function Site() { - const settings = useSettings(); - - useEffect(() => { - sessionStorage.setItem("graphql_url", settings.graphql_url); - }, [settings.graphql_url]); - return ( <>
diff --git a/remix.env.d.ts b/remix.env.d.ts index 3a15a38..3bd0dd4 100644 --- a/remix.env.d.ts +++ b/remix.env.d.ts @@ -4,4 +4,5 @@ interface Window { __APOLLO_STATE__: any; __USER_STATE__: any; + __GRAPHQLURL__: string; }