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.
218 lines
7.7 KiB
218 lines
7.7 KiB
"use client";
|
|
|
|
import Image from "next/image";
|
|
import { useRouter } from "next/navigation";
|
|
import { useEffect, useMemo } from "react";
|
|
import { useHardwareBackHandler } from "@/hooks/use-hardware-back-handler";
|
|
import { useHabibWebReady } from "@/hooks/use-habib-web-ready";
|
|
import { Ic } from "@/icons";
|
|
import AdvisorActionsCard from "@/components/Componentes/advisor-actions-card";
|
|
import MarriageAdvisorsOverlay, {
|
|
useMarriageAdvisorsOverlay,
|
|
} from "@/components/Componentes/marriage-advisors-overlay";
|
|
import Button from "@/components/Componentes/button";
|
|
import { FixToTheEnd } from "@/components/Componentes/fix-to-the-end";
|
|
import { PageBackground } from "@/components/Componentes/page-background";
|
|
import PageHeader from "@/components/Componentes/page-header";
|
|
import { useMarriageProfileQuery } from "@/hooks/marriage/use-profile-main";
|
|
import { useRejectionSeenMutation } from "@/hooks/marriage/use-rejection-seen";
|
|
import { getSubmitPath } from "@/lib/get-submit-path";
|
|
import { localizePath } from "@/translations/config";
|
|
import { useI18n } from "@/translations/provider";
|
|
|
|
const advisorAvatars = [
|
|
{ id: "advisor-primary", src: "/assets/images/Avatar Image.png" },
|
|
{ id: "advisor-secondary", src: "/assets/images/Avatar Image.png" },
|
|
{ id: "advisor-tertiary", src: "/assets/images/Avatar Image.png" },
|
|
];
|
|
|
|
export default function FindingMatchClient() {
|
|
const router = useRouter();
|
|
const { dictionary: t, locale } = useI18n();
|
|
const { isAdvisorOpen, openAdvisors, closeAdvisors } =
|
|
useMarriageAdvisorsOverlay();
|
|
const { data: profile, isLoading, isFetched } = useMarriageProfileQuery({
|
|
refetchInterval: 3000,
|
|
});
|
|
|
|
const { mutate: markRejectionSeen, isPending: isMarkingSeen } =
|
|
useRejectionSeenMutation();
|
|
|
|
useHardwareBackHandler(() => {
|
|
if (isAdvisorOpen) {
|
|
closeAdvisors();
|
|
return true;
|
|
}
|
|
return false; // Hardware back closes the service in Flutter
|
|
});
|
|
|
|
useEffect(() => {
|
|
if (!profile) {
|
|
return;
|
|
}
|
|
// Don't bounce away from finding-match if we only have preliminary initialData
|
|
// with pending_info before the fresh server query finishes
|
|
if (!isFetched && profile.status === "pending_info") {
|
|
return;
|
|
}
|
|
const targetPath = getSubmitPath(profile);
|
|
if (targetPath !== "/finding-match") {
|
|
router.replace(localizePath(targetPath, locale));
|
|
}
|
|
}, [profile, isFetched, locale, router]);
|
|
|
|
// Signal Flutter to lift its loading cover immediately so page renders with 0ms latency.
|
|
useHabibWebReady(true);
|
|
|
|
const isRedirecting = useMemo(() => {
|
|
if (!profile) return false;
|
|
return getSubmitPath(profile) !== "/finding-match";
|
|
}, [profile]);
|
|
|
|
const copy = {
|
|
title: t["SEARCH IN PROGRESS"],
|
|
description:
|
|
t[
|
|
"Our system is actively looking for compatible partners based on your criteria. This process requires time and patience. We will notify you immediately once a profile is ready for your review."
|
|
],
|
|
advisorTitle: t["Get an advisor"],
|
|
advisorDescription:
|
|
t[
|
|
"Not sure what to do next? Our psychology section is here to guide you at every step."
|
|
],
|
|
getAdvisor: t["Get Advisor"],
|
|
editProfile: t["Edit Profile"],
|
|
};
|
|
const matchImageSrc = "/assets/images/Group 1597880466.svg";
|
|
// This notice belongs exclusively to the gentleman whose accepted request
|
|
// was later rejected by the lady. The API enforces the same rule.
|
|
const unseenRejection =
|
|
profile?.gender === "male" ? profile.unseen_rejection : null;
|
|
|
|
return (
|
|
<>
|
|
<PageBackground />
|
|
|
|
<PageHeader
|
|
profile={profile}
|
|
sticky
|
|
leftButton={{
|
|
icon: "back",
|
|
onClick: () => {
|
|
if (typeof window !== "undefined" && (window as any).HabibApp) {
|
|
(window as any).HabibApp.postMessage(
|
|
JSON.stringify({ action: "close_service" }),
|
|
);
|
|
} else {
|
|
router.back();
|
|
}
|
|
},
|
|
}}
|
|
/>
|
|
|
|
<main
|
|
style={{ paddingBottom: "calc(80px + var(--safe-bottom))" }}
|
|
className="flex min-h-0 flex-1 flex-col justify-between text-center page-slide-enter"
|
|
>
|
|
|
|
<section className="mt-6 flex flex-1 flex-col items-center px-[23px]">
|
|
<div className="relative h-[124px] w-[130px]" aria-hidden="true">
|
|
<Image
|
|
src={matchImageSrc}
|
|
alt=""
|
|
fill
|
|
sizes="58px"
|
|
className="object-cover"
|
|
priority
|
|
/>
|
|
</div>
|
|
<h1 className="mt-4 group-16 font-bold leading-none tracking-[0.02em] text-[#171717] uppercase">
|
|
{copy.title}
|
|
</h1>
|
|
<p className="mt-3 max-w-[320px] mx-auto text-center group-12 leading-[1.35] font-semibold text-[#747474]">
|
|
{copy.description}
|
|
</p>
|
|
{unseenRejection && (
|
|
<aside
|
|
className="mt-5 w-full rounded-[20px] border border-[#F2465F]/15 bg-white p-4 text-start shadow-[0_10px_28px_rgba(242,70,95,0.08)]"
|
|
aria-live="polite"
|
|
aria-labelledby="rejection-notice-title"
|
|
>
|
|
<div className="flex items-start gap-3">
|
|
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-[#FFF0F2] text-[#F2465F]">
|
|
<Ic name="alert" className="h-6 w-6" aria-hidden="true" />
|
|
</div>
|
|
|
|
<div className="min-w-0 flex-1">
|
|
<h2
|
|
id="rejection-notice-title"
|
|
className="text-[16px] font-bold leading-[1.3] text-[#171717]"
|
|
>
|
|
{t["Your request was rejected"]}
|
|
</h2>
|
|
|
|
<p className="mt-1.5 text-[13px] font-semibold leading-[1.5] text-[#747474]">
|
|
{
|
|
t[
|
|
"Your request was rejected by the lady. You will be introduced to other candidates in the future."
|
|
]
|
|
}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="mt-4 w-full">
|
|
<Button
|
|
isLoading={isMarkingSeen}
|
|
onClick={() => {
|
|
markRejectionSeen({
|
|
rejection_id: unseenRejection.id,
|
|
});
|
|
}}
|
|
>
|
|
{t["Got it"]}
|
|
</Button>
|
|
</div>
|
|
</aside>
|
|
)}{" "}
|
|
</section>
|
|
|
|
<AdvisorActionsCard
|
|
title={copy.advisorTitle}
|
|
description={copy.advisorDescription}
|
|
avatars={advisorAvatars}
|
|
extraCount={7}
|
|
getAdvisorLabel={copy.getAdvisor}
|
|
onGetAdvisor={openAdvisors}
|
|
/>
|
|
|
|
<FixToTheEnd>
|
|
{profile?.can_edit_profile === false ? (
|
|
<div
|
|
className="inline-flex w-full items-center justify-center gap-2 rounded-[9px] border-none bg-[#D1D1D6] dark:bg-[#3D3E42] px-4 py-[17px] text-center text-[#747474] dark:text-[#A1A1A1] shadow-none"
|
|
aria-live="polite"
|
|
>
|
|
<Ic name="lock" aria-hidden="true" className="h-3.5 w-3.5 shrink-0" />
|
|
<span className="group-16 leading-none font-semibold">
|
|
{t["Profile is locked"]}
|
|
</span>
|
|
</div>
|
|
) : (
|
|
<Button
|
|
variant="dark"
|
|
href={localizePath("/questions-list", locale)}
|
|
>
|
|
<Ic name="pencil" aria-hidden="true" className="h-3.5 w-3.5 shrink-0" />
|
|
<span>{copy.editProfile}</span>
|
|
</Button>
|
|
)}
|
|
</FixToTheEnd>
|
|
</main>
|
|
|
|
<MarriageAdvisorsOverlay
|
|
open={isAdvisorOpen}
|
|
onClose={closeAdvisors}
|
|
/>
|
|
</>
|
|
);
|
|
}
|