Files
HealthLog/src/lib/onboarding/checklist-storage.ts
T
Marc-André Bombeck 1c2e7c29de Add the setup flow's welcome screen and shell
The front door reads the same ledger every screen reads: a record that
never entered the flow sees the welcome, one mid-way is sent to the step
it owes, a finished one is offered the questions again. The shell prints
the counter and an ordered step list off the step machine, so it shows
exactly the screens this flow has, and every screen moves focus to its
heading on arrival.

"Skip for now" is a real exit — it stamps the account past the first-run
redirect and opens the checklist on the dashboard — and the one-time
medical disclaimer now gates it as well as "Set up", because a skip that
reached the dashboard without it would be a way round the acknowledgment.

The five-step wizard's welcome carousel, goal picker and source grid go
with it; the numbered step route follows in the next commit.
2026-09-10 15:10:50 +02:00

57 lines
1.9 KiB
TypeScript

/**
* The getting-started checklist's per-browser state.
*
* Three keys, all of them conveniences rather than record: which rows this
* browser hid, whether the whole card was hidden, and whether it is open.
* They were private to the card until the setup flow needed two of them —
* the done screen and "skip for now" open the list, and Settings brings a
* hidden list back — and a second copy of a storage key is how two surfaces
* end up writing different ones.
*
* Every access is wrapped: storage can be full, disabled, or absent, and the
* card renders correctly with no stored value.
*/
export const CHECKLIST_DISMISSED_ITEMS_KEY =
"healthlog-getting-started-dismissed";
export const CHECKLIST_DISMISSED_ALL_KEY = "healthlog-getting-started-hidden";
export const CHECKLIST_EXPANDED_KEY = "healthlog-getting-started-expanded";
function storage(): Storage | null {
if (typeof window === "undefined") return null;
try {
return window.localStorage;
} catch {
return null;
}
}
/** Open the checklist on the next dashboard visit. */
export function markChecklistExpanded(): void {
try {
storage()?.setItem(CHECKLIST_EXPANDED_KEY, "1");
} catch {
/* storage may be full or disabled */
}
}
/**
* "Show the checklist again": forget every dismissal and open the list.
* Returns whether anything was stored to forget, so the caller can say
* "it is back" rather than "done" to somebody who never hid it.
*/
export function resetChecklistDismissals(): boolean {
const store = storage();
if (!store) return false;
try {
const hadState =
store.getItem(CHECKLIST_DISMISSED_ALL_KEY) === "1" ||
(store.getItem(CHECKLIST_DISMISSED_ITEMS_KEY) ?? "[]") !== "[]";
store.removeItem(CHECKLIST_DISMISSED_ITEMS_KEY);
store.removeItem(CHECKLIST_DISMISSED_ALL_KEY);
store.setItem(CHECKLIST_EXPANDED_KEY, "1");
return hadState;
} catch {
return false;
}
}