"use client"; import Image from "next/image"; import { useRouter } from "next/navigation"; import { useEffect, useMemo, useState } from "react"; import { IoClose } from "react-icons/io5"; import { getSubmitPath } from "@/lib/get-submit-path"; import { getLocalSectionProgress, getStoredAge, } from "@/components/Componentes/progress-helper"; import QuestionCard from "@/components/Componentes/question-card"; import RequiredStepsCard from "@/components/Componentes/required-steps-card"; import Button from "@/components/Componentes/button"; import InformationSheet from "@/components/Componentes/information-sheet"; import NavigationButton from "@/components/Componentes/navigation-button"; import { FixToTheEnd } from "@/components/Componentes/fix-to-the-end"; import { LoadingSkeleton } from "@/components/Componentes/loading-skeleton"; import { PageBackground } from "@/components/Componentes/page-background"; import ErrorToast from "@/components/Componentes/error-toast"; import { useQueryClient } from "@tanstack/react-query"; import { useStartMarriageMatchMutation } from "@/hooks/marriage/use-match-start"; import { useMarriageProfileQuery } from "@/hooks/marriage/use-profile-main"; import { useMarriageSectionsQuery } from "@/hooks/marriage/use-sections"; import { useFormSchemaQuery } from "@/hooks/marriage/use-form-schema"; import { convertSchemaToFrontendItems } from "@/lib/schema-adapter"; import type { QuestionListItem } from "@/data/question-data"; import { useCloseServiceOnBack } from "@/hooks/use-close-service-on-back"; import { clearMatchStartGrace, markMatchStarted, } from "@/lib/match-start-grace"; import { localizePath } from "@/translations/config"; import { useI18n } from "@/translations/provider"; import { triggerSilentReload } from "@/components/Componentes/silent-reloader"; import SectionsRequest from "./sections-request"; export default function QuestionsListPage() { useCloseServiceOnBack(); const { dictionary: t, locale } = useI18n(); const router = useRouter(); const queryClient = useQueryClient(); const { data: profile, isLoading: isProfileLoading } = useMarriageProfileQuery(); const { data: sections, isLoading: isSectionsLoading } = useMarriageSectionsQuery(); const { data: schema, isLoading: isSchemaLoading } = useFormSchemaQuery("profile", locale); useEffect(() => { triggerSilentReload(queryClient); }, [queryClient]); const startMatchMutation = useStartMarriageMatchMutation({ onSuccess: () => { markMatchStarted(); router.push(localizePath("/finding-match", locale)); }, onError: () => { // Never pretend the request went through – the user stays here and can // retry instead of being parked on the waiting screen forever. clearMatchStartGrace(); }, }); const [isOptionalInfoSheetOpen, setIsOptionalInfoSheetOpen] = useState(false); const [selectedSection, setSelectedSection] = useState(null); const questionListItems = useMemo( () => convertSchemaToFrontendItems(schema, locale), [schema, locale], ); const sectionProgressBySlug = useMemo(() => { const progressBySlug = new Map(); if (schema?.progress?.sections_progress) { Object.entries(schema.progress.sections_progress).forEach(([slug, prog]) => { progressBySlug.set(slug, Math.max(0, Math.min(100, Math.round(prog.completion_percent)))); }); } // Add fallback for combined section from the schema adapter which attaches it to questionListItems directly questionListItems.forEach((item) => { progressBySlug.set(item.slug, item.progress); }); return progressBySlug; }, [schema, questionListItems]); const requiredQuestionListItems = useMemo( () => questionListItems.filter((item) => Boolean(item.required)), [questionListItems], ); const allRequiredSectionsCompleted = useMemo(() => { if (requiredQuestionListItems.length === 0) { return false; } return requiredQuestionListItems.every((item) => { const progress = sectionProgressBySlug.get(item.slug) ?? 0; return progress >= 100; }); }, [requiredQuestionListItems, sectionProgressBySlug]); const profileStatus = profile?.status; const isProfileSuspended = profileStatus === "suspended"; const isProfileBlocked = profileStatus === "in_case" || profileStatus === "matched"; const canStartMatch = !isProfileSuspended && !isProfileBlocked && allRequiredSectionsCompleted; const [isSyncError, setIsSyncError] = useState(false); const [isSyncing, setIsSyncing] = useState(false); const [toastMessage, setToastMessage] = useState(null); useEffect(() => { if (startMatchMutation.isError || isSyncError) { setToastMessage( t[ "Sending the match request failed. Please check your connection and try again." ], ); } }, [ startMatchMutation.isError, isSyncError, t[ "Sending the match request failed. Please check your connection and try again." ], ]); const handleCloseToast = () => { setToastMessage(null); setIsSyncError(false); startMatchMutation.reset(); }; const isStartMatchDisabled = startMatchMutation.isPending || isSyncing || !canStartMatch; const hasIncompleteOptionalSections = useMemo(() => { return questionListItems.some( (item) => !item.required && (sectionProgressBySlug.get(item.slug) ?? 0) < 100, ); }, [questionListItems, sectionProgressBySlug]); const handleStartMatch = async () => { if (isStartMatchDisabled || isSyncing) { return; } setIsSyncing(true); setIsSyncError(false); try { const slugsToCheck = [ "personal_info", "contact_residence_family_communication", "appearance_health_activity", "education_career_economic_status", "family_marital_history", "beliefs_lifestyle_boundaries", "future_spouse_criteria", "identity_verification", ]; for (const slug of slugsToCheck) { const rawValue = window.localStorage.getItem( `marriage:sections:${slug}:answers`, ); if (rawValue) { const storedValue = JSON.parse(rawValue); if (storedValue.pending_sync && storedValue.fields) { const payload = { current_step: storedValue.current_step, fields: storedValue.fields, }; const { updateMarriageSectionData } = await import( "@/hooks/marriage/use-section-data" ); await updateMarriageSectionData(slug, payload); storedValue.pending_sync = false; window.localStorage.setItem( `marriage:sections:${slug}:answers`, JSON.stringify(storedValue), ); } } } await queryClient.invalidateQueries(); startMatchMutation.mutate(); } catch (err) { console.error("Failed to sync pending sections:", err); setIsSyncError(true); } finally { setIsSyncing(false); } }; if (isProfileLoading || isSectionsLoading || isSchemaLoading) { return ( <>
{ e.preventDefault(); if (typeof window !== "undefined" && (window as any).HabibApp) { (window as any).HabibApp.postMessage( JSON.stringify({ action: "close_service" }), ); } else { router.push("/"); } }} />

{t["Profile registration"]}

{/* Required Steps Card Skeleton */} {/* Section Cards Skeletons */}
{Array.from({ length: 6 }).map((_, idx) => (
))}
); } return ( <> {toastMessage && ( )} {isOptionalInfoSheetOpen ? ( { t[ "You've completed all required fields. However, filling in all sections will help us find better matches for you" ] }

} onClose={() => setIsOptionalInfoSheetOpen(false)} buttons={({ close }) => (
)} /> ) : null} {selectedSection ? ( ( {selectedSection.title} )} description={

{selectedSection.summary}

} onClose={() => setSelectedSection(null)} className="text-left" /> ) : null}
{ e.preventDefault(); if (typeof window !== "undefined" && (window as any).HabibApp) { (window as any).HabibApp.postMessage( JSON.stringify({ action: "close_service" }), ); } else { router.push("/"); } }} />

{t["Profile registration"]}

{questionListItems.map((item) => ( setSelectedSection(section)} /> ))}
); }