|
|
|
@ -2,15 +2,18 @@ |
|
|
|
|
|
|
|
import Image from "next/image"; |
|
|
|
import { useRouter } from "next/navigation"; |
|
|
|
import { useState } from "react"; |
|
|
|
import { useCallback, useEffect, useState } from "react"; |
|
|
|
import Button from "@/components/Componentes/button"; |
|
|
|
import NetworkImage from "@/components/Componentes/network-image"; |
|
|
|
import PageHeader from "@/components/Componentes/page-header"; |
|
|
|
import ReportActionsSheet from "@/components/Componentes/report-actions-sheet"; |
|
|
|
import SectionOverlayHost from "@/components/Componentes/section-overlay-host"; |
|
|
|
import SliderPage from "@/components/Componentes/slider-page"; |
|
|
|
import VideoPlayer from "@/components/Componentes/video-player"; |
|
|
|
import { useMarriageConfigQuery } from "@/hooks/marriage/use-marriage-config"; |
|
|
|
import { useMarriageProfileQuery } from "@/hooks/marriage/use-profile-main"; |
|
|
|
import { useHabibWebReady } from "@/hooks/use-habib-web-ready"; |
|
|
|
import { useHardwareBackHandler } from "@/hooks/use-hardware-back-handler"; |
|
|
|
import { authBridge } from "@/lib/auth-bridge"; |
|
|
|
import { getSubmitPath } from "@/lib/get-submit-path"; |
|
|
|
import { localizePath } from "@/translations/config"; |
|
|
|
@ -26,6 +29,7 @@ export default function IntroClient() { |
|
|
|
const [isReportSheetOpen, setIsReportSheetOpen] = useState(false); |
|
|
|
const [isSubmitting, setIsSubmitting] = useState(false); |
|
|
|
const [isPlayerOpen, setIsPlayerOpen] = useState(false); |
|
|
|
const [isStepsOpen, setIsStepsOpen] = useState(false); |
|
|
|
|
|
|
|
const { data: config } = useMarriageConfigQuery(); |
|
|
|
|
|
|
|
@ -33,6 +37,47 @@ export default function IntroClient() { |
|
|
|
// image so we don't need to wait for it — announce immediately on mount.
|
|
|
|
useHabibWebReady(true); |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
const readStepsFromUrl = () => { |
|
|
|
if (typeof window === "undefined") return; |
|
|
|
const params = new URLSearchParams(window.location.search); |
|
|
|
setIsStepsOpen(params.get("steps") === "open"); |
|
|
|
}; |
|
|
|
|
|
|
|
readStepsFromUrl(); |
|
|
|
window.addEventListener("popstate", readStepsFromUrl); |
|
|
|
return () => window.removeEventListener("popstate", readStepsFromUrl); |
|
|
|
}, []); |
|
|
|
|
|
|
|
const handleOpenSteps = useCallback(() => { |
|
|
|
setIsStepsOpen(true); |
|
|
|
if (typeof window !== "undefined") { |
|
|
|
const url = new URL(window.location.href); |
|
|
|
url.searchParams.set("steps", "open"); |
|
|
|
window.history.pushState({ steps: "open" }, "", url.toString()); |
|
|
|
} |
|
|
|
}, []); |
|
|
|
|
|
|
|
const handleCloseSteps = useCallback(() => { |
|
|
|
if (typeof window !== "undefined") { |
|
|
|
const params = new URLSearchParams(window.location.search); |
|
|
|
if (params.get("steps") === "open") { |
|
|
|
setIsStepsOpen(false); |
|
|
|
window.history.back(); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
setIsStepsOpen(false); |
|
|
|
}, []); |
|
|
|
|
|
|
|
useHardwareBackHandler(() => { |
|
|
|
if (isStepsOpen) { |
|
|
|
handleCloseSteps(); |
|
|
|
return true; // handled: keep WebView open, just close the overlay
|
|
|
|
} |
|
|
|
return false; // Root: tell Flutter to close WebView screen
|
|
|
|
}, isStepsOpen); |
|
|
|
|
|
|
|
const handleSubmit = async () => { |
|
|
|
if (isSubmitting) { |
|
|
|
return; |
|
|
|
@ -61,137 +106,148 @@ export default function IntroClient() { |
|
|
|
} |
|
|
|
|
|
|
|
const submitPath = getSubmitPath(profileResponse); |
|
|
|
const nextPath = localizePath( |
|
|
|
submitPath === "/intro" ? "/terms" : submitPath, |
|
|
|
locale, |
|
|
|
); |
|
|
|
router.push(nextPath); |
|
|
|
if (submitPath === "/intro" || submitPath === "/terms") { |
|
|
|
handleOpenSteps(); |
|
|
|
} else { |
|
|
|
router.push(localizePath(submitPath, locale)); |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
console.error("Submission/redirect failed", error); |
|
|
|
router.push(localizePath("/terms", locale)); |
|
|
|
handleOpenSteps(); |
|
|
|
} finally { |
|
|
|
setIsSubmitting(false); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
return ( |
|
|
|
<div className="pt-[max(12px,calc(var(--safe-top)+4px))]"> |
|
|
|
{isReportSheetOpen && ( |
|
|
|
<ReportActionsSheet onClose={() => setIsReportSheetOpen(false)} /> |
|
|
|
)} |
|
|
|
<PageHeader |
|
|
|
rightButton={{ |
|
|
|
icon: "support", |
|
|
|
onClick: () => setIsReportSheetOpen(true), |
|
|
|
}} |
|
|
|
/> |
|
|
|
<main className="pb-[calc(90px+var(--safe-bottom))]"> |
|
|
|
<div className="flex flex-col items-center mt-16"> |
|
|
|
<Image |
|
|
|
src={"/assets/images/Group 1597880466.svg"} |
|
|
|
alt={t["heavenly marriage"]} |
|
|
|
width={168} |
|
|
|
height={155} |
|
|
|
/> |
|
|
|
<h2 className="group-16 text-[#475569] font-bold mt-5 text-center"> |
|
|
|
{t["A Path to Heavenly Marriage"]} |
|
|
|
</h2> |
|
|
|
<p className="text-center mt-2 group-12 text-[#4D4D4D]"> |
|
|
|
{ |
|
|
|
t[ |
|
|
|
'We have come together with the goal of creating a secure and confidential path for "permanent marriage" among Muslims' |
|
|
|
] |
|
|
|
} |
|
|
|
</p> |
|
|
|
</div> |
|
|
|
<div className="flex items-center justify-between mt-4"> |
|
|
|
<div className="flex items-center gap-0.5 p-2 border border-[#FD6ABB]/10 rounded-2xl"> |
|
|
|
<> |
|
|
|
<div className="pt-[max(12px,calc(var(--safe-top)+4px))]"> |
|
|
|
{isReportSheetOpen && ( |
|
|
|
<ReportActionsSheet onClose={() => setIsReportSheetOpen(false)} /> |
|
|
|
)} |
|
|
|
<PageHeader |
|
|
|
rightButton={{ |
|
|
|
icon: "support", |
|
|
|
onClick: () => setIsReportSheetOpen(true), |
|
|
|
}} |
|
|
|
/> |
|
|
|
<main className="pb-[calc(90px+var(--safe-bottom))]"> |
|
|
|
<div className="flex flex-col items-center mt-16"> |
|
|
|
<Image |
|
|
|
src={"/assets/images/tabler_user-filled.svg"} |
|
|
|
alt={t["user profiles"]} |
|
|
|
width={37} |
|
|
|
height={37} |
|
|
|
src={"/assets/images/Group 1597880466.svg"} |
|
|
|
alt={t["heavenly marriage"]} |
|
|
|
width={168} |
|
|
|
height={155} |
|
|
|
/> |
|
|
|
<div className="flex flex-col items-start justify-start -mb-2"> |
|
|
|
<p className="text-[#36363C] group-16 font-bold leading-3">120</p> |
|
|
|
<p className="text-[#36363C] group-10 font-semibold capitalize"> |
|
|
|
{t["user profiles"]} |
|
|
|
</p> |
|
|
|
<h2 className="group-16 text-[#475569] font-bold mt-5 text-center"> |
|
|
|
{t["A Path to Heavenly Marriage"]} |
|
|
|
</h2> |
|
|
|
<p className="text-center mt-2 group-12 text-[#4D4D4D]"> |
|
|
|
{ |
|
|
|
t[ |
|
|
|
'We have come together with the goal of creating a secure and confidential path for "permanent marriage" among Muslims' |
|
|
|
] |
|
|
|
} |
|
|
|
</p> |
|
|
|
</div> |
|
|
|
<div className="flex items-center justify-between mt-4"> |
|
|
|
<div className="flex items-center gap-0.5 p-2 border border-[#FD6ABB]/10 rounded-2xl"> |
|
|
|
<Image |
|
|
|
src={"/assets/images/tabler_user-filled.svg"} |
|
|
|
alt={t["user profiles"]} |
|
|
|
width={37} |
|
|
|
height={37} |
|
|
|
/> |
|
|
|
<div className="flex flex-col items-start justify-start -mb-2"> |
|
|
|
<p className="text-[#36363C] group-16 font-bold leading-3">120</p> |
|
|
|
<p className="text-[#36363C] group-10 font-semibold capitalize"> |
|
|
|
{t["user profiles"]} |
|
|
|
</p> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div className="flex items-center gap-0.5 p-2 border border-[#FD6ABB]/10 rounded-2xl"> |
|
|
|
<Image |
|
|
|
src={"/assets/images/icon-park-solid_success.svg"} |
|
|
|
alt={t["matches"]} |
|
|
|
width={37} |
|
|
|
height={37} |
|
|
|
priority |
|
|
|
/> |
|
|
|
<div className="flex flex-col items-start justify-start -mb-2"> |
|
|
|
<p className="text-[#36363C] group-16 font-bold leading-3">14</p> |
|
|
|
<p className="text-[#36363C] group-10 font-semibold capitalize"> |
|
|
|
{t["matches"]} |
|
|
|
</p> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div className="flex items-center gap-0.5 p-2 border border-[#FD6ABB]/10 rounded-2xl"> |
|
|
|
<Image |
|
|
|
src={"/assets/images/typcn_heart-full-outline.svg"} |
|
|
|
alt={t["marriages"]} |
|
|
|
width={37} |
|
|
|
height={37} |
|
|
|
priority |
|
|
|
/> |
|
|
|
<div className="flex flex-col items-start justify-start -mb-2"> |
|
|
|
<p className="text-[#36363C] group-16 font-bold leading-3">14</p> |
|
|
|
<p className="text-[#36363C] group-10 font-semibold capitalize"> |
|
|
|
{t["marriages"]} |
|
|
|
</p> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div className="flex items-center gap-0.5 p-2 border border-[#FD6ABB]/10 rounded-2xl"> |
|
|
|
<Image |
|
|
|
src={"/assets/images/icon-park-solid_success.svg"} |
|
|
|
alt={t["matches"]} |
|
|
|
width={37} |
|
|
|
height={37} |
|
|
|
<div |
|
|
|
className="mt-14 relative cursor-pointer group rounded-2xl overflow-hidden aspect-[344/221] max-w-[344px] w-full mx-auto" |
|
|
|
onClick={() => setIsPlayerOpen(true)} |
|
|
|
> |
|
|
|
<NetworkImage |
|
|
|
src={config?.intro_video_thumbnail_url} |
|
|
|
fallbackSrc="/assets/images/Frame 2095586523.png" |
|
|
|
alt={t["video"]} |
|
|
|
fill |
|
|
|
className="object-cover transition-transform duration-300 group-hover:scale-105" |
|
|
|
priority |
|
|
|
/> |
|
|
|
<div className="flex flex-col items-start justify-start -mb-2"> |
|
|
|
<p className="text-[#36363C] group-16 font-bold leading-3">14</p> |
|
|
|
<p className="text-[#36363C] group-10 font-semibold capitalize"> |
|
|
|
{t["matches"]} |
|
|
|
</p> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div className="flex items-center gap-0.5 p-2 border border-[#FD6ABB]/10 rounded-2xl"> |
|
|
|
<div className="absolute inset-0 bg-black/10 transition-colors duration-300 group-hover:bg-black/20" /> |
|
|
|
<Image |
|
|
|
src={"/assets/images/typcn_heart-full-outline.svg"} |
|
|
|
alt={t["marriages"]} |
|
|
|
width={37} |
|
|
|
height={37} |
|
|
|
priority |
|
|
|
src={"/assets/images/Frame 1116607280.svg"} |
|
|
|
alt={t["play"]} |
|
|
|
width={68} |
|
|
|
height={68} |
|
|
|
className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 transition-transform duration-300 group-hover:scale-110 active:scale-95" |
|
|
|
/> |
|
|
|
<div className="flex flex-col items-start justify-start -mb-2"> |
|
|
|
<p className="text-[#36363C] group-16 font-bold leading-3">14</p> |
|
|
|
<p className="text-[#36363C] group-10 font-semibold capitalize"> |
|
|
|
{t["marriages"]} |
|
|
|
</p> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div |
|
|
|
className="mt-14 relative cursor-pointer group rounded-2xl overflow-hidden aspect-[344/221] max-w-[344px] w-full mx-auto" |
|
|
|
onClick={() => setIsPlayerOpen(true)} |
|
|
|
> |
|
|
|
<NetworkImage |
|
|
|
src={config?.intro_video_thumbnail_url} |
|
|
|
fallbackSrc="/assets/images/Frame 2095586523.png" |
|
|
|
alt={t["video"]} |
|
|
|
fill |
|
|
|
className="object-cover transition-transform duration-300 group-hover:scale-105" |
|
|
|
priority |
|
|
|
/> |
|
|
|
<div className="absolute inset-0 bg-black/10 transition-colors duration-300 group-hover:bg-black/20" /> |
|
|
|
<Image |
|
|
|
src={"/assets/images/Frame 1116607280.svg"} |
|
|
|
alt={t["play"]} |
|
|
|
width={68} |
|
|
|
height={68} |
|
|
|
className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 transition-transform duration-300 group-hover:scale-110 active:scale-95" |
|
|
|
/> |
|
|
|
</div> |
|
|
|
|
|
|
|
<VideoPlayer |
|
|
|
isOpen={isPlayerOpen} |
|
|
|
onClose={() => setIsPlayerOpen(false)} |
|
|
|
videoUrl={config?.intro_video_url} |
|
|
|
/> |
|
|
|
<div className="pointer-events-none fixed bottom-0 left-1/2 z-20 w-full sm:max-w-[375px] -translate-x-1/2 bg-[#F5F5F5]"> |
|
|
|
<div |
|
|
|
style={{ paddingBottom: "calc(20px + var(--safe-bottom))" }} |
|
|
|
className="pointer-events-auto px-[17px] pt-3" |
|
|
|
> |
|
|
|
<Button |
|
|
|
onClick={handleSubmit} |
|
|
|
disabled={isSubmitting} |
|
|
|
isLoading={isSubmitting} |
|
|
|
<VideoPlayer |
|
|
|
isOpen={isPlayerOpen} |
|
|
|
onClose={() => setIsPlayerOpen(false)} |
|
|
|
videoUrl={config?.intro_video_url} |
|
|
|
/> |
|
|
|
<div className="pointer-events-none fixed bottom-0 left-1/2 z-20 w-full sm:max-w-[375px] -translate-x-1/2 bg-[#F5F5F5]"> |
|
|
|
<div |
|
|
|
style={{ paddingBottom: "calc(20px + var(--safe-bottom))" }} |
|
|
|
className="pointer-events-auto px-[17px] pt-3" |
|
|
|
> |
|
|
|
{t["Submit"]} |
|
|
|
</Button> |
|
|
|
<Button |
|
|
|
onClick={handleSubmit} |
|
|
|
disabled={isSubmitting} |
|
|
|
isLoading={isSubmitting} |
|
|
|
> |
|
|
|
{t["Submit"]} |
|
|
|
</Button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</main> |
|
|
|
</div> |
|
|
|
</main> |
|
|
|
</div> |
|
|
|
|
|
|
|
<SectionOverlayHost |
|
|
|
open={isStepsOpen} |
|
|
|
onClose={handleCloseSteps} |
|
|
|
> |
|
|
|
{isStepsOpen && ( |
|
|
|
<SliderPage onClose={handleCloseSteps} /> |
|
|
|
)} |
|
|
|
</SectionOverlayHost> |
|
|
|
</> |
|
|
|
); |
|
|
|
} |