diff --git a/frontend/index.html b/frontend/index.html index b13d84f2..8cb7c97a 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -24,7 +24,7 @@ limitations under the License. matrix-authentication-service - +
diff --git a/frontend/package-lock.json b/frontend/package-lock.json index c9ca823b..1141cd76 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -11,6 +11,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-relay": "^14.1.0", + "react-router-dom": "^6.4.3", "relay-runtime": "^14.1.0" }, "devDependencies": { @@ -2648,6 +2649,14 @@ "node": ">=10.12.0" } }, + "node_modules/@remix-run/router": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.0.3.tgz", + "integrity": "sha512-ceuyTSs7PZ/tQqi19YZNBc5X7kj1f8p+4DIyrcIYFY9h+hd1OKm4RqtiWldR9eGEvIiJfsqwM4BsuCtRIuEw6Q==", + "engines": { + "node": ">=14" + } + }, "node_modules/@repeaterjs/repeater": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@repeaterjs/repeater/-/repeater-3.0.4.tgz", @@ -6983,6 +6992,36 @@ "react": "^16.9.0 || ^17 || ^18" } }, + "node_modules/react-router": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.4.3.tgz", + "integrity": "sha512-BT6DoGn6aV1FVP5yfODMOiieakp3z46P1Fk0RNzJMACzE7C339sFuHebfvWtnB4pzBvXXkHP2vscJzWRuUjTtA==", + "dependencies": { + "@remix-run/router": "1.0.3" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.4.3.tgz", + "integrity": "sha512-MiaYQU8CwVCaOfJdYvt84KQNjT78VF0TJrA17SIQgNHRvLnXDJO6qsFqq8F/zzB1BWZjCFIrQpu4QxcshitziQ==", + "dependencies": { + "@remix-run/router": "1.0.3", + "react-router": "6.4.3" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -9927,6 +9966,11 @@ "webcrypto-core": "^1.7.4" } }, + "@remix-run/router": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.0.3.tgz", + "integrity": "sha512-ceuyTSs7PZ/tQqi19YZNBc5X7kj1f8p+4DIyrcIYFY9h+hd1OKm4RqtiWldR9eGEvIiJfsqwM4BsuCtRIuEw6Q==" + }, "@repeaterjs/repeater": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@repeaterjs/repeater/-/repeater-3.0.4.tgz", @@ -12972,6 +13016,23 @@ "relay-runtime": "14.1.0" } }, + "react-router": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.4.3.tgz", + "integrity": "sha512-BT6DoGn6aV1FVP5yfODMOiieakp3z46P1Fk0RNzJMACzE7C339sFuHebfvWtnB4pzBvXXkHP2vscJzWRuUjTtA==", + "requires": { + "@remix-run/router": "1.0.3" + } + }, + "react-router-dom": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.4.3.tgz", + "integrity": "sha512-MiaYQU8CwVCaOfJdYvt84KQNjT78VF0TJrA17SIQgNHRvLnXDJO6qsFqq8F/zzB1BWZjCFIrQpu4QxcshitziQ==", + "requires": { + "@remix-run/router": "1.0.3", + "react-router": "6.4.3" + } + }, "read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index ebcc56f7..160a08e3 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -15,6 +15,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-relay": "^14.1.0", + "react-router-dom": "^6.4.3", "relay-runtime": "^14.1.0" }, "devDependencies": { diff --git a/frontend/src/Router.tsx b/frontend/src/Router.tsx new file mode 100644 index 00000000..f62b6bbd --- /dev/null +++ b/frontend/src/Router.tsx @@ -0,0 +1,48 @@ +// Copyright 2022 The Matrix.org Foundation C.I.C. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { lazy, Suspense } from "react"; +import { createHashRouter, Outlet, RouterProvider } from "react-router-dom"; + +import Layout from "./components/Layout"; +import LoadingSpinner from "./components/LoadingSpinner"; + +const Home = lazy(() => import("./pages/Home")); + +export const router = createHashRouter([ + { + path: "/", + element: ( + + }> + + + + ), + children: [ + { + index: true, + element: , + }, + { + path: "dumb", + element: <>Hello from another dumb page., + }, + ], + }, +]); + +const Router = () => ; + +export default Router; diff --git a/frontend/src/components/Layout.tsx b/frontend/src/components/Layout.tsx new file mode 100644 index 00000000..467fb380 --- /dev/null +++ b/frontend/src/components/Layout.tsx @@ -0,0 +1,31 @@ +// Copyright 2022 The Matrix.org Foundation C.I.C. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import NavBar from "./NavBar"; +import NavItem from "./NavItem"; + +const Layout: React.FC<{ children?: React.ReactNode }> = ({ children }) => { + return ( +
+ + Home + Dumb + + +
{children}
+
+ ); +}; + +export default Layout; diff --git a/frontend/src/components/LoadingScreen.tsx b/frontend/src/components/LoadingScreen.tsx new file mode 100644 index 00000000..6071f39a --- /dev/null +++ b/frontend/src/components/LoadingScreen.tsx @@ -0,0 +1,23 @@ +// Copyright 2022 The Matrix.org Foundation C.I.C. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import LoadingSpinner from "./LoadingSpinner"; + +const LoadingScreen: React.FC = () => ( +
+ +
+); + +export default LoadingScreen; diff --git a/frontend/src/components/LoadingSpinner.tsx b/frontend/src/components/LoadingSpinner.tsx new file mode 100644 index 00000000..c7472510 --- /dev/null +++ b/frontend/src/components/LoadingSpinner.tsx @@ -0,0 +1,34 @@ +// Copyright 2022 The Matrix.org Foundation C.I.C. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import React from "react"; + +const LoadingSpinner: React.FC = () => ( +
+ + + + Loading... +
+); + +export default LoadingSpinner; diff --git a/frontend/src/components/NavBar.tsx b/frontend/src/components/NavBar.tsx new file mode 100644 index 00000000..3184f2b9 --- /dev/null +++ b/frontend/src/components/NavBar.tsx @@ -0,0 +1,24 @@ +// Copyright 2022 The Matrix.org Foundation C.I.C. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +const NavBar: React.FC<{ + className: string; + children: React.ReactNode; +}> = ({ className, children }) => ( + +); + +export default NavBar; diff --git a/frontend/src/components/NavItem.tsx b/frontend/src/components/NavItem.tsx new file mode 100644 index 00000000..acea1b13 --- /dev/null +++ b/frontend/src/components/NavItem.tsx @@ -0,0 +1,36 @@ +// Copyright 2022 The Matrix.org Foundation C.I.C. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { NavLink } from "react-router-dom"; + +const NavItem: React.FC<{ to: string; children: React.ReactNode }> = ({ + to, + children, +}) => ( +
  • + + (isActive + ? "bg-accent text-white" + : "hover:bg-grey-100 dark:hover:bg-grey-450 opacity-80 hover:opacity-100") + + " p-2 rounded block uppercase font-medium" + } + > + {children} + +
  • +); + +export default NavItem; diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx index 5823ab87..8d4a944e 100644 --- a/frontend/src/main.tsx +++ b/frontend/src/main.tsx @@ -12,18 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from "react"; +import React, { lazy } from "react"; import ReactDOM from "react-dom/client"; import { RelayEnvironmentProvider } from "react-relay"; -import { App } from "./App"; +import LoadingScreen from "./components/LoadingScreen"; import RelayEnvironment from "./RelayEnvironment"; +const Router = lazy(() => import("./Router")); + ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( - - + }> + diff --git a/frontend/src/App.tsx b/frontend/src/pages/Home.tsx similarity index 74% rename from frontend/src/App.tsx rename to frontend/src/pages/Home.tsx index 1e41e611..3e360019 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/pages/Home.tsx @@ -12,15 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from "react"; import { graphql, useLazyLoadQuery } from "react-relay"; -import type { AppQuery } from "./__generated__/AppQuery.graphql"; +import type { HomeQuery } from "./__generated__/HomeQuery.graphql"; -export const App: React.FC = () => { - const data = useLazyLoadQuery( +const Home: React.FC = () => { + const data = useLazyLoadQuery( graphql` - query AppQuery { + query HomeQuery { currentUser { id username @@ -32,9 +31,15 @@ export const App: React.FC = () => { if (data.currentUser) { return ( -

    Hello {data.currentUser.username}!

    + <> +

    + Hello {data.currentUser.username}! +

    + ); } else { return
    You're not logged in.
    ; } }; + +export default Home; diff --git a/frontend/src/__generated__/AppQuery.graphql.ts b/frontend/src/pages/__generated__/HomeQuery.graphql.ts similarity index 71% rename from frontend/src/__generated__/AppQuery.graphql.ts rename to frontend/src/pages/__generated__/HomeQuery.graphql.ts index 5df9dbf9..9435a099 100644 --- a/frontend/src/__generated__/AppQuery.graphql.ts +++ b/frontend/src/pages/__generated__/HomeQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<1d2a0ace12c4e6d2a684909c137cbc73>> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -9,16 +9,16 @@ // @ts-nocheck import { ConcreteRequest, Query } from 'relay-runtime'; -export type AppQuery$variables = {}; -export type AppQuery$data = { +export type HomeQuery$variables = {}; +export type HomeQuery$data = { readonly currentUser: { readonly id: string; readonly username: string; } | null; }; -export type AppQuery = { - response: AppQuery$data; - variables: AppQuery$variables; +export type HomeQuery = { + response: HomeQuery$data; + variables: HomeQuery$variables; }; const node: ConcreteRequest = (function(){ @@ -54,7 +54,7 @@ return { "argumentDefinitions": [], "kind": "Fragment", "metadata": null, - "name": "AppQuery", + "name": "HomeQuery", "selections": (v0/*: any*/), "type": "RootQuery", "abstractKey": null @@ -63,20 +63,20 @@ return { "operation": { "argumentDefinitions": [], "kind": "Operation", - "name": "AppQuery", + "name": "HomeQuery", "selections": (v0/*: any*/) }, "params": { - "cacheID": "34c6b7534570705caab3d20018e06721", + "cacheID": "ed11a3960d77e44416be48bbade86350", "id": null, "metadata": {}, - "name": "AppQuery", + "name": "HomeQuery", "operationKind": "query", - "text": "query AppQuery {\n currentUser {\n id\n username\n }\n}\n" + "text": "query HomeQuery {\n currentUser {\n id\n username\n }\n}\n" } }; })(); -(node as any).hash = "25e4287bcbdf0f3f35028d4be484dda9"; +(node as any).hash = "9746f86ec5c6368af275e5eb2789bff7"; export default node;