Browse Source

refactor(auth): optimize onboarding redirection logic

Refactor the profile resolution flow to explicitly cache and redirect
to the `/intro` route when marriage profile basics are incomplete.
This ensures users are correctly routed to the onboarding sequence
via the entry route cache.

Additionally, adds optional chaining to `router.prefetch` calls to
prevent runtime errors and updates test suites to reflect the
newly cached `/intro` path behavior.
master
mortezaei 5 days ago
parent
commit
576b538f13
  1. 16
      src/app/[lang]/page.tsx
  2. 2
      src/app/intro/intro-client.tsx
  3. 1
      src/components/Componentes/slider-page.test.tsx
  4. 2
      src/components/Componentes/slider-page.tsx
  5. 4
      src/hooks/marriage/use-profile-main.test.ts
  6. 2
      src/hooks/marriage/use-profile-main.ts
  7. 3
      src/lib/entry-route-cache.test.ts
  8. 1
      src/lib/entry-route-cache.ts

16
src/app/[lang]/page.tsx

@ -39,15 +39,25 @@ export default async function LocaleEntryPage({
);
if (cachedEntryPath) {
if (cachedEntryPath === "/intro") {
return <Intro />;
}
redirect(localizePath(cachedEntryPath, lang));
}
// 3. Deep SSR Profile Resolution: resolve profile & redirect directly on server
const profile = await fetchProfileSSR(token);
if (profile) {
const targetPath = hasCompletedMarriageProfileBasics(profile)
? getSubmitPath(profile)
: "/intro";
const isBasicsCompleted = hasCompletedMarriageProfileBasics(profile);
if (!isBasicsCompleted) {
return <Intro />;
}
const targetPath = getSubmitPath(profile);
if (targetPath === "/intro") {
return <Intro />;
}
redirect(localizePath(targetPath, lang));
}

2
src/app/intro/intro-client.tsx

@ -128,7 +128,7 @@ export default function IntroClient() {
const handleSliderComplete = useCallback(
(targetPath: string) => {
const destination = localizePath(targetPath, locale);
router.prefetch(destination);
router.prefetch?.(destination);
setIsStepsOpen(false);
router.replace(destination);
},

1
src/components/Componentes/slider-page.test.tsx

@ -32,6 +32,7 @@ vi.mock('@/hooks/marriage/query-keys', () => ({
vi.mock('next/navigation', () => ({
useRouter: () => ({
replace: mockReplace,
prefetch: vi.fn(),
back: vi.fn(),
}),
}));

2
src/components/Componentes/slider-page.tsx

@ -120,7 +120,7 @@ export default function SliderPage({
const targetPath = getSubmitPath(freshProfile);
const localizedTarget = localizePath(targetPath, locale);
router.prefetch(localizedTarget);
router.prefetch?.(localizedTarget);
if (onComplete) {
onComplete(targetPath);

4
src/hooks/marriage/use-profile-main.test.ts

@ -32,7 +32,7 @@ describe("getMarriageProfile", () => {
expect(mocks.setCachedEntryPath).toHaveBeenCalledWith("/questions-list");
});
it("clears the route for an incomplete onboarding profile", async () => {
it("caches the intro route for an incomplete onboarding profile", async () => {
mocks.get.mockResolvedValue({
data: {
status: "pending_onboarding",
@ -43,7 +43,7 @@ describe("getMarriageProfile", () => {
await getMarriageProfile();
expect(mocks.setCachedEntryPath).toHaveBeenCalledWith(null);
expect(mocks.setCachedEntryPath).toHaveBeenCalledWith("/intro");
});
it("overwrites the old questions route when the backend advances state", async () => {

2
src/hooks/marriage/use-profile-main.ts

@ -31,7 +31,7 @@ export async function getMarriageProfile() {
});
setCachedMarriageEntryPath(
hasCompletedMarriageProfileBasics(data) ? getSubmitPath(data) : null,
hasCompletedMarriageProfileBasics(data) ? getSubmitPath(data) : "/intro",
);
return data;

3
src/lib/entry-route-cache.test.ts

@ -21,7 +21,8 @@ describe("entry route cache", () => {
);
expect(normalizeCachedMarriageEntryPath("https://example.com")).toBeNull();
expect(normalizeCachedMarriageEntryPath("//example.com")).toBeNull();
expect(normalizeCachedMarriageEntryPath("/intro")).toBeNull();
expect(normalizeCachedMarriageEntryPath("/intro")).toBe("/intro");
expect(normalizeCachedMarriageEntryPath("/invalid-path")).toBeNull();
});
it("requires a real token before trusting the cached route", () => {

1
src/lib/entry-route-cache.ts

@ -7,6 +7,7 @@ import {
export const MARRIAGE_ENTRY_PATH_COOKIE = "HABIB_MARRIAGE_ENTRY_PATH";
const AUTHENTICATED_ENTRY_PATHS = new Set([
"/intro",
"/terms",
"/questions-list",
"/finding-match",

Loading…
Cancel
Save