Browse Source
refactor: simplify routing by removing server-side data fetching and hydration across all app pages
master
refactor: simplify routing by removing server-side data fetching and hydration across all app pages
master
12 changed files with 23 additions and 314 deletions
-
31src/app/[lang]/page.tsx
-
4src/app/candidate-contact/candidate-contact-client.tsx
-
38src/app/candidate-contact/page.tsx
-
38src/app/finding-match/page.tsx
-
41src/app/intro/page.tsx
-
38src/app/new-match/page.tsx
-
13src/app/page.tsx
-
48src/app/questions-list/page.tsx
-
5src/app/questions-list/questions-list-client.tsx
-
38src/app/request-accepted/page.tsx
-
38src/app/request-sent/page.tsx
-
5src/app/terms/page.tsx
@ -1,39 +1,5 @@ |
|||
import { cookies } from "next/headers"; |
|||
import { |
|||
dehydrate, |
|||
HydrationBoundary, |
|||
QueryClient, |
|||
} from "@tanstack/react-query"; |
|||
import { isAuthenticatedToken } from "@/lib/entry-route-cache"; |
|||
import { fetchProfileSSR } from "@/lib/ssr-fetch"; |
|||
import { marriageQueryKeys } from "@/hooks/marriage/query-keys"; |
|||
import CandidateContactClient from "./candidate-contact-client"; |
|||
|
|||
export const dynamic = "force-dynamic"; |
|||
|
|||
export default async function CandidateContactPage() { |
|||
const cookieStore = await cookies(); |
|||
|
|||
const token = |
|||
cookieStore.get("HABIB_TOKEN")?.value ?? |
|||
cookieStore.get("habib_token")?.value; |
|||
|
|||
const queryClient = new QueryClient({ |
|||
defaultOptions: { |
|||
queries: { staleTime: 10 * 1000 }, |
|||
}, |
|||
}); |
|||
|
|||
if (isAuthenticatedToken(token)) { |
|||
await queryClient.prefetchQuery({ |
|||
queryKey: marriageQueryKeys.profile(), |
|||
queryFn: () => fetchProfileSSR(token!), |
|||
}); |
|||
} |
|||
|
|||
return ( |
|||
<HydrationBoundary state={dehydrate(queryClient)}> |
|||
<CandidateContactClient /> |
|||
</HydrationBoundary> |
|||
); |
|||
export default function CandidateContactPage() { |
|||
return <CandidateContactClient />; |
|||
} |
|||
@ -1,39 +1,5 @@ |
|||
import { cookies } from "next/headers"; |
|||
import { |
|||
dehydrate, |
|||
HydrationBoundary, |
|||
QueryClient, |
|||
} from "@tanstack/react-query"; |
|||
import { isAuthenticatedToken } from "@/lib/entry-route-cache"; |
|||
import { fetchProfileSSR } from "@/lib/ssr-fetch"; |
|||
import { marriageQueryKeys } from "@/hooks/marriage/query-keys"; |
|||
import FindingMatchClient from "./finding-match-client"; |
|||
|
|||
export const dynamic = "force-dynamic"; |
|||
|
|||
export default async function FindingMatchPage() { |
|||
const cookieStore = await cookies(); |
|||
|
|||
const token = |
|||
cookieStore.get("HABIB_TOKEN")?.value ?? |
|||
cookieStore.get("habib_token")?.value; |
|||
|
|||
const queryClient = new QueryClient({ |
|||
defaultOptions: { |
|||
queries: { staleTime: 10 * 1000 }, |
|||
}, |
|||
}); |
|||
|
|||
if (isAuthenticatedToken(token)) { |
|||
await queryClient.prefetchQuery({ |
|||
queryKey: marriageQueryKeys.profile(), |
|||
queryFn: () => fetchProfileSSR(token!), |
|||
}); |
|||
} |
|||
|
|||
return ( |
|||
<HydrationBoundary state={dehydrate(queryClient)}> |
|||
<FindingMatchClient /> |
|||
</HydrationBoundary> |
|||
); |
|||
export default function FindingMatchPage() { |
|||
return <FindingMatchClient />; |
|||
} |
|||
@ -1,42 +1,5 @@ |
|||
import { |
|||
dehydrate, |
|||
HydrationBoundary, |
|||
QueryClient, |
|||
} from "@tanstack/react-query"; |
|||
import { marriageQueryKeys } from "@/hooks/marriage/query-keys"; |
|||
import { fetchConfigSSR } from "@/lib/ssr-fetch"; |
|||
import IntroClient from "./intro-client"; |
|||
|
|||
export const dynamic = "force-dynamic"; |
|||
|
|||
/** |
|||
* Server Component wrapper for the Intro page. |
|||
* |
|||
* Follows the same SSR-prefetch pattern as questions-list/page.tsx: |
|||
* create a server QueryClient, prefetch critical data, dehydrate, and |
|||
* wrap the client component in HydrationBoundary so TanStack Query |
|||
* hydrates the cache instantly — no client-side waterfall. |
|||
* |
|||
* Config is the only data Intro needs. Even if the fetch fails, IntroClient |
|||
* has a local fallback image so the UI is never broken. |
|||
*/ |
|||
export default async function IntroPage() { |
|||
const queryClient = new QueryClient({ |
|||
defaultOptions: { |
|||
queries: { staleTime: 30 * 1000 }, |
|||
}, |
|||
}); |
|||
|
|||
// Prefetch marriage config — Intro uses it for the video thumbnail.
|
|||
// Failure is non-blocking because IntroClient has a fallbackSrc.
|
|||
await queryClient.prefetchQuery({ |
|||
queryKey: marriageQueryKeys.config(), |
|||
queryFn: () => fetchConfigSSR(), |
|||
}); |
|||
|
|||
return ( |
|||
<HydrationBoundary state={dehydrate(queryClient)}> |
|||
<IntroClient /> |
|||
</HydrationBoundary> |
|||
); |
|||
export default function IntroPage() { |
|||
return <IntroClient />; |
|||
} |
|||
@ -1,39 +1,5 @@ |
|||
import { cookies } from "next/headers"; |
|||
import { |
|||
dehydrate, |
|||
HydrationBoundary, |
|||
QueryClient, |
|||
} from "@tanstack/react-query"; |
|||
import { isAuthenticatedToken } from "@/lib/entry-route-cache"; |
|||
import { fetchProfileSSR } from "@/lib/ssr-fetch"; |
|||
import { marriageQueryKeys } from "@/hooks/marriage/query-keys"; |
|||
import NewMatchClient from "./new-match-client"; |
|||
|
|||
export const dynamic = "force-dynamic"; |
|||
|
|||
export default async function NewMatchPage() { |
|||
const cookieStore = await cookies(); |
|||
|
|||
const token = |
|||
cookieStore.get("HABIB_TOKEN")?.value ?? |
|||
cookieStore.get("habib_token")?.value; |
|||
|
|||
const queryClient = new QueryClient({ |
|||
defaultOptions: { |
|||
queries: { staleTime: 10 * 1000 }, |
|||
}, |
|||
}); |
|||
|
|||
if (isAuthenticatedToken(token)) { |
|||
await queryClient.prefetchQuery({ |
|||
queryKey: marriageQueryKeys.profile(), |
|||
queryFn: () => fetchProfileSSR(token!), |
|||
}); |
|||
} |
|||
|
|||
return ( |
|||
<HydrationBoundary state={dehydrate(queryClient)}> |
|||
<NewMatchClient /> |
|||
</HydrationBoundary> |
|||
); |
|||
export default function NewMatchPage() { |
|||
return <NewMatchClient />; |
|||
} |
|||
@ -1,49 +1,5 @@ |
|||
import { cookies } from "next/headers"; |
|||
import { |
|||
dehydrate, |
|||
HydrationBoundary, |
|||
QueryClient, |
|||
} from "@tanstack/react-query"; |
|||
import { isAuthenticatedToken } from "@/lib/entry-route-cache"; |
|||
import { fetchProfileSSR } from "@/lib/ssr-fetch"; |
|||
import { marriageQueryKeys } from "@/hooks/marriage/query-keys"; |
|||
import QuestionsListClient from "./questions-list-client"; |
|||
|
|||
export const dynamic = "force-dynamic"; |
|||
|
|||
/** |
|||
* Server Component wrapper for questions-list. |
|||
* |
|||
* Prefetches the marriage profile server-side using the HABIB_TOKEN cookie |
|||
* (Flutter sets it via WebViewCookieManager before loadRequest). The profile |
|||
* determines which page the user should see — having it in the HTML avoids |
|||
* the white-flash caused by waiting for the client-side API call. |
|||
* |
|||
* The sections/form-overview loads client-side with shimmer — that's fine. |
|||
*/ |
|||
export default async function QuestionsListPage() { |
|||
const cookieStore = await cookies(); |
|||
|
|||
const token = |
|||
cookieStore.get("HABIB_TOKEN")?.value ?? |
|||
cookieStore.get("habib_token")?.value; |
|||
|
|||
const queryClient = new QueryClient({ |
|||
defaultOptions: { |
|||
queries: { staleTime: 10 * 1000 }, |
|||
}, |
|||
}); |
|||
|
|||
if (isAuthenticatedToken(token)) { |
|||
await queryClient.prefetchQuery({ |
|||
queryKey: marriageQueryKeys.profile(), |
|||
queryFn: () => fetchProfileSSR(token!), |
|||
}); |
|||
} |
|||
|
|||
return ( |
|||
<HydrationBoundary state={dehydrate(queryClient)}> |
|||
<QuestionsListClient /> |
|||
</HydrationBoundary> |
|||
); |
|||
export default function QuestionsListPage() { |
|||
return <QuestionsListClient />; |
|||
} |
|||
@ -1,39 +1,5 @@ |
|||
import { cookies } from "next/headers"; |
|||
import { |
|||
dehydrate, |
|||
HydrationBoundary, |
|||
QueryClient, |
|||
} from "@tanstack/react-query"; |
|||
import { isAuthenticatedToken } from "@/lib/entry-route-cache"; |
|||
import { fetchProfileSSR } from "@/lib/ssr-fetch"; |
|||
import { marriageQueryKeys } from "@/hooks/marriage/query-keys"; |
|||
import RequestAcceptedClient from "./request-accepted-client"; |
|||
|
|||
export const dynamic = "force-dynamic"; |
|||
|
|||
export default async function RequestAcceptedPage() { |
|||
const cookieStore = await cookies(); |
|||
|
|||
const token = |
|||
cookieStore.get("HABIB_TOKEN")?.value ?? |
|||
cookieStore.get("habib_token")?.value; |
|||
|
|||
const queryClient = new QueryClient({ |
|||
defaultOptions: { |
|||
queries: { staleTime: 10 * 1000 }, |
|||
}, |
|||
}); |
|||
|
|||
if (isAuthenticatedToken(token)) { |
|||
await queryClient.prefetchQuery({ |
|||
queryKey: marriageQueryKeys.profile(), |
|||
queryFn: () => fetchProfileSSR(token!), |
|||
}); |
|||
} |
|||
|
|||
return ( |
|||
<HydrationBoundary state={dehydrate(queryClient)}> |
|||
<RequestAcceptedClient /> |
|||
</HydrationBoundary> |
|||
); |
|||
export default function RequestAcceptedPage() { |
|||
return <RequestAcceptedClient />; |
|||
} |
|||
@ -1,39 +1,5 @@ |
|||
import { cookies } from "next/headers"; |
|||
import { |
|||
dehydrate, |
|||
HydrationBoundary, |
|||
QueryClient, |
|||
} from "@tanstack/react-query"; |
|||
import { isAuthenticatedToken } from "@/lib/entry-route-cache"; |
|||
import { fetchProfileSSR } from "@/lib/ssr-fetch"; |
|||
import { marriageQueryKeys } from "@/hooks/marriage/query-keys"; |
|||
import RequestSentClient from "./request-sent-client"; |
|||
|
|||
export const dynamic = "force-dynamic"; |
|||
|
|||
export default async function RequestSentPage() { |
|||
const cookieStore = await cookies(); |
|||
|
|||
const token = |
|||
cookieStore.get("HABIB_TOKEN")?.value ?? |
|||
cookieStore.get("habib_token")?.value; |
|||
|
|||
const queryClient = new QueryClient({ |
|||
defaultOptions: { |
|||
queries: { staleTime: 10 * 1000 }, |
|||
}, |
|||
}); |
|||
|
|||
if (isAuthenticatedToken(token)) { |
|||
await queryClient.prefetchQuery({ |
|||
queryKey: marriageQueryKeys.profile(), |
|||
queryFn: () => fetchProfileSSR(token!), |
|||
}); |
|||
} |
|||
|
|||
return ( |
|||
<HydrationBoundary state={dehydrate(queryClient)}> |
|||
<RequestSentClient /> |
|||
</HydrationBoundary> |
|||
); |
|||
export default function RequestSentPage() { |
|||
return <RequestSentClient />; |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue