- Fahrzeuge der Strecke {track_data?.start} - {track_data?.end}
-
+
+
+ Fahrzeuge der Strecke {track_data?.start} - {track_data?.end}
+
+
+
>
);
diff --git a/Website/src/app/components/dynmap.tsx b/Website/src/app/components/dynmap.tsx
index b403f645..3386b58f 100644
--- a/Website/src/app/components/dynmap.tsx
+++ b/Website/src/app/components/dynmap.tsx
@@ -6,6 +6,7 @@ import useSWR from "swr";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { getFetcher } from "@/utils/fetcher";
+import { SelectTrackButton } from "@/app/components/selectTrackButton";
// This complicated thing with `dynamic` is necessary to disable server side rendering
// for the actual map, which does not work with leaflet.
@@ -76,6 +77,10 @@ export default function DynamicMap({
setFocus
}}
/>
+ {/* This will stack over the map, if all map layers have a z-index < 1100 (which should be the default) */}
+
-
- )
+export function FormWrapper({ children }: { children: React.ReactNode }) {
+ return (
+
+
{children}
+
+ );
}
// TODO: create a component for a form in a dialog to replace/refactor
-// the LoginDialog and SelectionDialog components.
\ No newline at end of file
+// the LoginDialog and SelectionDialog components.
diff --git a/Website/src/app/components/layout/header.tsx b/Website/src/app/components/layout/header.tsx
index babaec65..3b55a5ef 100644
--- a/Website/src/app/components/layout/header.tsx
+++ b/Website/src/app/components/layout/header.tsx
@@ -1,5 +1,6 @@
import Link from "next/link";
import { CurrentUser } from "@/app/components/layout/currentUser";
+import SmartNavigation from "@/app/components/layout/smart_navigation";
/**
* The header for the web page
@@ -8,18 +9,22 @@ export default function Header() {
return (
RailTrail Verwaltung
-
+
{/* Force a line break for small devices */}
-
+
-
Foo
-
Bar
-
Baz
+ Karte
+ Liste
+
+ Karte + Liste
+
+
+ Datenverwaltung
);
}
diff --git a/Website/src/app/components/layout/smart_navigation.tsx b/Website/src/app/components/layout/smart_navigation.tsx
new file mode 100644
index 00000000..7b287e57
--- /dev/null
+++ b/Website/src/app/components/layout/smart_navigation.tsx
@@ -0,0 +1,39 @@
+"use client";
+
+import Link, { LinkProps } from "next/link";
+import { usePathname } from "next/navigation";
+import { PropsWithChildren } from "react";
+
+/**
+ * A navigation link that has a different style when the user is on the page it links to, or on a sub-page
+ * @param href The URL to navigate to
+ * @param className CSS classes for the enclosing div
+ * @param activeClassName Additional CSS classes for the enclosing div, when active
+ * @param linkClassName The CSS classes for the anchor tag
+ * @param children The contents in the anchor tag
+ * @param props Other options applicable to
+ * @constructor
+ */
+export default function SmartNavigation({
+ href,
+ className = "px-2 border-2 border-transparent",
+ linkClassName,
+ children,
+ ...props
+}: PropsWithChildren) {
+ // get the path of the currently open page
+ const currentPath = usePathname();
+
+ // and determine if we are currently on that path
+ const active = (currentPath === href || currentPath?.startsWith(href + "/")) ?? false;
+
+ const activeClassName = "bg-neutral-500/20 !border-gray-500 rounded";
+
+ return (
+
+
+ {children}
+
+
+ );
+}
diff --git a/Website/src/app/components/selectTrackButton.tsx b/Website/src/app/components/selectTrackButton.tsx
new file mode 100644
index 00000000..0e2e5b48
--- /dev/null
+++ b/Website/src/app/components/selectTrackButton.tsx
@@ -0,0 +1,14 @@
+import Link from "next/link";
+
+/**
+ * A link that somewhat resembles a button to select a different track.
+ */
+export function SelectTrackButton() {
+ return (
+
+ Andere Strecke wählen
+
+ );
+}
diff --git a/Website/src/app/components/track_selection.tsx b/Website/src/app/components/track_selection.tsx
index dc9b60cd..12e8c6a4 100644
--- a/Website/src/app/components/track_selection.tsx
+++ b/Website/src/app/components/track_selection.tsx
@@ -1,10 +1,8 @@
-"use client";
-
import { Dispatch, FormEventHandler, PropsWithChildren, useEffect, useRef, useState } from "react";
import Footer from "@/app/components/layout/footer";
import useSWR from "swr";
-import { setCookie } from "cookies-next";
+import { getCookie, setCookie } from "cookies-next";
import { inter } from "@/utils/common";
import { getFetcher } from "@/utils/fetcher";
import { useRouter } from "next/navigation";
@@ -24,6 +22,7 @@ export default function Selection({
const { data, error, isLoading } = useSWR("/webapi/tracks/list", getFetcher<"/webapi/tracks/list">);
// get the next page router
const router = useRouter();
+ const selectedTrack = getCookie("track_id")?.toString();
const selectTrack: FormEventHandler = e => {
e.preventDefault();
@@ -41,7 +40,7 @@ export default function Selection({
};
return (
-