diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index 540ea4f..c2b2435 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -37,68 +37,70 @@ import {ThemeProvider} from "./contexts/theme"
function App({..._}: RouteComponentProps) {
return React.useMemo(
() => <>
-
-
-
-
- <>
-
- >}
- selectedRoute={() => <>
-
-
-
-
-
- <>
- <>
-
-
-
-
-
- <>
-
-
-
- >}
- selectedRoute={({selection}) => <>
-
-
- <>
-
-
-
- >}
- selectedRoute={({selection}) => <>
-
-
-
-
- >}
- />
-
- >}
- />
-
- >}
- />
- >}
- />
-
-
- >}
- />
-
+
+
+
+
+
+ <>
+
+ >}
+ selectedRoute={() => <>
+
+
+
+
+
+ <>
+ <>
+
+
+
+
+
+ <>
+
+
+
+ >}
+ selectedRoute={({selection}) => <>
+
+
+ <>
+
+
+
+ >}
+ selectedRoute={({selection}) => <>
+
+
+
+
+ >}
+ />
+
+ >}
+ />
+
+ >}
+ />
+ >}
+ />
+
+
+ >}
+ />
+
+
>,
[],
)
@@ -112,11 +114,9 @@ export default function AppWrapper() {
-
-
diff --git a/frontend/src/components/elements/GoBackButton.tsx b/frontend/src/components/elements/GoBackButton.tsx
new file mode 100644
index 0000000..2c1ed67
--- /dev/null
+++ b/frontend/src/components/elements/GoBackButton.tsx
@@ -0,0 +1,34 @@
+import {faLevelUpAlt} from "@fortawesome/free-solid-svg-icons"
+import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"
+import * as Reach from "@reach/router"
+import {Button} from "@steffo/bluelib-react"
+import {ButtonProps} from "@steffo/bluelib-react/dist/components/inputs/Button"
+import * as React from "react"
+import {useSophonPath} from "../../hooks/useSophonPath"
+
+
+/**
+ * A button that takes the user back one sophon level (so two levels).
+ *
+ * @constructor
+ */
+export function GoBackButton({onClick, ...props}: Omit): JSX.Element {
+ const location = useSophonPath()
+
+ const onClickWrapped = React.useCallback(
+ async event => {
+ event.preventDefault()
+ if(onClick) {
+ onClick(event)
+ }
+ await Reach.navigate("../..")
+ },
+ [onClick],
+ )
+
+ return (
+
+ )
+}
diff --git a/frontend/src/components/elements/NavigateButton.tsx b/frontend/src/components/elements/NavigateButton.tsx
new file mode 100644
index 0000000..08a5a0a
--- /dev/null
+++ b/frontend/src/components/elements/NavigateButton.tsx
@@ -0,0 +1,40 @@
+import * as Reach from "@reach/router"
+import {Button} from "@steffo/bluelib-react"
+import {ButtonProps} from "@steffo/bluelib-react/dist/components/inputs/Button"
+import * as React from "react"
+
+
+/**
+ * The props of {@link NavigateButton}.
+ */
+export interface NavigateButtonProps extends ButtonProps {
+ href: string,
+}
+
+
+/**
+ * A button functioning like a {@link Link}.
+ *
+ * @constructor
+ */
+export function NavigateButton({href, children, onClick, ...props}: NavigateButtonProps): JSX.Element {
+ const location = Reach.useLocation()
+
+ const onClickWrapped = React.useCallback(
+ event => {
+ event.preventDefault()
+ if(onClick) {
+ onClick(event)
+ }
+ if(href) {
+ // noinspection JSIgnoredPromiseFromCall
+ Reach.navigate(href)
+ }
+ },
+ [href, onClick],
+ )
+
+ return (
+
+ )
+}
diff --git a/frontend/src/components/errors/ErrorCatcherBox.tsx b/frontend/src/components/errors/ErrorCatcherBox.tsx
index 94c530b..2ba9d82 100644
--- a/frontend/src/components/errors/ErrorCatcherBox.tsx
+++ b/frontend/src/components/errors/ErrorCatcherBox.tsx
@@ -1,7 +1,9 @@
-import {Box, Form} from "@steffo/bluelib-react"
+import {faAngleDoubleRight, faBug} from "@fortawesome/free-solid-svg-icons"
+import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"
+import {Box, Button, Form} from "@steffo/bluelib-react"
import * as React from "react"
-import {IgnoreErrorButton} from "./IgnoreErrorButton"
-import {ReportBugButton} from "./ReportBugButton"
+import {GoBackButton} from "../elements/GoBackButton"
+import {NavigateButton} from "../elements/NavigateButton"
interface ErrorCatcherBoxProps {
@@ -44,8 +46,13 @@ export class ErrorCatcherBox extends React.Component
-
-
+
+ Report bug
+
+
+
diff --git a/frontend/src/components/errors/IgnoreErrorButton.tsx b/frontend/src/components/errors/IgnoreErrorButton.tsx
deleted file mode 100644
index 7795f3c..0000000
--- a/frontend/src/components/errors/IgnoreErrorButton.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import {faAngleDoubleRight} from "@fortawesome/free-solid-svg-icons"
-import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"
-import {Button} from "@steffo/bluelib-react"
-import * as React from "react"
-
-
-export interface IgnoreErrorButtonProps {
- onClick?: (event: React.MouseEvent) => void;
-}
-
-
-export function IgnoreErrorButton({onClick}: IgnoreErrorButtonProps): JSX.Element {
- return (
-
- )
-}
diff --git a/frontend/src/components/errors/ReportBugButton.tsx b/frontend/src/components/errors/ReportBugButton.tsx
deleted file mode 100644
index 8705b09..0000000
--- a/frontend/src/components/errors/ReportBugButton.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import {faBug} from "@fortawesome/free-solid-svg-icons"
-import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"
-import {navigate} from "@reach/router"
-import {Button} from "@steffo/bluelib-react"
-import * as React from "react"
-
-
-export function ReportBugButton(): JSX.Element {
- const onClick =
- React.useCallback(
- async () => {
- await navigate("https://github.com/Steffo99/sophon/issues/new?assignees=&labels=bug&template=1_bug_report.md&title=")
- },
- [],
- )
-
- return React.useMemo(
- () => (
-
- ),
- [onClick],
- )
-}
diff --git a/frontend/src/utils/ParsePath.ts b/frontend/src/utils/ParsePath.ts
index 57da1ad..28f5835 100644
--- a/frontend/src/utils/ParsePath.ts
+++ b/frontend/src/utils/ParsePath.ts
@@ -37,6 +37,11 @@ export interface ParsedPath {
* Passed the login page (either by browsing as guest or by logging in).
*/
loggedIn?: boolean,
+
+ /**
+ * The number of pages that separate this to the website root.
+ */
+ count: number,
}
/**
@@ -44,7 +49,9 @@ export interface ParsedPath {
* @param path - The path to split.
*/
export function parsePath(path: string): ParsedPath {
- let result: ParsedPath = {}
+ let result: ParsedPath = {
+ count: 0,
+ }
result.instance = path.match(/[/]i[/]([^/]+)/)?.[1]
result.userId = path.match(/[/]u[/]([0-9]+)/)?.[1]
@@ -54,5 +61,27 @@ export function parsePath(path: string): ParsedPath {
result.notebook = path.match(/[/]n[/]([A-Za-z0-9_-]+)/)?.[1]
result.loggedIn = Boolean(path.match(/[/]l[/]/))
+ if(result.instance) {
+ result.count += 1
+ }
+ if(result.userId) {
+ result.count += 1
+ }
+ if(result.userName) {
+ result.count += 1
+ }
+ if(result.researchGroup) {
+ result.count += 1
+ }
+ if(result.researchProject) {
+ result.count += 1
+ }
+ if(result.notebook) {
+ result.count += 1
+ }
+ if(result.loggedIn) {
+ result.count += 1
+ }
+
return result
}