mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-15 15:02:04 +00:00
feat(nav): add the center capture action and More hub, move unit preference into the profile
Reshape the mobile bottom bar to the five-slot shape the native client uses: Home · Meds · Log · Insights · More. The center "Log" slot is a capture action rather than a destination — it opens a picker that routes to the existing measurement, medication-intake and mood quick-entry sheets (those forms already share a mount contract, so the picker reuses them verbatim). Expand the former overflow into a real "More" hub that holds the rest of the top-level destinations: Measurements, Mood, Workouts, Achievements, Notifications and Settings. The change is additive — Measurements and Mood leave the always-visible strip but stay reachable through the More hub and the capture picker, so nothing loses its route. On desktop the sidebar still lists every destination. Move the metric/imperial unit system from its standalone card into a dropdown in the Profile form beside the timezone picker — it is a display preference like language and timezone. Persistence is unchanged: the dropdown PATCHes /api/auth/me/unit-preference on change and invalidates the same query keys, so chart display transforms re-render without a reload. Retire the now-unused card.
This commit is contained in:
1 parent
488cc09ae9
commit
280bf42382
15 files changed
+716
-491
No files matched your search
@@ -172,4 +172,50 @@ test.describe("mobile-viewport smoke", () => {
|
||||
`Touch-targets below 44 px tall:\n ${failures.join("\n ")}`,
|
||||
).toEqual([]);
|
||||
});
|
||||
|
||||
test("center capture action opens the picker; the More hub keeps Mood + Measurements reachable", async ({
|
||||
page,
|
||||
}) => {
|
||||
await mockDashboardSnapshot(page, { summaries: WEIGHT_ONLY_SUMMARIES });
|
||||
await page.route(/\/api\/analytics(\?|$)/, (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: "application/json",
|
||||
body: JSON.stringify({
|
||||
data: { summaries: {}, bpInTargetPct: null, glucoseByContext: {} },
|
||||
error: null,
|
||||
}),
|
||||
}),
|
||||
);
|
||||
await page.route("**/api/mood/analytics", (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: "application/json",
|
||||
body: JSON.stringify({
|
||||
data: { entries: [], summary: { count: 0 } },
|
||||
error: null,
|
||||
}),
|
||||
}),
|
||||
);
|
||||
|
||||
await page.goto("/", { waitUntil: "domcontentloaded" });
|
||||
await page.waitForLoadState("networkidle");
|
||||
|
||||
// 1) The center capture action opens the capture picker.
|
||||
await page.getByTestId("bottom-nav-capture").click();
|
||||
await expect(page.getByTestId("capture-picker-options")).toBeVisible();
|
||||
for (const kind of ["measurement", "medication", "mood"]) {
|
||||
await expect(page.getByTestId(`capture-picker-${kind}`)).toBeVisible();
|
||||
}
|
||||
// Dismiss the picker before opening the hub.
|
||||
await page.keyboard.press("Escape");
|
||||
|
||||
// 2) The More hub keeps Mood + Measurements reachable (additive
|
||||
// middle-path — they left the strip but are NOT orphaned).
|
||||
await page.getByTestId("bottom-nav-more").click();
|
||||
const hub = page.getByTestId("bottom-nav-more-sheet");
|
||||
await expect(hub).toBeVisible();
|
||||
await expect(hub.locator("a[href='/measurements']")).toBeVisible();
|
||||
await expect(hub.locator("a[href='/mood']")).toBeVisible();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user