From 30cbad7e7d60f2b8c1a72ab8b983b276e446d244 Mon Sep 17 00:00:00 2001 From: Julia Dai Date: Mon, 20 Oct 2025 18:57:43 +0200 Subject: [PATCH 1/3] vf-259 create routing tabs with default tabs --- app/components/routing-tabs.tsx | 64 +++++++++++++++++++ app/routes/dashboard.intervjuer._index.tsx | 3 + .../dashboard.intervjufordeling._index.tsx | 3 + app/routes/dashboard.sokere._index.tsx | 2 + ...dashboard.tidligere-assistenter._index.tsx | 3 + app/routes/dashboard.tsx | 4 +- 6 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 app/components/routing-tabs.tsx diff --git a/app/components/routing-tabs.tsx b/app/components/routing-tabs.tsx new file mode 100644 index 0000000..ccb00b2 --- /dev/null +++ b/app/components/routing-tabs.tsx @@ -0,0 +1,64 @@ +"use client"; + +import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import * as React from "react"; +import { useNavigate } from "react-router"; + +type TabItem = { + label: React.ReactNode; + to: string; // route path + value: string; +}; + +type RoutingTabsProps = { + tabs?: TabItem[]; + defaultValue?: string; +}; + +// Provide an array of { label, to } and the component will navigate when a tab is selected. +export default function RoutingTabs({ tabs, defaultValue }: RoutingTabsProps) { + const navigate = useNavigate(); + + const defaultTabs: TabItem[] = React.useMemo( + () => [ + { label: "Søkere", to: "dashboard/sokere", value: "sokere" }, + { + label: "Tidligere assistenter", + to: "dashboard/tidligere-assistenter", + value: "tidligere-assistenter", + }, + { + label: "Intervjufordeling", + to: "dashboard/intervjufordeling", + value: "intervjufordeling", + }, + { label: "Intervjuer", to: "dashboard/intervjuer", value: "intervjuer" }, + ], + [] + ); + + const items = tabs ?? defaultTabs; + + const handleTabChange = (value: string) => { + const item = items.find((tab) => (tab.value ?? tab.to) === value); + if (item) navigate(item.to); + }; + + return ( + +
+ + {items.map((tab) => ( + + {tab.label} + + ))} + +
+
+ ); +} diff --git a/app/routes/dashboard.intervjuer._index.tsx b/app/routes/dashboard.intervjuer._index.tsx index a4adf1a..7fbb2ec 100644 --- a/app/routes/dashboard.intervjuer._index.tsx +++ b/app/routes/dashboard.intervjuer._index.tsx @@ -1,8 +1,11 @@ +import RoutingTabs from "@/components/routing-tabs"; + // biome-ignore lint/style/noDefaultExport: Route Modules require default export https://reactrouter.com/start/framework/route-module export default function Intervjuer() { return ( <>

Intervjuer

+ ); } diff --git a/app/routes/dashboard.intervjufordeling._index.tsx b/app/routes/dashboard.intervjufordeling._index.tsx index e6e38ba..6b0bc18 100644 --- a/app/routes/dashboard.intervjufordeling._index.tsx +++ b/app/routes/dashboard.intervjufordeling._index.tsx @@ -1,8 +1,11 @@ +import TabsNavigation from "@/components/routing-tabs"; + // biome-ignore lint/style/noDefaultExport: Route Modules require default export https://reactrouter.com/start/framework/route-module export default function Intervjufordeling() { return ( <>

Intervjufordeling

