diff --git a/src/app/globals.css b/src/app/globals.css index c4cb2a6..fe288c0 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -237,12 +237,12 @@ html:lang(ar) body, } } -body[data-page-background="none"] .app-shell { - background-image: none; -} - -.app-shell:has(.page-background-none) { - background-image: none; +body[data-page-background="none"] .app-shell, +.app-shell:has(.page-background-none), +body:has(.page-background-none), +html:has(.page-background-none) { + background-image: none !important; + background-color: #F7F1F0 !important; } body[data-page-background="custom"] .app-shell { diff --git a/src/app/layout.tsx b/src/app/layout.tsx index d90d076..97a842a 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -62,6 +62,7 @@ export const viewport: Viewport = { userScalable: false, viewportFit: "cover", themeColor: "#ffffff", + interactiveWidget: "overlays-content", }; export default async function RootLayout({ diff --git a/src/app/new-match/new-match-client.tsx b/src/app/new-match/new-match-client.tsx index ae1c0d7..6b717f7 100644 --- a/src/app/new-match/new-match-client.tsx +++ b/src/app/new-match/new-match-client.tsx @@ -20,6 +20,7 @@ import AdvisorActionsCard from "@/components/Componentes/advisor-actions-card"; import MarriageAdvisorsOverlay, { useMarriageAdvisorsOverlay, } from "@/components/Componentes/marriage-advisors-overlay"; +import ErrorToast from "@/components/Componentes/error-toast"; import MatchProfileOverlay, { useMatchProfileOverlay, } from "@/components/Componentes/match-profile-overlay"; @@ -118,6 +119,7 @@ const fieldCandidateMatchers = { "career", ], hobbies: [ + "what_are_your_main_hobbies_and_interests", "your_hobbies_and_main_interests", "hobbies_and_interests", "hobbies", @@ -502,6 +504,8 @@ export default function NewMatchClient() { const [paymentError, setPaymentError] = useState(null); const [isInsufficientCoins, setIsInsufficientCoins] = useState(false); + const [showPaymentSuccessToast, setShowPaymentSuccessToast] = useState(false); + const [appliedDiscount, setAppliedDiscount] = useState(null); @@ -539,6 +543,7 @@ export default function NewMatchClient() { discountCode: appliedDiscount?.valid ? appliedDiscount.code : undefined, }); setIsPaymentSheetOpen(false); + setShowPaymentSuccessToast(true); openProfile(); } catch (err: any) { console.error("Payment failed", err); @@ -629,12 +634,14 @@ export default function NewMatchClient() { <>
-
+
@@ -716,12 +723,14 @@ export default function NewMatchClient() {
-
+
@@ -1166,6 +1175,14 @@ export default function NewMatchClient() { + + {showPaymentSuccessToast && ( + setShowPaymentSuccessToast(false)} + /> + )} ); } diff --git a/src/app/questions-list/[slug]/question-detail-client.tsx b/src/app/questions-list/[slug]/question-detail-client.tsx index bb3bb15..0283ecd 100644 --- a/src/app/questions-list/[slug]/question-detail-client.tsx +++ b/src/app/questions-list/[slug]/question-detail-client.tsx @@ -270,12 +270,16 @@ export default function QuestionDetailClient({ const profileId = useCurrentProfileId(); const handleExit = useCallback(() => { + void queryClient.invalidateQueries({ + queryKey: [...marriageQueryKeys.all, "form-overview"], + exact: false, + }); if (onClose) { onClose(); return; } router.replace(questionsListHref); - }, [onClose, questionsListHref, router]); + }, [onClose, questionsListHref, router, queryClient]); // Hardware back in the detail page = navigate back to questions list. // QuestionAnswersProvider's pagehide/unmount safety net will flush diff --git a/src/app/questions-list/questions-list-client.tsx b/src/app/questions-list/questions-list-client.tsx index d8e08c2..cdeca38 100644 --- a/src/app/questions-list/questions-list-client.tsx +++ b/src/app/questions-list/questions-list-client.tsx @@ -18,8 +18,8 @@ import QuestionCard from "@/components/Componentes/question-card"; import RequiredStepsCard from "@/components/Componentes/required-steps-card"; import type { MarriageField } from "@/hooks/marriage/types"; import { marriageQueryKeys } from "@/hooks/marriage/query-keys"; -import { getCattellQuestions } from "@/hooks/marriage/use-cattell"; -import { getGlasserQuestions } from "@/hooks/marriage/use-glasser"; +import { getCattellQuestions, useCattellResultQuery } from "@/hooks/marriage/use-cattell"; +import { getGlasserQuestions, useGlasserResultQuery } from "@/hooks/marriage/use-glasser"; import { getFormSection, useFormOverviewQuery, @@ -97,6 +97,14 @@ export default function QuestionsListClient() { "profile", locale, ); + const { data: glasserResult } = useGlasserResultQuery(locale, { + enabled: Boolean(profile?.id), + retry: false, + }); + const { data: cattellResult } = useCattellResultQuery(locale, { + enabled: Boolean(profile?.id), + retry: false, + }); const isSectionsLoading = false; @@ -205,11 +213,46 @@ export default function QuestionsListClient() { const profileId = profile?.id; for (const slug of ["personality_test", "glasser_5_needs_test"]) { try { + // 1. Check backend test results + if ( + (slug === "glasser_5_needs_test" && Boolean(glasserResult)) || + (slug === "personality_test" && Boolean(cattellResult)) + ) { + next.set(slug, 100); + continue; + } + + // 2. Check local completion flag + if (typeof window !== "undefined") { + const completionKeys = [ + profileId ? `marriage:user:${profileId}:sections:${slug}:completed` : null, + `marriage:sections:${slug}:completed`, + `marriage:sections:${slug}:answers`, + ].filter(Boolean) as string[]; + + let isLocalCompleted = false; + for (const key of completionKeys) { + const raw = window.localStorage.getItem(key); + if (raw) { + try { + const parsed = JSON.parse(raw); + if (parsed?.completed === true) { + next.set(slug, 100); + isLocalCompleted = true; + break; + } + } catch {} + } + } + if (isLocalCompleted) continue; + } + + // 3. If not completed, read draft progress let draft: any = null; if (profileId) { draft = readScopedAssessmentDraft(profileId, slug); } - if (!draft) { + if (!draft && typeof window !== "undefined") { const raw = window.localStorage.getItem(`marriage:tests:${slug}:draft`); draft = raw ? JSON.parse(raw) : null; } @@ -220,7 +263,7 @@ export default function QuestionsListClient() { } } setLocalAssessmentProgress(next); - }, [overview, profile?.id]); + }, [overview, profile?.id, glasserResult, cattellResult]); const sectionProgressBySlug = useMemo(() => { const progressBySlug = new Map(); @@ -236,8 +279,7 @@ export default function QuestionsListClient() { ); } localAssessmentProgress.forEach((progress, slug) => { - if ((progressBySlug.get(slug) ?? 0) < 100) - progressBySlug.set(slug, progress); + progressBySlug.set(slug, progress); }); // Add fallback for combined section from the schema adapter which attaches it to questionListItems directly diff --git a/src/app/request-accepted/request-accepted-client.tsx b/src/app/request-accepted/request-accepted-client.tsx index de9e659..02ddae0 100644 --- a/src/app/request-accepted/request-accepted-client.tsx +++ b/src/app/request-accepted/request-accepted-client.tsx @@ -9,6 +9,7 @@ import AdvisorActionsCard from "@/components/Componentes/advisor-actions-card"; import MarriageAdvisorsOverlay, { useMarriageAdvisorsOverlay, } from "@/components/Componentes/marriage-advisors-overlay"; +import ErrorToast from "@/components/Componentes/error-toast"; import MatchProfileOverlay, { useMatchProfileOverlay, } from "@/components/Componentes/match-profile-overlay"; @@ -199,6 +200,7 @@ export default function RequestAcceptedClient() { useState(false); const [hasConfirmedFemaleContact, setHasConfirmedFemaleContact] = useState(false); + const [showPaymentSuccessToast, setShowPaymentSuccessToast] = useState(false); const profileHref = localizePath("/new-match/profile", locale); const { data: profile, isLoading } = useMarriageProfileQuery({ refetchInterval: 3000, @@ -260,6 +262,7 @@ export default function RequestAcceptedClient() { : caseStatus === "payment_done" || caseStatus === "contacted" ? t["Contact info released"] : t["Request approved!"]; + const primaryActionText = isFemaleProfile ? t["No Contact"] || t["No Contact Received"] || "No Contact" : t["View profile"]; @@ -272,6 +275,14 @@ export default function RequestAcceptedClient() { contactInfoQuery.data?.contact_info, ); + const handlePrimaryAction = () => { + if (isFemaleProfile) { + setIsDismissReasonSheetOpen(true); + } else { + openProfile(); + } + }; + const handleSecondaryAction = async () => { if (isFemaleProfile) { setIsContactReceivedConfirmOpen(true); @@ -314,6 +325,7 @@ export default function RequestAcceptedClient() { } setIsSubscriptionSheetOpen(false); + setShowPaymentSuccessToast(true); if (caseId) { await contactInfoQuery.refetch(); @@ -773,6 +785,14 @@ export default function RequestAcceptedClient() { open={isProfileOpen} onClose={closeProfile} /> + + {showPaymentSuccessToast && ( + setShowPaymentSuccessToast(false)} + /> + )} ); } diff --git a/src/components/Componentes/currency-sheet.tsx b/src/components/Componentes/currency-sheet.tsx index 22d00ad..766d83f 100644 --- a/src/components/Componentes/currency-sheet.tsx +++ b/src/components/Componentes/currency-sheet.tsx @@ -148,8 +148,8 @@ export function CurrencySheet({ ].join(" ")} > {/* Header */} -
-

+
+

{sheetTitle}