mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 21:32:18 +00:00
Appearance ("Darstellung") stacked every module's view and ordering
settings on one long page. Split it into a hub that lists the modules as
navigable rows, each opening its own /settings/layout/<module> subpage
with a back link — the per-module settings move verbatim, no restyling.
The module routes now redirect to those subpages instead of an in-page
anchor, and the in-app cogs link straight to them.
53 lines
1.6 KiB
TypeScript
53 lines
1.6 KiB
TypeScript
"use client";
|
|
|
|
import * as React from "react";
|
|
import { useRouter } from "next/navigation";
|
|
|
|
import { useAuth } from "@/hooks/use-auth";
|
|
import { useMounted } from "@/hooks/use-mounted";
|
|
import type { ModuleKey } from "@/lib/modules/registry";
|
|
|
|
/**
|
|
* v1.25.11 (#148) — client gate for an Appearance subpage
|
|
* (`/settings/layout/<module>`).
|
|
*
|
|
* A module's subpage may be reached by direct URL even when the user has the
|
|
* module turned off. This wrapper fails OPEN: it renders the section unless the
|
|
* resolved `useAuth().user.modules` map has the gate key explicitly `false`,
|
|
* in which case it bounces back to the hub (`/settings/layout`).
|
|
*
|
|
* The gate is hydration-stable: `useMounted()` returns `false` during SSR AND
|
|
* the first client paint, so the first render ALWAYS shows the section
|
|
* (matching the server HTML); the real check applies once, after hydration, as
|
|
* an ordinary client update. The redirect is a client-only effect, so it never
|
|
* diverges the initial render and cannot trigger a React #418 mismatch.
|
|
*
|
|
* Groups with no `moduleGate` (dashboard / insights / vorsorge) pass
|
|
* `moduleGate={undefined}` and always render.
|
|
*/
|
|
export function LayoutModuleGate({
|
|
moduleGate,
|
|
children,
|
|
}: {
|
|
moduleGate?: ModuleKey;
|
|
children: React.ReactNode;
|
|
}) {
|
|
const hydrated = useMounted();
|
|
const { user } = useAuth();
|
|
const router = useRouter();
|
|
|
|
const disabled =
|
|
hydrated &&
|
|
moduleGate !== undefined &&
|
|
user?.modules?.[moduleGate] === false;
|
|
|
|
React.useEffect(() => {
|
|
if (disabled) {
|
|
router.replace("/settings/layout");
|
|
}
|
|
}, [disabled, router]);
|
|
|
|
if (disabled) return null;
|
|
return <>{children}</>;
|
|
}
|