diff --git a/apps/web/src/router.tsx b/apps/web/src/router.tsx index 384d1b0..24728ef 100644 --- a/apps/web/src/router.tsx +++ b/apps/web/src/router.tsx @@ -117,9 +117,10 @@ function SetupLayout() { } /** Subscriptions layout — a standalone top-level section (its own header nav entry), - * with tabs for the subscriber catalog, the plan catalog, and the tariff lab. Each - * tab is a gated child route; an operator with only subscription:read sees just the - * first tab. */ + * with tabs for the subscriber catalog and the plan catalog. Each tab is a gated + * child route; an operator with only subscription:read sees just the first tab. + * (The tariff lab moved to /setup/tariff/lab, 2026-07-05 — it tests the tariff, so + * it lives with the tariff.) */ function SubscriptionsLayout() { const { user } = rootRoute.useRouteContext(); const { t } = useTranslation(); @@ -129,7 +130,21 @@ function SubscriptionsLayout() { + + + ); +} + +/** Tariff layout — the rate-card hub under Setup: the composer (index) and the + * pricing LAB as sub-tabs. One tariff:read gate on the parent covers both. */ +function TariffLayout() { + const { t } = useTranslation(); + return ( +
+
@@ -519,7 +534,10 @@ const legacyRedirects = ( ["/shift", "/shifts"], ["/setup/subscriptions", "/subscriptions"], ["/setup/plans", "/subscriptions/plans"], - ["/setup/tariff-lab", "/subscriptions/tariff-lab"], + // The tariff lab bounced twice: /setup/tariff-lab → /subscriptions/tariff-lab + // (2026-06-21) → /setup/tariff/lab (2026-07-05, back with the tariff it tests). + ["/setup/tariff-lab", "/setup/tariff/lab"], + ["/subscriptions/tariff-lab", "/setup/tariff/lab"], ["/setup/shifts", "/shifts"], ["/setup/reports", "/reports"], ] as const @@ -633,8 +651,20 @@ const tariffRoute = createRoute({ getParentRoute: () => setupRoute, path: "tariff", beforeLoad: ({ context }) => requirePerm("tariff:read")(context), + component: TariffLayout, +}); +const tariffComposerRoute = createRoute({ + getParentRoute: () => tariffRoute, + path: "/", component: () => , }); +// The tariff LAB — lives with the tariff it tests (moved from /subscriptions, +// 2026-07-05). The parent's tariff:read gate covers it. +const tariffLabRoute = createRoute({ + getParentRoute: () => tariffRoute, + path: "lab", + component: () => , +}); // --- /subscriptions — a standalone top-level section with its own tabs. The catalog // (index), the plan catalog, and the tariff lab live here, not under /setup. --- @@ -651,7 +681,6 @@ const subscriptionsIndexRoute = createRoute({ beforeLoad: ({ context }) => { if (can(context.user, "subscription:read")) return; if (can(context.user, "subscription:plan")) throw redirect({ to: "/subscriptions/plans" }); - if (can(context.user, "tariff:read")) throw redirect({ to: "/subscriptions/tariff-lab" }); throw redirect({ to: "/booth" }); }, component: function SubscriptionsRoute() { @@ -665,12 +694,6 @@ const subscriptionPlansRoute = createRoute({ beforeLoad: ({ context }) => requirePerm("subscription:plan")(context), component: () => , }); -const tariffLabRoute = createRoute({ - getParentRoute: () => subscriptionsRoute, - path: "tariff-lab", - beforeLoad: ({ context }) => requirePerm("tariff:read")(context), - component: () => , -}); const siteRoute = createRoute({ getParentRoute: () => setupRoute, path: "site", @@ -751,11 +774,10 @@ const routeTree = rootRoute.addChildren([ subscriptionsRoute.addChildren([ subscriptionsIndexRoute, subscriptionPlansRoute, - tariffLabRoute, ]), setupRoute.addChildren([ setupDevicesRoute, - tariffRoute, + tariffRoute.addChildren([tariffComposerRoute, tariffLabRoute]), siteRoute, usersRoute, rolesRoute,