feat: scope workspace routes by organization slug

This commit is contained in:
2026-07-02 20:11:57 -07:00
parent fae97a7046
commit 3ab0e3e034
48 changed files with 565 additions and 96 deletions

View File

@@ -0,0 +1,5 @@
import AlertsPage from "../../alerts/page";
export default function ScopedAlertsPage(): React.ReactElement {
return AlertsPage();
}

View File

@@ -0,0 +1,5 @@
import BedsPage from "../../beds/page";
export default async function ScopedBedsPage(): Promise<React.ReactElement> {
return BedsPage();
}

View File

@@ -0,0 +1,5 @@
import CarePage from "../../care/page";
export default function ScopedCarePage(): React.ReactElement {
return CarePage();
}

View File

@@ -0,0 +1,5 @@
import DashboardPage from "../../dashboard/page";
export default async function ScopedDashboardPage(): Promise<React.ReactElement> {
return DashboardPage();
}

View File

@@ -0,0 +1,5 @@
import DevicesPage from "../../devices/page";
export default function ScopedDevicesPage(): React.ReactElement {
return DevicesPage();
}

View File

@@ -0,0 +1,5 @@
import EldersPage from "../../elders/page";
export default async function ScopedEldersPage(): Promise<React.ReactElement> {
return EldersPage();
}

View File

@@ -0,0 +1,5 @@
import EmergencyPage from "../../emergency/page";
export default function ScopedEmergencyPage(): React.ReactElement {
return EmergencyPage();
}

View File

@@ -0,0 +1,5 @@
import FamilyPage from "../../family/page";
export default function ScopedFamilyPage(): React.ReactElement {
return FamilyPage();
}

View File

@@ -0,0 +1,5 @@
import HealthPage from "../../health/page";
export default function ScopedHealthPage(): React.ReactElement {
return HealthPage();
}

View File

@@ -0,0 +1,28 @@
import { redirect } from "next/navigation";
import { getCurrentAuthContext } from "@/modules/core/server/auth";
import { getWorkspaceHref } from "@/modules/shared/lib/workspace-routing";
type OrganizationWorkspaceLayoutProps = {
children: React.ReactNode;
params: Promise<{
organizationSlug: string;
}>;
};
export default async function OrganizationWorkspaceLayout({
children,
params,
}: OrganizationWorkspaceLayoutProps): Promise<React.ReactElement> {
const [{ organizationSlug }, context] = await Promise.all([params, getCurrentAuthContext()]);
if (!context) {
redirect("/login");
}
const activeSlug = context.organization?.slug;
if (activeSlug && activeSlug !== organizationSlug) {
redirect(getWorkspaceHref(activeSlug, "/dashboard"));
}
return <>{children}</>;
}

View File

@@ -0,0 +1,5 @@
import NoticesPage from "../../notices/page";
export default function ScopedNoticesPage(): React.ReactElement {
return NoticesPage();
}

View File

@@ -0,0 +1,14 @@
import { redirect } from "next/navigation";
import { getWorkspaceHref } from "@/modules/shared/lib/workspace-routing";
type ScopedAppIndexPageProps = {
params: Promise<{
organizationSlug: string;
}>;
};
export default async function ScopedAppIndexPage({ params }: ScopedAppIndexPageProps): Promise<never> {
const { organizationSlug } = await params;
redirect(getWorkspaceHref(organizationSlug, "/dashboard"));
}

View File

@@ -0,0 +1,10 @@
import AuditPage from "../../../settings/audit/page";
import type { SearchParams } from "@/modules/settings/lib/pagination";
type ScopedAuditPageProps = {
searchParams?: Promise<SearchParams>;
};
export default async function ScopedAuditPage({ searchParams }: ScopedAuditPageProps): Promise<React.ReactElement> {
return AuditPage({ searchParams });
}

View File

@@ -0,0 +1,5 @@
import GlobalSettingsPage from "../../../settings/global/page";
export default async function ScopedGlobalSettingsPage(): Promise<React.ReactElement> {
return GlobalSettingsPage();
}

View File

@@ -0,0 +1,9 @@
import SettingsLayout from "../../settings/layout";
type ScopedSettingsLayoutProps = {
children: React.ReactNode;
};
export default function ScopedSettingsLayout({ children }: ScopedSettingsLayoutProps): React.ReactElement {
return <SettingsLayout>{children}</SettingsLayout>;
}

View File

@@ -0,0 +1,15 @@
import OrganizationDetailPage from "../../../../settings/organizations/[id]/page";
type ScopedOrganizationDetailPageProps = {
params: Promise<{
organizationSlug: string;
id: string;
}>;
};
export default async function ScopedOrganizationDetailPage({
params,
}: ScopedOrganizationDetailPageProps): Promise<React.ReactElement> {
const { id } = await params;
return OrganizationDetailPage({ params: Promise.resolve({ id }) });
}

View File

@@ -0,0 +1,12 @@
import OrganizationsPage from "../../../settings/organizations/page";
import type { SearchParams } from "@/modules/settings/lib/pagination";
type ScopedOrganizationsPageProps = {
searchParams?: Promise<SearchParams>;
};
export default async function ScopedOrganizationsPage({
searchParams,
}: ScopedOrganizationsPageProps): Promise<React.ReactElement> {
return OrganizationsPage({ searchParams });
}

View File

@@ -0,0 +1,5 @@
import SettingsPage from "../../settings/page";
export default async function ScopedSettingsPage(): Promise<React.ReactElement> {
return SettingsPage();
}

View File

@@ -0,0 +1,10 @@
import RolesPage from "../../../settings/roles/page";
import type { SearchParams } from "@/modules/settings/lib/pagination";
type ScopedRolesPageProps = {
searchParams?: Promise<SearchParams>;
};
export default async function ScopedRolesPage({ searchParams }: ScopedRolesPageProps): Promise<React.ReactElement> {
return RolesPage({ searchParams });
}

View File

@@ -0,0 +1,10 @@
import StatusPage from "../../../settings/status/page";
import type { SearchParams } from "@/modules/settings/lib/pagination";
type ScopedStatusPageProps = {
searchParams?: Promise<SearchParams>;
};
export default async function ScopedStatusPage({ searchParams }: ScopedStatusPageProps): Promise<React.ReactElement> {
return StatusPage({ searchParams });
}

View File

@@ -0,0 +1,10 @@
import UsersPage from "../../../settings/users/page";
import type { SearchParams } from "@/modules/settings/lib/pagination";
type ScopedUsersPageProps = {
searchParams?: Promise<SearchParams>;
};
export default async function ScopedUsersPage({ searchParams }: ScopedUsersPageProps): Promise<React.ReactElement> {
return UsersPage({ searchParams });
}