Files
HealthLog/src/hooks/use-module-enabled.ts
T
Marc-André Bombeck 61d912627d feat(coach): follow the coach capability at every entry point
The floating button, the drawer, the launch pills, the nav entry and the
Coach pages read the coach capability from /api/auth/me instead of
combining the operator switch with Hide Coach on their own. A missing
provider or consent now hides the Coach too, instead of opening one that
can only answer with an error.

Stored conversations stay reachable: while the Coach is unavailable the
conversation list turns read-only, opens a transcript in place and keeps
delete. Refusals before the stream opens are read by meta.errorCode and
each code has its own copy.
2026-09-24 11:05:38 +02:00

34 lines
1.3 KiB
TypeScript

"use client";
import { useAuth } from "@/hooks/use-auth";
import { useQueryClientMounted } from "@/hooks/_internal/use-query-client-safe";
import type { ModuleKey } from "@/lib/modules/registry";
/**
* v1.18.0 R4 — SSR-safe accessor for a per-account module flag.
*
* `useAuth()` calls `useQuery` directly and
* crashes when a legacy presentational component (`<HeroStrip>`, the
* isolated score-card snapshots, …) renders without a
* `<QueryClientProvider>`. We gate the inner hook on
* `useQueryClientMounted()` and short-circuit to the default-on result
* when no client is in the tree — the branch is stable across the
* component's lifetime, so the conditional call is safe per the Rules of
* Hooks.
*
* Default-on (disabled allowlist): an absent map, a missing key, or any
* non-`false` value reads as enabled — matching the server gate in
* `src/lib/modules/gate.ts`.
*/
export function useModuleEnabled(moduleKey: ModuleKey): boolean {
const hasClient = useQueryClientMounted();
if (!hasClient) return true;
// eslint-disable-next-line react-hooks/rules-of-hooks
return useModuleEnabledInner(moduleKey);
}
function useModuleEnabledInner(moduleKey: ModuleKey): boolean {
const { user } = useAuth();
return user?.modules?.[moduleKey] !== false;
}