mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-11 05:42:19 +00:00
The getting-started checklist reads the answers: a visit named within a month adds a "prepare the visit" row that is done once one is on the calendar, and the data-source row names the wearable that was chosen. Its per-browser state moves to one module so the done screen, the skip and Settings write the same keys. Settings → Account gains the two ways back in: "Set up again" through the restart route, which resets the ledger, keeps the answers as prefill and touches no module; and "Show the checklist again", which forgets what this browser hid. A page whose module is off now answers with the shared notice and the one action that helps, in one place for every module page: the shell maps the route to the module through the navigation model's own gate, so a page and its nav entry cannot disagree about which switch they follow. And the tour's two dead stops get their anchors on the integrations and health-record group headings.
64 lines
2.4 KiB
TypeScript
64 lines
2.4 KiB
TypeScript
"use client";
|
|
|
|
import Link from "next/link";
|
|
import { usePathname } from "next/navigation";
|
|
import type { ReactNode } from "react";
|
|
|
|
import { ModuleDisabledNotice } from "@/components/layout/module-disabled-notice";
|
|
import {
|
|
isNavDestinationActive,
|
|
NAV_DESTINATIONS,
|
|
} from "@/components/layout/nav-model";
|
|
import { Button } from "@/components/ui/button";
|
|
import { useAuth } from "@/hooks/use-auth";
|
|
import { useTranslations } from "@/lib/i18n/context";
|
|
|
|
/**
|
|
* v1.39 (C2) — the page of a module that is switched off answers with an
|
|
* empty state that names the switch (design spec §After the flow), in one
|
|
* place for every module page.
|
|
*
|
|
* The setup flow switches modules OFF for a new record — an explicit `false`
|
|
* for every module the answers did not name — and the navigation drops the
|
|
* entry. A person who reaches the page anyway (a bookmark, a link in a
|
|
* report, the tour) used to get the page's own empty state, which said
|
|
* "nothing here yet" about a module that is not there at all. This maps the
|
|
* route to the module through the navigation model's own gate, so a module
|
|
* page and its nav entry can never disagree about which switch they follow,
|
|
* and renders the shared notice with the one action that can help: the
|
|
* Modules settings, offered only when the record's own switch is what is off.
|
|
*
|
|
* Paint, not enforcement: every route behind a module refuses on its own
|
|
* through the server gate. Mounted inside the shell, which renders children
|
|
* only after the account payload resolved, so the map is never read on a
|
|
* hydration render.
|
|
*/
|
|
export function ModulePageGate({ children }: { children: ReactNode }) {
|
|
const pathname = usePathname();
|
|
const { user } = useAuth();
|
|
const { t } = useTranslations();
|
|
|
|
const destination = NAV_DESTINATIONS.find(
|
|
(d) => d.requiresModule && isNavDestinationActive(d.href, pathname),
|
|
);
|
|
const moduleKey = destination?.requiresModule;
|
|
const off = moduleKey !== undefined && user?.modules?.[moduleKey] === false;
|
|
|
|
if (!off || !destination || !moduleKey) return <>{children}</>;
|
|
|
|
const Icon = destination.icon;
|
|
return (
|
|
<ModuleDisabledNotice
|
|
moduleKey={moduleKey}
|
|
icon={<Icon className="size-6" />}
|
|
action={
|
|
<Button asChild size="sm">
|
|
<Link href="/settings/modules" data-slot="module-off-open-settings">
|
|
{t("moduleOff.openModules")}
|
|
</Link>
|
|
</Button>
|
|
}
|
|
/>
|
|
);
|
|
}
|