"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, hasCompletedMarriageProfileBasics, } from "@/lib/get-submit-path"; 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 { getQuestionAnswersStorageKey } from "@/components/Componentes/question-answer-storage"; 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 "@/lib/schema-adapter"; 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 profileTargetPath = useMemo( () => (profile ? getSubmitPath(profile) : null), [profile], ); const isProfileRedirecting = profileTargetPath !== null && profileTargetPath !== "/questions-list" && (!hasCompletedMarriageProfileBasics(profile) || profile?.can_edit_profile === false); useEffect(() => { if (isProfileRedirecting && profileTargetPath) { router.replace(localizePath(profileTargetPath, locale)); } }, [isProfileRedirecting, locale, profileTargetPath, router]); 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) => { if (!progressBySlug.has(item.slug)) { 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 = questionListItems.map(item => item.slug); for (const slug of slugsToCheck) { const storageKey = getQuestionAnswersStorageKey(slug); const rawValue = window.localStorage.getItem(storageKey); 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( storageKey, JSON.stringify(storedValue), ); } } } queryClient.invalidateQueries(); startMatchMutation.mutate(); } catch (err) { console.error("Failed to sync pending sections:", err); setIsSyncError(true); } finally { setIsSyncing(false); } }; if ( isProfileLoading || isSectionsLoading || isSchemaLoading || isProfileRedirecting ) { 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 (Hosseinieh Card Style) */}
{/* 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)} /> ))}
); }