diff --git a/web/src/shell/app-shell.test.tsx b/web/src/shell/app-shell.test.tsx new file mode 100644 index 0000000..1e58ec9 --- /dev/null +++ b/web/src/shell/app-shell.test.tsx @@ -0,0 +1,40 @@ +import { expect, test, beforeEach, afterEach } from "vitest"; +import { screen, waitFor } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import { Routes, Route } from "react-router-dom"; +import i18n from "../i18n"; +import { renderApp } from "../test/render"; +import { AppShell } from "./app-shell"; + +beforeEach(async () => { + await i18n.changeLanguage("en"); +}); + +afterEach(async () => { + await i18n.changeLanguage("en"); +}); + +function tree() { + return ( + + }> + objects outlet} /> + + login page} /> + + ); +} + +test("shows active and disabled nav and renders the outlet", async () => { + renderApp(tree(), { route: "/objects" }); + expect(await screen.findByText("objects outlet")).toBeInTheDocument(); + expect(screen.getByRole("link", { name: /objects/i })).toBeInTheDocument(); + // later milestones are present but disabled + expect(screen.getByRole("button", { name: /search/i })).toBeDisabled(); +}); + +test("language switch toggles to Swedish", async () => { + renderApp(tree(), { route: "/objects" }); + await userEvent.click(await screen.findByRole("button", { name: "SV" })); + await waitFor(() => expect(screen.getByText("Föremål")).toBeInTheDocument()); +}); diff --git a/web/src/shell/app-shell.tsx b/web/src/shell/app-shell.tsx new file mode 100644 index 0000000..2ff6c69 --- /dev/null +++ b/web/src/shell/app-shell.tsx @@ -0,0 +1,59 @@ +import { NavLink, Outlet, useNavigate } from "react-router-dom"; +import { useTranslation } from "react-i18next"; + +import { useLogout } from "../api/queries"; +import { Button } from "@/components/ui/button"; +import { LangSwitch } from "./lang-switch"; + +const FUTURE = ["vocabularies", "authorities", "fields", "search"] as const; + +export function AppShell() { + const { t } = useTranslation(); + const navigate = useNavigate(); + const logout = useLogout(); + + const onSignOut = () => + logout.mutate(undefined, { + onSuccess: () => navigate("/login", { replace: true }), + }); + + return ( +
+ +
+
+
+ + +
+
+ +
+
+
+ ); +} diff --git a/web/src/shell/lang-switch.tsx b/web/src/shell/lang-switch.tsx new file mode 100644 index 0000000..67b9090 --- /dev/null +++ b/web/src/shell/lang-switch.tsx @@ -0,0 +1,21 @@ +import { useLocale } from "../i18n/use-locale"; + +export function LangSwitch() { + const { locale, setLocale } = useLocale(); + const base = locale.startsWith("sv") ? "sv" : "en"; + + return ( +
+ {(["sv", "en"] as const).map((lng) => ( + + ))} +
+ ); +}