diff --git a/frontend/package-lock.json b/frontend/package-lock.json index cbd3ca61..4a9cfdb0 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -9,7 +9,8 @@ "version": "0.0.0", "dependencies": { "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-router-dom": "^6.22.2" }, "devDependencies": { "@types/react": "^18.2.56", @@ -991,6 +992,14 @@ "node": ">= 8" } }, + "node_modules/@remix-run/router": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.2.tgz", + "integrity": "sha512-+Rnav+CaoTE5QJc4Jcwh5toUpnVLKYbpU6Ys0zqbakqbaLQHeglLVHPfxOiQqdNmUy5C2lXz5dwC6tQNX2JW2Q==", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.12.0.tgz", @@ -3875,6 +3884,36 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.22.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.2.tgz", + "integrity": "sha512-YD3Dzprzpcq+tBMHBS822tCjnWD3iIZbTeSXMY9LPSG541EfoBGyZ3bS25KEnaZjLcmQpw2AVLkFyfgXY8uvcw==", + "dependencies": { + "@remix-run/router": "1.15.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.22.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.2.tgz", + "integrity": "sha512-WgqxD2qySEIBPZ3w0sHH+PUAiamDeszls9tzqMPBDA1YYVucTBXLU7+gtRfcSnhe92A3glPnvSxK2dhNoAVOIQ==", + "dependencies": { + "@remix-run/router": "1.15.2", + "react-router": "6.22.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.5.tgz", diff --git a/frontend/package.json b/frontend/package.json index 7e34d8ff..2649e602 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -6,12 +6,13 @@ "scripts": { "dev": "vite", "build": "tsc && vite build", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "lint": "tsc --noEmit && eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview" }, "dependencies": { "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-router-dom": "^6.22.2" }, "devDependencies": { "@types/react": "^18.2.56", diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx index 3d7150da..2912f985 100644 --- a/frontend/src/main.tsx +++ b/frontend/src/main.tsx @@ -1,10 +1,39 @@ import React from 'react' import ReactDOM from 'react-dom/client' -import App from './App.tsx' +import {createBrowserRouter, RouterProvider,} from "react-router-dom"; import './index.css' +import Root from './pages/root.tsx' +import ErrorPage from './pages/error.tsx' +import LoginScreen from "./pages/login/LoginScreen.tsx"; +import HomeAdmin from "./pages/admin/HomeAdmin.tsx"; +import HomeStudent from "./pages/student/HomeStudent.tsx"; +import HomeTeacher from "./pages/teacher/HomeTeacher.tsx"; +const router = createBrowserRouter([ + { + path: "/", + element: , + errorElement: + }, + { + path: "/login", + element: + }, + { + path: "/admin", + element: + }, + { + path: "/student", + element: + }, + { + path: "/teacher", + element: + } +]); ReactDOM.createRoot(document.getElementById('root')!).render( - + , ) diff --git a/frontend/src/pages/admin/HomeAdmin.tsx b/frontend/src/pages/admin/HomeAdmin.tsx index bc8e262e..287be44d 100644 --- a/frontend/src/pages/admin/HomeAdmin.tsx +++ b/frontend/src/pages/admin/HomeAdmin.tsx @@ -1,6 +1,6 @@ import {JSX} from "react"; -export function HomeAdmin(): JSX.Element { +export default function HomeAdmin(): JSX.Element { return ( <>Homescreen for an admin ) diff --git a/frontend/src/pages/error.tsx b/frontend/src/pages/error.tsx new file mode 100644 index 00000000..5d059a1e --- /dev/null +++ b/frontend/src/pages/error.tsx @@ -0,0 +1,38 @@ +import {isRouteErrorResponse, useRouteError} from "react-router-dom"; +import {JSX} from 'react'; + +export default function ErrorPage(): JSX.Element { + const error = useRouteError(); + console.error(error); + + return ( +
+

Oops!

+

Sorry, an unexpected error has occurred.

+

+ {errorMessage(error)} +

+
+ ); +} + +interface RouterError extends Error {} + +function isRouterError(object: unknown): object is RouterError { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + return 'message' in object; +} + +function errorMessage(error: unknown): string { + if (isRouteErrorResponse(error)) { + return `${error.status} ${error.statusText}` + } else if (error != undefined && isRouterError(error)) { + return error.message; + } else if (typeof error === 'string') { + return error + } else { + console.error(error) + return 'Unknown error' + } +} \ No newline at end of file diff --git a/frontend/src/pages/login/LoginScreen.tsx b/frontend/src/pages/login/LoginScreen.tsx index cb2d874d..b109f9af 100644 --- a/frontend/src/pages/login/LoginScreen.tsx +++ b/frontend/src/pages/login/LoginScreen.tsx @@ -1,6 +1,6 @@ import {JSX} from "react"; -export function LoginScreen(): JSX.Element { +export default function LoginScreen(): JSX.Element { return ( <>Login screen ) diff --git a/frontend/src/pages/root.tsx b/frontend/src/pages/root.tsx new file mode 100644 index 00000000..486b9417 --- /dev/null +++ b/frontend/src/pages/root.tsx @@ -0,0 +1,12 @@ +import {JSX} from "react"; +import {Link} from "react-router-dom"; + +export default function Root(): JSX.Element { + // TODO: logic to send user to /login or + return ( + <> + <>Redirecting ... + goto login page + +) +} \ No newline at end of file diff --git a/frontend/src/pages/student/HomeStudent.tsx b/frontend/src/pages/student/HomeStudent.tsx index e83c8057..19404c00 100644 --- a/frontend/src/pages/student/HomeStudent.tsx +++ b/frontend/src/pages/student/HomeStudent.tsx @@ -1,6 +1,6 @@ import {JSX} from "react"; -export function HomeStudent(): JSX.Element { +export default function HomeStudent(): JSX.Element { return ( <>Homescreen for a student ) diff --git a/frontend/src/pages/teacher/HomeTeacher.tsx b/frontend/src/pages/teacher/HomeTeacher.tsx index b6f01b7c..5ff9bbe1 100644 --- a/frontend/src/pages/teacher/HomeTeacher.tsx +++ b/frontend/src/pages/teacher/HomeTeacher.tsx @@ -1,6 +1,6 @@ import {JSX} from "react"; -export function HomeTeacher(): JSX.Element { +export default function HomeTeacher(): JSX.Element { return ( <>Homescreen for a teacher )