You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
270 lines
8.8 KiB
270 lines
8.8 KiB
"use client";
|
|
|
|
import Image from "next/image";
|
|
import { useRouter } from "next/navigation";
|
|
import { useEffect, useRef, useState } from "react";
|
|
import Button from "@/components/Componentes/button";
|
|
import PageHeader from "@/components/Componentes/page-header";
|
|
import ReportActionsSheet from "@/components/Componentes/report-actions-sheet";
|
|
import VideoPlayer from "@/components/Componentes/video-player";
|
|
import type { MarriageProfileResponse } from "@/hooks/marriage/types";
|
|
import { useMarriageConfigQuery } from "@/hooks/marriage/use-marriage-config";
|
|
import { useMarriageProfileQuery } from "@/hooks/marriage/use-profile-main";
|
|
import { authBridge } from "@/lib/auth-bridge";
|
|
import { getSubmitPath } from "@/lib/get-submit-path";
|
|
import { localizePath } from "@/translations/config";
|
|
import { useI18n } from "@/translations/provider";
|
|
|
|
const REDIRECT_SESSION_KEY = "redirect";
|
|
|
|
export default function Intro() {
|
|
const router = useRouter();
|
|
const { dictionary: t, locale } = useI18n();
|
|
const { data: profile, refetch } = useMarriageProfileQuery({
|
|
enabled: false,
|
|
retry: false,
|
|
});
|
|
const [isReportSheetOpen, setIsReportSheetOpen] = useState(false);
|
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
const [isCheckingRedirect, setIsCheckingRedirect] = useState(true);
|
|
const [isPlayerOpen, setIsPlayerOpen] = useState(false);
|
|
const isRedirectingRef = useRef(false);
|
|
|
|
const { data: config } = useMarriageConfigQuery();
|
|
|
|
useEffect(() => {
|
|
let isCancelled = false;
|
|
|
|
const redirectIfNeeded = async () => {
|
|
if (isRedirectingRef.current) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const isAuthenticated = authBridge.isAuthenticated();
|
|
|
|
if (!isAuthenticated) {
|
|
if (!isCancelled) {
|
|
setIsCheckingRedirect(false);
|
|
}
|
|
return;
|
|
}
|
|
|
|
isRedirectingRef.current = true;
|
|
|
|
if (!isCancelled) {
|
|
setIsCheckingRedirect(true);
|
|
}
|
|
|
|
const profileResponse = profile ?? (await refetch()).data;
|
|
const nextPath = localizePath(getSubmitPath(profileResponse), locale);
|
|
if (typeof window !== "undefined") {
|
|
try {
|
|
window.sessionStorage.removeItem(REDIRECT_SESSION_KEY);
|
|
} catch (e) {
|
|
console.warn("sessionStorage is not accessible:", e);
|
|
}
|
|
}
|
|
|
|
if (!isCancelled) {
|
|
const currentPath =
|
|
typeof window !== "undefined" ? window.location.pathname : "";
|
|
if (currentPath === nextPath) {
|
|
setIsCheckingRedirect(false);
|
|
} else {
|
|
router.replace(nextPath);
|
|
}
|
|
return;
|
|
}
|
|
} catch (error) {
|
|
console.error("Error in redirectIfNeeded:", error);
|
|
if (!isCancelled) {
|
|
setIsCheckingRedirect(false);
|
|
}
|
|
} finally {
|
|
isRedirectingRef.current = false;
|
|
}
|
|
};
|
|
|
|
void redirectIfNeeded();
|
|
|
|
const unsubscribe = window.addFlutterResponseListener?.((event) => {
|
|
if (event.action === "login" && event.success) {
|
|
void redirectIfNeeded();
|
|
}
|
|
});
|
|
|
|
return () => {
|
|
isCancelled = true;
|
|
unsubscribe?.();
|
|
};
|
|
}, [locale, profile, refetch, router]);
|
|
|
|
const handleSubmit = async () => {
|
|
if (isSubmitting) {
|
|
return;
|
|
}
|
|
|
|
setIsSubmitting(true);
|
|
|
|
try {
|
|
if (!authBridge.isAuthenticated()) {
|
|
const token = await authBridge.ensureToken();
|
|
if (!token) {
|
|
console.warn("No token from bridge – proceeding with fallback path");
|
|
}
|
|
}
|
|
|
|
let profileResponse = profile;
|
|
try {
|
|
const { data: freshProfile } = await refetch();
|
|
profileResponse = freshProfile ?? profile;
|
|
} catch (refetchError) {
|
|
console.warn(
|
|
"Could not refetch profile data – using fallback",
|
|
refetchError,
|
|
);
|
|
}
|
|
|
|
const submitPath = getSubmitPath(profileResponse);
|
|
const nextPath = localizePath(
|
|
submitPath === "/intro" ? "/terms" : submitPath,
|
|
locale,
|
|
);
|
|
router.push(nextPath);
|
|
} catch (error) {
|
|
console.error("Submission/redirect failed", error);
|
|
router.push(localizePath("/terms", locale));
|
|
} finally {
|
|
setIsSubmitting(false);
|
|
}
|
|
};
|
|
|
|
if (isCheckingRedirect) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<div className="pt-[max(16px,calc(var(--safe-top)+8px))]">
|
|
{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">
|
|
<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="mt-14 relative cursor-pointer group rounded-2xl overflow-hidden aspect-[344/221] max-w-[344px] w-full mx-auto"
|
|
onClick={() => setIsPlayerOpen(true)}
|
|
>
|
|
<Image
|
|
src={
|
|
config?.intro_video_thumbnail_url ||
|
|
"/assets/images/Frame 2095586523.png"
|
|
}
|
|
alt={t["video"]}
|
|
fill
|
|
sizes="344px"
|
|
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}
|
|
>
|
|
{t["Submit"]}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
);
|
|
}
|