diff --git a/src/app/[lang]/page.tsx b/src/app/[lang]/page.tsx index af36864..7465e02 100644 --- a/src/app/[lang]/page.tsx +++ b/src/app/[lang]/page.tsx @@ -7,6 +7,11 @@ import { isAuthenticatedToken, MARRIAGE_ENTRY_PATH_COOKIE, } from "@/lib/entry-route-cache"; +import { + getSubmitPath, + hasCompletedMarriageProfileBasics, +} from "@/lib/get-submit-path"; +import { fetchProfileSSR } from "@/lib/ssr-fetch"; import { localizePath } from "@/translations/config"; export const dynamic = "force-dynamic"; @@ -21,6 +26,13 @@ export default async function LocaleEntryPage({ cookieStore.get("HABIB_TOKEN")?.value ?? cookieStore.get("habib_token")?.value; const hasToken = isAuthenticatedToken(token); + + // 1. If not authenticated, render instantly in SSR + if (!hasToken) { + return ; + } + + // 2. Check cached entry path first const cachedEntryPath = getAuthenticatedCachedEntryPath( token, cookieStore.get(MARRIAGE_ENTRY_PATH_COOKIE)?.value, @@ -30,12 +42,16 @@ export default async function LocaleEntryPage({ redirect(localizePath(cachedEntryPath, lang)); } - // 1. If not authenticated, render instantly in SSR (0ms client delay) - if (!hasToken) { - return ; + // 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"; + redirect(localizePath(targetPath, lang)); } - // 2. If authenticated without cached route, deliver head/web_ready immediately and resolve in client + // 4. Graceful Fallback if server fetch was unreachable return ( <> diff --git a/src/app/page.tsx b/src/app/page.tsx index b42f0bf..aae23df 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -5,6 +5,11 @@ import { isAuthenticatedToken, MARRIAGE_ENTRY_PATH_COOKIE, } from "@/lib/entry-route-cache"; +import { + getSubmitPath, + hasCompletedMarriageProfileBasics, +} from "@/lib/get-submit-path"; +import { fetchProfileSSR } from "@/lib/ssr-fetch"; import { defaultLocale, isLocale, @@ -52,5 +57,13 @@ export default async function RootPage() { redirect(localizePath(cachedEntryPath, targetLocale)); } + const profile = await fetchProfileSSR(token); + if (profile) { + const targetPath = hasCompletedMarriageProfileBasics(profile) + ? getSubmitPath(profile) + : "/intro"; + redirect(localizePath(targetPath, targetLocale)); + } + redirect(`/${targetLocale}`); } diff --git a/src/lib/ssr-fetch.ts b/src/lib/ssr-fetch.ts index 828fb03..e46470d 100644 --- a/src/lib/ssr-fetch.ts +++ b/src/lib/ssr-fetch.ts @@ -14,8 +14,14 @@ function getApiBaseUrl(): string { * @param token - The user authentication token * @returns Profile data or null on failure */ -export async function fetchProfileSSR(token: string): Promise { - if (!token) return null; +export async function fetchProfileSSR( + token: string, + timeoutMs = 1500, +): Promise { + if (!token || token === "NO_TOKEN" || token.trim() === "") return null; + + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), timeoutMs); try { const baseUrl = getApiBaseUrl(); @@ -24,9 +30,10 @@ export async function fetchProfileSSR(token: string): Promise { const response = await fetch(url, { method: "GET", cache: "no-store", + signal: controller.signal, headers: { Accept: "application/json", - Authorization: `Token ${token}`, + Authorization: `Token ${token.trim()}`, }, }); @@ -36,7 +43,8 @@ export async function fetchProfileSSR(token: string): Promise { return await response.json(); } catch (error) { - console.error("fetchProfileSSR Error:", error); return null; + } finally { + clearTimeout(timeoutId); } }