60 changed files with 7934 additions and 3423 deletions
-
31src/app/[lang]/page.tsx
-
2src/app/api/proxy/route.ts
-
15src/app/candidate-contact/candidate-contact-client.tsx
-
38src/app/candidate-contact/page.tsx
-
50src/app/finding-match/finding-match-client.tsx
-
38src/app/finding-match/page.tsx
-
4src/app/globals.css
-
41src/app/intro/page.tsx
-
49src/app/layout.tsx
-
4src/app/marriage-advisors/page.tsx
-
148src/app/new-match/new-match-client.tsx
-
38src/app/new-match/page.tsx
-
14src/app/new-match/profile/page.tsx
-
13src/app/page.tsx
-
17src/app/providers.tsx
-
1src/app/questions-list/[slug]/question-detail-client.test.tsx
-
10src/app/questions-list/[slug]/question-detail-client.tsx
-
48src/app/questions-list/page.tsx
-
28src/app/questions-list/questions-list-client.tsx
-
38src/app/request-accepted/page.tsx
-
67src/app/request-accepted/request-accepted-client.tsx
-
38src/app/request-sent/page.tsx
-
46src/app/request-sent/request-sent-client.tsx
-
5src/app/terms/page.tsx
-
4src/components/Componentes/auth-data-boundary.tsx
-
2src/components/Componentes/button.tsx
-
7src/components/Componentes/fix-to-the-end.tsx
-
8src/components/Componentes/question-exit-navigation-button.tsx
-
4807src/data/countries.ts
-
7src/hooks/marriage/use-match-start.ts
-
69src/hooks/marriage/use-profile-main.ts
-
15src/hooks/use-habib-web-ready.ts
-
47src/lib/auth-bridge.ts
-
8src/lib/cookies.ts
-
14src/lib/entry-route-cache.ts
-
30src/lib/marriage-field-formatter.ts
-
50src/lib/user-scoped-storage.test.ts
-
82src/lib/user-scoped-storage.ts
-
52src/translations/locales/ar.json
-
40src/translations/locales/az.json
-
40src/translations/locales/bn.json
-
160src/translations/locales/da.json
-
200src/translations/locales/de.json
-
210src/translations/locales/es.json
-
248src/translations/locales/fr.json
-
364src/translations/locales/gu.json
-
226src/translations/locales/ha.json
-
384src/translations/locales/he.json
-
368src/translations/locales/hi.json
-
168src/translations/locales/id.json
-
388src/translations/locales/ks.json
-
284src/translations/locales/pt.json
-
354src/translations/locales/ru.json
-
234src/translations/locales/sw.json
-
384src/translations/locales/tg.json
-
280src/translations/locales/tr.json
-
76src/translations/locales/ul.json
-
388src/translations/locales/ur.json
-
320src/translations/locales/uz.json
-
180src/translations/locales/zh.json
@ -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 />; |
|||
} |
|||
4807
src/data/countries.ts
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
Write
Preview
Loading…
Cancel
Save
Reference in new issue