diff --git a/ui/src/components/access/CompanySettingsNav.test.tsx b/ui/src/components/access/CompanySettingsNav.test.tsx
new file mode 100644
index 00000000000..543735dfec9
--- /dev/null
+++ b/ui/src/components/access/CompanySettingsNav.test.tsx
@@ -0,0 +1,99 @@
+// @vitest-environment jsdom
+
+import { act } from "react";
+import { createRoot } from "react-dom/client";
+import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
+import { CompanySettingsNav, getCompanySettingsTab } from "./CompanySettingsNav";
+
+let currentPathname = "/company/settings";
+const navigateMock = vi.hoisted(() => vi.fn());
+const pageTabBarMock = vi.hoisted(() => vi.fn());
+
+vi.mock("@/lib/router", () => ({
+ useLocation: () => ({ pathname: currentPathname, search: "", hash: "" }),
+ useNavigate: () => navigateMock,
+}));
+
+vi.mock("@/components/ui/tabs", () => ({
+ Tabs: ({ children }: { children: React.ReactNode }) =>
{children}
,
+}));
+
+vi.mock("@/components/PageTabBar", () => ({
+ PageTabBar: (props: {
+ items: Array<{ value: string; label: string }>;
+ value?: string;
+ onValueChange?: (value: string) => void;
+ }) => {
+ pageTabBarMock(props);
+
+ return (
+
+
{props.value}
+
+
+ );
+ },
+}));
+
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+(globalThis as any).IS_REACT_ACT_ENVIRONMENT = true;
+
+describe("CompanySettingsNav", () => {
+ let container: HTMLDivElement;
+
+ beforeEach(() => {
+ container = document.createElement("div");
+ document.body.appendChild(container);
+ currentPathname = "/company/settings";
+ });
+
+ afterEach(() => {
+ container.remove();
+ document.body.innerHTML = "";
+ vi.clearAllMocks();
+ });
+
+ it("maps company settings routes to the expected shared tab value", () => {
+ expect(getCompanySettingsTab("/company/settings")).toBe("general");
+ expect(getCompanySettingsTab("/PAP/company/settings")).toBe("general");
+ expect(getCompanySettingsTab("/company/settings/access")).toBe("access");
+ expect(getCompanySettingsTab("/PAP/company/settings/access")).toBe("access");
+ expect(getCompanySettingsTab("/company/settings/invites")).toBe("invites");
+ });
+
+ it("renders the active tab and navigates when a different tab is selected", async () => {
+ currentPathname = "/PAP/company/settings/access";
+ const root = createRoot(container);
+
+ await act(async () => {
+ root.render();
+ });
+
+ expect(container.textContent).toContain("access");
+ expect(pageTabBarMock).toHaveBeenCalledWith(
+ expect.objectContaining({
+ value: "access",
+ items: [
+ { value: "general", label: "General" },
+ { value: "access", label: "Access" },
+ { value: "invites", label: "Invites" },
+ ],
+ }),
+ );
+
+ const button = container.querySelector("button");
+ expect(button).not.toBeNull();
+
+ await act(async () => {
+ button?.dispatchEvent(new MouseEvent("click", { bubbles: true }));
+ });
+
+ expect(navigateMock).toHaveBeenCalledWith("/company/settings/invites");
+
+ await act(async () => {
+ root.unmount();
+ });
+ });
+});
diff --git a/ui/src/components/access/CompanySettingsNav.tsx b/ui/src/components/access/CompanySettingsNav.tsx
new file mode 100644
index 00000000000..daa34a86b5b
--- /dev/null
+++ b/ui/src/components/access/CompanySettingsNav.tsx
@@ -0,0 +1,46 @@
+import { PageTabBar } from "@/components/PageTabBar";
+import { Tabs } from "@/components/ui/tabs";
+import { useLocation, useNavigate } from "@/lib/router";
+
+const items = [
+ { value: "general", label: "General", href: "/company/settings" },
+ { value: "access", label: "Access", href: "/company/settings/access" },
+ { value: "invites", label: "Invites", href: "/company/settings/invites" },
+] as const;
+
+type CompanySettingsTab = (typeof items)[number]["value"];
+
+export function getCompanySettingsTab(pathname: string): CompanySettingsTab {
+ if (pathname.includes("/company/settings/access")) {
+ return "access";
+ }
+
+ if (pathname.includes("/company/settings/invites")) {
+ return "invites";
+ }
+
+ return "general";
+}
+
+export function CompanySettingsNav() {
+ const location = useLocation();
+ const navigate = useNavigate();
+ const activeTab = getCompanySettingsTab(location.pathname);
+
+ function handleTabChange(value: string) {
+ const nextTab = items.find((item) => item.value === value);
+ if (!nextTab || nextTab.value === activeTab) return;
+ navigate(nextTab.href);
+ }
+
+ return (
+
+ ({ value, label }))}
+ value={activeTab}
+ onValueChange={handleTabChange}
+ align="start"
+ />
+
+ );
+}