mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 13:01:00 +00:00
fix(onboarding): skip the achievements tour stop when the module is off
The dashboard tour launcher now derives includeAchievements from the per-user module map (modules?.achievements !== false), so an account that has the achievements module turned off no longer walks the user to a page it has hidden. Mention the module on/off concept in the integrations tour stop, where the tour introduces Settings and customization, so a first-time user learns whole areas can be turned on or off.
This commit is contained in:
1 parent
f72d0b0ef3
commit
ca196f27a6
3 files changed
+43
-1
No files matched your search
+1
-1
@@ -3687,7 +3687,7 @@
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Connect your devices",
|
||||
"body": "Open Settings to link Withings (auto-sync weight, BP and pulse), moodLog, or your Insights provider. Everything stays optional and encrypted."
|
||||
"body": "Open Settings to link Withings (auto-sync weight, BP and pulse), moodLog, or your Insights provider. Everything stays optional and encrypted — and under Settings → Modules you can turn whole areas like sleep, mood or achievements on or off to keep HealthLog focused on what you track."
|
||||
},
|
||||
"achievements": {
|
||||
"title": "Earn streaks and badges",
|
||||
|
||||
@@ -21,6 +21,7 @@ import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
import {
|
||||
setTourForceLaunch,
|
||||
shouldAutoLaunchTour,
|
||||
tourIncludesAchievements,
|
||||
TOUR_AUTOLAUNCH_DELAY_MS,
|
||||
tourForceLaunchKey,
|
||||
} from "../tour-launcher";
|
||||
@@ -132,6 +133,27 @@ describe("shouldAutoLaunchTour() — v1.4.47 W5 chain-gate", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("tourIncludesAchievements() — v1.18.0 B5 module gate", () => {
|
||||
it("includes the achievements stop by default (no module map)", () => {
|
||||
expect(tourIncludesAchievements(undefined)).toBe(true);
|
||||
expect(tourIncludesAchievements({})).toBe(true);
|
||||
});
|
||||
|
||||
it("includes the achievements stop when the module is explicitly on", () => {
|
||||
expect(tourIncludesAchievements({ achievements: true })).toBe(true);
|
||||
});
|
||||
|
||||
it("drops the achievements stop when the module is explicitly off", () => {
|
||||
expect(tourIncludesAchievements({ achievements: false })).toBe(false);
|
||||
});
|
||||
|
||||
it("ignores other disabled modules — only the achievements key matters", () => {
|
||||
expect(
|
||||
tourIncludesAchievements({ sleep: false, mood: false }),
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("setTourForceLaunch() — v1.4.47 W5 manual replay bypass", () => {
|
||||
// (c) of the W5 acceptance: the manual "launch tour" trigger still
|
||||
// works. The launcher's render-phase gate is exercised by
|
||||
|
||||
@@ -101,6 +101,19 @@ export function shouldAutoLaunchTour(args: {
|
||||
return args.nowMs - completedMs >= TOUR_AUTOLAUNCH_DELAY_MS;
|
||||
}
|
||||
|
||||
/**
|
||||
* v1.18.0 B5 — whether the achievements tour stop should be included.
|
||||
* Reads the per-user module map with the standard client default-on
|
||||
* convention (`modules?.achievements !== false`): only an explicit
|
||||
* `false` drops the stop. Pure + exported so the rule is unit-pinned
|
||||
* without rendering the launcher.
|
||||
*/
|
||||
export function tourIncludesAchievements(
|
||||
modules: Partial<Record<string, boolean>> | undefined,
|
||||
): boolean {
|
||||
return modules?.achievements !== false;
|
||||
}
|
||||
|
||||
// v1.4.15 H4 — sessionStorage keys are now scoped by user id so an
|
||||
// admin impersonating a second user does not inherit the first user's
|
||||
// "tour dismissed for this session" state. The previous global keys
|
||||
@@ -348,8 +361,15 @@ export function TourLauncher({ ready }: TourLauncherProps) {
|
||||
|
||||
if (showTour !== true) return null;
|
||||
|
||||
// v1.18.0 B5 — drop the achievements tour stop when the account has the
|
||||
// achievements module turned off. Reads the per-user module map the same
|
||||
// way every other client gate does (`modules?.<key> !== false`,
|
||||
// default-on).
|
||||
const includeAchievements = tourIncludesAchievements(user?.modules);
|
||||
|
||||
return (
|
||||
<OnboardingTour
|
||||
includeAchievements={includeAchievements}
|
||||
onClose={async (outcome) => {
|
||||
// Optimistic: hide the overlay immediately, persist in the
|
||||
// background. The flag is idempotent so re-fires are safe;
|
||||
|
||||
Reference in new issue
Block a user