49 lines
2.0 KiB
TypeScript
49 lines
2.0 KiB
TypeScript
import { notFound } from 'next/navigation';
|
|
import { eq } from 'drizzle-orm';
|
|
|
|
import { db } from '@/lib/db';
|
|
import { ports as portsTable } from '@/lib/db/schema/ports';
|
|
import { isResidentialModuleEnabled } from '@/lib/services/residential-module.service';
|
|
import { ModuleDisabledPage } from '@/components/shared/module-disabled-page';
|
|
|
|
interface ResidentialLayoutProps {
|
|
children: React.ReactNode;
|
|
params: Promise<{ portSlug: string }>;
|
|
}
|
|
|
|
/**
|
|
* Layout-level gate for the entire /residential subtree (clients +
|
|
* interests, list + detail). When the port has
|
|
* residential_module_enabled = false, every route under /residential
|
|
* renders the ModuleDisabledPage instead of the real content. This is
|
|
* the route-level half of the "hybrid hide+block" model (the sidebar
|
|
* "Residential" section + mobile entry are independently hidden via
|
|
* residentialModuleByPort on the SSR-resolved sidebar prop).
|
|
*
|
|
* Using a layout rather than per-page guards means: (a) one place to
|
|
* change the gate logic, (b) nested routes ([id]) are covered
|
|
* automatically, (c) the children subtree never mounts when disabled,
|
|
* so its data-fetching effects don't fire.
|
|
*/
|
|
export default async function ResidentialLayout({ children, params }: ResidentialLayoutProps) {
|
|
const { portSlug } = await params;
|
|
const port = await db.query.ports.findFirst({
|
|
where: eq(portsTable.slug, portSlug),
|
|
columns: { id: true },
|
|
});
|
|
// Fail closed: an unresolved slug means the port doesn't exist (or the
|
|
// user mistyped one) — 404 rather than silently rendering the gated
|
|
// subtree without a module check.
|
|
if (!port) notFound();
|
|
const enabled = await isResidentialModuleEnabled(port.id);
|
|
if (enabled) return children;
|
|
return (
|
|
<ModuleDisabledPage
|
|
moduleName="Residential"
|
|
description="The Residential clients and interests pipeline is turned off for this port. Existing residential records are preserved and will reappear when the module is re-enabled."
|
|
settingsHref={`/${portSlug}/admin/settings`}
|
|
fallbackHref={`/${portSlug}/dashboard`}
|
|
/>
|
|
);
|
|
}
|