+ ); } diff --git a/app/routes/dashboard.sokere._index.tsx b/app/routes/dashboard.sokere._index.tsx index 8689b45..8812158 100644 --- a/app/routes/dashboard.sokere._index.tsx +++ b/app/routes/dashboard.sokere._index.tsx @@ -1,4 +1,5 @@ import { DataTable } from "@/components/data-table"; +import RoutingTabs from "@/components/routing-tabs"; import { Checkbox } from "@/components/ui/checkbox"; import type { ColumnDef } from "@tanstack/react-table"; import { DataSokere } from "../mock/api/data-sokere"; @@ -71,6 +72,7 @@ export const columns: Array> = [ export default function Sokere() { return (
+ {/* Søkere diff --git a/app/routes/dashboard.tidligere-assistenter._index.tsx b/app/routes/dashboard.tidligere-assistenter._index.tsx index ba506e8..a96a9a9 100644 --- a/app/routes/dashboard.tidligere-assistenter._index.tsx +++ b/app/routes/dashboard.tidligere-assistenter._index.tsx @@ -1,8 +1,11 @@ +import TabsNavigation from "@/components/routing-tabs"; + // biome-ignore lint/style/noDefaultExport: Route Modules require default export https://reactrouter.com/start/framework/route-module export default function TidligereAssistenter() { return ( <>

Tidligere Assistenter

+ ); } diff --git a/app/routes/dashboard.tsx b/app/routes/dashboard.tsx index 74ff5b7..f68487b 100644 --- a/app/routes/dashboard.tsx +++ b/app/routes/dashboard.tsx @@ -141,7 +141,7 @@ const mainLinks = [ }, { title: "Tidligere Assistenter", - url: href("/dashboard/tidligereassistenter"), + url: href("/dashboard/tidligere-assistenter"), }, { title: "Intervjufordeling", @@ -398,7 +398,7 @@ function Breadcrumbs() { to={`/${fullPath}`} className={cn( isEnd ? "text-black" : "text-gray-500", - "hover:text-black", + "hover:text-black" )} prefetch="intent" > From 2ebbdd3e887ce4d670892648e332f1dffa4973d8 Mon Sep 17 00:00:00 2001 From: Julia Dai Date: Wed, 22 Oct 2025 18:03:13 +0200 Subject: [PATCH 2/3] vf-259 add hover color to routing tabs --- app/components/routing-tabs.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/components/routing-tabs.tsx b/app/components/routing-tabs.tsx index ccb00b2..32603e2 100644 --- a/app/components/routing-tabs.tsx +++ b/app/components/routing-tabs.tsx @@ -53,7 +53,11 @@ export default function RoutingTabs({ tabs, defaultValue }: RoutingTabsProps) {
{items.map((tab) => ( - + {tab.label} ))} From d094e25781de2295a30b4102cd04c32380cc986d Mon Sep 17 00:00:00 2001 From: Julia Dai Date: Wed, 22 Oct 2025 18:23:07 +0200 Subject: [PATCH 3/3] fix: use array over [ ] and and replace default exports --- app/components/routing-tabs.tsx | 12 ++++++------ app/routes/dashboard.intervjuer._index.tsx | 3 +-- app/routes/dashboard.intervjufordeling._index.tsx | 4 ++-- app/routes/dashboard.sokere._index.tsx | 2 +- .../dashboard.tidligere-assistenter._index.tsx | 4 ++-- app/routes/dashboard.tsx | 2 +- 6 files changed, 13 insertions(+), 14 deletions(-) diff --git a/app/components/routing-tabs.tsx b/app/components/routing-tabs.tsx index 32603e2..dd4635a 100644 --- a/app/components/routing-tabs.tsx +++ b/app/components/routing-tabs.tsx @@ -1,7 +1,7 @@ "use client"; import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; -import * as React from "react"; +import React from "react"; import { useNavigate } from "react-router"; type TabItem = { @@ -11,15 +11,15 @@ type TabItem = { }; type RoutingTabsProps = { - tabs?: TabItem[]; + tabs?: Array; defaultValue?: string; }; // Provide an array of { label, to } and the component will navigate when a tab is selected. -export default function RoutingTabs({ tabs, defaultValue }: RoutingTabsProps) { +export function RoutingTabs({ tabs, defaultValue }: RoutingTabsProps) { const navigate = useNavigate(); - const defaultTabs: TabItem[] = React.useMemo( + const defaultTabs: Array = React.useMemo( () => [ { label: "Søkere", to: "dashboard/sokere", value: "sokere" }, { @@ -34,7 +34,7 @@ export default function RoutingTabs({ tabs, defaultValue }: RoutingTabsProps) { }, { label: "Intervjuer", to: "dashboard/intervjuer", value: "intervjuer" }, ], - [] + [], ); const items = tabs ?? defaultTabs; @@ -47,7 +47,7 @@ export default function RoutingTabs({ tabs, defaultValue }: RoutingTabsProps) { return (
diff --git a/app/routes/dashboard.intervjuer._index.tsx b/app/routes/dashboard.intervjuer._index.tsx index 7fbb2ec..69785fe 100644 --- a/app/routes/dashboard.intervjuer._index.tsx +++ b/app/routes/dashboard.intervjuer._index.tsx @@ -1,5 +1,4 @@ -import RoutingTabs from "@/components/routing-tabs"; - +import { RoutingTabs } from "@/components/routing-tabs"; // biome-ignore lint/style/noDefaultExport: Route Modules require default export https://reactrouter.com/start/framework/route-module export default function Intervjuer() { return ( diff --git a/app/routes/dashboard.intervjufordeling._index.tsx b/app/routes/dashboard.intervjufordeling._index.tsx index 6b0bc18..b37cd40 100644 --- a/app/routes/dashboard.intervjufordeling._index.tsx +++ b/app/routes/dashboard.intervjufordeling._index.tsx @@ -1,11 +1,11 @@ -import TabsNavigation from "@/components/routing-tabs"; +import { RoutingTabs } from "@/components/routing-tabs"; // biome-ignore lint/style/noDefaultExport: Route Modules require default export https://reactrouter.com/start/framework/route-module export default function Intervjufordeling() { return ( <>

Intervjufordeling

- + ); } diff --git a/app/routes/dashboard.sokere._index.tsx b/app/routes/dashboard.sokere._index.tsx index 8812158..7b1c58c 100644 --- a/app/routes/dashboard.sokere._index.tsx +++ b/app/routes/dashboard.sokere._index.tsx @@ -1,5 +1,5 @@ import { DataTable } from "@/components/data-table"; -import RoutingTabs from "@/components/routing-tabs"; +import { RoutingTabs } from "@/components/routing-tabs"; import { Checkbox } from "@/components/ui/checkbox"; import type { ColumnDef } from "@tanstack/react-table"; import { DataSokere } from "../mock/api/data-sokere"; diff --git a/app/routes/dashboard.tidligere-assistenter._index.tsx b/app/routes/dashboard.tidligere-assistenter._index.tsx index a96a9a9..918680c 100644 --- a/app/routes/dashboard.tidligere-assistenter._index.tsx +++ b/app/routes/dashboard.tidligere-assistenter._index.tsx @@ -1,11 +1,11 @@ -import TabsNavigation from "@/components/routing-tabs"; +import { RoutingTabs } from "@/components/routing-tabs"; // biome-ignore lint/style/noDefaultExport: Route Modules require default export https://reactrouter.com/start/framework/route-module export default function TidligereAssistenter() { return ( <>

Tidligere Assistenter

- + ); } diff --git a/app/routes/dashboard.tsx b/app/routes/dashboard.tsx index f68487b..a8762b8 100644 --- a/app/routes/dashboard.tsx +++ b/app/routes/dashboard.tsx @@ -398,7 +398,7 @@ function Breadcrumbs() { to={`/${fullPath}`} className={cn( isEnd ? "text-black" : "text-gray-500", - "hover:text-black" + "hover:text-black", )} prefetch="intent" >