feat(onboarding): skippable avatar with first-match prompt and usage-reason pack picks

Lets new users skip the onboarding avatar step and instead defers the ask
to a lightweight, dismissible prompt shown once after the couple's first
match. Also personalizes the home screen's first pack recommendation using
the usage_reason already collected during onboarding, which now round-trips
through GET /v1/me.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
jjbruntonandClaude Fable 5 committed 2026-08-30 19:12:56 +01:00
1 parent f22d4a3649
commit fd8981fa28
14 files changed
+567 -77

No files matched your search

@@ -0,0 +1,34 @@
import { hasSeenAvatarPrompt, markAvatarPromptSeen } from "@/lib/avatarPromptSeen";
jest.mock("expo-secure-store", () => {
const store = new Map<string, string>();
return {
__store: store,
getItemAsync: jest.fn(async (key: string) => store.get(key) ?? null),
setItemAsync: jest.fn(async (key: string, value: string) => { store.set(key, value); }),
};
});
// eslint-disable-next-line @typescript-eslint/no-var-requires
const secureStore = require("expo-secure-store") as { __store: Map<string, string> };
describe("avatarPromptSeen", () => {
beforeEach(() => {
secureStore.__store.clear();
});
it("reports unseen until marked seen for that user", async () => {
expect(await hasSeenAvatarPrompt("user-1")).toBe(false);
await markAvatarPromptSeen("user-1");
expect(await hasSeenAvatarPrompt("user-1")).toBe(true);
});
it("tracks the seen flag per user, so a shared device does not skip the prompt for a new account", async () => {
await markAvatarPromptSeen("user-1");
expect(await hasSeenAvatarPrompt("user-1")).toBe(true);
expect(await hasSeenAvatarPrompt("user-2")).toBe(false);
});
});